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_AUTO,
98	ALC262_MODEL_LAST /* last tag */
99};
100
101/* ALC861 models */
102enum {
103	ALC861_3ST,
104	ALC660_3ST,
105	ALC861_3ST_DIG,
106	ALC861_6ST_DIG,
107	ALC861_UNIWILL_M31,
108	ALC861_TOSHIBA,
109	ALC861_ASUS,
110	ALC861_ASUS_LAPTOP,
111	ALC861_AUTO,
112	ALC861_MODEL_LAST,
113};
114
115/* ALC861-VD models */
116enum {
117	ALC660VD_3ST,
118	ALC861VD_3ST,
119	ALC861VD_3ST_DIG,
120	ALC861VD_6ST_DIG,
121	ALC861VD_LENOVO,
122	ALC861VD_DALLAS,
123	ALC861VD_AUTO,
124	ALC861VD_MODEL_LAST,
125};
126
127/* ALC662 models */
128enum {
129	ALC662_3ST_2ch_DIG,
130	ALC662_3ST_6ch_DIG,
131	ALC662_3ST_6ch,
132	ALC662_5ST_DIG,
133	ALC662_LENOVO_101E,
134	ALC662_AUTO,
135	ALC662_MODEL_LAST,
136};
137
138/* ALC882 models */
139enum {
140	ALC882_3ST_DIG,
141	ALC882_6ST_DIG,
142	ALC882_ARIMA,
143	ALC882_W2JC,
144	ALC882_TARGA,
145	ALC882_ASUS_A7J,
146	ALC885_MACPRO,
147	ALC882_AUTO,
148	ALC882_MODEL_LAST,
149};
150
151/* ALC883 models */
152enum {
153	ALC883_3ST_2ch_DIG,
154	ALC883_3ST_6ch_DIG,
155	ALC883_3ST_6ch,
156	ALC883_6ST_DIG,
157	ALC883_TARGA_DIG,
158	ALC883_TARGA_2ch_DIG,
159	ALC883_ACER,
160	ALC883_MEDION,
161	ALC883_MEDION_MD2,
162	ALC883_LAPTOP_EAPD,
163	ALC883_LENOVO_101E_2ch,
164	ALC883_LENOVO_NB0763,
165	ALC888_LENOVO_MS7195_DIG,
166	ALC883_AUTO,
167	ALC883_MODEL_LAST,
168};
169
170/* for GPIO Poll */
171#define GPIO_MASK	0x03
172
173struct alc_spec {
174	/* codec parameterization */
175	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
176	unsigned int num_mixers;
177
178	const struct hda_verb *init_verbs[5];	/* initialization verbs
179						 * don't forget NULL
180						 * termination!
181						 */
182	unsigned int num_init_verbs;
183
184	char *stream_name_analog;	/* analog PCM stream */
185	struct hda_pcm_stream *stream_analog_playback;
186	struct hda_pcm_stream *stream_analog_capture;
187
188	char *stream_name_digital;	/* digital PCM stream */
189	struct hda_pcm_stream *stream_digital_playback;
190	struct hda_pcm_stream *stream_digital_capture;
191
192	/* playback */
193	struct hda_multi_out multiout;	/* playback set-up
194					 * max_channels, dacs must be set
195					 * dig_out_nid and hp_nid are optional
196					 */
197
198	/* capture */
199	unsigned int num_adc_nids;
200	hda_nid_t *adc_nids;
201	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
202
203	/* capture source */
204	unsigned int num_mux_defs;
205	const struct hda_input_mux *input_mux;
206	unsigned int cur_mux[3];
207
208	/* channel model */
209	const struct hda_channel_mode *channel_mode;
210	int num_channel_mode;
211	int need_dac_fix;
212
213	/* PCM information */
214	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
215
216	/* dynamic controls, init_verbs and input_mux */
217	struct auto_pin_cfg autocfg;
218	unsigned int num_kctl_alloc, num_kctl_used;
219	struct snd_kcontrol_new *kctl_alloc;
220	struct hda_input_mux private_imux;
221	hda_nid_t private_dac_nids[5];
222
223	/* hooks */
224	void (*init_hook)(struct hda_codec *codec);
225	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
226
227	/* for pin sensing */
228	unsigned int sense_updated: 1;
229	unsigned int jack_present: 1;
230};
231
232/*
233 * configuration template - to be copied to the spec instance
234 */
235struct alc_config_preset {
236	struct snd_kcontrol_new *mixers[5]; /* should be identical size
237					     * with spec
238					     */
239	const struct hda_verb *init_verbs[5];
240	unsigned int num_dacs;
241	hda_nid_t *dac_nids;
242	hda_nid_t dig_out_nid;		/* optional */
243	hda_nid_t hp_nid;		/* optional */
244	unsigned int num_adc_nids;
245	hda_nid_t *adc_nids;
246	hda_nid_t dig_in_nid;
247	unsigned int num_channel_mode;
248	const struct hda_channel_mode *channel_mode;
249	int need_dac_fix;
250	unsigned int num_mux_defs;
251	const struct hda_input_mux *input_mux;
252	void (*unsol_event)(struct hda_codec *, unsigned int);
253	void (*init_hook)(struct hda_codec *);
254};
255
256
257/*
258 * input MUX handling
259 */
260static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
261			     struct snd_ctl_elem_info *uinfo)
262{
263	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
264	struct alc_spec *spec = codec->spec;
265	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
266	if (mux_idx >= spec->num_mux_defs)
267		mux_idx = 0;
268	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
269}
270
271static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
272			    struct snd_ctl_elem_value *ucontrol)
273{
274	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
275	struct alc_spec *spec = codec->spec;
276	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
277
278	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
279	return 0;
280}
281
282static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
283			    struct snd_ctl_elem_value *ucontrol)
284{
285	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
286	struct alc_spec *spec = codec->spec;
287	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
288	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
289	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
290				     spec->adc_nids[adc_idx],
291				     &spec->cur_mux[adc_idx]);
292}
293
294
295/*
296 * channel mode setting
297 */
298static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
299			    struct snd_ctl_elem_info *uinfo)
300{
301	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
302	struct alc_spec *spec = codec->spec;
303	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
304				    spec->num_channel_mode);
305}
306
307static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
308			   struct snd_ctl_elem_value *ucontrol)
309{
310	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
311	struct alc_spec *spec = codec->spec;
312	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
313				   spec->num_channel_mode,
314				   spec->multiout.max_channels);
315}
316
317static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
318			   struct snd_ctl_elem_value *ucontrol)
319{
320	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
321	struct alc_spec *spec = codec->spec;
322	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
323				      spec->num_channel_mode,
324				      &spec->multiout.max_channels);
325	if (err >= 0 && spec->need_dac_fix)
326		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
327	return err;
328}
329
330/*
331 * Control the mode of pin widget settings via the mixer.  "pc" is used
332 * instead of "%" to avoid consequences of accidently treating the % as
333 * being part of a format specifier.  Maximum allowed length of a value is
334 * 63 characters plus NULL terminator.
335 *
336 * Note: some retasking pin complexes seem to ignore requests for input
337 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
338 * are requested.  Therefore order this list so that this behaviour will not
339 * cause problems when mixer clients move through the enum sequentially.
340 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
341 * March 2006.
342 */
343static char *alc_pin_mode_names[] = {
344	"Mic 50pc bias", "Mic 80pc bias",
345	"Line in", "Line out", "Headphone out",
346};
347static unsigned char alc_pin_mode_values[] = {
348	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
349};
350/* The control can present all 5 options, or it can limit the options based
351 * in the pin being assumed to be exclusively an input or an output pin.  In
352 * addition, "input" pins may or may not process the mic bias option
353 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
354 * accept requests for bias as of chip versions up to March 2006) and/or
355 * wiring in the computer.
356 */
357#define ALC_PIN_DIR_IN              0x00
358#define ALC_PIN_DIR_OUT             0x01
359#define ALC_PIN_DIR_INOUT           0x02
360#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
361#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
362
363/* Info about the pin modes supported by the different pin direction modes.
364 * For each direction the minimum and maximum values are given.
365 */
366static signed char alc_pin_mode_dir_info[5][2] = {
367	{ 0, 2 },    /* ALC_PIN_DIR_IN */
368	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
369	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
370	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
371	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
372};
373#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
374#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
375#define alc_pin_mode_n_items(_dir) \
376	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
377
378static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
379			     struct snd_ctl_elem_info *uinfo)
380{
381	unsigned int item_num = uinfo->value.enumerated.item;
382	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
383
384	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
385	uinfo->count = 1;
386	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
387
388	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
389		item_num = alc_pin_mode_min(dir);
390	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
391	return 0;
392}
393
394static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
395			    struct snd_ctl_elem_value *ucontrol)
396{
397	unsigned int i;
398	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399	hda_nid_t nid = kcontrol->private_value & 0xffff;
400	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
401	long *valp = ucontrol->value.integer.value;
402	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
403						 AC_VERB_GET_PIN_WIDGET_CONTROL,
404						 0x00);
405
406	/* Find enumerated value for current pinctl setting */
407	i = alc_pin_mode_min(dir);
408	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
409		i++;
410	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
411	return 0;
412}
413
414static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
415			    struct snd_ctl_elem_value *ucontrol)
416{
417	signed int change;
418	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
419	hda_nid_t nid = kcontrol->private_value & 0xffff;
420	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
421	long val = *ucontrol->value.integer.value;
422	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
423						 AC_VERB_GET_PIN_WIDGET_CONTROL,
424						 0x00);
425
426	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
427		val = alc_pin_mode_min(dir);
428
429	change = pinctl != alc_pin_mode_values[val];
430	if (change) {
431		/* Set pin mode to that requested */
432		snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
433				    alc_pin_mode_values[val]);
434
435		/* Also enable the retasking pin's input/output as required
436		 * for the requested pin mode.  Enum values of 2 or less are
437		 * input modes.
438		 *
439		 * Dynamically switching the input/output buffers probably
440		 * reduces noise slightly (particularly on input) so we'll
441		 * do it.  However, having both input and output buffers
442		 * enabled simultaneously doesn't seem to be problematic if
443		 * this turns out to be necessary in the future.
444		 */
445		if (val <= 2) {
446			snd_hda_codec_write(codec, nid, 0,
447					    AC_VERB_SET_AMP_GAIN_MUTE,
448					    AMP_OUT_MUTE);
449			snd_hda_codec_write(codec, nid, 0,
450					    AC_VERB_SET_AMP_GAIN_MUTE,
451					    AMP_IN_UNMUTE(0));
452		} else {
453			snd_hda_codec_write(codec, nid, 0,
454					    AC_VERB_SET_AMP_GAIN_MUTE,
455					    AMP_IN_MUTE(0));
456			snd_hda_codec_write(codec, nid, 0,
457					    AC_VERB_SET_AMP_GAIN_MUTE,
458					    AMP_OUT_UNMUTE);
459		}
460	}
461	return change;
462}
463
464#define ALC_PIN_MODE(xname, nid, dir) \
465	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
466	  .info = alc_pin_mode_info, \
467	  .get = alc_pin_mode_get, \
468	  .put = alc_pin_mode_put, \
469	  .private_value = nid | (dir<<16) }
470
471/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
472 * together using a mask with more than one bit set.  This control is
473 * currently used only by the ALC260 test model.  At this stage they are not
474 * needed for any "production" models.
475 */
476#ifdef CONFIG_SND_DEBUG
477static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
478			      struct snd_ctl_elem_info *uinfo)
479{
480	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
481	uinfo->count = 1;
482	uinfo->value.integer.min = 0;
483	uinfo->value.integer.max = 1;
484	return 0;
485}
486
487static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
488			     struct snd_ctl_elem_value *ucontrol)
489{
490	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
491	hda_nid_t nid = kcontrol->private_value & 0xffff;
492	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
493	long *valp = ucontrol->value.integer.value;
494	unsigned int val = snd_hda_codec_read(codec, nid, 0,
495					      AC_VERB_GET_GPIO_DATA, 0x00);
496
497	*valp = (val & mask) != 0;
498	return 0;
499}
500static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
501			     struct snd_ctl_elem_value *ucontrol)
502{
503	signed int change;
504	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
505	hda_nid_t nid = kcontrol->private_value & 0xffff;
506	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
507	long val = *ucontrol->value.integer.value;
508	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
509						    AC_VERB_GET_GPIO_DATA,
510						    0x00);
511
512	/* Set/unset the masked GPIO bit(s) as needed */
513	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
514	if (val == 0)
515		gpio_data &= ~mask;
516	else
517		gpio_data |= mask;
518	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
519
520	return change;
521}
522#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
523	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
524	  .info = alc_gpio_data_info, \
525	  .get = alc_gpio_data_get, \
526	  .put = alc_gpio_data_put, \
527	  .private_value = nid | (mask<<16) }
528#endif   /* CONFIG_SND_DEBUG */
529
530/* A switch control to allow the enabling of the digital IO pins on the
531 * ALC260.  This is incredibly simplistic; the intention of this control is
532 * to provide something in the test model allowing digital outputs to be
533 * identified if present.  If models are found which can utilise these
534 * outputs a more complete mixer control can be devised for those models if
535 * necessary.
536 */
537#ifdef CONFIG_SND_DEBUG
538static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
539			       struct snd_ctl_elem_info *uinfo)
540{
541	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
542	uinfo->count = 1;
543	uinfo->value.integer.min = 0;
544	uinfo->value.integer.max = 1;
545	return 0;
546}
547
548static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
549			      struct snd_ctl_elem_value *ucontrol)
550{
551	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
552	hda_nid_t nid = kcontrol->private_value & 0xffff;
553	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
554	long *valp = ucontrol->value.integer.value;
555	unsigned int val = snd_hda_codec_read(codec, nid, 0,
556					      AC_VERB_GET_DIGI_CONVERT, 0x00);
557
558	*valp = (val & mask) != 0;
559	return 0;
560}
561static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
562			      struct snd_ctl_elem_value *ucontrol)
563{
564	signed int change;
565	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566	hda_nid_t nid = kcontrol->private_value & 0xffff;
567	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
568	long val = *ucontrol->value.integer.value;
569	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
570						    AC_VERB_GET_DIGI_CONVERT,
571						    0x00);
572
573	/* Set/unset the masked control bit(s) as needed */
574	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
575	if (val==0)
576		ctrl_data &= ~mask;
577	else
578		ctrl_data |= mask;
579	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
580			    ctrl_data);
581
582	return change;
583}
584#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
585	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
586	  .info = alc_spdif_ctrl_info, \
587	  .get = alc_spdif_ctrl_get, \
588	  .put = alc_spdif_ctrl_put, \
589	  .private_value = nid | (mask<<16) }
590#endif   /* CONFIG_SND_DEBUG */
591
592/*
593 * set up from the preset table
594 */
595static void setup_preset(struct alc_spec *spec,
596			 const struct alc_config_preset *preset)
597{
598	int i;
599
600	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
601		spec->mixers[spec->num_mixers++] = preset->mixers[i];
602	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
603	     i++)
604		spec->init_verbs[spec->num_init_verbs++] =
605			preset->init_verbs[i];
606
607	spec->channel_mode = preset->channel_mode;
608	spec->num_channel_mode = preset->num_channel_mode;
609	spec->need_dac_fix = preset->need_dac_fix;
610
611	spec->multiout.max_channels = spec->channel_mode[0].channels;
612
613	spec->multiout.num_dacs = preset->num_dacs;
614	spec->multiout.dac_nids = preset->dac_nids;
615	spec->multiout.dig_out_nid = preset->dig_out_nid;
616	spec->multiout.hp_nid = preset->hp_nid;
617
618	spec->num_mux_defs = preset->num_mux_defs;
619	if (!spec->num_mux_defs)
620		spec->num_mux_defs = 1;
621	spec->input_mux = preset->input_mux;
622
623	spec->num_adc_nids = preset->num_adc_nids;
624	spec->adc_nids = preset->adc_nids;
625	spec->dig_in_nid = preset->dig_in_nid;
626
627	spec->unsol_event = preset->unsol_event;
628	spec->init_hook = preset->init_hook;
629}
630
631/* Enable GPIO mask and set output */
632static struct hda_verb alc_gpio1_init_verbs[] = {
633	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
634	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
635	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
636	{ }
637};
638
639static struct hda_verb alc_gpio2_init_verbs[] = {
640	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
641	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
642	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
643	{ }
644};
645
646static struct hda_verb alc_gpio3_init_verbs[] = {
647	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
648	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
649	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
650	{ }
651};
652
653/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
654 *	31 ~ 16 :	Manufacture ID
655 *	15 ~ 8	:	SKU ID
656 *	7  ~ 0	:	Assembly ID
657 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
658 */
659static void alc_subsystem_id(struct hda_codec *codec,
660			     unsigned int porta, unsigned int porte,
661			     unsigned int portd)
662{
663	unsigned int ass, tmp;
664
665	ass = codec->subsystem_id;
666	if (!(ass & 1))
667		return;
668
669	/* Override */
670	tmp = (ass & 0x38) >> 3;	/* external Amp control */
671	switch (tmp) {
672	case 1:
673		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
674		break;
675	case 3:
676		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
677		break;
678	case 7:
679		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
680		break;
681	case 5:
682		switch (codec->vendor_id) {
683		case 0x10ec0862:
684		case 0x10ec0660:
685		case 0x10ec0662:
686		case 0x10ec0267:
687		case 0x10ec0268:
688			snd_hda_codec_write(codec, 0x14, 0,
689					    AC_VERB_SET_EAPD_BTLENABLE, 2);
690			snd_hda_codec_write(codec, 0x15, 0,
691					    AC_VERB_SET_EAPD_BTLENABLE, 2);
692			return;
693		}
694	case 6:
695		if (ass & 4) {	/* bit 2 : 0 = Desktop, 1 = Laptop */
696			hda_nid_t port = 0;
697			tmp = (ass & 0x1800) >> 11;
698			switch (tmp) {
699			case 0: port = porta; break;
700			case 1: port = porte; break;
701			case 2: port = portd; break;
702			}
703			if (port)
704				snd_hda_codec_write(codec, port, 0,
705						    AC_VERB_SET_EAPD_BTLENABLE,
706						    2);
707		}
708		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
709		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
710				    (tmp == 5 ? 0x3040 : 0x3050));
711		break;
712	}
713}
714
715/*
716 * ALC880 3-stack model
717 *
718 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
719 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
720 *                 F-Mic = 0x1b, HP = 0x19
721 */
722
723static hda_nid_t alc880_dac_nids[4] = {
724	/* front, rear, clfe, rear_surr */
725	0x02, 0x05, 0x04, 0x03
726};
727
728static hda_nid_t alc880_adc_nids[3] = {
729	/* ADC0-2 */
730	0x07, 0x08, 0x09,
731};
732
733/* The datasheet says the node 0x07 is connected from inputs,
734 * but it shows zero connection in the real implementation on some devices.
735 * Note: this is a 915GAV bug, fixed on 915GLV
736 */
737static hda_nid_t alc880_adc_nids_alt[2] = {
738	/* ADC1-2 */
739	0x08, 0x09,
740};
741
742#define ALC880_DIGOUT_NID	0x06
743#define ALC880_DIGIN_NID	0x0a
744
745static struct hda_input_mux alc880_capture_source = {
746	.num_items = 4,
747	.items = {
748		{ "Mic", 0x0 },
749		{ "Front Mic", 0x3 },
750		{ "Line", 0x2 },
751		{ "CD", 0x4 },
752	},
753};
754
755/* channel source setting (2/6 channel selection for 3-stack) */
756/* 2ch mode */
757static struct hda_verb alc880_threestack_ch2_init[] = {
758	/* set line-in to input, mute it */
759	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
760	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
761	/* set mic-in to input vref 80%, mute it */
762	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
763	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
764	{ } /* end */
765};
766
767/* 6ch mode */
768static struct hda_verb alc880_threestack_ch6_init[] = {
769	/* set line-in to output, unmute it */
770	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
771	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
772	/* set mic-in to output, unmute it */
773	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
774	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
775	{ } /* end */
776};
777
778static struct hda_channel_mode alc880_threestack_modes[2] = {
779	{ 2, alc880_threestack_ch2_init },
780	{ 6, alc880_threestack_ch6_init },
781};
782
783static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
784	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
785	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
786	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
787	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
788	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
789	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
790	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
791	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
792	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
793	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
794	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
795	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
796	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
797	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
798	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
799	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
800	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
801	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
802	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
803	{
804		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
805		.name = "Channel Mode",
806		.info = alc_ch_mode_info,
807		.get = alc_ch_mode_get,
808		.put = alc_ch_mode_put,
809	},
810	{ } /* end */
811};
812
813/* capture mixer elements */
814static struct snd_kcontrol_new alc880_capture_mixer[] = {
815	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
816	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
817	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
818	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
819	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
820	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
821	{
822		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
823		/* .name = "Capture Source", */
824		.name = "Input Source",
825		.count = 3,
826		.info = alc_mux_enum_info,
827		.get = alc_mux_enum_get,
828		.put = alc_mux_enum_put,
829	},
830	{ } /* end */
831};
832
833/* capture mixer elements (in case NID 0x07 not available) */
834static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
835	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
836	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
837	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
838	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
839	{
840		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
841		/* .name = "Capture Source", */
842		.name = "Input Source",
843		.count = 2,
844		.info = alc_mux_enum_info,
845		.get = alc_mux_enum_get,
846		.put = alc_mux_enum_put,
847	},
848	{ } /* end */
849};
850
851
852
853/*
854 * ALC880 5-stack model
855 *
856 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
857 *      Side = 0x02 (0xd)
858 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
859 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
860 */
861
862/* additional mixers to alc880_three_stack_mixer */
863static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
864	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
865	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
866	{ } /* end */
867};
868
869/* channel source setting (6/8 channel selection for 5-stack) */
870/* 6ch mode */
871static struct hda_verb alc880_fivestack_ch6_init[] = {
872	/* set line-in to input, mute it */
873	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
874	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
875	{ } /* end */
876};
877
878/* 8ch mode */
879static struct hda_verb alc880_fivestack_ch8_init[] = {
880	/* set line-in to output, unmute it */
881	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
882	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
883	{ } /* end */
884};
885
886static struct hda_channel_mode alc880_fivestack_modes[2] = {
887	{ 6, alc880_fivestack_ch6_init },
888	{ 8, alc880_fivestack_ch8_init },
889};
890
891
892/*
893 * ALC880 6-stack model
894 *
895 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
896 *      Side = 0x05 (0x0f)
897 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
898 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
899 */
900
901static hda_nid_t alc880_6st_dac_nids[4] = {
902	/* front, rear, clfe, rear_surr */
903	0x02, 0x03, 0x04, 0x05
904};
905
906static struct hda_input_mux alc880_6stack_capture_source = {
907	.num_items = 4,
908	.items = {
909		{ "Mic", 0x0 },
910		{ "Front Mic", 0x1 },
911		{ "Line", 0x2 },
912		{ "CD", 0x4 },
913	},
914};
915
916/* fixed 8-channels */
917static struct hda_channel_mode alc880_sixstack_modes[1] = {
918	{ 8, NULL },
919};
920
921static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
922	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
923	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
924	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
925	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
926	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
927	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
928	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
929	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
930	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
931	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
932	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
933	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
934	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
935	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
936	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
937	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
938	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
939	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
940	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
941	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
942	{
943		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
944		.name = "Channel Mode",
945		.info = alc_ch_mode_info,
946		.get = alc_ch_mode_get,
947		.put = alc_ch_mode_put,
948	},
949	{ } /* end */
950};
951
952
953/*
954 * ALC880 W810 model
955 *
956 * W810 has rear IO for:
957 * Front (DAC 02)
958 * Surround (DAC 03)
959 * Center/LFE (DAC 04)
960 * Digital out (06)
961 *
962 * The system also has a pair of internal speakers, and a headphone jack.
963 * These are both connected to Line2 on the codec, hence to DAC 02.
964 *
965 * There is a variable resistor to control the speaker or headphone
966 * volume. This is a hardware-only device without a software API.
967 *
968 * Plugging headphones in will disable the internal speakers. This is
969 * implemented in hardware, not via the driver using jack sense. In
970 * a similar fashion, plugging into the rear socket marked "front" will
971 * disable both the speakers and headphones.
972 *
973 * For input, there's a microphone jack, and an "audio in" jack.
974 * These may not do anything useful with this driver yet, because I
975 * haven't setup any initialization verbs for these yet...
976 */
977
978static hda_nid_t alc880_w810_dac_nids[3] = {
979	/* front, rear/surround, clfe */
980	0x02, 0x03, 0x04
981};
982
983/* fixed 6 channels */
984static struct hda_channel_mode alc880_w810_modes[1] = {
985	{ 6, NULL }
986};
987
988/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
989static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
990	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
991	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
992	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
993	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
994	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
995	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
996	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
997	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
998	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
999	{ } /* end */
1000};
1001
1002
1003/*
1004 * Z710V model
1005 *
1006 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1007 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1008 *                 Line = 0x1a
1009 */
1010
1011static hda_nid_t alc880_z71v_dac_nids[1] = {
1012	0x02
1013};
1014#define ALC880_Z71V_HP_DAC	0x03
1015
1016/* fixed 2 channels */
1017static struct hda_channel_mode alc880_2_jack_modes[1] = {
1018	{ 2, NULL }
1019};
1020
1021static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1022	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1023	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1024	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1025	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1026	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1027	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1028	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1029	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1030	{ } /* end */
1031};
1032
1033
1034/*
1035 * ALC880 F1734 model
1036 *
1037 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1038 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1039 */
1040
1041static hda_nid_t alc880_f1734_dac_nids[1] = {
1042	0x03
1043};
1044#define ALC880_F1734_HP_DAC	0x02
1045
1046static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1047	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1048	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1049	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1050	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1051	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1052	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1053	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1054	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1055	{ } /* end */
1056};
1057
1058
1059/*
1060 * ALC880 ASUS model
1061 *
1062 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1063 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1064 *  Mic = 0x18, Line = 0x1a
1065 */
1066
1067#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1068#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1069
1070static struct snd_kcontrol_new alc880_asus_mixer[] = {
1071	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1072	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1073	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1074	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1075	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1076	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1077	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1078	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1079	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1080	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1081	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1082	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1083	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1084	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1085	{
1086		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1087		.name = "Channel Mode",
1088		.info = alc_ch_mode_info,
1089		.get = alc_ch_mode_get,
1090		.put = alc_ch_mode_put,
1091	},
1092	{ } /* end */
1093};
1094
1095/*
1096 * ALC880 ASUS W1V model
1097 *
1098 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1099 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1100 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1101 */
1102
1103/* additional mixers to alc880_asus_mixer */
1104static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1105	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1106	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1107	{ } /* end */
1108};
1109
1110/* additional mixers to alc880_asus_mixer */
1111static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1112	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1113	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1114	{ } /* end */
1115};
1116
1117/* TCL S700 */
1118static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1119	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1120	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1121	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1122	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1123	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1124	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1125	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1126	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1127	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1128	{
1129		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1130		/* .name = "Capture Source", */
1131		.name = "Input Source",
1132		.count = 1,
1133		.info = alc_mux_enum_info,
1134		.get = alc_mux_enum_get,
1135		.put = alc_mux_enum_put,
1136	},
1137	{ } /* end */
1138};
1139
1140/* Uniwill */
1141static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1142	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1143	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1144	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1145	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1146	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1147	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1148	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1149	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1150	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1151	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1152	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1153	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1154	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1155	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1156	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1157	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1158	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1159	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1160	{
1161		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1162		.name = "Channel Mode",
1163		.info = alc_ch_mode_info,
1164		.get = alc_ch_mode_get,
1165		.put = alc_ch_mode_put,
1166	},
1167	{ } /* end */
1168};
1169
1170static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1171	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1172	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1173	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1174	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1175	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1176	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1177	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1178	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1179	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1180	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1181	{ } /* end */
1182};
1183
1184static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1185	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1186	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1187	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1188	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1189	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1190	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1191	{ } /* end */
1192};
1193
1194/*
1195 * build control elements
1196 */
1197static int alc_build_controls(struct hda_codec *codec)
1198{
1199	struct alc_spec *spec = codec->spec;
1200	int err;
1201	int i;
1202
1203	for (i = 0; i < spec->num_mixers; i++) {
1204		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1205		if (err < 0)
1206			return err;
1207	}
1208
1209	if (spec->multiout.dig_out_nid) {
1210		err = snd_hda_create_spdif_out_ctls(codec,
1211						    spec->multiout.dig_out_nid);
1212		if (err < 0)
1213			return err;
1214	}
1215	if (spec->dig_in_nid) {
1216		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1217		if (err < 0)
1218			return err;
1219	}
1220	return 0;
1221}
1222
1223
1224/*
1225 * initialize the codec volumes, etc
1226 */
1227
1228/*
1229 * generic initialization of ADC, input mixers and output mixers
1230 */
1231static struct hda_verb alc880_volume_init_verbs[] = {
1232	/*
1233	 * Unmute ADC0-2 and set the default input to mic-in
1234	 */
1235	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1236	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1237	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1238	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1239	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1240	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1241
1242	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1243	 * mixer widget
1244	 * Note: PASD motherboards uses the Line In 2 as the input for front
1245	 * panel mic (mic 2)
1246	 */
1247	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1248	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1249	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1250	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1251	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1252	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1253
1254	/*
1255	 * Set up output mixers (0x0c - 0x0f)
1256	 */
1257	/* set vol=0 to output mixers */
1258	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1259	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1260	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1261	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1262	/* set up input amps for analog loopback */
1263	/* Amp Indices: DAC = 0, mixer = 1 */
1264	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1265	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1266	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1267	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1268	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1269	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1270	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1271	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1272
1273	{ }
1274};
1275
1276/*
1277 * 3-stack pin configuration:
1278 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1279 */
1280static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1281	/*
1282	 * preset connection lists of input pins
1283	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1284	 */
1285	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1286	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1287	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1288
1289	/*
1290	 * Set pin mode and muting
1291	 */
1292	/* set front pin widgets 0x14 for output */
1293	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1294	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1295	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1296	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1297	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1298	/* Mic2 (as headphone out) for HP output */
1299	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1300	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1301	/* Line In pin widget for input */
1302	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1303	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1304	/* Line2 (as front mic) pin widget for input and vref at 80% */
1305	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1306	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1307	/* CD pin widget for input */
1308	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1309
1310	{ }
1311};
1312
1313/*
1314 * 5-stack pin configuration:
1315 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1316 * line-in/side = 0x1a, f-mic = 0x1b
1317 */
1318static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1319	/*
1320	 * preset connection lists of input pins
1321	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1322	 */
1323	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1324	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1325
1326	/*
1327	 * Set pin mode and muting
1328	 */
1329	/* set pin widgets 0x14-0x17 for output */
1330	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1331	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1332	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1333	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1334	/* unmute pins for output (no gain on this amp) */
1335	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1336	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1337	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1338	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1339
1340	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1341	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1342	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1343	/* Mic2 (as headphone out) for HP output */
1344	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1345	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1346	/* Line In pin widget for input */
1347	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1348	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1349	/* Line2 (as front mic) pin widget for input and vref at 80% */
1350	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1351	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1352	/* CD pin widget for input */
1353	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1354
1355	{ }
1356};
1357
1358/*
1359 * W810 pin configuration:
1360 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1361 */
1362static struct hda_verb alc880_pin_w810_init_verbs[] = {
1363	/* hphone/speaker input selector: front DAC */
1364	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1365
1366	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1367	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1368	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1369	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1370	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1371	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1372
1373	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1374	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1375
1376	{ }
1377};
1378
1379/*
1380 * Z71V pin configuration:
1381 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1382 */
1383static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1384	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1385	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1386	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1387	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1388
1389	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1390	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1391	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1392	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1393
1394	{ }
1395};
1396
1397/*
1398 * 6-stack pin configuration:
1399 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1400 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1401 */
1402static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1403	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1404
1405	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1406	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1407	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1408	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1409	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1410	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1411	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1412	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1413
1414	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1415	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1416	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1417	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1418	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1419	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1420	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1421	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1422	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1423
1424	{ }
1425};
1426
1427/*
1428 * Uniwill pin configuration:
1429 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1430 * line = 0x1a
1431 */
1432static struct hda_verb alc880_uniwill_init_verbs[] = {
1433	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1434
1435	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1436	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1437	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1438	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1439	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1440	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1441	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1442	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1443	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1444	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1445	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1446	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1447	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1448	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1449
1450	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1451	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1452	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1453	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1454	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1455	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1456	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1457	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1458	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1459
1460	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1461	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1462
1463	{ }
1464};
1465
1466/*
1467* Uniwill P53
1468* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1469 */
1470static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1471	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1472
1473	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1474	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1475	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1476	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1477	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1478	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1479	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1480	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1481	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1482	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1483	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1484	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1485
1486	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1487	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1488	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1489	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1490	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1491	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1492
1493	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1494	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1495
1496	{ }
1497};
1498
1499static struct hda_verb alc880_beep_init_verbs[] = {
1500	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1501	{ }
1502};
1503
1504/* toggle speaker-output according to the hp-jack state */
1505static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1506{
1507 	unsigned int present;
1508	unsigned char bits;
1509
1510 	present = snd_hda_codec_read(codec, 0x14, 0,
1511				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1512	bits = present ? 0x80 : 0;
1513	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1514				 0x80, bits);
1515	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1516				 0x80, bits);
1517	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1518				 0x80, bits);
1519	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1520				 0x80, bits);
1521}
1522
1523/* auto-toggle front mic */
1524static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1525{
1526 	unsigned int present;
1527	unsigned char bits;
1528
1529	present = snd_hda_codec_read(codec, 0x18, 0,
1530				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1531	bits = present ? 0x80 : 0;
1532	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
1533				 0x80, bits);
1534	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
1535				 0x80, bits);
1536}
1537
1538static void alc880_uniwill_automute(struct hda_codec *codec)
1539{
1540	alc880_uniwill_hp_automute(codec);
1541	alc880_uniwill_mic_automute(codec);
1542}
1543
1544static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1545				       unsigned int res)
1546{
1547	/* Looks like the unsol event is incompatible with the standard
1548	 * definition.  4bit tag is placed at 28 bit!
1549	 */
1550	switch (res >> 28) {
1551	case ALC880_HP_EVENT:
1552		alc880_uniwill_hp_automute(codec);
1553		break;
1554	case ALC880_MIC_EVENT:
1555		alc880_uniwill_mic_automute(codec);
1556		break;
1557	}
1558}
1559
1560static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1561{
1562 	unsigned int present;
1563	unsigned char bits;
1564
1565 	present = snd_hda_codec_read(codec, 0x14, 0,
1566				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1567	bits = present ? 0x80 : 0;
1568	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1569				 0x80, bits);
1570	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1571				 0x80, bits);
1572}
1573
1574static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1575{
1576	unsigned int present;
1577
1578	present = snd_hda_codec_read(codec, 0x21, 0,
1579				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1580
1581	snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1582				 0x7f, present);
1583	snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1584				 0x7f,  present);
1585
1586	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1587				 0x7f,  present);
1588	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1589				 0x7f, present);
1590
1591}
1592static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1593					   unsigned int res)
1594{
1595	/* Looks like the unsol event is incompatible with the standard
1596	 * definition.  4bit tag is placed at 28 bit!
1597	 */
1598	if ((res >> 28) == ALC880_HP_EVENT)
1599		alc880_uniwill_p53_hp_automute(codec);
1600	if ((res >> 28) == ALC880_DCVOL_EVENT)
1601		alc880_uniwill_p53_dcvol_automute(codec);
1602}
1603
1604/*
1605 * F1734 pin configuration:
1606 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1607 */
1608static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1609	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1610	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1611	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1612	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1613
1614	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1615	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1616	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1617	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1618
1619	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1620	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1621	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1622	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1623	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1624	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1625	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1626	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1627	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1628
1629	{ }
1630};
1631
1632/*
1633 * ASUS pin configuration:
1634 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1635 */
1636static struct hda_verb alc880_pin_asus_init_verbs[] = {
1637	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1638	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1639	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1640	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1641
1642	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1643	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1644	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1645	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1646	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1647	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1648	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1649	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1650
1651	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1652	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1653	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1654	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1655	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1656	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1657	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1658	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1659	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1660
1661	{ }
1662};
1663
1664/* Enable GPIO mask and set output */
1665#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1666#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1667
1668/* Clevo m520g init */
1669static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1670	/* headphone output */
1671	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1672	/* line-out */
1673	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1674	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1675	/* Line-in */
1676	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1677	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1678	/* CD */
1679	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1680	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1681	/* Mic1 (rear panel) */
1682	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1683	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1684	/* Mic2 (front panel) */
1685	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1686	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1687	/* headphone */
1688	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1689	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690        /* change to EAPD mode */
1691	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1692	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1693
1694	{ }
1695};
1696
1697static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1698	/* change to EAPD mode */
1699	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1700	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1701
1702	/* Headphone output */
1703	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1704	/* Front output*/
1705	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1706	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1707
1708	/* Line In pin widget for input */
1709	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1710	/* CD pin widget for input */
1711	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1712	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1713	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1714
1715	/* change to EAPD mode */
1716	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1717	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1718
1719	{ }
1720};
1721
1722/*
1723 * LG m1 express dual
1724 *
1725 * Pin assignment:
1726 *   Rear Line-In/Out (blue): 0x14
1727 *   Build-in Mic-In: 0x15
1728 *   Speaker-out: 0x17
1729 *   HP-Out (green): 0x1b
1730 *   Mic-In/Out (red): 0x19
1731 *   SPDIF-Out: 0x1e
1732 */
1733
1734/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1735static hda_nid_t alc880_lg_dac_nids[3] = {
1736	0x05, 0x02, 0x03
1737};
1738
1739/* seems analog CD is not working */
1740static struct hda_input_mux alc880_lg_capture_source = {
1741	.num_items = 3,
1742	.items = {
1743		{ "Mic", 0x1 },
1744		{ "Line", 0x5 },
1745		{ "Internal Mic", 0x6 },
1746	},
1747};
1748
1749/* 2,4,6 channel modes */
1750static struct hda_verb alc880_lg_ch2_init[] = {
1751	/* set line-in and mic-in to input */
1752	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1753	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1754	{ }
1755};
1756
1757static struct hda_verb alc880_lg_ch4_init[] = {
1758	/* set line-in to out and mic-in to input */
1759	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1760	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1761	{ }
1762};
1763
1764static struct hda_verb alc880_lg_ch6_init[] = {
1765	/* set line-in and mic-in to output */
1766	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1767	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1768	{ }
1769};
1770
1771static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1772	{ 2, alc880_lg_ch2_init },
1773	{ 4, alc880_lg_ch4_init },
1774	{ 6, alc880_lg_ch6_init },
1775};
1776
1777static struct snd_kcontrol_new alc880_lg_mixer[] = {
1778	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1779	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1780	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1781	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1782	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1783	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1784	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1785	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1786	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1787	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1788	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1789	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1790	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1791	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1792	{
1793		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1794		.name = "Channel Mode",
1795		.info = alc_ch_mode_info,
1796		.get = alc_ch_mode_get,
1797		.put = alc_ch_mode_put,
1798	},
1799	{ } /* end */
1800};
1801
1802static struct hda_verb alc880_lg_init_verbs[] = {
1803	/* set capture source to mic-in */
1804	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1805	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1806	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1807	/* mute all amp mixer inputs */
1808	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1809	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1810	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1811	/* line-in to input */
1812	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1813	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1814	/* built-in mic */
1815	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1816	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1817	/* speaker-out */
1818	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1819	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1820	/* mic-in to input */
1821	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1822	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1823	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824	/* HP-out */
1825	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1826	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1827	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1828	/* jack sense */
1829	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1830	{ }
1831};
1832
1833/* toggle speaker-output according to the hp-jack state */
1834static void alc880_lg_automute(struct hda_codec *codec)
1835{
1836	unsigned int present;
1837	unsigned char bits;
1838
1839	present = snd_hda_codec_read(codec, 0x1b, 0,
1840				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1841	bits = present ? 0x80 : 0;
1842	snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1843				 0x80, bits);
1844	snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1845				 0x80, bits);
1846}
1847
1848static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1849{
1850	/* Looks like the unsol event is incompatible with the standard
1851	 * definition.  4bit tag is placed at 28 bit!
1852	 */
1853	if ((res >> 28) == 0x01)
1854		alc880_lg_automute(codec);
1855}
1856
1857/*
1858 * LG LW20
1859 *
1860 * Pin assignment:
1861 *   Speaker-out: 0x14
1862 *   Mic-In: 0x18
1863 *   Built-in Mic-In: 0x19 (?)
1864 *   HP-Out: 0x1b
1865 *   SPDIF-Out: 0x1e
1866 */
1867
1868/* seems analog CD is not working */
1869static struct hda_input_mux alc880_lg_lw_capture_source = {
1870	.num_items = 2,
1871	.items = {
1872		{ "Mic", 0x0 },
1873		{ "Internal Mic", 0x1 },
1874	},
1875};
1876
1877static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1878	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1879	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1880	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1881	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1882	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1883	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1884	{ } /* end */
1885};
1886
1887static struct hda_verb alc880_lg_lw_init_verbs[] = {
1888	/* set capture source to mic-in */
1889	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1890	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1891	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1892	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1893	/* speaker-out */
1894	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1895	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1896	/* HP-out */
1897	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1898	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1899	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1900	/* mic-in to input */
1901	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1902	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1903	/* built-in mic */
1904	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1905	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1906	/* jack sense */
1907	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1908	{ }
1909};
1910
1911/* toggle speaker-output according to the hp-jack state */
1912static void alc880_lg_lw_automute(struct hda_codec *codec)
1913{
1914	unsigned int present;
1915	unsigned char bits;
1916
1917	present = snd_hda_codec_read(codec, 0x1b, 0,
1918				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1919	bits = present ? 0x80 : 0;
1920	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1921				 0x80, bits);
1922	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1923				 0x80, bits);
1924}
1925
1926static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1927{
1928	/* Looks like the unsol event is incompatible with the standard
1929	 * definition.  4bit tag is placed at 28 bit!
1930	 */
1931	if ((res >> 28) == 0x01)
1932		alc880_lg_lw_automute(codec);
1933}
1934
1935/*
1936 * Common callbacks
1937 */
1938
1939static int alc_init(struct hda_codec *codec)
1940{
1941	struct alc_spec *spec = codec->spec;
1942	unsigned int i;
1943
1944	for (i = 0; i < spec->num_init_verbs; i++)
1945		snd_hda_sequence_write(codec, spec->init_verbs[i]);
1946
1947	if (spec->init_hook)
1948		spec->init_hook(codec);
1949
1950	return 0;
1951}
1952
1953static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1954{
1955	struct alc_spec *spec = codec->spec;
1956
1957	if (spec->unsol_event)
1958		spec->unsol_event(codec, res);
1959}
1960
1961#ifdef CONFIG_PM
1962/*
1963 * resume
1964 */
1965static int alc_resume(struct hda_codec *codec)
1966{
1967	struct alc_spec *spec = codec->spec;
1968	int i;
1969
1970	alc_init(codec);
1971	for (i = 0; i < spec->num_mixers; i++)
1972		snd_hda_resume_ctls(codec, spec->mixers[i]);
1973	if (spec->multiout.dig_out_nid)
1974		snd_hda_resume_spdif_out(codec);
1975	if (spec->dig_in_nid)
1976		snd_hda_resume_spdif_in(codec);
1977
1978	return 0;
1979}
1980#endif
1981
1982/*
1983 * Analog playback callbacks
1984 */
1985static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
1986				    struct hda_codec *codec,
1987				    struct snd_pcm_substream *substream)
1988{
1989	struct alc_spec *spec = codec->spec;
1990	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1991}
1992
1993static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1994				       struct hda_codec *codec,
1995				       unsigned int stream_tag,
1996				       unsigned int format,
1997				       struct snd_pcm_substream *substream)
1998{
1999	struct alc_spec *spec = codec->spec;
2000	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2001						stream_tag, format, substream);
2002}
2003
2004static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2005				       struct hda_codec *codec,
2006				       struct snd_pcm_substream *substream)
2007{
2008	struct alc_spec *spec = codec->spec;
2009	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2010}
2011
2012/*
2013 * Digital out
2014 */
2015static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2016					struct hda_codec *codec,
2017					struct snd_pcm_substream *substream)
2018{
2019	struct alc_spec *spec = codec->spec;
2020	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2021}
2022
2023static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2024					   struct hda_codec *codec,
2025					   unsigned int stream_tag,
2026					   unsigned int format,
2027					   struct snd_pcm_substream *substream)
2028{
2029	struct alc_spec *spec = codec->spec;
2030	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2031					     stream_tag, format, substream);
2032}
2033
2034static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2035					 struct hda_codec *codec,
2036					 struct snd_pcm_substream *substream)
2037{
2038	struct alc_spec *spec = codec->spec;
2039	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2040}
2041
2042/*
2043 * Analog capture
2044 */
2045static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2046				      struct hda_codec *codec,
2047				      unsigned int stream_tag,
2048				      unsigned int format,
2049				      struct snd_pcm_substream *substream)
2050{
2051	struct alc_spec *spec = codec->spec;
2052
2053	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2054				   stream_tag, 0, format);
2055	return 0;
2056}
2057
2058static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2059				      struct hda_codec *codec,
2060				      struct snd_pcm_substream *substream)
2061{
2062	struct alc_spec *spec = codec->spec;
2063
2064	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2065				   0, 0, 0);
2066	return 0;
2067}
2068
2069
2070/*
2071 */
2072static struct hda_pcm_stream alc880_pcm_analog_playback = {
2073	.substreams = 1,
2074	.channels_min = 2,
2075	.channels_max = 8,
2076	/* NID is set in alc_build_pcms */
2077	.ops = {
2078		.open = alc880_playback_pcm_open,
2079		.prepare = alc880_playback_pcm_prepare,
2080		.cleanup = alc880_playback_pcm_cleanup
2081	},
2082};
2083
2084static struct hda_pcm_stream alc880_pcm_analog_capture = {
2085	.substreams = 2,
2086	.channels_min = 2,
2087	.channels_max = 2,
2088	/* NID is set in alc_build_pcms */
2089	.ops = {
2090		.prepare = alc880_capture_pcm_prepare,
2091		.cleanup = alc880_capture_pcm_cleanup
2092	},
2093};
2094
2095static struct hda_pcm_stream alc880_pcm_digital_playback = {
2096	.substreams = 1,
2097	.channels_min = 2,
2098	.channels_max = 2,
2099	/* NID is set in alc_build_pcms */
2100	.ops = {
2101		.open = alc880_dig_playback_pcm_open,
2102		.close = alc880_dig_playback_pcm_close,
2103		.prepare = alc880_dig_playback_pcm_prepare
2104	},
2105};
2106
2107static struct hda_pcm_stream alc880_pcm_digital_capture = {
2108	.substreams = 1,
2109	.channels_min = 2,
2110	.channels_max = 2,
2111	/* NID is set in alc_build_pcms */
2112};
2113
2114/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2115static struct hda_pcm_stream alc_pcm_null_playback = {
2116	.substreams = 0,
2117	.channels_min = 0,
2118	.channels_max = 0,
2119};
2120
2121static int alc_build_pcms(struct hda_codec *codec)
2122{
2123	struct alc_spec *spec = codec->spec;
2124	struct hda_pcm *info = spec->pcm_rec;
2125	int i;
2126
2127	codec->num_pcms = 1;
2128	codec->pcm_info = info;
2129
2130	info->name = spec->stream_name_analog;
2131	if (spec->stream_analog_playback) {
2132		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2133		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2134		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2135	}
2136	if (spec->stream_analog_capture) {
2137		snd_assert(spec->adc_nids, return -EINVAL);
2138		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2139		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2140	}
2141
2142	if (spec->channel_mode) {
2143		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2144		for (i = 0; i < spec->num_channel_mode; i++) {
2145			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2146				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2147			}
2148		}
2149	}
2150
2151	/* SPDIF for stream index #1 */
2152	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2153		codec->num_pcms = 2;
2154		info = spec->pcm_rec + 1;
2155		info->name = spec->stream_name_digital;
2156		if (spec->multiout.dig_out_nid &&
2157		    spec->stream_digital_playback) {
2158			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2159			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2160		}
2161		if (spec->dig_in_nid &&
2162		    spec->stream_digital_capture) {
2163			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2164			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2165		}
2166	}
2167
2168	/* If the use of more than one ADC is requested for the current
2169	 * model, configure a second analog capture-only PCM.
2170	 */
2171	/* Additional Analaog capture for index #2 */
2172	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2173	    spec->adc_nids) {
2174		codec->num_pcms = 3;
2175		info = spec->pcm_rec + 2;
2176		info->name = spec->stream_name_analog;
2177		/* No playback stream for second PCM */
2178		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2179		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2180		if (spec->stream_analog_capture) {
2181			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2182			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2183		}
2184	}
2185
2186	return 0;
2187}
2188
2189static void alc_free(struct hda_codec *codec)
2190{
2191	struct alc_spec *spec = codec->spec;
2192	unsigned int i;
2193
2194	if (!spec)
2195		return;
2196
2197	if (spec->kctl_alloc) {
2198		for (i = 0; i < spec->num_kctl_used; i++)
2199			kfree(spec->kctl_alloc[i].name);
2200		kfree(spec->kctl_alloc);
2201	}
2202	kfree(spec);
2203}
2204
2205/*
2206 */
2207static struct hda_codec_ops alc_patch_ops = {
2208	.build_controls = alc_build_controls,
2209	.build_pcms = alc_build_pcms,
2210	.init = alc_init,
2211	.free = alc_free,
2212	.unsol_event = alc_unsol_event,
2213#ifdef CONFIG_PM
2214	.resume = alc_resume,
2215#endif
2216};
2217
2218
2219/*
2220 * Test configuration for debugging
2221 *
2222 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2223 * enum controls.
2224 */
2225#ifdef CONFIG_SND_DEBUG
2226static hda_nid_t alc880_test_dac_nids[4] = {
2227	0x02, 0x03, 0x04, 0x05
2228};
2229
2230static struct hda_input_mux alc880_test_capture_source = {
2231	.num_items = 7,
2232	.items = {
2233		{ "In-1", 0x0 },
2234		{ "In-2", 0x1 },
2235		{ "In-3", 0x2 },
2236		{ "In-4", 0x3 },
2237		{ "CD", 0x4 },
2238		{ "Front", 0x5 },
2239		{ "Surround", 0x6 },
2240	},
2241};
2242
2243static struct hda_channel_mode alc880_test_modes[4] = {
2244	{ 2, NULL },
2245	{ 4, NULL },
2246	{ 6, NULL },
2247	{ 8, NULL },
2248};
2249
2250static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2251				 struct snd_ctl_elem_info *uinfo)
2252{
2253	static char *texts[] = {
2254		"N/A", "Line Out", "HP Out",
2255		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2256	};
2257	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2258	uinfo->count = 1;
2259	uinfo->value.enumerated.items = 8;
2260	if (uinfo->value.enumerated.item >= 8)
2261		uinfo->value.enumerated.item = 7;
2262	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2263	return 0;
2264}
2265
2266static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2267				struct snd_ctl_elem_value *ucontrol)
2268{
2269	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2270	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2271	unsigned int pin_ctl, item = 0;
2272
2273	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2274				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2275	if (pin_ctl & AC_PINCTL_OUT_EN) {
2276		if (pin_ctl & AC_PINCTL_HP_EN)
2277			item = 2;
2278		else
2279			item = 1;
2280	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2281		switch (pin_ctl & AC_PINCTL_VREFEN) {
2282		case AC_PINCTL_VREF_HIZ: item = 3; break;
2283		case AC_PINCTL_VREF_50:  item = 4; break;
2284		case AC_PINCTL_VREF_GRD: item = 5; break;
2285		case AC_PINCTL_VREF_80:  item = 6; break;
2286		case AC_PINCTL_VREF_100: item = 7; break;
2287		}
2288	}
2289	ucontrol->value.enumerated.item[0] = item;
2290	return 0;
2291}
2292
2293static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2294				struct snd_ctl_elem_value *ucontrol)
2295{
2296	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2297	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2298	static unsigned int ctls[] = {
2299		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2300		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2301		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2302		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2303		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2304		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2305	};
2306	unsigned int old_ctl, new_ctl;
2307
2308	old_ctl = snd_hda_codec_read(codec, nid, 0,
2309				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2310	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2311	if (old_ctl != new_ctl) {
2312		snd_hda_codec_write(codec, nid, 0,
2313				    AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2314		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2315				    (ucontrol->value.enumerated.item[0] >= 3 ?
2316				     0xb080 : 0xb000));
2317		return 1;
2318	}
2319	return 0;
2320}
2321
2322static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2323				 struct snd_ctl_elem_info *uinfo)
2324{
2325	static char *texts[] = {
2326		"Front", "Surround", "CLFE", "Side"
2327	};
2328	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2329	uinfo->count = 1;
2330	uinfo->value.enumerated.items = 4;
2331	if (uinfo->value.enumerated.item >= 4)
2332		uinfo->value.enumerated.item = 3;
2333	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2334	return 0;
2335}
2336
2337static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2338				struct snd_ctl_elem_value *ucontrol)
2339{
2340	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2341	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2342	unsigned int sel;
2343
2344	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2345	ucontrol->value.enumerated.item[0] = sel & 3;
2346	return 0;
2347}
2348
2349static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2350				struct snd_ctl_elem_value *ucontrol)
2351{
2352	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2353	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2354	unsigned int sel;
2355
2356	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2357	if (ucontrol->value.enumerated.item[0] != sel) {
2358		sel = ucontrol->value.enumerated.item[0] & 3;
2359		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2360		return 1;
2361	}
2362	return 0;
2363}
2364
2365#define PIN_CTL_TEST(xname,nid) {			\
2366		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2367			.name = xname,		       \
2368			.info = alc_test_pin_ctl_info, \
2369			.get = alc_test_pin_ctl_get,   \
2370			.put = alc_test_pin_ctl_put,   \
2371			.private_value = nid	       \
2372			}
2373
2374#define PIN_SRC_TEST(xname,nid) {			\
2375		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2376			.name = xname,		       \
2377			.info = alc_test_pin_src_info, \
2378			.get = alc_test_pin_src_get,   \
2379			.put = alc_test_pin_src_put,   \
2380			.private_value = nid	       \
2381			}
2382
2383static struct snd_kcontrol_new alc880_test_mixer[] = {
2384	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2385	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2386	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2387	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2388	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2389	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2390	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2391	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2392	PIN_CTL_TEST("Front Pin Mode", 0x14),
2393	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2394	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2395	PIN_CTL_TEST("Side Pin Mode", 0x17),
2396	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2397	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2398	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2399	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2400	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2401	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2402	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2403	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2404	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2405	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2406	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2407	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2408	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2409	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2410	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2411	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2412	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2413	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2414	{
2415		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2416		.name = "Channel Mode",
2417		.info = alc_ch_mode_info,
2418		.get = alc_ch_mode_get,
2419		.put = alc_ch_mode_put,
2420	},
2421	{ } /* end */
2422};
2423
2424static struct hda_verb alc880_test_init_verbs[] = {
2425	/* Unmute inputs of 0x0c - 0x0f */
2426	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2427	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2428	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2429	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2430	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2431	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2432	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2433	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2434	/* Vol output for 0x0c-0x0f */
2435	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2436	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2437	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2438	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2439	/* Set output pins 0x14-0x17 */
2440	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2441	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2442	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2443	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2444	/* Unmute output pins 0x14-0x17 */
2445	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2446	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2447	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2448	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2449	/* Set input pins 0x18-0x1c */
2450	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2451	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2452	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2453	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2454	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2455	/* Mute input pins 0x18-0x1b */
2456	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2458	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2459	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2460	/* ADC set up */
2461	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2462	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2463	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2464	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2465	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2466	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2467	/* Analog input/passthru */
2468	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2469	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2470	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2471	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2472	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2473	{ }
2474};
2475#endif
2476
2477/*
2478 */
2479
2480static const char *alc880_models[ALC880_MODEL_LAST] = {
2481	[ALC880_3ST]		= "3stack",
2482	[ALC880_TCL_S700]	= "tcl",
2483	[ALC880_3ST_DIG]	= "3stack-digout",
2484	[ALC880_CLEVO]		= "clevo",
2485	[ALC880_5ST]		= "5stack",
2486	[ALC880_5ST_DIG]	= "5stack-digout",
2487	[ALC880_W810]		= "w810",
2488	[ALC880_Z71V]		= "z71v",
2489	[ALC880_6ST]		= "6stack",
2490	[ALC880_6ST_DIG]	= "6stack-digout",
2491	[ALC880_ASUS]		= "asus",
2492	[ALC880_ASUS_W1V]	= "asus-w1v",
2493	[ALC880_ASUS_DIG]	= "asus-dig",
2494	[ALC880_ASUS_DIG2]	= "asus-dig2",
2495	[ALC880_UNIWILL_DIG]	= "uniwill",
2496	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2497	[ALC880_FUJITSU]	= "fujitsu",
2498	[ALC880_F1734]		= "F1734",
2499	[ALC880_LG]		= "lg",
2500	[ALC880_LG_LW]		= "lg-lw",
2501#ifdef CONFIG_SND_DEBUG
2502	[ALC880_TEST]		= "test",
2503#endif
2504	[ALC880_AUTO]		= "auto",
2505};
2506
2507static struct snd_pci_quirk alc880_cfg_tbl[] = {
2508	/* Broken BIOS configuration */
2509	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2510	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2511
2512	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2513	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2514	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2515	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2516	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2517	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2518	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2519	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2520	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2521
2522	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2523	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2524
2525	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2526	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2527	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2528	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2529	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2530	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2531	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2532	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2533	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2534	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2535	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2536	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2537	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2538	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2539	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2540
2541	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2542	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2543	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2544	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2545	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2546	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2547	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2548	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2549	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2550	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2551	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2552	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2553	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2554	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2555	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2556	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2557	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2558	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2559
2560	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2561	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2562	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2563	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2564
2565	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2566	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2567	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2568	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2569
2570	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2571	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2572	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2573	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2574
2575	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2576	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2577	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2578	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2579	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2580	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2581	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2582	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2583	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2584	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2585	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2586
2587	{}
2588};
2589
2590/*
2591 * ALC880 codec presets
2592 */
2593static struct alc_config_preset alc880_presets[] = {
2594	[ALC880_3ST] = {
2595		.mixers = { alc880_three_stack_mixer },
2596		.init_verbs = { alc880_volume_init_verbs,
2597				alc880_pin_3stack_init_verbs },
2598		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2599		.dac_nids = alc880_dac_nids,
2600		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2601		.channel_mode = alc880_threestack_modes,
2602		.need_dac_fix = 1,
2603		.input_mux = &alc880_capture_source,
2604	},
2605	[ALC880_3ST_DIG] = {
2606		.mixers = { alc880_three_stack_mixer },
2607		.init_verbs = { alc880_volume_init_verbs,
2608				alc880_pin_3stack_init_verbs },
2609		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2610		.dac_nids = alc880_dac_nids,
2611		.dig_out_nid = ALC880_DIGOUT_NID,
2612		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2613		.channel_mode = alc880_threestack_modes,
2614		.need_dac_fix = 1,
2615		.input_mux = &alc880_capture_source,
2616	},
2617	[ALC880_TCL_S700] = {
2618		.mixers = { alc880_tcl_s700_mixer },
2619		.init_verbs = { alc880_volume_init_verbs,
2620				alc880_pin_tcl_S700_init_verbs,
2621				alc880_gpio2_init_verbs },
2622		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2623		.dac_nids = alc880_dac_nids,
2624		.hp_nid = 0x03,
2625		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2626		.channel_mode = alc880_2_jack_modes,
2627		.input_mux = &alc880_capture_source,
2628	},
2629	[ALC880_5ST] = {
2630		.mixers = { alc880_three_stack_mixer,
2631			    alc880_five_stack_mixer},
2632		.init_verbs = { alc880_volume_init_verbs,
2633				alc880_pin_5stack_init_verbs },
2634		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2635		.dac_nids = alc880_dac_nids,
2636		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2637		.channel_mode = alc880_fivestack_modes,
2638		.input_mux = &alc880_capture_source,
2639	},
2640	[ALC880_5ST_DIG] = {
2641		.mixers = { alc880_three_stack_mixer,
2642			    alc880_five_stack_mixer },
2643		.init_verbs = { alc880_volume_init_verbs,
2644				alc880_pin_5stack_init_verbs },
2645		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2646		.dac_nids = alc880_dac_nids,
2647		.dig_out_nid = ALC880_DIGOUT_NID,
2648		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2649		.channel_mode = alc880_fivestack_modes,
2650		.input_mux = &alc880_capture_source,
2651	},
2652	[ALC880_6ST] = {
2653		.mixers = { alc880_six_stack_mixer },
2654		.init_verbs = { alc880_volume_init_verbs,
2655				alc880_pin_6stack_init_verbs },
2656		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2657		.dac_nids = alc880_6st_dac_nids,
2658		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2659		.channel_mode = alc880_sixstack_modes,
2660		.input_mux = &alc880_6stack_capture_source,
2661	},
2662	[ALC880_6ST_DIG] = {
2663		.mixers = { alc880_six_stack_mixer },
2664		.init_verbs = { alc880_volume_init_verbs,
2665				alc880_pin_6stack_init_verbs },
2666		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2667		.dac_nids = alc880_6st_dac_nids,
2668		.dig_out_nid = ALC880_DIGOUT_NID,
2669		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2670		.channel_mode = alc880_sixstack_modes,
2671		.input_mux = &alc880_6stack_capture_source,
2672	},
2673	[ALC880_W810] = {
2674		.mixers = { alc880_w810_base_mixer },
2675		.init_verbs = { alc880_volume_init_verbs,
2676				alc880_pin_w810_init_verbs,
2677				alc880_gpio2_init_verbs },
2678		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2679		.dac_nids = alc880_w810_dac_nids,
2680		.dig_out_nid = ALC880_DIGOUT_NID,
2681		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2682		.channel_mode = alc880_w810_modes,
2683		.input_mux = &alc880_capture_source,
2684	},
2685	[ALC880_Z71V] = {
2686		.mixers = { alc880_z71v_mixer },
2687		.init_verbs = { alc880_volume_init_verbs,
2688				alc880_pin_z71v_init_verbs },
2689		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2690		.dac_nids = alc880_z71v_dac_nids,
2691		.dig_out_nid = ALC880_DIGOUT_NID,
2692		.hp_nid = 0x03,
2693		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2694		.channel_mode = alc880_2_jack_modes,
2695		.input_mux = &alc880_capture_source,
2696	},
2697	[ALC880_F1734] = {
2698		.mixers = { alc880_f1734_mixer },
2699		.init_verbs = { alc880_volume_init_verbs,
2700				alc880_pin_f1734_init_verbs },
2701		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2702		.dac_nids = alc880_f1734_dac_nids,
2703		.hp_nid = 0x02,
2704		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2705		.channel_mode = alc880_2_jack_modes,
2706		.input_mux = &alc880_capture_source,
2707	},
2708	[ALC880_ASUS] = {
2709		.mixers = { alc880_asus_mixer },
2710		.init_verbs = { alc880_volume_init_verbs,
2711				alc880_pin_asus_init_verbs,
2712				alc880_gpio1_init_verbs },
2713		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2714		.dac_nids = alc880_asus_dac_nids,
2715		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2716		.channel_mode = alc880_asus_modes,
2717		.need_dac_fix = 1,
2718		.input_mux = &alc880_capture_source,
2719	},
2720	[ALC880_ASUS_DIG] = {
2721		.mixers = { alc880_asus_mixer },
2722		.init_verbs = { alc880_volume_init_verbs,
2723				alc880_pin_asus_init_verbs,
2724				alc880_gpio1_init_verbs },
2725		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2726		.dac_nids = alc880_asus_dac_nids,
2727		.dig_out_nid = ALC880_DIGOUT_NID,
2728		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2729		.channel_mode = alc880_asus_modes,
2730		.need_dac_fix = 1,
2731		.input_mux = &alc880_capture_source,
2732	},
2733	[ALC880_ASUS_DIG2] = {
2734		.mixers = { alc880_asus_mixer },
2735		.init_verbs = { alc880_volume_init_verbs,
2736				alc880_pin_asus_init_verbs,
2737				alc880_gpio2_init_verbs }, /* use GPIO2 */
2738		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2739		.dac_nids = alc880_asus_dac_nids,
2740		.dig_out_nid = ALC880_DIGOUT_NID,
2741		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2742		.channel_mode = alc880_asus_modes,
2743		.need_dac_fix = 1,
2744		.input_mux = &alc880_capture_source,
2745	},
2746	[ALC880_ASUS_W1V] = {
2747		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2748		.init_verbs = { alc880_volume_init_verbs,
2749				alc880_pin_asus_init_verbs,
2750				alc880_gpio1_init_verbs },
2751		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2752		.dac_nids = alc880_asus_dac_nids,
2753		.dig_out_nid = ALC880_DIGOUT_NID,
2754		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2755		.channel_mode = alc880_asus_modes,
2756		.need_dac_fix = 1,
2757		.input_mux = &alc880_capture_source,
2758	},
2759	[ALC880_UNIWILL_DIG] = {
2760		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2761		.init_verbs = { alc880_volume_init_verbs,
2762				alc880_pin_asus_init_verbs },
2763		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2764		.dac_nids = alc880_asus_dac_nids,
2765		.dig_out_nid = ALC880_DIGOUT_NID,
2766		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2767		.channel_mode = alc880_asus_modes,
2768		.need_dac_fix = 1,
2769		.input_mux = &alc880_capture_source,
2770	},
2771	[ALC880_UNIWILL] = {
2772		.mixers = { alc880_uniwill_mixer },
2773		.init_verbs = { alc880_volume_init_verbs,
2774				alc880_uniwill_init_verbs },
2775		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2776		.dac_nids = alc880_asus_dac_nids,
2777		.dig_out_nid = ALC880_DIGOUT_NID,
2778		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2779		.channel_mode = alc880_threestack_modes,
2780		.need_dac_fix = 1,
2781		.input_mux = &alc880_capture_source,
2782		.unsol_event = alc880_uniwill_unsol_event,
2783		.init_hook = alc880_uniwill_automute,
2784	},
2785	[ALC880_UNIWILL_P53] = {
2786		.mixers = { alc880_uniwill_p53_mixer },
2787		.init_verbs = { alc880_volume_init_verbs,
2788				alc880_uniwill_p53_init_verbs },
2789		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2790		.dac_nids = alc880_asus_dac_nids,
2791		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2792		.channel_mode = alc880_threestack_modes,
2793		.input_mux = &alc880_capture_source,
2794		.unsol_event = alc880_uniwill_p53_unsol_event,
2795		.init_hook = alc880_uniwill_p53_hp_automute,
2796	},
2797	[ALC880_FUJITSU] = {
2798		.mixers = { alc880_fujitsu_mixer,
2799			    alc880_pcbeep_mixer, },
2800		.init_verbs = { alc880_volume_init_verbs,
2801				alc880_uniwill_p53_init_verbs,
2802	       			alc880_beep_init_verbs },
2803		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2804		.dac_nids = alc880_dac_nids,
2805		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2806		.channel_mode = alc880_2_jack_modes,
2807		.input_mux = &alc880_capture_source,
2808		.unsol_event = alc880_uniwill_p53_unsol_event,
2809		.init_hook = alc880_uniwill_p53_hp_automute,
2810	},
2811	[ALC880_CLEVO] = {
2812		.mixers = { alc880_three_stack_mixer },
2813		.init_verbs = { alc880_volume_init_verbs,
2814				alc880_pin_clevo_init_verbs },
2815		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2816		.dac_nids = alc880_dac_nids,
2817		.hp_nid = 0x03,
2818		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2819		.channel_mode = alc880_threestack_modes,
2820		.need_dac_fix = 1,
2821		.input_mux = &alc880_capture_source,
2822	},
2823	[ALC880_LG] = {
2824		.mixers = { alc880_lg_mixer },
2825		.init_verbs = { alc880_volume_init_verbs,
2826				alc880_lg_init_verbs },
2827		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2828		.dac_nids = alc880_lg_dac_nids,
2829		.dig_out_nid = ALC880_DIGOUT_NID,
2830		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2831		.channel_mode = alc880_lg_ch_modes,
2832		.need_dac_fix = 1,
2833		.input_mux = &alc880_lg_capture_source,
2834		.unsol_event = alc880_lg_unsol_event,
2835		.init_hook = alc880_lg_automute,
2836	},
2837	[ALC880_LG_LW] = {
2838		.mixers = { alc880_lg_lw_mixer },
2839		.init_verbs = { alc880_volume_init_verbs,
2840				alc880_lg_lw_init_verbs },
2841		.num_dacs = 1,
2842		.dac_nids = alc880_dac_nids,
2843		.dig_out_nid = ALC880_DIGOUT_NID,
2844		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2845		.channel_mode = alc880_2_jack_modes,
2846		.input_mux = &alc880_lg_lw_capture_source,
2847		.unsol_event = alc880_lg_lw_unsol_event,
2848		.init_hook = alc880_lg_lw_automute,
2849	},
2850#ifdef CONFIG_SND_DEBUG
2851	[ALC880_TEST] = {
2852		.mixers = { alc880_test_mixer },
2853		.init_verbs = { alc880_test_init_verbs },
2854		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2855		.dac_nids = alc880_test_dac_nids,
2856		.dig_out_nid = ALC880_DIGOUT_NID,
2857		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2858		.channel_mode = alc880_test_modes,
2859		.input_mux = &alc880_test_capture_source,
2860	},
2861#endif
2862};
2863
2864/*
2865 * Automatic parse of I/O pins from the BIOS configuration
2866 */
2867
2868#define NUM_CONTROL_ALLOC	32
2869#define NUM_VERB_ALLOC		32
2870
2871enum {
2872	ALC_CTL_WIDGET_VOL,
2873	ALC_CTL_WIDGET_MUTE,
2874	ALC_CTL_BIND_MUTE,
2875};
2876static struct snd_kcontrol_new alc880_control_templates[] = {
2877	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2878	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2879	HDA_BIND_MUTE(NULL, 0, 0, 0),
2880};
2881
2882/* add dynamic controls */
2883static int add_control(struct alc_spec *spec, int type, const char *name,
2884		       unsigned long val)
2885{
2886	struct snd_kcontrol_new *knew;
2887
2888	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2889		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2890
2891		/* array + terminator */
2892		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2893		if (!knew)
2894			return -ENOMEM;
2895		if (spec->kctl_alloc) {
2896			memcpy(knew, spec->kctl_alloc,
2897			       sizeof(*knew) * spec->num_kctl_alloc);
2898			kfree(spec->kctl_alloc);
2899		}
2900		spec->kctl_alloc = knew;
2901		spec->num_kctl_alloc = num;
2902	}
2903
2904	knew = &spec->kctl_alloc[spec->num_kctl_used];
2905	*knew = alc880_control_templates[type];
2906	knew->name = kstrdup(name, GFP_KERNEL);
2907	if (!knew->name)
2908		return -ENOMEM;
2909	knew->private_value = val;
2910	spec->num_kctl_used++;
2911	return 0;
2912}
2913
2914#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2915#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2916#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2917#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2918#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2919#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2920#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2921#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2922#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2923#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2924#define ALC880_PIN_CD_NID		0x1c
2925
2926/* fill in the dac_nids table from the parsed pin configuration */
2927static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
2928				     const struct auto_pin_cfg *cfg)
2929{
2930	hda_nid_t nid;
2931	int assigned[4];
2932	int i, j;
2933
2934	memset(assigned, 0, sizeof(assigned));
2935	spec->multiout.dac_nids = spec->private_dac_nids;
2936
2937	/* check the pins hardwired to audio widget */
2938	for (i = 0; i < cfg->line_outs; i++) {
2939		nid = cfg->line_out_pins[i];
2940		if (alc880_is_fixed_pin(nid)) {
2941			int idx = alc880_fixed_pin_idx(nid);
2942			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2943			assigned[idx] = 1;
2944		}
2945	}
2946	/* left pins can be connect to any audio widget */
2947	for (i = 0; i < cfg->line_outs; i++) {
2948		nid = cfg->line_out_pins[i];
2949		if (alc880_is_fixed_pin(nid))
2950			continue;
2951		/* search for an empty channel */
2952		for (j = 0; j < cfg->line_outs; j++) {
2953			if (!assigned[j]) {
2954				spec->multiout.dac_nids[i] =
2955					alc880_idx_to_dac(j);
2956				assigned[j] = 1;
2957				break;
2958			}
2959		}
2960	}
2961	spec->multiout.num_dacs = cfg->line_outs;
2962	return 0;
2963}
2964
2965/* add playback controls from the parsed DAC table */
2966static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
2967					     const struct auto_pin_cfg *cfg)
2968{
2969	char name[32];
2970	static const char *chname[4] = {
2971		"Front", "Surround", NULL /*CLFE*/, "Side"
2972	};
2973	hda_nid_t nid;
2974	int i, err;
2975
2976	for (i = 0; i < cfg->line_outs; i++) {
2977		if (!spec->multiout.dac_nids[i])
2978			continue;
2979		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
2980		if (i == 2) {
2981			/* Center/LFE */
2982			err = add_control(spec, ALC_CTL_WIDGET_VOL,
2983					  "Center Playback Volume",
2984					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
2985							      HDA_OUTPUT));
2986			if (err < 0)
2987				return err;
2988			err = add_control(spec, ALC_CTL_WIDGET_VOL,
2989					  "LFE Playback Volume",
2990					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
2991							      HDA_OUTPUT));
2992			if (err < 0)
2993				return err;
2994			err = add_control(spec, ALC_CTL_BIND_MUTE,
2995					  "Center Playback Switch",
2996					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
2997							      HDA_INPUT));
2998			if (err < 0)
2999				return err;
3000			err = add_control(spec, ALC_CTL_BIND_MUTE,
3001					  "LFE Playback Switch",
3002					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3003							      HDA_INPUT));
3004			if (err < 0)
3005				return err;
3006		} else {
3007			sprintf(name, "%s Playback Volume", chname[i]);
3008			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3009					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3010							      HDA_OUTPUT));
3011			if (err < 0)
3012				return err;
3013			sprintf(name, "%s Playback Switch", chname[i]);
3014			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3015					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3016							      HDA_INPUT));
3017			if (err < 0)
3018				return err;
3019		}
3020	}
3021	return 0;
3022}
3023
3024/* add playback controls for speaker and HP outputs */
3025static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3026					const char *pfx)
3027{
3028	hda_nid_t nid;
3029	int err;
3030	char name[32];
3031
3032	if (!pin)
3033		return 0;
3034
3035	if (alc880_is_fixed_pin(pin)) {
3036		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3037		/* specify the DAC as the extra output */
3038		if (!spec->multiout.hp_nid)
3039			spec->multiout.hp_nid = nid;
3040		else
3041			spec->multiout.extra_out_nid[0] = nid;
3042		/* control HP volume/switch on the output mixer amp */
3043		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3044		sprintf(name, "%s Playback Volume", pfx);
3045		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3046				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3047		if (err < 0)
3048			return err;
3049		sprintf(name, "%s Playback Switch", pfx);
3050		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3051				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3052		if (err < 0)
3053			return err;
3054	} else if (alc880_is_multi_pin(pin)) {
3055		/* set manual connection */
3056		/* we have only a switch on HP-out PIN */
3057		sprintf(name, "%s Playback Switch", pfx);
3058		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3059				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3060		if (err < 0)
3061			return err;
3062	}
3063	return 0;
3064}
3065
3066/* create input playback/capture controls for the given pin */
3067static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3068			    const char *ctlname,
3069			    int idx, hda_nid_t mix_nid)
3070{
3071	char name[32];
3072	int err;
3073
3074	sprintf(name, "%s Playback Volume", ctlname);
3075	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3076			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3077	if (err < 0)
3078		return err;
3079	sprintf(name, "%s Playback Switch", ctlname);
3080	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3081			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3082	if (err < 0)
3083		return err;
3084	return 0;
3085}
3086
3087/* create playback/capture controls for input pins */
3088static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3089						const struct auto_pin_cfg *cfg)
3090{
3091	struct hda_input_mux *imux = &spec->private_imux;
3092	int i, err, idx;
3093
3094	for (i = 0; i < AUTO_PIN_LAST; i++) {
3095		if (alc880_is_input_pin(cfg->input_pins[i])) {
3096			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3097			err = new_analog_input(spec, cfg->input_pins[i],
3098					       auto_pin_cfg_labels[i],
3099					       idx, 0x0b);
3100			if (err < 0)
3101				return err;
3102			imux->items[imux->num_items].label =
3103				auto_pin_cfg_labels[i];
3104			imux->items[imux->num_items].index =
3105				alc880_input_pin_idx(cfg->input_pins[i]);
3106			imux->num_items++;
3107		}
3108	}
3109	return 0;
3110}
3111
3112static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3113					      hda_nid_t nid, int pin_type,
3114					      int dac_idx)
3115{
3116	/* set as output */
3117	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3118			    pin_type);
3119	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3120			    AMP_OUT_UNMUTE);
3121	/* need the manual connection? */
3122	if (alc880_is_multi_pin(nid)) {
3123		struct alc_spec *spec = codec->spec;
3124		int idx = alc880_multi_pin_idx(nid);
3125		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3126				    AC_VERB_SET_CONNECT_SEL,
3127				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3128	}
3129}
3130
3131static int get_pin_type(int line_out_type)
3132{
3133	if (line_out_type == AUTO_PIN_HP_OUT)
3134		return PIN_HP;
3135	else
3136		return PIN_OUT;
3137}
3138
3139static void alc880_auto_init_multi_out(struct hda_codec *codec)
3140{
3141	struct alc_spec *spec = codec->spec;
3142	int i;
3143
3144	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3145	for (i = 0; i < spec->autocfg.line_outs; i++) {
3146		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3147		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3148		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3149	}
3150}
3151
3152static void alc880_auto_init_extra_out(struct hda_codec *codec)
3153{
3154	struct alc_spec *spec = codec->spec;
3155	hda_nid_t pin;
3156
3157	pin = spec->autocfg.speaker_pins[0];
3158	if (pin) /* connect to front */
3159		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3160	pin = spec->autocfg.hp_pins[0];
3161	if (pin) /* connect to front */
3162		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3163}
3164
3165static void alc880_auto_init_analog_input(struct hda_codec *codec)
3166{
3167	struct alc_spec *spec = codec->spec;
3168	int i;
3169
3170	for (i = 0; i < AUTO_PIN_LAST; i++) {
3171		hda_nid_t nid = spec->autocfg.input_pins[i];
3172		if (alc880_is_input_pin(nid)) {
3173			snd_hda_codec_write(codec, nid, 0,
3174					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3175					    i <= AUTO_PIN_FRONT_MIC ?
3176					    PIN_VREF80 : PIN_IN);
3177			if (nid != ALC880_PIN_CD_NID)
3178				snd_hda_codec_write(codec, nid, 0,
3179						    AC_VERB_SET_AMP_GAIN_MUTE,
3180						    AMP_OUT_MUTE);
3181		}
3182	}
3183}
3184
3185/* parse the BIOS configuration and set up the alc_spec */
3186/* return 1 if successful, 0 if the proper config is not found,
3187 * or a negative error code
3188 */
3189static int alc880_parse_auto_config(struct hda_codec *codec)
3190{
3191	struct alc_spec *spec = codec->spec;
3192	int err;
3193	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3194
3195	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3196					   alc880_ignore);
3197	if (err < 0)
3198		return err;
3199	if (!spec->autocfg.line_outs)
3200		return 0; /* can't find valid BIOS pin config */
3201
3202	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3203	if (err < 0)
3204		return err;
3205	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3206	if (err < 0)
3207		return err;
3208	err = alc880_auto_create_extra_out(spec,
3209					   spec->autocfg.speaker_pins[0],
3210					   "Speaker");
3211	if (err < 0)
3212		return err;
3213	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3214					   "Headphone");
3215	if (err < 0)
3216		return err;
3217	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3218	if (err < 0)
3219		return err;
3220
3221	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3222
3223	if (spec->autocfg.dig_out_pin)
3224		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3225	if (spec->autocfg.dig_in_pin)
3226		spec->dig_in_nid = ALC880_DIGIN_NID;
3227
3228	if (spec->kctl_alloc)
3229		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3230
3231	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3232
3233	spec->num_mux_defs = 1;
3234	spec->input_mux = &spec->private_imux;
3235
3236	return 1;
3237}
3238
3239/* additional initialization for auto-configuration model */
3240static void alc880_auto_init(struct hda_codec *codec)
3241{
3242	alc880_auto_init_multi_out(codec);
3243	alc880_auto_init_extra_out(codec);
3244	alc880_auto_init_analog_input(codec);
3245}
3246
3247/*
3248 * OK, here we have finally the patch for ALC880
3249 */
3250
3251static int patch_alc880(struct hda_codec *codec)
3252{
3253	struct alc_spec *spec;
3254	int board_config;
3255	int err;
3256
3257	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3258	if (spec == NULL)
3259		return -ENOMEM;
3260
3261	codec->spec = spec;
3262
3263	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3264						  alc880_models,
3265						  alc880_cfg_tbl);
3266	if (board_config < 0) {
3267		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3268		       "trying auto-probe from BIOS...\n");
3269		board_config = ALC880_AUTO;
3270	}
3271
3272	if (board_config == ALC880_AUTO) {
3273		/* automatic parse from the BIOS config */
3274		err = alc880_parse_auto_config(codec);
3275		if (err < 0) {
3276			alc_free(codec);
3277			return err;
3278		} else if (!err) {
3279			printk(KERN_INFO
3280			       "hda_codec: Cannot set up configuration "
3281			       "from BIOS.  Using 3-stack mode...\n");
3282			board_config = ALC880_3ST;
3283		}
3284	}
3285
3286	if (board_config != ALC880_AUTO)
3287		setup_preset(spec, &alc880_presets[board_config]);
3288
3289	spec->stream_name_analog = "ALC880 Analog";
3290	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3291	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3292
3293	spec->stream_name_digital = "ALC880 Digital";
3294	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3295	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3296
3297	if (!spec->adc_nids && spec->input_mux) {
3298		/* check whether NID 0x07 is valid */
3299		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3300		/* get type */
3301		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3302		if (wcap != AC_WID_AUD_IN) {
3303			spec->adc_nids = alc880_adc_nids_alt;
3304			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3305			spec->mixers[spec->num_mixers] =
3306				alc880_capture_alt_mixer;
3307			spec->num_mixers++;
3308		} else {
3309			spec->adc_nids = alc880_adc_nids;
3310			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3311			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3312			spec->num_mixers++;
3313		}
3314	}
3315
3316	codec->patch_ops = alc_patch_ops;
3317	if (board_config == ALC880_AUTO)
3318		spec->init_hook = alc880_auto_init;
3319
3320	return 0;
3321}
3322
3323
3324/*
3325 * ALC260 support
3326 */
3327
3328static hda_nid_t alc260_dac_nids[1] = {
3329	/* front */
3330	0x02,
3331};
3332
3333static hda_nid_t alc260_adc_nids[1] = {
3334	/* ADC0 */
3335	0x04,
3336};
3337
3338static hda_nid_t alc260_adc_nids_alt[1] = {
3339	/* ADC1 */
3340	0x05,
3341};
3342
3343static hda_nid_t alc260_hp_adc_nids[2] = {
3344	/* ADC1, 0 */
3345	0x05, 0x04
3346};
3347
3348/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3349 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3350 */
3351static hda_nid_t alc260_dual_adc_nids[2] = {
3352	/* ADC0, ADC1 */
3353	0x04, 0x05
3354};
3355
3356#define ALC260_DIGOUT_NID	0x03
3357#define ALC260_DIGIN_NID	0x06
3358
3359static struct hda_input_mux alc260_capture_source = {
3360	.num_items = 4,
3361	.items = {
3362		{ "Mic", 0x0 },
3363		{ "Front Mic", 0x1 },
3364		{ "Line", 0x2 },
3365		{ "CD", 0x4 },
3366	},
3367};
3368
3369/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3370 * headphone jack and the internal CD lines since these are the only pins at
3371 * which audio can appear.  For flexibility, also allow the option of
3372 * recording the mixer output on the second ADC (ADC0 doesn't have a
3373 * connection to the mixer output).
3374 */
3375static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3376	{
3377		.num_items = 3,
3378		.items = {
3379			{ "Mic/Line", 0x0 },
3380			{ "CD", 0x4 },
3381			{ "Headphone", 0x2 },
3382		},
3383	},
3384	{
3385		.num_items = 4,
3386		.items = {
3387			{ "Mic/Line", 0x0 },
3388			{ "CD", 0x4 },
3389			{ "Headphone", 0x2 },
3390			{ "Mixer", 0x5 },
3391		},
3392	},
3393
3394};
3395
3396/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3397 * the Fujitsu S702x, but jacks are marked differently.
3398 */
3399static struct hda_input_mux alc260_acer_capture_sources[2] = {
3400	{
3401		.num_items = 4,
3402		.items = {
3403			{ "Mic", 0x0 },
3404			{ "Line", 0x2 },
3405			{ "CD", 0x4 },
3406			{ "Headphone", 0x5 },
3407		},
3408	},
3409	{
3410		.num_items = 5,
3411		.items = {
3412			{ "Mic", 0x0 },
3413			{ "Line", 0x2 },
3414			{ "CD", 0x4 },
3415			{ "Headphone", 0x6 },
3416			{ "Mixer", 0x5 },
3417		},
3418	},
3419};
3420/*
3421 * This is just place-holder, so there's something for alc_build_pcms to look
3422 * at when it calculates the maximum number of channels. ALC260 has no mixer
3423 * element which allows changing the channel mode, so the verb list is
3424 * never used.
3425 */
3426static struct hda_channel_mode alc260_modes[1] = {
3427	{ 2, NULL },
3428};
3429
3430
3431/* Mixer combinations
3432 *
3433 * basic: base_output + input + pc_beep + capture
3434 * HP: base_output + input + capture_alt
3435 * HP_3013: hp_3013 + input + capture
3436 * fujitsu: fujitsu + capture
3437 * acer: acer + capture
3438 */
3439
3440static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3441	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3442	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3443	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3444	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3445	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3446	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3447	{ } /* end */
3448};
3449
3450static struct snd_kcontrol_new alc260_input_mixer[] = {
3451	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3452	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3453	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3454	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3455	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3456	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3457	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3458	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3459	{ } /* end */
3460};
3461
3462static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3463	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3464	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3465	{ } /* end */
3466};
3467
3468static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3469	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3470	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3471	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3472	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3473	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3474	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3475	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3476	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3477	{ } /* end */
3478};
3479
3480/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3481 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3482 */
3483static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3484	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3485	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3486	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3487	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3488	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3489	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3490	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3491	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3492	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3493	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3494	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3495	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3496	{ } /* end */
3497};
3498
3499/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3500 * versions of the ALC260 don't act on requests to enable mic bias from NID
3501 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3502 * datasheet doesn't mention this restriction.  At this stage it's not clear
3503 * whether this behaviour is intentional or is a hardware bug in chip
3504 * revisions available in early 2006.  Therefore for now allow the
3505 * "Headphone Jack Mode" control to span all choices, but if it turns out
3506 * that the lack of mic bias for this NID is intentional we could change the
3507 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3508 *
3509 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3510 * don't appear to make the mic bias available from the "line" jack, even
3511 * though the NID used for this jack (0x14) can supply it.  The theory is
3512 * that perhaps Acer have included blocking capacitors between the ALC260
3513 * and the output jack.  If this turns out to be the case for all such
3514 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3515 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3516 *
3517 * The C20x Tablet series have a mono internal speaker which is controlled
3518 * via the chip's Mono sum widget and pin complex, so include the necessary
3519 * controls for such models.  On models without a "mono speaker" the control
3520 * won't do anything.
3521 */
3522static struct snd_kcontrol_new alc260_acer_mixer[] = {
3523	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3524	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3525	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3526	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3527			      HDA_OUTPUT),
3528	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3529			   HDA_INPUT),
3530	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3531	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, 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	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3535	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3536	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3537	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3538	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3539	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3540	{ } /* end */
3541};
3542
3543/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3544 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3545 */
3546static struct snd_kcontrol_new alc260_will_mixer[] = {
3547	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3548	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3549	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3550	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3551	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3552	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3553	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3554	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3555	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3556	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3557	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3558	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3559	{ } /* end */
3560};
3561
3562/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3563 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3564 */
3565static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3566	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3567	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3568	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3569	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3570	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3571	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3572	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3573	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3574	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3575	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3576	{ } /* end */
3577};
3578
3579/* capture mixer elements */
3580static struct snd_kcontrol_new alc260_capture_mixer[] = {
3581	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3582	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3583	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3584	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3585	{
3586		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3587		/* .name = "Capture Source", */
3588		.name = "Input Source",
3589		.count = 2,
3590		.info = alc_mux_enum_info,
3591		.get = alc_mux_enum_get,
3592		.put = alc_mux_enum_put,
3593	},
3594	{ } /* end */
3595};
3596
3597static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3598	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3599	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3600	{
3601		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3602		/* .name = "Capture Source", */
3603		.name = "Input Source",
3604		.count = 1,
3605		.info = alc_mux_enum_info,
3606		.get = alc_mux_enum_get,
3607		.put = alc_mux_enum_put,
3608	},
3609	{ } /* end */
3610};
3611
3612/*
3613 * initialization verbs
3614 */
3615static struct hda_verb alc260_init_verbs[] = {
3616	/* Line In pin widget for input */
3617	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3618	/* CD pin widget for input */
3619	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3620	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3621	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3622	/* Mic2 (front panel) pin widget for input and vref at 80% */
3623	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3624	/* LINE-2 is used for line-out in rear */
3625	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3626	/* select line-out */
3627	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3628	/* LINE-OUT pin */
3629	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3630	/* enable HP */
3631	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3632	/* enable Mono */
3633	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3634	/* mute capture amp left and right */
3635	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3636	/* set connection select to line in (default select for this ADC) */
3637	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3638	/* mute capture amp left and right */
3639	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3640	/* set connection select to line in (default select for this ADC) */
3641	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3642	/* set vol=0 Line-Out mixer amp left and right */
3643	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3644	/* unmute pin widget amp left and right (no gain on this amp) */
3645	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3646	/* set vol=0 HP mixer amp left and right */
3647	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3648	/* unmute pin widget amp left and right (no gain on this amp) */
3649	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3650	/* set vol=0 Mono mixer amp left and right */
3651	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3652	/* unmute pin widget amp left and right (no gain on this amp) */
3653	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3654	/* unmute LINE-2 out pin */
3655	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3656	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3657	 * Line In 2 = 0x03
3658	 */
3659	/* mute CD */
3660	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3661	/* mute Line In */
3662	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3663	/* mute Mic */
3664	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3665	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3666	/* mute Front out path */
3667	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3668	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3669	/* mute Headphone out path */
3670	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3671	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3672	/* mute Mono out path */
3673	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3674	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3675	{ }
3676};
3677
3678
3679static struct hda_verb alc260_hp_3013_init_verbs[] = {
3680	/* Line out and output */
3681	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3682	/* mono output */
3683	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3684	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3685	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3686	/* Mic2 (front panel) pin widget for input and vref at 80% */
3687	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3688	/* Line In pin widget for input */
3689	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3690	/* Headphone pin widget for output */
3691	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3692	/* CD pin widget for input */
3693	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3694	/* unmute amp left and right */
3695	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3696	/* set connection select to line in (default select for this ADC) */
3697	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3698	/* unmute Line-Out mixer amp left and right (volume = 0) */
3699	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3700	/* mute pin widget amp left and right (no gain on this amp) */
3701	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3702	/* unmute HP mixer amp left and right (volume = 0) */
3703	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3704	/* mute pin widget amp left and right (no gain on this amp) */
3705	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3706	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3707	 * Line In 2 = 0x03
3708	 */
3709	/* unmute CD */
3710	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3711	/* unmute Line In */
3712	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3713	/* unmute Mic */
3714	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3715	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3716	/* Unmute Front out path */
3717	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3718	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3719	/* Unmute Headphone out path */
3720	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3721	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3722	/* Unmute Mono out path */
3723	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3724	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3725	{ }
3726};
3727
3728/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3729 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3730 * audio = 0x16, internal speaker = 0x10.
3731 */
3732static struct hda_verb alc260_fujitsu_init_verbs[] = {
3733	/* Disable all GPIOs */
3734	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3735	/* Internal speaker is connected to headphone pin */
3736	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3737	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3738	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3739	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3740	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3741	/* Ensure all other unused pins are disabled and muted. */
3742	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3743	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3744	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3745	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3746	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3747	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3748	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3749	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3750
3751	/* Disable digital (SPDIF) pins */
3752	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3753	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3754
3755	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3756	 * when acting as an output.
3757	 */
3758	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3759
3760	/* Start with output sum widgets muted and their output gains at min */
3761	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3762	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3763	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3764	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3765	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3766	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3767	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3768	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3769	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3770
3771	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3772	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3773	/* Unmute Line1 pin widget output buffer since it starts as an output.
3774	 * If the pin mode is changed by the user the pin mode control will
3775	 * take care of enabling the pin's input/output buffers as needed.
3776	 * Therefore there's no need to enable the input buffer at this
3777	 * stage.
3778	 */
3779	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3780	/* Unmute input buffer of pin widget used for Line-in (no equiv
3781	 * mixer ctrl)
3782	 */
3783	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3784
3785	/* Mute capture amp left and right */
3786	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3787	/* Set ADC connection select to match default mixer setting - line
3788	 * in (on mic1 pin)
3789	 */
3790	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3791
3792	/* Do the same for the second ADC: mute capture input amp and
3793	 * set ADC connection to line in (on mic1 pin)
3794	 */
3795	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3796	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3797
3798	/* Mute all inputs to mixer widget (even unconnected ones) */
3799	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3800	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3801	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3802	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3803	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3804	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3805	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3806	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3807
3808	{ }
3809};
3810
3811/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3812 * similar laptops (adapted from Fujitsu init verbs).
3813 */
3814static struct hda_verb alc260_acer_init_verbs[] = {
3815	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3816	 * the headphone jack.  Turn this on and rely on the standard mute
3817	 * methods whenever the user wants to turn these outputs off.
3818	 */
3819	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3820	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3821	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3822	/* Internal speaker/Headphone jack is connected to Line-out pin */
3823	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3824	/* Internal microphone/Mic jack is connected to Mic1 pin */
3825	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3826	/* Line In jack is connected to Line1 pin */
3827	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3828	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3829	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3830	/* Ensure all other unused pins are disabled and muted. */
3831	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3832	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3833	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3834	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3835	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3836	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3837	/* Disable digital (SPDIF) pins */
3838	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3839	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3840
3841	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3842	 * bus when acting as outputs.
3843	 */
3844	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3845	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3846
3847	/* Start with output sum widgets muted and their output gains at min */
3848	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3849	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3850	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3851	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3852	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3853	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3854	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3855	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3856	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3857
3858	/* Unmute Line-out pin widget amp left and right
3859	 * (no equiv mixer ctrl)
3860	 */
3861	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3862	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3863	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3864	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
3865	 * inputs. If the pin mode is changed by the user the pin mode control
3866	 * will take care of enabling the pin's input/output buffers as needed.
3867	 * Therefore there's no need to enable the input buffer at this
3868	 * stage.
3869	 */
3870	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3871	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3872
3873	/* Mute capture amp left and right */
3874	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3875	/* Set ADC connection select to match default mixer setting - mic
3876	 * (on mic1 pin)
3877	 */
3878	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3879
3880	/* Do similar with the second ADC: mute capture input amp and
3881	 * set ADC connection to mic to match ALSA's default state.
3882	 */
3883	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3884	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3885
3886	/* Mute all inputs to mixer widget (even unconnected ones) */
3887	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3888	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3889	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3890	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3891	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3892	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3893	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3894	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3895
3896	{ }
3897};
3898
3899static struct hda_verb alc260_will_verbs[] = {
3900	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3901	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
3902	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
3903	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3904	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
3905	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
3906	{}
3907};
3908
3909static struct hda_verb alc260_replacer_672v_verbs[] = {
3910	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3911	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
3912	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
3913
3914	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3915	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3916	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
3917
3918	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3919	{}
3920};
3921
3922/* toggle speaker-output according to the hp-jack state */
3923static void alc260_replacer_672v_automute(struct hda_codec *codec)
3924{
3925        unsigned int present;
3926
3927	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
3928        present = snd_hda_codec_read(codec, 0x0f, 0,
3929                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
3930	if (present) {
3931		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
3932		snd_hda_codec_write(codec, 0x0f, 0,
3933				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
3934	} else {
3935		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3936		snd_hda_codec_write(codec, 0x0f, 0,
3937				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3938	}
3939}
3940
3941static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
3942                                       unsigned int res)
3943{
3944        if ((res >> 26) == ALC880_HP_EVENT)
3945                alc260_replacer_672v_automute(codec);
3946}
3947
3948/* Test configuration for debugging, modelled after the ALC880 test
3949 * configuration.
3950 */
3951#ifdef CONFIG_SND_DEBUG
3952static hda_nid_t alc260_test_dac_nids[1] = {
3953	0x02,
3954};
3955static hda_nid_t alc260_test_adc_nids[2] = {
3956	0x04, 0x05,
3957};
3958/* For testing the ALC260, each input MUX needs its own definition since
3959 * the signal assignments are different.  This assumes that the first ADC
3960 * is NID 0x04.
3961 */
3962static struct hda_input_mux alc260_test_capture_sources[2] = {
3963	{
3964		.num_items = 7,
3965		.items = {
3966			{ "MIC1 pin", 0x0 },
3967			{ "MIC2 pin", 0x1 },
3968			{ "LINE1 pin", 0x2 },
3969			{ "LINE2 pin", 0x3 },
3970			{ "CD pin", 0x4 },
3971			{ "LINE-OUT pin", 0x5 },
3972			{ "HP-OUT pin", 0x6 },
3973		},
3974        },
3975	{
3976		.num_items = 8,
3977		.items = {
3978			{ "MIC1 pin", 0x0 },
3979			{ "MIC2 pin", 0x1 },
3980			{ "LINE1 pin", 0x2 },
3981			{ "LINE2 pin", 0x3 },
3982			{ "CD pin", 0x4 },
3983			{ "Mixer", 0x5 },
3984			{ "LINE-OUT pin", 0x6 },
3985			{ "HP-OUT pin", 0x7 },
3986		},
3987        },
3988};
3989static struct snd_kcontrol_new alc260_test_mixer[] = {
3990	/* Output driver widgets */
3991	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3992	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3993	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3994	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
3995	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3996	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
3997
3998	/* Modes for retasking pin widgets
3999	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4000         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4001         * mention this restriction.  At this stage it's not clear whether
4002         * this behaviour is intentional or is a hardware bug in chip
4003         * revisions available at least up until early 2006.  Therefore for
4004         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4005         * choices, but if it turns out that the lack of mic bias for these
4006         * NIDs is intentional we could change their modes from
4007         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4008	 */
4009	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4010	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4011	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4012	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4013	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4014	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4015
4016	/* Loopback mixer controls */
4017	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4018	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4019	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4020	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4021	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4022	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4023	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4024	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4025	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4026	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4027	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4028	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4029	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4030	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4031	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4032	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4033
4034	/* Controls for GPIO pins, assuming they are configured as outputs */
4035	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4036	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4037	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4038	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4039
4040	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4041	 * is ambigious as to which NID is which; testing on laptops which
4042	 * make this output available should provide clarification.
4043	 */
4044	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4045	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4046
4047	{ } /* end */
4048};
4049static struct hda_verb alc260_test_init_verbs[] = {
4050	/* Enable all GPIOs as outputs with an initial value of 0 */
4051	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4052	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4053	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4054
4055	/* Enable retasking pins as output, initially without power amp */
4056	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4057	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4058	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4059	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4060	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4061	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4062
4063	/* Disable digital (SPDIF) pins initially, but users can enable
4064	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4065	 * payload also sets the generation to 0, output to be in "consumer"
4066	 * PCM format, copyright asserted, no pre-emphasis and no validity
4067	 * control.
4068	 */
4069	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4070	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4071
4072	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4073	 * OUT1 sum bus when acting as an output.
4074	 */
4075	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4076	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4077	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4078	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4079
4080	/* Start with output sum widgets muted and their output gains at min */
4081	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4082	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4083	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4084	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4085	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4086	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4087	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4088	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4089	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4090
4091	/* Unmute retasking pin widget output buffers since the default
4092	 * state appears to be output.  As the pin mode is changed by the
4093	 * user the pin mode control will take care of enabling the pin's
4094	 * input/output buffers as needed.
4095	 */
4096	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4097	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4098	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4099	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4100	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4101	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4102	/* Also unmute the mono-out pin widget */
4103	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4104
4105	/* Mute capture amp left and right */
4106	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4107	/* Set ADC connection select to match default mixer setting (mic1
4108	 * pin)
4109	 */
4110	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4111
4112	/* Do the same for the second ADC: mute capture input amp and
4113	 * set ADC connection to mic1 pin
4114	 */
4115	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4116	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4117
4118	/* Mute all inputs to mixer widget (even unconnected ones) */
4119	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4120	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4121	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4122	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4123	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4124	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4125	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4126	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4127
4128	{ }
4129};
4130#endif
4131
4132static struct hda_pcm_stream alc260_pcm_analog_playback = {
4133	.substreams = 1,
4134	.channels_min = 2,
4135	.channels_max = 2,
4136};
4137
4138static struct hda_pcm_stream alc260_pcm_analog_capture = {
4139	.substreams = 1,
4140	.channels_min = 2,
4141	.channels_max = 2,
4142};
4143
4144#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4145#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4146
4147/*
4148 * for BIOS auto-configuration
4149 */
4150
4151static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4152					const char *pfx)
4153{
4154	hda_nid_t nid_vol;
4155	unsigned long vol_val, sw_val;
4156	char name[32];
4157	int err;
4158
4159	if (nid >= 0x0f && nid < 0x11) {
4160		nid_vol = nid - 0x7;
4161		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4162		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4163	} else if (nid == 0x11) {
4164		nid_vol = nid - 0x7;
4165		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4166		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4167	} else if (nid >= 0x12 && nid <= 0x15) {
4168		nid_vol = 0x08;
4169		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4170		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4171	} else
4172		return 0; /* N/A */
4173
4174	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4175	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4176	if (err < 0)
4177		return err;
4178	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4179	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4180	if (err < 0)
4181		return err;
4182	return 1;
4183}
4184
4185/* add playback controls from the parsed DAC table */
4186static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4187					     const struct auto_pin_cfg *cfg)
4188{
4189	hda_nid_t nid;
4190	int err;
4191
4192	spec->multiout.num_dacs = 1;
4193	spec->multiout.dac_nids = spec->private_dac_nids;
4194	spec->multiout.dac_nids[0] = 0x02;
4195
4196	nid = cfg->line_out_pins[0];
4197	if (nid) {
4198		err = alc260_add_playback_controls(spec, nid, "Front");
4199		if (err < 0)
4200			return err;
4201	}
4202
4203	nid = cfg->speaker_pins[0];
4204	if (nid) {
4205		err = alc260_add_playback_controls(spec, nid, "Speaker");
4206		if (err < 0)
4207			return err;
4208	}
4209
4210	nid = cfg->hp_pins[0];
4211	if (nid) {
4212		err = alc260_add_playback_controls(spec, nid, "Headphone");
4213		if (err < 0)
4214			return err;
4215	}
4216	return 0;
4217}
4218
4219/* create playback/capture controls for input pins */
4220static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4221						const struct auto_pin_cfg *cfg)
4222{
4223	struct hda_input_mux *imux = &spec->private_imux;
4224	int i, err, idx;
4225
4226	for (i = 0; i < AUTO_PIN_LAST; i++) {
4227		if (cfg->input_pins[i] >= 0x12) {
4228			idx = cfg->input_pins[i] - 0x12;
4229			err = new_analog_input(spec, cfg->input_pins[i],
4230					       auto_pin_cfg_labels[i], idx,
4231					       0x07);
4232			if (err < 0)
4233				return err;
4234			imux->items[imux->num_items].label =
4235				auto_pin_cfg_labels[i];
4236			imux->items[imux->num_items].index = idx;
4237			imux->num_items++;
4238		}
4239		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4240			idx = cfg->input_pins[i] - 0x09;
4241			err = new_analog_input(spec, cfg->input_pins[i],
4242					       auto_pin_cfg_labels[i], idx,
4243					       0x07);
4244			if (err < 0)
4245				return err;
4246			imux->items[imux->num_items].label =
4247				auto_pin_cfg_labels[i];
4248			imux->items[imux->num_items].index = idx;
4249			imux->num_items++;
4250		}
4251	}
4252	return 0;
4253}
4254
4255static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4256					      hda_nid_t nid, int pin_type,
4257					      int sel_idx)
4258{
4259	/* set as output */
4260	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4261			    pin_type);
4262	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4263			    AMP_OUT_UNMUTE);
4264	/* need the manual connection? */
4265	if (nid >= 0x12) {
4266		int idx = nid - 0x12;
4267		snd_hda_codec_write(codec, idx + 0x0b, 0,
4268				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4269	}
4270}
4271
4272static void alc260_auto_init_multi_out(struct hda_codec *codec)
4273{
4274	struct alc_spec *spec = codec->spec;
4275	hda_nid_t nid;
4276
4277	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4278	nid = spec->autocfg.line_out_pins[0];
4279	if (nid) {
4280		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4281		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4282	}
4283
4284	nid = spec->autocfg.speaker_pins[0];
4285	if (nid)
4286		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4287
4288	nid = spec->autocfg.hp_pins[0];
4289	if (nid)
4290		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4291}
4292
4293#define ALC260_PIN_CD_NID		0x16
4294static void alc260_auto_init_analog_input(struct hda_codec *codec)
4295{
4296	struct alc_spec *spec = codec->spec;
4297	int i;
4298
4299	for (i = 0; i < AUTO_PIN_LAST; i++) {
4300		hda_nid_t nid = spec->autocfg.input_pins[i];
4301		if (nid >= 0x12) {
4302			snd_hda_codec_write(codec, nid, 0,
4303					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4304					    i <= AUTO_PIN_FRONT_MIC ?
4305					    PIN_VREF80 : PIN_IN);
4306			if (nid != ALC260_PIN_CD_NID)
4307				snd_hda_codec_write(codec, nid, 0,
4308						    AC_VERB_SET_AMP_GAIN_MUTE,
4309						    AMP_OUT_MUTE);
4310		}
4311	}
4312}
4313
4314/*
4315 * generic initialization of ADC, input mixers and output mixers
4316 */
4317static struct hda_verb alc260_volume_init_verbs[] = {
4318	/*
4319	 * Unmute ADC0-1 and set the default input to mic-in
4320	 */
4321	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4322	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4323	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4324	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4325
4326	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4327	 * mixer widget
4328	 * Note: PASD motherboards uses the Line In 2 as the input for
4329	 * front panel mic (mic 2)
4330	 */
4331	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4332	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4333	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4334	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4335	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4336	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4337
4338	/*
4339	 * Set up output mixers (0x08 - 0x0a)
4340	 */
4341	/* set vol=0 to output mixers */
4342	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4343	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4344	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4345	/* set up input amps for analog loopback */
4346	/* Amp Indices: DAC = 0, mixer = 1 */
4347	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4348	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4349	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4350	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4351	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4352	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4353
4354	{ }
4355};
4356
4357static int alc260_parse_auto_config(struct hda_codec *codec)
4358{
4359	struct alc_spec *spec = codec->spec;
4360	unsigned int wcap;
4361	int err;
4362	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4363
4364	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4365					   alc260_ignore);
4366	if (err < 0)
4367		return err;
4368	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4369	if (err < 0)
4370		return err;
4371	if (!spec->kctl_alloc)
4372		return 0; /* can't find valid BIOS pin config */
4373	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4374	if (err < 0)
4375		return err;
4376
4377	spec->multiout.max_channels = 2;
4378
4379	if (spec->autocfg.dig_out_pin)
4380		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4381	if (spec->kctl_alloc)
4382		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4383
4384	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4385
4386	spec->num_mux_defs = 1;
4387	spec->input_mux = &spec->private_imux;
4388
4389	/* check whether NID 0x04 is valid */
4390	wcap = get_wcaps(codec, 0x04);
4391	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4392	if (wcap != AC_WID_AUD_IN) {
4393		spec->adc_nids = alc260_adc_nids_alt;
4394		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4395		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4396	} else {
4397		spec->adc_nids = alc260_adc_nids;
4398		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4399		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4400	}
4401	spec->num_mixers++;
4402
4403	return 1;
4404}
4405
4406/* additional initialization for auto-configuration model */
4407static void alc260_auto_init(struct hda_codec *codec)
4408{
4409	alc260_auto_init_multi_out(codec);
4410	alc260_auto_init_analog_input(codec);
4411}
4412
4413/*
4414 * ALC260 configurations
4415 */
4416static const char *alc260_models[ALC260_MODEL_LAST] = {
4417	[ALC260_BASIC]		= "basic",
4418	[ALC260_HP]		= "hp",
4419	[ALC260_HP_3013]	= "hp-3013",
4420	[ALC260_FUJITSU_S702X]	= "fujitsu",
4421	[ALC260_ACER]		= "acer",
4422	[ALC260_WILL]		= "will",
4423	[ALC260_REPLACER_672V]	= "replacer",
4424#ifdef CONFIG_SND_DEBUG
4425	[ALC260_TEST]		= "test",
4426#endif
4427	[ALC260_AUTO]		= "auto",
4428};
4429
4430static struct snd_pci_quirk alc260_cfg_tbl[] = {
4431	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4432	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4433	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4434	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4435	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4436	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4437	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4438	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4439	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4440	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4441	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4442	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4443	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4444	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4445	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4446	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4447	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4448	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4449	{}
4450};
4451
4452static struct alc_config_preset alc260_presets[] = {
4453	[ALC260_BASIC] = {
4454		.mixers = { alc260_base_output_mixer,
4455			    alc260_input_mixer,
4456			    alc260_pc_beep_mixer,
4457			    alc260_capture_mixer },
4458		.init_verbs = { alc260_init_verbs },
4459		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4460		.dac_nids = alc260_dac_nids,
4461		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4462		.adc_nids = alc260_adc_nids,
4463		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4464		.channel_mode = alc260_modes,
4465		.input_mux = &alc260_capture_source,
4466	},
4467	[ALC260_HP] = {
4468		.mixers = { alc260_base_output_mixer,
4469			    alc260_input_mixer,
4470			    alc260_capture_alt_mixer },
4471		.init_verbs = { alc260_init_verbs },
4472		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4473		.dac_nids = alc260_dac_nids,
4474		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4475		.adc_nids = alc260_hp_adc_nids,
4476		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4477		.channel_mode = alc260_modes,
4478		.input_mux = &alc260_capture_source,
4479	},
4480	[ALC260_HP_3013] = {
4481		.mixers = { alc260_hp_3013_mixer,
4482			    alc260_input_mixer,
4483			    alc260_capture_alt_mixer },
4484		.init_verbs = { alc260_hp_3013_init_verbs },
4485		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4486		.dac_nids = alc260_dac_nids,
4487		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4488		.adc_nids = alc260_hp_adc_nids,
4489		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4490		.channel_mode = alc260_modes,
4491		.input_mux = &alc260_capture_source,
4492	},
4493	[ALC260_FUJITSU_S702X] = {
4494		.mixers = { alc260_fujitsu_mixer,
4495			    alc260_capture_mixer },
4496		.init_verbs = { alc260_fujitsu_init_verbs },
4497		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4498		.dac_nids = alc260_dac_nids,
4499		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4500		.adc_nids = alc260_dual_adc_nids,
4501		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4502		.channel_mode = alc260_modes,
4503		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4504		.input_mux = alc260_fujitsu_capture_sources,
4505	},
4506	[ALC260_ACER] = {
4507		.mixers = { alc260_acer_mixer,
4508			    alc260_capture_mixer },
4509		.init_verbs = { alc260_acer_init_verbs },
4510		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4511		.dac_nids = alc260_dac_nids,
4512		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4513		.adc_nids = alc260_dual_adc_nids,
4514		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4515		.channel_mode = alc260_modes,
4516		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4517		.input_mux = alc260_acer_capture_sources,
4518	},
4519	[ALC260_WILL] = {
4520		.mixers = { alc260_will_mixer,
4521			    alc260_capture_mixer },
4522		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4523		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4524		.dac_nids = alc260_dac_nids,
4525		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4526		.adc_nids = alc260_adc_nids,
4527		.dig_out_nid = ALC260_DIGOUT_NID,
4528		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4529		.channel_mode = alc260_modes,
4530		.input_mux = &alc260_capture_source,
4531	},
4532	[ALC260_REPLACER_672V] = {
4533		.mixers = { alc260_replacer_672v_mixer,
4534			    alc260_capture_mixer },
4535		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4536		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4537		.dac_nids = alc260_dac_nids,
4538		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4539		.adc_nids = alc260_adc_nids,
4540		.dig_out_nid = ALC260_DIGOUT_NID,
4541		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4542		.channel_mode = alc260_modes,
4543		.input_mux = &alc260_capture_source,
4544		.unsol_event = alc260_replacer_672v_unsol_event,
4545		.init_hook = alc260_replacer_672v_automute,
4546	},
4547#ifdef CONFIG_SND_DEBUG
4548	[ALC260_TEST] = {
4549		.mixers = { alc260_test_mixer,
4550			    alc260_capture_mixer },
4551		.init_verbs = { alc260_test_init_verbs },
4552		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4553		.dac_nids = alc260_test_dac_nids,
4554		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4555		.adc_nids = alc260_test_adc_nids,
4556		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4557		.channel_mode = alc260_modes,
4558		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4559		.input_mux = alc260_test_capture_sources,
4560	},
4561#endif
4562};
4563
4564static int patch_alc260(struct hda_codec *codec)
4565{
4566	struct alc_spec *spec;
4567	int err, board_config;
4568
4569	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4570	if (spec == NULL)
4571		return -ENOMEM;
4572
4573	codec->spec = spec;
4574
4575	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4576						  alc260_models,
4577						  alc260_cfg_tbl);
4578	if (board_config < 0) {
4579		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4580			   "trying auto-probe from BIOS...\n");
4581		board_config = ALC260_AUTO;
4582	}
4583
4584	if (board_config == ALC260_AUTO) {
4585		/* automatic parse from the BIOS config */
4586		err = alc260_parse_auto_config(codec);
4587		if (err < 0) {
4588			alc_free(codec);
4589			return err;
4590		} else if (!err) {
4591			printk(KERN_INFO
4592			       "hda_codec: Cannot set up configuration "
4593			       "from BIOS.  Using base mode...\n");
4594			board_config = ALC260_BASIC;
4595		}
4596	}
4597
4598	if (board_config != ALC260_AUTO)
4599		setup_preset(spec, &alc260_presets[board_config]);
4600
4601	spec->stream_name_analog = "ALC260 Analog";
4602	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4603	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4604
4605	spec->stream_name_digital = "ALC260 Digital";
4606	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4607	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4608
4609	codec->patch_ops = alc_patch_ops;
4610	if (board_config == ALC260_AUTO)
4611		spec->init_hook = alc260_auto_init;
4612
4613	return 0;
4614}
4615
4616
4617/*
4618 * ALC882 support
4619 *
4620 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4621 * configuration.  Each pin widget can choose any input DACs and a mixer.
4622 * Each ADC is connected from a mixer of all inputs.  This makes possible
4623 * 6-channel independent captures.
4624 *
4625 * In addition, an independent DAC for the multi-playback (not used in this
4626 * driver yet).
4627 */
4628#define ALC882_DIGOUT_NID	0x06
4629#define ALC882_DIGIN_NID	0x0a
4630
4631static struct hda_channel_mode alc882_ch_modes[1] = {
4632	{ 8, NULL }
4633};
4634
4635static hda_nid_t alc882_dac_nids[4] = {
4636	/* front, rear, clfe, rear_surr */
4637	0x02, 0x03, 0x04, 0x05
4638};
4639
4640/* identical with ALC880 */
4641#define alc882_adc_nids		alc880_adc_nids
4642#define alc882_adc_nids_alt	alc880_adc_nids_alt
4643
4644/* input MUX */
4645
4646static struct hda_input_mux alc882_capture_source = {
4647	.num_items = 4,
4648	.items = {
4649		{ "Mic", 0x0 },
4650		{ "Front Mic", 0x1 },
4651		{ "Line", 0x2 },
4652		{ "CD", 0x4 },
4653	},
4654};
4655#define alc882_mux_enum_info alc_mux_enum_info
4656#define alc882_mux_enum_get alc_mux_enum_get
4657
4658static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4659			       struct snd_ctl_elem_value *ucontrol)
4660{
4661	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4662	struct alc_spec *spec = codec->spec;
4663	const struct hda_input_mux *imux = spec->input_mux;
4664	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4665	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4666	hda_nid_t nid = capture_mixers[adc_idx];
4667	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4668	unsigned int i, idx;
4669
4670	idx = ucontrol->value.enumerated.item[0];
4671	if (idx >= imux->num_items)
4672		idx = imux->num_items - 1;
4673	if (*cur_val == idx && !codec->in_resume)
4674		return 0;
4675	for (i = 0; i < imux->num_items; i++) {
4676		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4677		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4678				    v | (imux->items[i].index << 8));
4679	}
4680	*cur_val = idx;
4681	return 1;
4682}
4683
4684/*
4685 * 2ch mode
4686 */
4687static struct hda_verb alc882_3ST_ch2_init[] = {
4688	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4689	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4690	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4691	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4692	{ } /* end */
4693};
4694
4695/*
4696 * 6ch mode
4697 */
4698static struct hda_verb alc882_3ST_ch6_init[] = {
4699	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4700	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4701	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4702	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4703	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4704	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4705	{ } /* end */
4706};
4707
4708static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4709	{ 2, alc882_3ST_ch2_init },
4710	{ 6, alc882_3ST_ch6_init },
4711};
4712
4713/*
4714 * 6ch mode
4715 */
4716static struct hda_verb alc882_sixstack_ch6_init[] = {
4717	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4718	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4719	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4720	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4721	{ } /* end */
4722};
4723
4724/*
4725 * 8ch mode
4726 */
4727static struct hda_verb alc882_sixstack_ch8_init[] = {
4728	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4729	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4730	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4731	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4732	{ } /* end */
4733};
4734
4735static struct hda_channel_mode alc882_sixstack_modes[2] = {
4736	{ 6, alc882_sixstack_ch6_init },
4737	{ 8, alc882_sixstack_ch8_init },
4738};
4739
4740/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4741 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4742 */
4743static struct snd_kcontrol_new alc882_base_mixer[] = {
4744	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4745	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4746	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4747	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4748	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4749	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4750	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4751	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4752	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4753	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4754	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4755	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4756	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4757	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4758	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4759	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4760	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4761	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4762	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4763	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4764	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4765	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4766	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4767	{ } /* end */
4768};
4769
4770static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4771	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4772	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4773	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4774	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4775	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4776	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4777	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4778	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4779	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4780	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4781	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4782	{ } /* end */
4783};
4784
4785static struct snd_kcontrol_new alc882_targa_mixer[] = {
4786	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4787	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4788	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4789	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4790	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4791	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4792	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4793	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4794	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4795	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4796	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4797	{ } /* end */
4798};
4799
4800/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4801 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4802 */
4803static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4804	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4805	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4806	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4807	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4808	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4809	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4810	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4811	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4812	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4813	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4814	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4815	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4816	{ } /* end */
4817};
4818
4819static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4820	{
4821		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4822		.name = "Channel Mode",
4823		.info = alc_ch_mode_info,
4824		.get = alc_ch_mode_get,
4825		.put = alc_ch_mode_put,
4826	},
4827	{ } /* end */
4828};
4829
4830static struct hda_verb alc882_init_verbs[] = {
4831	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4832	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4833	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4834	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4835	/* Rear mixer */
4836	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4837	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4838	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4839	/* CLFE mixer */
4840	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4841	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4842	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4843	/* Side mixer */
4844	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4845	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4846	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4847
4848	/* Front Pin: output 0 (0x0c) */
4849	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4850	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4851	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4852	/* Rear Pin: output 1 (0x0d) */
4853	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4854	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4855	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4856	/* CLFE Pin: output 2 (0x0e) */
4857	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4858	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4859	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4860	/* Side Pin: output 3 (0x0f) */
4861	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4862	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4863	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4864	/* Mic (rear) pin: input vref at 80% */
4865	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4866	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4867	/* Front Mic pin: input vref at 80% */
4868	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4869	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4870	/* Line In pin: input */
4871	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4872	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4873	/* Line-2 In: Headphone output (output 0 - 0x0c) */
4874	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4875	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4876	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4877	/* CD pin widget for input */
4878	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4879
4880	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4881	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4882	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4883	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4884	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4885	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4886	/* Input mixer2 */
4887	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4888	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4889	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4890	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4891	/* Input mixer3 */
4892	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4893	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4894	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4895	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4896	/* ADC1: mute amp left and right */
4897	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4898	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4899	/* ADC2: mute amp left and right */
4900	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4901	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4902	/* ADC3: mute amp left and right */
4903	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4904	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4905
4906	{ }
4907};
4908
4909static struct hda_verb alc882_eapd_verbs[] = {
4910	/* change to EAPD mode */
4911	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4912	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4913	{ }
4914};
4915
4916/* Mac Pro test */
4917static struct snd_kcontrol_new alc882_macpro_mixer[] = {
4918	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4919	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4920	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
4921	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
4922	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
4923	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
4924	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
4925	{ } /* end */
4926};
4927
4928static struct hda_verb alc882_macpro_init_verbs[] = {
4929	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4930	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4931	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4932	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4933	/* Front Pin: output 0 (0x0c) */
4934	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4935	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4936	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
4937	/* Front Mic pin: input vref at 80% */
4938	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4939	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4940	/* Speaker:  output */
4941	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4942	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4943	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
4944	/* Headphone output (output 0 - 0x0c) */
4945	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4946	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4947	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
4948
4949	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4950	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4951	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4952	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4953	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4954	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4955	/* Input mixer2 */
4956	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4957	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4958	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4959	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4960	/* Input mixer3 */
4961	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4962	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4963	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4964	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4965	/* ADC1: mute amp left and right */
4966	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4967	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4968	/* ADC2: mute amp left and right */
4969	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4970	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4971	/* ADC3: mute amp left and right */
4972	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4973	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4974
4975	{ }
4976};
4977
4978static struct hda_verb alc882_targa_verbs[] = {
4979	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4980	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4981
4982	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4983	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4984
4985	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4986	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
4987	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4988
4989	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4990	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
4991	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
4992	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
4993	{ } /* end */
4994};
4995
4996/* toggle speaker-output according to the hp-jack state */
4997static void alc882_targa_automute(struct hda_codec *codec)
4998{
4999 	unsigned int present;
5000
5001 	present = snd_hda_codec_read(codec, 0x14, 0,
5002				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5003	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5004				 0x80, present ? 0x80 : 0);
5005	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5006				 0x80, present ? 0x80 : 0);
5007	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5008}
5009
5010static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5011{
5012	/* Looks like the unsol event is incompatible with the standard
5013	 * definition.  4bit tag is placed at 26 bit!
5014	 */
5015	if (((res >> 26) == ALC880_HP_EVENT)) {
5016		alc882_targa_automute(codec);
5017	}
5018}
5019
5020static struct hda_verb alc882_asus_a7j_verbs[] = {
5021	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5022	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5023
5024	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5025	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5026	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5027
5028	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5029	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5030	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5031
5032	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5033	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5034	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5035	{ } /* end */
5036};
5037
5038static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5039{
5040	unsigned int gpiostate, gpiomask, gpiodir;
5041
5042	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5043				       AC_VERB_GET_GPIO_DATA, 0);
5044
5045	if (!muted)
5046		gpiostate |= (1 << pin);
5047	else
5048		gpiostate &= ~(1 << pin);
5049
5050	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5051				      AC_VERB_GET_GPIO_MASK, 0);
5052	gpiomask |= (1 << pin);
5053
5054	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5055				     AC_VERB_GET_GPIO_DIRECTION, 0);
5056	gpiodir |= (1 << pin);
5057
5058
5059	snd_hda_codec_write(codec, codec->afg, 0,
5060			    AC_VERB_SET_GPIO_MASK, gpiomask);
5061	snd_hda_codec_write(codec, codec->afg, 0,
5062			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5063
5064	msleep(1);
5065
5066	snd_hda_codec_write(codec, codec->afg, 0,
5067			    AC_VERB_SET_GPIO_DATA, gpiostate);
5068}
5069
5070/*
5071 * generic initialization of ADC, input mixers and output mixers
5072 */
5073static struct hda_verb alc882_auto_init_verbs[] = {
5074	/*
5075	 * Unmute ADC0-2 and set the default input to mic-in
5076	 */
5077	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5078	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5079	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5080	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5081	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5082	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5083
5084	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5085	 * mixer widget
5086	 * Note: PASD motherboards uses the Line In 2 as the input for
5087	 * front panel mic (mic 2)
5088	 */
5089	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5090	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5091	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5092	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5093	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5094	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5095
5096	/*
5097	 * Set up output mixers (0x0c - 0x0f)
5098	 */
5099	/* set vol=0 to output mixers */
5100	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5101	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5102	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5103	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5104	/* set up input amps for analog loopback */
5105	/* Amp Indices: DAC = 0, mixer = 1 */
5106	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5107	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5108	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5109	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5110	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5111	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5112	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5113	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5114	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5115	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5116
5117	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5118	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5119	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5120	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5121	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5122	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5123	/* Input mixer2 */
5124	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5125	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5126	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5127	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5128	/* Input mixer3 */
5129	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5130	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5131	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5132	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5133
5134	{ }
5135};
5136
5137/* capture mixer elements */
5138static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5139	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5140	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5141	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5142	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5143	{
5144		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5145		/* .name = "Capture Source", */
5146		.name = "Input Source",
5147		.count = 2,
5148		.info = alc882_mux_enum_info,
5149		.get = alc882_mux_enum_get,
5150		.put = alc882_mux_enum_put,
5151	},
5152	{ } /* end */
5153};
5154
5155static struct snd_kcontrol_new alc882_capture_mixer[] = {
5156	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5157	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5158	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5159	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5160	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5161	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5162	{
5163		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5164		/* .name = "Capture Source", */
5165		.name = "Input Source",
5166		.count = 3,
5167		.info = alc882_mux_enum_info,
5168		.get = alc882_mux_enum_get,
5169		.put = alc882_mux_enum_put,
5170	},
5171	{ } /* end */
5172};
5173
5174/* pcm configuration: identiacal with ALC880 */
5175#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5176#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5177#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5178#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5179
5180/*
5181 * configuration and preset
5182 */
5183static const char *alc882_models[ALC882_MODEL_LAST] = {
5184	[ALC882_3ST_DIG]	= "3stack-dig",
5185	[ALC882_6ST_DIG]	= "6stack-dig",
5186	[ALC882_ARIMA]		= "arima",
5187	[ALC882_W2JC]		= "w2jc",
5188	[ALC885_MACPRO]		= "macpro",
5189	[ALC882_AUTO]		= "auto",
5190};
5191
5192static struct snd_pci_quirk alc882_cfg_tbl[] = {
5193	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5194	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5195	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5196	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5197	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5198	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5199	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5200	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5201	{}
5202};
5203
5204static struct alc_config_preset alc882_presets[] = {
5205	[ALC882_3ST_DIG] = {
5206		.mixers = { alc882_base_mixer },
5207		.init_verbs = { alc882_init_verbs },
5208		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5209		.dac_nids = alc882_dac_nids,
5210		.dig_out_nid = ALC882_DIGOUT_NID,
5211		.dig_in_nid = ALC882_DIGIN_NID,
5212		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5213		.channel_mode = alc882_ch_modes,
5214		.need_dac_fix = 1,
5215		.input_mux = &alc882_capture_source,
5216	},
5217	[ALC882_6ST_DIG] = {
5218		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5219		.init_verbs = { alc882_init_verbs },
5220		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5221		.dac_nids = alc882_dac_nids,
5222		.dig_out_nid = ALC882_DIGOUT_NID,
5223		.dig_in_nid = ALC882_DIGIN_NID,
5224		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5225		.channel_mode = alc882_sixstack_modes,
5226		.input_mux = &alc882_capture_source,
5227	},
5228	[ALC882_ARIMA] = {
5229		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5230		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5231		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5232		.dac_nids = alc882_dac_nids,
5233		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5234		.channel_mode = alc882_sixstack_modes,
5235		.input_mux = &alc882_capture_source,
5236	},
5237	[ALC882_W2JC] = {
5238		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5239		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5240				alc880_gpio1_init_verbs },
5241		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5242		.dac_nids = alc882_dac_nids,
5243		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5244		.channel_mode = alc880_threestack_modes,
5245		.need_dac_fix = 1,
5246		.input_mux = &alc882_capture_source,
5247		.dig_out_nid = ALC882_DIGOUT_NID,
5248	},
5249	[ALC885_MACPRO] = {
5250		.mixers = { alc882_macpro_mixer },
5251		.init_verbs = { alc882_macpro_init_verbs },
5252		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5253		.dac_nids = alc882_dac_nids,
5254		.dig_out_nid = ALC882_DIGOUT_NID,
5255		.dig_in_nid = ALC882_DIGIN_NID,
5256		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5257		.channel_mode = alc882_ch_modes,
5258		.input_mux = &alc882_capture_source,
5259	},
5260	[ALC882_TARGA] = {
5261		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5262			    alc882_capture_mixer },
5263		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5264		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5265		.dac_nids = alc882_dac_nids,
5266		.dig_out_nid = ALC882_DIGOUT_NID,
5267		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5268		.adc_nids = alc882_adc_nids,
5269		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5270		.channel_mode = alc882_3ST_6ch_modes,
5271		.need_dac_fix = 1,
5272		.input_mux = &alc882_capture_source,
5273		.unsol_event = alc882_targa_unsol_event,
5274		.init_hook = alc882_targa_automute,
5275	},
5276	[ALC882_ASUS_A7J] = {
5277		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5278			    alc882_capture_mixer },
5279		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5280		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5281		.dac_nids = alc882_dac_nids,
5282		.dig_out_nid = ALC882_DIGOUT_NID,
5283		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5284		.adc_nids = alc882_adc_nids,
5285		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5286		.channel_mode = alc882_3ST_6ch_modes,
5287		.need_dac_fix = 1,
5288		.input_mux = &alc882_capture_source,
5289	},
5290};
5291
5292
5293/*
5294 * BIOS auto configuration
5295 */
5296static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5297					      hda_nid_t nid, int pin_type,
5298					      int dac_idx)
5299{
5300	/* set as output */
5301	struct alc_spec *spec = codec->spec;
5302	int idx;
5303
5304	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5305		idx = 4;
5306	else
5307		idx = spec->multiout.dac_nids[dac_idx] - 2;
5308
5309	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5310			    pin_type);
5311	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5312			    AMP_OUT_UNMUTE);
5313	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5314
5315}
5316
5317static void alc882_auto_init_multi_out(struct hda_codec *codec)
5318{
5319	struct alc_spec *spec = codec->spec;
5320	int i;
5321
5322	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5323	for (i = 0; i <= HDA_SIDE; i++) {
5324		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5325		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5326		if (nid)
5327			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5328							  i);
5329	}
5330}
5331
5332static void alc882_auto_init_hp_out(struct hda_codec *codec)
5333{
5334	struct alc_spec *spec = codec->spec;
5335	hda_nid_t pin;
5336
5337	pin = spec->autocfg.hp_pins[0];
5338	if (pin) /* connect to front */
5339		/* use dac 0 */
5340		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5341}
5342
5343#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
5344#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
5345
5346static void alc882_auto_init_analog_input(struct hda_codec *codec)
5347{
5348	struct alc_spec *spec = codec->spec;
5349	int i;
5350
5351	for (i = 0; i < AUTO_PIN_LAST; i++) {
5352		hda_nid_t nid = spec->autocfg.input_pins[i];
5353		if (alc882_is_input_pin(nid)) {
5354			snd_hda_codec_write(codec, nid, 0,
5355					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5356					    i <= AUTO_PIN_FRONT_MIC ?
5357					    PIN_VREF80 : PIN_IN);
5358			if (nid != ALC882_PIN_CD_NID)
5359				snd_hda_codec_write(codec, nid, 0,
5360						    AC_VERB_SET_AMP_GAIN_MUTE,
5361						    AMP_OUT_MUTE);
5362		}
5363	}
5364}
5365
5366/* almost identical with ALC880 parser... */
5367static int alc882_parse_auto_config(struct hda_codec *codec)
5368{
5369	struct alc_spec *spec = codec->spec;
5370	int err = alc880_parse_auto_config(codec);
5371
5372	if (err < 0)
5373		return err;
5374	else if (err > 0)
5375		/* hack - override the init verbs */
5376		spec->init_verbs[0] = alc882_auto_init_verbs;
5377	return err;
5378}
5379
5380/* additional initialization for auto-configuration model */
5381static void alc882_auto_init(struct hda_codec *codec)
5382{
5383	alc882_auto_init_multi_out(codec);
5384	alc882_auto_init_hp_out(codec);
5385	alc882_auto_init_analog_input(codec);
5386}
5387
5388static int patch_alc882(struct hda_codec *codec)
5389{
5390	struct alc_spec *spec;
5391	int err, board_config;
5392
5393	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5394	if (spec == NULL)
5395		return -ENOMEM;
5396
5397	codec->spec = spec;
5398
5399	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5400						  alc882_models,
5401						  alc882_cfg_tbl);
5402
5403	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5404		/* Pick up systems that don't supply PCI SSID */
5405		switch (codec->subsystem_id) {
5406		case 0x106b0c00: /* Mac Pro */
5407			board_config = ALC885_MACPRO;
5408			break;
5409		default:
5410			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5411		       			 "trying auto-probe from BIOS...\n");
5412			board_config = ALC882_AUTO;
5413		}
5414	}
5415
5416	if (board_config == ALC882_AUTO) {
5417		/* automatic parse from the BIOS config */
5418		err = alc882_parse_auto_config(codec);
5419		if (err < 0) {
5420			alc_free(codec);
5421			return err;
5422		} else if (!err) {
5423			printk(KERN_INFO
5424			       "hda_codec: Cannot set up configuration "
5425			       "from BIOS.  Using base mode...\n");
5426			board_config = ALC882_3ST_DIG;
5427		}
5428	}
5429
5430	if (board_config != ALC882_AUTO)
5431		setup_preset(spec, &alc882_presets[board_config]);
5432
5433	if (board_config == ALC885_MACPRO) {
5434		alc882_gpio_mute(codec, 0, 0);
5435		alc882_gpio_mute(codec, 1, 0);
5436	}
5437
5438	spec->stream_name_analog = "ALC882 Analog";
5439	spec->stream_analog_playback = &alc882_pcm_analog_playback;
5440	spec->stream_analog_capture = &alc882_pcm_analog_capture;
5441
5442	spec->stream_name_digital = "ALC882 Digital";
5443	spec->stream_digital_playback = &alc882_pcm_digital_playback;
5444	spec->stream_digital_capture = &alc882_pcm_digital_capture;
5445
5446	if (!spec->adc_nids && spec->input_mux) {
5447		/* check whether NID 0x07 is valid */
5448		unsigned int wcap = get_wcaps(codec, 0x07);
5449		/* get type */
5450		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5451		if (wcap != AC_WID_AUD_IN) {
5452			spec->adc_nids = alc882_adc_nids_alt;
5453			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5454			spec->mixers[spec->num_mixers] =
5455				alc882_capture_alt_mixer;
5456			spec->num_mixers++;
5457		} else {
5458			spec->adc_nids = alc882_adc_nids;
5459			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5460			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5461			spec->num_mixers++;
5462		}
5463	}
5464
5465	codec->patch_ops = alc_patch_ops;
5466	if (board_config == ALC882_AUTO)
5467		spec->init_hook = alc882_auto_init;
5468
5469	return 0;
5470}
5471
5472/*
5473 * ALC883 support
5474 *
5475 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5476 * configuration.  Each pin widget can choose any input DACs and a mixer.
5477 * Each ADC is connected from a mixer of all inputs.  This makes possible
5478 * 6-channel independent captures.
5479 *
5480 * In addition, an independent DAC for the multi-playback (not used in this
5481 * driver yet).
5482 */
5483#define ALC883_DIGOUT_NID	0x06
5484#define ALC883_DIGIN_NID	0x0a
5485
5486static hda_nid_t alc883_dac_nids[4] = {
5487	/* front, rear, clfe, rear_surr */
5488	0x02, 0x04, 0x03, 0x05
5489};
5490
5491static hda_nid_t alc883_adc_nids[2] = {
5492	/* ADC1-2 */
5493	0x08, 0x09,
5494};
5495
5496/* input MUX */
5497
5498static struct hda_input_mux alc883_capture_source = {
5499	.num_items = 4,
5500	.items = {
5501		{ "Mic", 0x0 },
5502		{ "Front Mic", 0x1 },
5503		{ "Line", 0x2 },
5504		{ "CD", 0x4 },
5505	},
5506};
5507
5508static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5509	.num_items = 2,
5510	.items = {
5511		{ "Mic", 0x1 },
5512		{ "Line", 0x2 },
5513	},
5514};
5515
5516static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5517	.num_items = 4,
5518	.items = {
5519		{ "Mic", 0x0 },
5520		{ "iMic", 0x1 },
5521		{ "Line", 0x2 },
5522		{ "CD", 0x4 },
5523	},
5524};
5525
5526#define alc883_mux_enum_info alc_mux_enum_info
5527#define alc883_mux_enum_get alc_mux_enum_get
5528
5529static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5530			       struct snd_ctl_elem_value *ucontrol)
5531{
5532	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5533	struct alc_spec *spec = codec->spec;
5534	const struct hda_input_mux *imux = spec->input_mux;
5535	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5536	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5537	hda_nid_t nid = capture_mixers[adc_idx];
5538	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5539	unsigned int i, idx;
5540
5541	idx = ucontrol->value.enumerated.item[0];
5542	if (idx >= imux->num_items)
5543		idx = imux->num_items - 1;
5544	if (*cur_val == idx && !codec->in_resume)
5545		return 0;
5546	for (i = 0; i < imux->num_items; i++) {
5547		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
5548		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5549				    v | (imux->items[i].index << 8));
5550	}
5551	*cur_val = idx;
5552	return 1;
5553}
5554
5555/*
5556 * 2ch mode
5557 */
5558static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5559	{ 2, NULL }
5560};
5561
5562/*
5563 * 2ch mode
5564 */
5565static struct hda_verb alc883_3ST_ch2_init[] = {
5566	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5567	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5568	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5569	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5570	{ } /* end */
5571};
5572
5573/*
5574 * 6ch mode
5575 */
5576static struct hda_verb alc883_3ST_ch6_init[] = {
5577	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5578	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5579	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5580	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5581	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5582	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5583	{ } /* end */
5584};
5585
5586static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5587	{ 2, alc883_3ST_ch2_init },
5588	{ 6, alc883_3ST_ch6_init },
5589};
5590
5591/*
5592 * 6ch mode
5593 */
5594static struct hda_verb alc883_sixstack_ch6_init[] = {
5595	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5596	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5597	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5598	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5599	{ } /* end */
5600};
5601
5602/*
5603 * 8ch mode
5604 */
5605static struct hda_verb alc883_sixstack_ch8_init[] = {
5606	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5607	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5608	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5609	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5610	{ } /* end */
5611};
5612
5613static struct hda_channel_mode alc883_sixstack_modes[2] = {
5614	{ 6, alc883_sixstack_ch6_init },
5615	{ 8, alc883_sixstack_ch8_init },
5616};
5617
5618static struct hda_verb alc883_medion_eapd_verbs[] = {
5619        /* eanable EAPD on medion laptop */
5620	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5621	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5622	{ }
5623};
5624
5625/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5626 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5627 */
5628
5629static struct snd_kcontrol_new alc883_base_mixer[] = {
5630	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5631	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5632	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5633	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5634	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5635	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5636	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5637	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5638	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5639	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5640	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5641	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5642	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5643	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5644	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5645	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5646	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5647	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5648	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5649	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5650	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5651	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5652	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5653	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5654	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5655	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5656	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5657	{
5658		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5659		/* .name = "Capture Source", */
5660		.name = "Input Source",
5661		.count = 2,
5662		.info = alc883_mux_enum_info,
5663		.get = alc883_mux_enum_get,
5664		.put = alc883_mux_enum_put,
5665	},
5666	{ } /* end */
5667};
5668
5669static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5670	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5671	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5672	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5673	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5674	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5675	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5676	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5677	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5678	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5679	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5680	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5681	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5682	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5683	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5684	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5685	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5686	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5687	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5688	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5689	{
5690		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5691		/* .name = "Capture Source", */
5692		.name = "Input Source",
5693		.count = 2,
5694		.info = alc883_mux_enum_info,
5695		.get = alc883_mux_enum_get,
5696		.put = alc883_mux_enum_put,
5697	},
5698	{ } /* end */
5699};
5700
5701static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5702	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5703	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5704	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5705	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5706	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5707	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5708	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5709	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5710	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5711	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5712	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5713	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5714	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5715	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5716	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5717	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5718	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5719	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5720	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5721	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5722	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5723	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5724	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5725	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5726	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5727	{
5728		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5729		/* .name = "Capture Source", */
5730		.name = "Input Source",
5731		.count = 2,
5732		.info = alc883_mux_enum_info,
5733		.get = alc883_mux_enum_get,
5734		.put = alc883_mux_enum_put,
5735	},
5736	{ } /* end */
5737};
5738
5739static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5740	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5741	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5742	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5743	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5744	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5745	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5746	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5747	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5748	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5749	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5750	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5751	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5752	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5753	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5754	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5755	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5756	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5757	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5758	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5759	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5760	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5761	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5762	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5763
5764	{
5765		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5766		/* .name = "Capture Source", */
5767		.name = "Input Source",
5768		.count = 1,
5769		.info = alc883_mux_enum_info,
5770		.get = alc883_mux_enum_get,
5771		.put = alc883_mux_enum_put,
5772	},
5773	{ } /* end */
5774};
5775
5776static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5777	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5778	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5779	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5780	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5781	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5782	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5783	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5784	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5785	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5786	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5787	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5788	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5789	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5790	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5791	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5792	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5793	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5794	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5795	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5796	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5797	{
5798		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5799		/* .name = "Capture Source", */
5800		.name = "Input Source",
5801		.count = 2,
5802		.info = alc883_mux_enum_info,
5803		.get = alc883_mux_enum_get,
5804		.put = alc883_mux_enum_put,
5805	},
5806	{ } /* end */
5807};
5808
5809static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5810	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5811	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5812	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5813	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5814	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5815	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5816	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5817	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5818	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5819	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5820	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5821	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5822	{
5823		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5824		/* .name = "Capture Source", */
5825		.name = "Input Source",
5826		.count = 2,
5827		.info = alc883_mux_enum_info,
5828		.get = alc883_mux_enum_get,
5829		.put = alc883_mux_enum_put,
5830	},
5831	{ } /* end */
5832};
5833
5834static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
5835	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5836	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5837	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5838	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
5839	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5840	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5841	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5842	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5843	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5844	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5845	{
5846		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5847		/* .name = "Capture Source", */
5848		.name = "Input Source",
5849		.count = 1,
5850		.info = alc883_mux_enum_info,
5851		.get = alc883_mux_enum_get,
5852		.put = alc883_mux_enum_put,
5853	},
5854	{ } /* end */
5855};
5856
5857static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
5858	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5859	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
5860	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5861	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5862	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5863	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5864	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5865	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5866	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5867	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5868	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5869	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5870	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5871	{
5872		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5873		/* .name = "Capture Source", */
5874		.name = "Input Source",
5875		.count = 2,
5876		.info = alc883_mux_enum_info,
5877		.get = alc883_mux_enum_get,
5878		.put = alc883_mux_enum_put,
5879	},
5880	{ } /* end */
5881};
5882
5883static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
5884	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5885	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5886	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5887	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5888	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5889	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5890	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5891	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5892	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5893	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5894	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5895	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5896	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5897	{
5898		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5899		/* .name = "Capture Source", */
5900		.name = "Input Source",
5901		.count = 2,
5902		.info = alc883_mux_enum_info,
5903		.get = alc883_mux_enum_get,
5904		.put = alc883_mux_enum_put,
5905	},
5906	{ } /* end */
5907};
5908
5909static struct snd_kcontrol_new alc883_chmode_mixer[] = {
5910	{
5911		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5912		.name = "Channel Mode",
5913		.info = alc_ch_mode_info,
5914		.get = alc_ch_mode_get,
5915		.put = alc_ch_mode_put,
5916	},
5917	{ } /* end */
5918};
5919
5920static struct hda_verb alc883_init_verbs[] = {
5921	/* ADC1: mute amp left and right */
5922	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5923	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5924	/* ADC2: mute amp left and right */
5925	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5926	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5927	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5928	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5929	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5930	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5931	/* Rear mixer */
5932	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5933	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5934	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5935	/* CLFE mixer */
5936	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5937	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5938	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5939	/* Side mixer */
5940	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5941	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5942	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5943
5944	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5945	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5946	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5947	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5948	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5949
5950	/* Front Pin: output 0 (0x0c) */
5951	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5952	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5953	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5954	/* Rear Pin: output 1 (0x0d) */
5955	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5956	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5957	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5958	/* CLFE Pin: output 2 (0x0e) */
5959	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5960	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5961	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5962	/* Side Pin: output 3 (0x0f) */
5963	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5964	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5965	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5966	/* Mic (rear) pin: input vref at 80% */
5967	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5968	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5969	/* Front Mic pin: input vref at 80% */
5970	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5971	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5972	/* Line In pin: input */
5973	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5974	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5975	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5976	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5977	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5978	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5979	/* CD pin widget for input */
5980	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5981
5982	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5983	/* Input mixer2 */
5984	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5985	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5986	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5987	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5988	/* Input mixer3 */
5989	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5990	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5991	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5992	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5993	{ }
5994};
5995
5996static struct hda_verb alc883_tagra_verbs[] = {
5997	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5998	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5999
6000	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6001	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6002
6003	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6004	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6005	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6006
6007	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6008	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6009	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6010	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6011
6012	{ } /* end */
6013};
6014
6015static struct hda_verb alc883_lenovo_101e_verbs[] = {
6016	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6017	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6018        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6019	{ } /* end */
6020};
6021
6022static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6023        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6024	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6025        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6026        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6027	{ } /* end */
6028};
6029
6030static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6031	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6032	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6033	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6034	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6035	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6036	{ } /* end */
6037};
6038
6039/* toggle front-jack and RCA according to the hp-jack state */
6040static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6041{
6042 	unsigned int present;
6043
6044 	present = snd_hda_codec_read(codec, 0x1b, 0,
6045				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6046	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6047				 0x80, present ? 0x80 : 0);
6048	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6049				 0x80, present ? 0x80 : 0);
6050	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6051				 0x80, present ? 0x80 : 0);
6052	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6053				 0x80, present ? 0x80 : 0);
6054
6055}
6056
6057/* toggle RCA according to the front-jack state */
6058static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6059{
6060 	unsigned int present;
6061
6062 	present = snd_hda_codec_read(codec, 0x14, 0,
6063				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6064	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6065				 0x80, present ? 0x80 : 0);
6066	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6067				 0x80, present ? 0x80 : 0);
6068
6069}
6070static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6071					     unsigned int res)
6072{
6073	if ((res >> 26) == ALC880_HP_EVENT)
6074		alc888_lenovo_ms7195_front_automute(codec);
6075	if ((res >> 26) == ALC880_FRONT_EVENT)
6076		alc888_lenovo_ms7195_rca_automute(codec);
6077}
6078
6079static struct hda_verb alc883_medion_md2_verbs[] = {
6080	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6081	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6082
6083	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6084
6085	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6086	{ } /* end */
6087};
6088
6089/* toggle speaker-output according to the hp-jack state */
6090static void alc883_medion_md2_automute(struct hda_codec *codec)
6091{
6092 	unsigned int present;
6093
6094 	present = snd_hda_codec_read(codec, 0x14, 0,
6095				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6096	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6097				 0x80, present ? 0x80 : 0);
6098	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6099				 0x80, present ? 0x80 : 0);
6100}
6101
6102static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6103					  unsigned int res)
6104{
6105	if ((res >> 26) == ALC880_HP_EVENT)
6106		alc883_medion_md2_automute(codec);
6107}
6108
6109/* toggle speaker-output according to the hp-jack state */
6110static void alc883_tagra_automute(struct hda_codec *codec)
6111{
6112 	unsigned int present;
6113	unsigned char bits;
6114
6115 	present = snd_hda_codec_read(codec, 0x14, 0,
6116				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6117	bits = present ? 0x80 : 0;
6118	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
6119				 0x80, bits);
6120	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6121				 0x80, bits);
6122	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6123			    present ? 1 : 3);
6124}
6125
6126static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6127{
6128	if ((res >> 26) == ALC880_HP_EVENT)
6129		alc883_tagra_automute(codec);
6130}
6131
6132static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6133{
6134 	unsigned int present;
6135	unsigned char bits;
6136
6137 	present = snd_hda_codec_read(codec, 0x14, 0,
6138				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6139	bits = present ? 0x80 : 0;
6140	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6141				 0x80, bits);
6142	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6143				 0x80, bits);
6144}
6145
6146static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6147{
6148 	unsigned int present;
6149	unsigned char bits;
6150
6151 	present = snd_hda_codec_read(codec, 0x1b, 0,
6152				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6153	bits = present ? 0x80 : 0;
6154	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6155				 0x80, bits);
6156	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6157				 0x80, bits);
6158	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6159				 0x80, bits);
6160	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6161				 0x80, bits);
6162}
6163
6164static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6165					   unsigned int res)
6166{
6167	if ((res >> 26) == ALC880_HP_EVENT)
6168		alc883_lenovo_101e_all_automute(codec);
6169	if ((res >> 26) == ALC880_FRONT_EVENT)
6170		alc883_lenovo_101e_ispeaker_automute(codec);
6171}
6172
6173/*
6174 * generic initialization of ADC, input mixers and output mixers
6175 */
6176static struct hda_verb alc883_auto_init_verbs[] = {
6177	/*
6178	 * Unmute ADC0-2 and set the default input to mic-in
6179	 */
6180	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6181	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6182	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6183	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6184
6185	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6186	 * mixer widget
6187	 * Note: PASD motherboards uses the Line In 2 as the input for
6188	 * front panel mic (mic 2)
6189	 */
6190	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6191	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6192	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6193	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6194	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6195	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6196
6197	/*
6198	 * Set up output mixers (0x0c - 0x0f)
6199	 */
6200	/* set vol=0 to output mixers */
6201	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6202	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6203	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6204	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6205	/* set up input amps for analog loopback */
6206	/* Amp Indices: DAC = 0, mixer = 1 */
6207	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6208	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6209	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6210	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6211	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6212	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6213	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6214	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6215	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6216	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6217
6218	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6219	/* Input mixer1 */
6220	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6221	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6222	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6223	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6224	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6225	/* Input mixer2 */
6226	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6227	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6228	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6229	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6230	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6231
6232	{ }
6233};
6234
6235/* capture mixer elements */
6236static struct snd_kcontrol_new alc883_capture_mixer[] = {
6237	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6238	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6239	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6240	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6241	{
6242		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6243		/* .name = "Capture Source", */
6244		.name = "Input Source",
6245		.count = 2,
6246		.info = alc882_mux_enum_info,
6247		.get = alc882_mux_enum_get,
6248		.put = alc882_mux_enum_put,
6249	},
6250	{ } /* end */
6251};
6252
6253/* pcm configuration: identiacal with ALC880 */
6254#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
6255#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
6256#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
6257#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
6258
6259/*
6260 * configuration and preset
6261 */
6262static const char *alc883_models[ALC883_MODEL_LAST] = {
6263	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
6264	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
6265	[ALC883_3ST_6ch]	= "3stack-6ch",
6266	[ALC883_6ST_DIG]	= "6stack-dig",
6267	[ALC883_TARGA_DIG]	= "targa-dig",
6268	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
6269	[ALC883_ACER]		= "acer",
6270	[ALC883_MEDION]		= "medion",
6271	[ALC883_MEDION_MD2]	= "medion-md2",
6272	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
6273	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6274	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
6275	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6276	[ALC883_AUTO]		= "auto",
6277};
6278
6279static struct snd_pci_quirk alc883_cfg_tbl[] = {
6280	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6281	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6282	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6283	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6284	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6285	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6286	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6287	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6288	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6289	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6290	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6291	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6292	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6293	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6294	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6295	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6296	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6297	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6298	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6299	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6300	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6301	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6302	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6303	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6304	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6305	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6306	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6307	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6308	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6309	{}
6310};
6311
6312static struct alc_config_preset alc883_presets[] = {
6313	[ALC883_3ST_2ch_DIG] = {
6314		.mixers = { alc883_3ST_2ch_mixer },
6315		.init_verbs = { alc883_init_verbs },
6316		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6317		.dac_nids = alc883_dac_nids,
6318		.dig_out_nid = ALC883_DIGOUT_NID,
6319		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6320		.adc_nids = alc883_adc_nids,
6321		.dig_in_nid = ALC883_DIGIN_NID,
6322		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6323		.channel_mode = alc883_3ST_2ch_modes,
6324		.input_mux = &alc883_capture_source,
6325	},
6326	[ALC883_3ST_6ch_DIG] = {
6327		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6328		.init_verbs = { alc883_init_verbs },
6329		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6330		.dac_nids = alc883_dac_nids,
6331		.dig_out_nid = ALC883_DIGOUT_NID,
6332		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6333		.adc_nids = alc883_adc_nids,
6334		.dig_in_nid = ALC883_DIGIN_NID,
6335		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6336		.channel_mode = alc883_3ST_6ch_modes,
6337		.need_dac_fix = 1,
6338		.input_mux = &alc883_capture_source,
6339	},
6340	[ALC883_3ST_6ch] = {
6341		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6342		.init_verbs = { alc883_init_verbs },
6343		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6344		.dac_nids = alc883_dac_nids,
6345		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6346		.adc_nids = alc883_adc_nids,
6347		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6348		.channel_mode = alc883_3ST_6ch_modes,
6349		.need_dac_fix = 1,
6350		.input_mux = &alc883_capture_source,
6351	},
6352	[ALC883_6ST_DIG] = {
6353		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
6354		.init_verbs = { alc883_init_verbs },
6355		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6356		.dac_nids = alc883_dac_nids,
6357		.dig_out_nid = ALC883_DIGOUT_NID,
6358		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6359		.adc_nids = alc883_adc_nids,
6360		.dig_in_nid = ALC883_DIGIN_NID,
6361		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6362		.channel_mode = alc883_sixstack_modes,
6363		.input_mux = &alc883_capture_source,
6364	},
6365	[ALC883_TARGA_DIG] = {
6366		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6367		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6368		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6369		.dac_nids = alc883_dac_nids,
6370		.dig_out_nid = ALC883_DIGOUT_NID,
6371		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6372		.adc_nids = alc883_adc_nids,
6373		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6374		.channel_mode = alc883_3ST_6ch_modes,
6375		.need_dac_fix = 1,
6376		.input_mux = &alc883_capture_source,
6377		.unsol_event = alc883_tagra_unsol_event,
6378		.init_hook = alc883_tagra_automute,
6379	},
6380	[ALC883_TARGA_2ch_DIG] = {
6381		.mixers = { alc883_tagra_2ch_mixer},
6382		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6383		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6384		.dac_nids = alc883_dac_nids,
6385		.dig_out_nid = ALC883_DIGOUT_NID,
6386		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6387		.adc_nids = alc883_adc_nids,
6388		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6389		.channel_mode = alc883_3ST_2ch_modes,
6390		.input_mux = &alc883_capture_source,
6391		.unsol_event = alc883_tagra_unsol_event,
6392		.init_hook = alc883_tagra_automute,
6393	},
6394	[ALC883_ACER] = {
6395		.mixers = { alc883_base_mixer,
6396			    alc883_chmode_mixer },
6397		/* On TravelMate laptops, GPIO 0 enables the internal speaker
6398		 * and the headphone jack.  Turn this on and rely on the
6399		 * standard mute methods whenever the user wants to turn
6400		 * these outputs off.
6401		 */
6402		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6403		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6404		.dac_nids = alc883_dac_nids,
6405		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6406		.adc_nids = alc883_adc_nids,
6407		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6408		.channel_mode = alc883_3ST_2ch_modes,
6409		.input_mux = &alc883_capture_source,
6410	},
6411	[ALC883_MEDION] = {
6412		.mixers = { alc883_fivestack_mixer,
6413			    alc883_chmode_mixer },
6414		.init_verbs = { alc883_init_verbs,
6415				alc883_medion_eapd_verbs },
6416		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6417		.dac_nids = alc883_dac_nids,
6418		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6419		.adc_nids = alc883_adc_nids,
6420		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6421		.channel_mode = alc883_sixstack_modes,
6422		.input_mux = &alc883_capture_source,
6423	},
6424	[ALC883_MEDION_MD2] = {
6425		.mixers = { alc883_medion_md2_mixer},
6426		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6427		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6428		.dac_nids = alc883_dac_nids,
6429		.dig_out_nid = ALC883_DIGOUT_NID,
6430		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6431		.adc_nids = alc883_adc_nids,
6432		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6433		.channel_mode = alc883_3ST_2ch_modes,
6434		.input_mux = &alc883_capture_source,
6435		.unsol_event = alc883_medion_md2_unsol_event,
6436		.init_hook = alc883_medion_md2_automute,
6437	},
6438	[ALC883_LAPTOP_EAPD] = {
6439		.mixers = { alc883_base_mixer,
6440			    alc883_chmode_mixer },
6441		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6442		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6443		.dac_nids = alc883_dac_nids,
6444		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6445		.adc_nids = alc883_adc_nids,
6446		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6447		.channel_mode = alc883_3ST_2ch_modes,
6448		.input_mux = &alc883_capture_source,
6449	},
6450	[ALC883_LENOVO_101E_2ch] = {
6451		.mixers = { alc883_lenovo_101e_2ch_mixer},
6452		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6453		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6454		.dac_nids = alc883_dac_nids,
6455		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6456		.adc_nids = alc883_adc_nids,
6457		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6458		.channel_mode = alc883_3ST_2ch_modes,
6459		.input_mux = &alc883_lenovo_101e_capture_source,
6460		.unsol_event = alc883_lenovo_101e_unsol_event,
6461		.init_hook = alc883_lenovo_101e_all_automute,
6462	},
6463	[ALC883_LENOVO_NB0763] = {
6464		.mixers = { alc883_lenovo_nb0763_mixer },
6465		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6466		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6467		.dac_nids = alc883_dac_nids,
6468		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6469		.adc_nids = alc883_adc_nids,
6470		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6471		.channel_mode = alc883_3ST_2ch_modes,
6472		.need_dac_fix = 1,
6473		.input_mux = &alc883_lenovo_nb0763_capture_source,
6474		.unsol_event = alc883_medion_md2_unsol_event,
6475		.init_hook = alc883_medion_md2_automute,
6476	},
6477	[ALC888_LENOVO_MS7195_DIG] = {
6478		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6479		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6480		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6481		.dac_nids = alc883_dac_nids,
6482		.dig_out_nid = ALC883_DIGOUT_NID,
6483		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6484		.adc_nids = alc883_adc_nids,
6485		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6486		.channel_mode = alc883_3ST_6ch_modes,
6487		.need_dac_fix = 1,
6488		.input_mux = &alc883_capture_source,
6489		.unsol_event = alc883_lenovo_ms7195_unsol_event,
6490		.init_hook = alc888_lenovo_ms7195_front_automute,
6491	},
6492};
6493
6494
6495/*
6496 * BIOS auto configuration
6497 */
6498static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6499					      hda_nid_t nid, int pin_type,
6500					      int dac_idx)
6501{
6502	/* set as output */
6503	struct alc_spec *spec = codec->spec;
6504	int idx;
6505
6506	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6507		idx = 4;
6508	else
6509		idx = spec->multiout.dac_nids[dac_idx] - 2;
6510
6511	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6512			    pin_type);
6513	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6514			    AMP_OUT_UNMUTE);
6515	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6516
6517}
6518
6519static void alc883_auto_init_multi_out(struct hda_codec *codec)
6520{
6521	struct alc_spec *spec = codec->spec;
6522	int i;
6523
6524	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6525	for (i = 0; i <= HDA_SIDE; i++) {
6526		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6527		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6528		if (nid)
6529			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6530							  i);
6531	}
6532}
6533
6534static void alc883_auto_init_hp_out(struct hda_codec *codec)
6535{
6536	struct alc_spec *spec = codec->spec;
6537	hda_nid_t pin;
6538
6539	pin = spec->autocfg.hp_pins[0];
6540	if (pin) /* connect to front */
6541		/* use dac 0 */
6542		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6543}
6544
6545#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
6546#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
6547
6548static void alc883_auto_init_analog_input(struct hda_codec *codec)
6549{
6550	struct alc_spec *spec = codec->spec;
6551	int i;
6552
6553	for (i = 0; i < AUTO_PIN_LAST; i++) {
6554		hda_nid_t nid = spec->autocfg.input_pins[i];
6555		if (alc883_is_input_pin(nid)) {
6556			snd_hda_codec_write(codec, nid, 0,
6557					    AC_VERB_SET_PIN_WIDGET_CONTROL,
6558					    (i <= AUTO_PIN_FRONT_MIC ?
6559					     PIN_VREF80 : PIN_IN));
6560			if (nid != ALC883_PIN_CD_NID)
6561				snd_hda_codec_write(codec, nid, 0,
6562						    AC_VERB_SET_AMP_GAIN_MUTE,
6563						    AMP_OUT_MUTE);
6564		}
6565	}
6566}
6567
6568/* almost identical with ALC880 parser... */
6569static int alc883_parse_auto_config(struct hda_codec *codec)
6570{
6571	struct alc_spec *spec = codec->spec;
6572	int err = alc880_parse_auto_config(codec);
6573
6574	if (err < 0)
6575		return err;
6576	else if (err > 0)
6577		/* hack - override the init verbs */
6578		spec->init_verbs[0] = alc883_auto_init_verbs;
6579	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6580	spec->num_mixers++;
6581	return err;
6582}
6583
6584/* additional initialization for auto-configuration model */
6585static void alc883_auto_init(struct hda_codec *codec)
6586{
6587	alc883_auto_init_multi_out(codec);
6588	alc883_auto_init_hp_out(codec);
6589	alc883_auto_init_analog_input(codec);
6590}
6591
6592static int patch_alc883(struct hda_codec *codec)
6593{
6594	struct alc_spec *spec;
6595	int err, board_config;
6596
6597	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6598	if (spec == NULL)
6599		return -ENOMEM;
6600
6601	codec->spec = spec;
6602
6603	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
6604						  alc883_models,
6605						  alc883_cfg_tbl);
6606	if (board_config < 0) {
6607		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
6608		       "trying auto-probe from BIOS...\n");
6609		board_config = ALC883_AUTO;
6610	}
6611
6612	if (board_config == ALC883_AUTO) {
6613		/* automatic parse from the BIOS config */
6614		err = alc883_parse_auto_config(codec);
6615		if (err < 0) {
6616			alc_free(codec);
6617			return err;
6618		} else if (!err) {
6619			printk(KERN_INFO
6620			       "hda_codec: Cannot set up configuration "
6621			       "from BIOS.  Using base mode...\n");
6622			board_config = ALC883_3ST_2ch_DIG;
6623		}
6624	}
6625
6626	if (board_config != ALC883_AUTO)
6627		setup_preset(spec, &alc883_presets[board_config]);
6628
6629	spec->stream_name_analog = "ALC883 Analog";
6630	spec->stream_analog_playback = &alc883_pcm_analog_playback;
6631	spec->stream_analog_capture = &alc883_pcm_analog_capture;
6632
6633	spec->stream_name_digital = "ALC883 Digital";
6634	spec->stream_digital_playback = &alc883_pcm_digital_playback;
6635	spec->stream_digital_capture = &alc883_pcm_digital_capture;
6636
6637	if (!spec->adc_nids && spec->input_mux) {
6638		spec->adc_nids = alc883_adc_nids;
6639		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
6640	}
6641
6642	codec->patch_ops = alc_patch_ops;
6643	if (board_config == ALC883_AUTO)
6644		spec->init_hook = alc883_auto_init;
6645
6646	return 0;
6647}
6648
6649/*
6650 * ALC262 support
6651 */
6652
6653#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
6654#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
6655
6656#define alc262_dac_nids		alc260_dac_nids
6657#define alc262_adc_nids		alc882_adc_nids
6658#define alc262_adc_nids_alt	alc882_adc_nids_alt
6659
6660#define alc262_modes		alc260_modes
6661#define alc262_capture_source	alc882_capture_source
6662
6663static struct snd_kcontrol_new alc262_base_mixer[] = {
6664	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6665	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6666	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6667	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6668	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6669	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6670	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6671	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6672	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6673	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6674	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6675	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6676	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6677	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
6678	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
6679	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6680	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6681	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6682	{ } /* end */
6683};
6684
6685static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
6686	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6687	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6688	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6689	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6690	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6691	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6692	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6693	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6694	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6695	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6696	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6697	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6698	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6699	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
6700	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
6701	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6702	{ } /* end */
6703};
6704
6705static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
6706	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6707	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6708	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6709	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6710	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6711
6712	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6713	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6714	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6715	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6716	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6717	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6718	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6719	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6720	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6721	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6722	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6723	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
6724	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
6725	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
6726	{ } /* end */
6727};
6728
6729static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
6730	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6731	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6732	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6733	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6734	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6735	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6736	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
6737	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
6738	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
6739	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6740	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6741	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6742	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6743	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
6744	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
6745	{ } /* end */
6746};
6747
6748static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
6749	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6750	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6751	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
6752	{ } /* end */
6753};
6754
6755static struct snd_kcontrol_new alc262_sony_mixer[] = {
6756	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6757	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6758	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6759	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6760	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6761	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6762	{ } /* end */
6763};
6764
6765
6766
6767#define alc262_capture_mixer		alc882_capture_mixer
6768#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
6769
6770/*
6771 * generic initialization of ADC, input mixers and output mixers
6772 */
6773static struct hda_verb alc262_init_verbs[] = {
6774	/*
6775	 * Unmute ADC0-2 and set the default input to mic-in
6776	 */
6777	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6778	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6779	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6780	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6781	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6782	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6783
6784	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6785	 * mixer widget
6786	 * Note: PASD motherboards uses the Line In 2 as the input for
6787	 * front panel mic (mic 2)
6788	 */
6789	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6790	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6791	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6792	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6793	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6794	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6795
6796	/*
6797	 * Set up output mixers (0x0c - 0x0e)
6798	 */
6799	/* set vol=0 to output mixers */
6800	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6801	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6802	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6803	/* set up input amps for analog loopback */
6804	/* Amp Indices: DAC = 0, mixer = 1 */
6805	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6806	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6807	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6808	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6809	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6810	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6811
6812	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6813	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6814	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6815	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6816	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6817	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6818
6819	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6820	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6821	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6822	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6823	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6824
6825	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6826	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6827
6828	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6829	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6830	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6831	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6832	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6833	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6834	/* Input mixer2 */
6835	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6836	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6837	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6838	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6839	/* Input mixer3 */
6840	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6841	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6842	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6843	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6844
6845	{ }
6846};
6847
6848static struct hda_verb alc262_hippo_unsol_verbs[] = {
6849	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6850	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6851	{}
6852};
6853
6854static struct hda_verb alc262_hippo1_unsol_verbs[] = {
6855	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6856	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6857	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6858
6859	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6860	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6861	{}
6862};
6863
6864static struct hda_verb alc262_sony_unsol_verbs[] = {
6865	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6866	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6867	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
6868
6869	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6870	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6871};
6872
6873/* mute/unmute internal speaker according to the hp jack and mute state */
6874static void alc262_hippo_automute(struct hda_codec *codec, int force)
6875{
6876	struct alc_spec *spec = codec->spec;
6877	unsigned int mute;
6878
6879	if (force || !spec->sense_updated) {
6880		unsigned int present;
6881		/* need to execute and sync at first */
6882		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
6883		present = snd_hda_codec_read(codec, 0x15, 0,
6884				    	 AC_VERB_GET_PIN_SENSE, 0);
6885		spec->jack_present = (present & 0x80000000) != 0;
6886		spec->sense_updated = 1;
6887	}
6888	if (spec->jack_present) {
6889		/* mute internal speaker */
6890		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6891					 0x80, 0x80);
6892		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6893					 0x80, 0x80);
6894	} else {
6895		/* unmute internal speaker if necessary */
6896		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
6897		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6898					 0x80, mute & 0x80);
6899		mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
6900		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6901					 0x80, mute & 0x80);
6902	}
6903}
6904
6905/* unsolicited event for HP jack sensing */
6906static void alc262_hippo_unsol_event(struct hda_codec *codec,
6907				       unsigned int res)
6908{
6909	if ((res >> 26) != ALC880_HP_EVENT)
6910		return;
6911	alc262_hippo_automute(codec, 1);
6912}
6913
6914static void alc262_hippo1_automute(struct hda_codec *codec, int force)
6915{
6916	struct alc_spec *spec = codec->spec;
6917	unsigned int mute;
6918
6919	if (force || !spec->sense_updated) {
6920		unsigned int present;
6921		/* need to execute and sync at first */
6922		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
6923		present = snd_hda_codec_read(codec, 0x1b, 0,
6924				    	 AC_VERB_GET_PIN_SENSE, 0);
6925		spec->jack_present = (present & 0x80000000) != 0;
6926		spec->sense_updated = 1;
6927	}
6928	if (spec->jack_present) {
6929		/* mute internal speaker */
6930		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6931					 0x80, 0x80);
6932		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6933					 0x80, 0x80);
6934	} else {
6935		/* unmute internal speaker if necessary */
6936		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
6937		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6938					 0x80, mute & 0x80);
6939		mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
6940		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6941					 0x80, mute & 0x80);
6942	}
6943}
6944
6945/* unsolicited event for HP jack sensing */
6946static void alc262_hippo1_unsol_event(struct hda_codec *codec,
6947				       unsigned int res)
6948{
6949	if ((res >> 26) != ALC880_HP_EVENT)
6950		return;
6951	alc262_hippo1_automute(codec, 1);
6952}
6953
6954/*
6955 * fujitsu model
6956 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
6957 */
6958
6959#define ALC_HP_EVENT	0x37
6960
6961static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
6962	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
6963	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6964	{}
6965};
6966
6967static struct hda_input_mux alc262_fujitsu_capture_source = {
6968	.num_items = 2,
6969	.items = {
6970		{ "Mic", 0x0 },
6971		{ "CD", 0x4 },
6972	},
6973};
6974
6975static struct hda_input_mux alc262_HP_capture_source = {
6976	.num_items = 5,
6977	.items = {
6978		{ "Mic", 0x0 },
6979		{ "Front Mic", 0x3 },
6980		{ "Line", 0x2 },
6981		{ "CD", 0x4 },
6982		{ "AUX IN", 0x6 },
6983	},
6984};
6985
6986/* mute/unmute internal speaker according to the hp jack and mute state */
6987static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
6988{
6989	struct alc_spec *spec = codec->spec;
6990	unsigned int mute;
6991
6992	if (force || !spec->sense_updated) {
6993		unsigned int present;
6994		/* need to execute and sync at first */
6995		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
6996		present = snd_hda_codec_read(codec, 0x14, 0,
6997				    	 AC_VERB_GET_PIN_SENSE, 0);
6998		spec->jack_present = (present & 0x80000000) != 0;
6999		spec->sense_updated = 1;
7000	}
7001	if (spec->jack_present) {
7002		/* mute internal speaker */
7003		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7004					 0x80, 0x80);
7005		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7006					 0x80, 0x80);
7007	} else {
7008		/* unmute internal speaker if necessary */
7009		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7010		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7011					 0x80, mute & 0x80);
7012		mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
7013		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7014					 0x80, mute & 0x80);
7015	}
7016}
7017
7018/* unsolicited event for HP jack sensing */
7019static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7020				       unsigned int res)
7021{
7022	if ((res >> 26) != ALC_HP_EVENT)
7023		return;
7024	alc262_fujitsu_automute(codec, 1);
7025}
7026
7027/* bind volumes of both NID 0x0c and 0x0d */
7028static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7029					 struct snd_ctl_elem_value *ucontrol)
7030{
7031	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7032	long *valp = ucontrol->value.integer.value;
7033	int change;
7034
7035	change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7036					  0x7f, valp[0] & 0x7f);
7037	change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7038					   0x7f, valp[1] & 0x7f);
7039	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7040				 0x7f, valp[0] & 0x7f);
7041	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7042				 0x7f, valp[1] & 0x7f);
7043	return change;
7044}
7045
7046/* bind hp and internal speaker mute (with plug check) */
7047static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7048					 struct snd_ctl_elem_value *ucontrol)
7049{
7050	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7051	long *valp = ucontrol->value.integer.value;
7052	int change;
7053
7054	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7055					  0x80, valp[0] ? 0 : 0x80);
7056	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7057					   0x80, valp[1] ? 0 : 0x80);
7058	if (change || codec->in_resume)
7059		alc262_fujitsu_automute(codec, codec->in_resume);
7060	return change;
7061}
7062
7063static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7064	{
7065		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7066		.name = "Master Playback Volume",
7067		.info = snd_hda_mixer_amp_volume_info,
7068		.get = snd_hda_mixer_amp_volume_get,
7069		.put = alc262_fujitsu_master_vol_put,
7070		.tlv = { .c = snd_hda_mixer_amp_tlv },
7071		.private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7072	},
7073	{
7074		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7075		.name = "Master Playback Switch",
7076		.info = snd_hda_mixer_amp_switch_info,
7077		.get = snd_hda_mixer_amp_switch_get,
7078		.put = alc262_fujitsu_master_sw_put,
7079		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7080	},
7081	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7082	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7083	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7084	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7085	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7086	{ } /* end */
7087};
7088
7089/* additional init verbs for Benq laptops */
7090static struct hda_verb alc262_EAPD_verbs[] = {
7091	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7092	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7093	{}
7094};
7095
7096/* add playback controls from the parsed DAC table */
7097static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7098					     const struct auto_pin_cfg *cfg)
7099{
7100	hda_nid_t nid;
7101	int err;
7102
7103	spec->multiout.num_dacs = 1;	/* only use one dac */
7104	spec->multiout.dac_nids = spec->private_dac_nids;
7105	spec->multiout.dac_nids[0] = 2;
7106
7107	nid = cfg->line_out_pins[0];
7108	if (nid) {
7109		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7110				  "Front Playback Volume",
7111				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7112		if (err < 0)
7113			return err;
7114		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7115				  "Front Playback Switch",
7116				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7117		if (err < 0)
7118			return err;
7119	}
7120
7121	nid = cfg->speaker_pins[0];
7122	if (nid) {
7123		if (nid == 0x16) {
7124			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7125					  "Speaker Playback Volume",
7126					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7127							      HDA_OUTPUT));
7128			if (err < 0)
7129				return err;
7130			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7131					  "Speaker Playback Switch",
7132					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7133							      HDA_OUTPUT));
7134			if (err < 0)
7135				return err;
7136		} else {
7137			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7138					  "Speaker Playback Switch",
7139					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7140							      HDA_OUTPUT));
7141			if (err < 0)
7142				return err;
7143		}
7144	}
7145	nid = cfg->hp_pins[0];
7146	if (nid) {
7147		/* spec->multiout.hp_nid = 2; */
7148		if (nid == 0x16) {
7149			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7150					  "Headphone Playback Volume",
7151					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7152							      HDA_OUTPUT));
7153			if (err < 0)
7154				return err;
7155			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7156					  "Headphone Playback Switch",
7157					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7158							      HDA_OUTPUT));
7159			if (err < 0)
7160				return err;
7161		} else {
7162			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7163					  "Headphone Playback Switch",
7164					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7165							      HDA_OUTPUT));
7166			if (err < 0)
7167				return err;
7168		}
7169	}
7170	return 0;
7171}
7172
7173/* identical with ALC880 */
7174#define alc262_auto_create_analog_input_ctls \
7175	alc880_auto_create_analog_input_ctls
7176
7177/*
7178 * generic initialization of ADC, input mixers and output mixers
7179 */
7180static struct hda_verb alc262_volume_init_verbs[] = {
7181	/*
7182	 * Unmute ADC0-2 and set the default input to mic-in
7183	 */
7184	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7185	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7186	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7187	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7188	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7189	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7190
7191	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7192	 * mixer widget
7193	 * Note: PASD motherboards uses the Line In 2 as the input for
7194	 * front panel mic (mic 2)
7195	 */
7196	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7197	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7198	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7199	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7200	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7201	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7202
7203	/*
7204	 * Set up output mixers (0x0c - 0x0f)
7205	 */
7206	/* set vol=0 to output mixers */
7207	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7208	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7209	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7210
7211	/* set up input amps for analog loopback */
7212	/* Amp Indices: DAC = 0, mixer = 1 */
7213	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7214	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7215	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7216	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7217	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7218	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7219
7220	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7221	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7222	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7223	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7224	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7225	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7226	/* Input mixer2 */
7227	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7228	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7229	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7230	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7231	/* Input mixer3 */
7232	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7233	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7234	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7235	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7236
7237	{ }
7238};
7239
7240static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7241	/*
7242	 * Unmute ADC0-2 and set the default input to mic-in
7243	 */
7244	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7245	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7246	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7247	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7248	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7249	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7250
7251	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7252	 * mixer widget
7253	 * Note: PASD motherboards uses the Line In 2 as the input for
7254	 * front panel mic (mic 2)
7255	 */
7256	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7257	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7258	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7259	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7260	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7261	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7262	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7263        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7264
7265	/*
7266	 * Set up output mixers (0x0c - 0x0e)
7267	 */
7268	/* set vol=0 to output mixers */
7269	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7270	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7271	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7272
7273	/* set up input amps for analog loopback */
7274	/* Amp Indices: DAC = 0, mixer = 1 */
7275	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7276	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7277	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7278	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7279	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7280	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7281
7282	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7283	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7284	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7285
7286	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7287	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7288
7289	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7290	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7291
7292	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7293	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7294        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7295	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7296	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7297
7298	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7299	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7300        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7301	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7302	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7303	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7304
7305
7306	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7307	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7308	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7309	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7310	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7311	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7312	/* Input mixer2 */
7313	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7314	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7315	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7316	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7317	/* Input mixer3 */
7318	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7319	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7320	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7321	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7322
7323	{ }
7324};
7325
7326static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7327	/*
7328	 * Unmute ADC0-2 and set the default input to mic-in
7329	 */
7330	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7331	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7332	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7333	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7334	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7335	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7336
7337	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7338	 * mixer widget
7339	 * Note: PASD motherboards uses the Line In 2 as the input for front
7340	 * panel mic (mic 2)
7341	 */
7342	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7343	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7344	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7345	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7346	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7347	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7348	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7349	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7350	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7351	/*
7352	 * Set up output mixers (0x0c - 0x0e)
7353	 */
7354	/* set vol=0 to output mixers */
7355	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7356	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7357	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7358
7359	/* set up input amps for analog loopback */
7360	/* Amp Indices: DAC = 0, mixer = 1 */
7361	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7362	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7363	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7364	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7365	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7366	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7367
7368
7369	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
7370	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
7371	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
7372	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
7373	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
7374	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
7375	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
7376
7377	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7378	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7379
7380	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7381	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7382
7383	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7384	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7385	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7386	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7387	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7388	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7389
7390	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7391	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7392	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7393	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7394	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7395	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7396	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7397        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7398	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7399	/* Input mixer2 */
7400	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7401	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7402	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7403	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7404	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7405        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7406	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7407	/* Input mixer3 */
7408	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7409	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7410	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7411	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7412	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7413        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7414	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7415
7416	{ }
7417};
7418
7419/* pcm configuration: identiacal with ALC880 */
7420#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
7421#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
7422#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
7423#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
7424
7425/*
7426 * BIOS auto configuration
7427 */
7428static int alc262_parse_auto_config(struct hda_codec *codec)
7429{
7430	struct alc_spec *spec = codec->spec;
7431	int err;
7432	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7433
7434	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7435					   alc262_ignore);
7436	if (err < 0)
7437		return err;
7438	if (!spec->autocfg.line_outs)
7439		return 0; /* can't find valid BIOS pin config */
7440	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7441	if (err < 0)
7442		return err;
7443	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7444	if (err < 0)
7445		return err;
7446
7447	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7448
7449	if (spec->autocfg.dig_out_pin)
7450		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7451	if (spec->autocfg.dig_in_pin)
7452		spec->dig_in_nid = ALC262_DIGIN_NID;
7453
7454	if (spec->kctl_alloc)
7455		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7456
7457	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7458	spec->num_mux_defs = 1;
7459	spec->input_mux = &spec->private_imux;
7460
7461	return 1;
7462}
7463
7464#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
7465#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
7466#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
7467
7468
7469/* init callback for auto-configuration model -- overriding the default init */
7470static void alc262_auto_init(struct hda_codec *codec)
7471{
7472	alc262_auto_init_multi_out(codec);
7473	alc262_auto_init_hp_out(codec);
7474	alc262_auto_init_analog_input(codec);
7475}
7476
7477/*
7478 * configuration and preset
7479 */
7480static const char *alc262_models[ALC262_MODEL_LAST] = {
7481	[ALC262_BASIC]		= "basic",
7482	[ALC262_HIPPO]		= "hippo",
7483	[ALC262_HIPPO_1]	= "hippo_1",
7484	[ALC262_FUJITSU]	= "fujitsu",
7485	[ALC262_HP_BPC]		= "hp-bpc",
7486	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7487	[ALC262_BENQ_ED8]	= "benq",
7488	[ALC262_BENQ_ED8]	= "sony-assamd",
7489	[ALC262_AUTO]		= "auto",
7490};
7491
7492static struct snd_pci_quirk alc262_cfg_tbl[] = {
7493	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7494	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7495	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7496	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7497	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7498	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7499	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7500	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7501	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7502	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7503	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7504	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7505	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7506	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7507	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7508	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7509	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7510	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7511	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7512	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7513	{}
7514};
7515
7516static struct alc_config_preset alc262_presets[] = {
7517	[ALC262_BASIC] = {
7518		.mixers = { alc262_base_mixer },
7519		.init_verbs = { alc262_init_verbs },
7520		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7521		.dac_nids = alc262_dac_nids,
7522		.hp_nid = 0x03,
7523		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7524		.channel_mode = alc262_modes,
7525		.input_mux = &alc262_capture_source,
7526	},
7527	[ALC262_HIPPO] = {
7528		.mixers = { alc262_base_mixer },
7529		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7530		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7531		.dac_nids = alc262_dac_nids,
7532		.hp_nid = 0x03,
7533		.dig_out_nid = ALC262_DIGOUT_NID,
7534		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7535		.channel_mode = alc262_modes,
7536		.input_mux = &alc262_capture_source,
7537		.unsol_event = alc262_hippo_unsol_event,
7538	},
7539	[ALC262_HIPPO_1] = {
7540		.mixers = { alc262_hippo1_mixer },
7541		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7542		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7543		.dac_nids = alc262_dac_nids,
7544		.hp_nid = 0x02,
7545		.dig_out_nid = ALC262_DIGOUT_NID,
7546		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7547		.channel_mode = alc262_modes,
7548		.input_mux = &alc262_capture_source,
7549		.unsol_event = alc262_hippo1_unsol_event,
7550	},
7551	[ALC262_FUJITSU] = {
7552		.mixers = { alc262_fujitsu_mixer },
7553		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7554		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7555		.dac_nids = alc262_dac_nids,
7556		.hp_nid = 0x03,
7557		.dig_out_nid = ALC262_DIGOUT_NID,
7558		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7559		.channel_mode = alc262_modes,
7560		.input_mux = &alc262_fujitsu_capture_source,
7561		.unsol_event = alc262_fujitsu_unsol_event,
7562	},
7563	[ALC262_HP_BPC] = {
7564		.mixers = { alc262_HP_BPC_mixer },
7565		.init_verbs = { alc262_HP_BPC_init_verbs },
7566		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7567		.dac_nids = alc262_dac_nids,
7568		.hp_nid = 0x03,
7569		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7570		.channel_mode = alc262_modes,
7571		.input_mux = &alc262_HP_capture_source,
7572	},
7573	[ALC262_HP_BPC_D7000_WF] = {
7574		.mixers = { alc262_HP_BPC_WildWest_mixer },
7575		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7576		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7577		.dac_nids = alc262_dac_nids,
7578		.hp_nid = 0x03,
7579		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7580		.channel_mode = alc262_modes,
7581		.input_mux = &alc262_HP_capture_source,
7582	},
7583	[ALC262_HP_BPC_D7000_WL] = {
7584		.mixers = { alc262_HP_BPC_WildWest_mixer,
7585			    alc262_HP_BPC_WildWest_option_mixer },
7586		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7587		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7588		.dac_nids = alc262_dac_nids,
7589		.hp_nid = 0x03,
7590		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7591		.channel_mode = alc262_modes,
7592		.input_mux = &alc262_HP_capture_source,
7593	},
7594	[ALC262_BENQ_ED8] = {
7595		.mixers = { alc262_base_mixer },
7596		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
7597		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7598		.dac_nids = alc262_dac_nids,
7599		.hp_nid = 0x03,
7600		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7601		.channel_mode = alc262_modes,
7602		.input_mux = &alc262_capture_source,
7603	},
7604	[ALC262_SONY_ASSAMD] = {
7605		.mixers = { alc262_sony_mixer },
7606		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
7607		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7608		.dac_nids = alc262_dac_nids,
7609		.hp_nid = 0x02,
7610		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7611		.channel_mode = alc262_modes,
7612		.input_mux = &alc262_capture_source,
7613		.unsol_event = alc262_hippo_unsol_event,
7614	},
7615};
7616
7617static int patch_alc262(struct hda_codec *codec)
7618{
7619	struct alc_spec *spec;
7620	int board_config;
7621	int err;
7622
7623	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7624	if (spec == NULL)
7625		return -ENOMEM;
7626
7627	codec->spec = spec;
7628
7629	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
7630						  alc262_models,
7631						  alc262_cfg_tbl);
7632
7633	if (board_config < 0) {
7634		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
7635		       "trying auto-probe from BIOS...\n");
7636		board_config = ALC262_AUTO;
7637	}
7638
7639	if (board_config == ALC262_AUTO) {
7640		/* automatic parse from the BIOS config */
7641		err = alc262_parse_auto_config(codec);
7642		if (err < 0) {
7643			alc_free(codec);
7644			return err;
7645		} else if (!err) {
7646			printk(KERN_INFO
7647			       "hda_codec: Cannot set up configuration "
7648			       "from BIOS.  Using base mode...\n");
7649			board_config = ALC262_BASIC;
7650		}
7651	}
7652
7653	if (board_config != ALC262_AUTO)
7654		setup_preset(spec, &alc262_presets[board_config]);
7655
7656	spec->stream_name_analog = "ALC262 Analog";
7657	spec->stream_analog_playback = &alc262_pcm_analog_playback;
7658	spec->stream_analog_capture = &alc262_pcm_analog_capture;
7659
7660	spec->stream_name_digital = "ALC262 Digital";
7661	spec->stream_digital_playback = &alc262_pcm_digital_playback;
7662	spec->stream_digital_capture = &alc262_pcm_digital_capture;
7663
7664	if (!spec->adc_nids && spec->input_mux) {
7665		/* check whether NID 0x07 is valid */
7666		unsigned int wcap = get_wcaps(codec, 0x07);
7667
7668		/* get type */
7669		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7670		if (wcap != AC_WID_AUD_IN) {
7671			spec->adc_nids = alc262_adc_nids_alt;
7672			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
7673			spec->mixers[spec->num_mixers] =
7674				alc262_capture_alt_mixer;
7675			spec->num_mixers++;
7676		} else {
7677			spec->adc_nids = alc262_adc_nids;
7678			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
7679			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
7680			spec->num_mixers++;
7681		}
7682	}
7683
7684	codec->patch_ops = alc_patch_ops;
7685	if (board_config == ALC262_AUTO)
7686		spec->init_hook = alc262_auto_init;
7687
7688	return 0;
7689}
7690
7691/*
7692 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
7693 */
7694
7695/*
7696 * set the path ways for 2 channel output
7697 * need to set the codec line out and mic 1 pin widgets to inputs
7698 */
7699static struct hda_verb alc861_threestack_ch2_init[] = {
7700	/* set pin widget 1Ah (line in) for input */
7701	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7702	/* set pin widget 18h (mic1/2) for input, for mic also enable
7703	 * the vref
7704	 */
7705	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7706
7707	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
7708	{ } /* end */
7709};
7710/*
7711 * 6ch mode
7712 * need to set the codec line out and mic 1 pin widgets to outputs
7713 */
7714static struct hda_verb alc861_threestack_ch6_init[] = {
7715	/* set pin widget 1Ah (line in) for output (Back Surround)*/
7716	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7717	/* set pin widget 18h (mic1) for output (CLFE)*/
7718	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7719
7720	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
7721	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
7722
7723	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
7724	{ } /* end */
7725};
7726
7727static struct hda_channel_mode alc861_threestack_modes[2] = {
7728	{ 2, alc861_threestack_ch2_init },
7729	{ 6, alc861_threestack_ch6_init },
7730};
7731/* Set mic1 as input and unmute the mixer */
7732static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
7733	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7734	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
7735	{ } /* end */
7736};
7737/* Set mic1 as output and mute mixer */
7738static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
7739	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7740	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
7741	{ } /* end */
7742};
7743
7744static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
7745	{ 2, alc861_uniwill_m31_ch2_init },
7746	{ 4, alc861_uniwill_m31_ch4_init },
7747};
7748
7749/* Set mic1 and line-in as input and unmute the mixer */
7750static struct hda_verb alc861_asus_ch2_init[] = {
7751	/* set pin widget 1Ah (line in) for input */
7752	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7753	/* set pin widget 18h (mic1/2) for input, for mic also enable
7754	 * the vref
7755	 */
7756	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7757
7758	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
7759	{ } /* end */
7760};
7761/* Set mic1 nad line-in as output and mute mixer */
7762static struct hda_verb alc861_asus_ch6_init[] = {
7763	/* set pin widget 1Ah (line in) for output (Back Surround)*/
7764	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7765	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
7766	/* set pin widget 18h (mic1) for output (CLFE)*/
7767	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7768	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
7769	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
7770	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
7771
7772	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
7773	{ } /* end */
7774};
7775
7776static struct hda_channel_mode alc861_asus_modes[2] = {
7777	{ 2, alc861_asus_ch2_init },
7778	{ 6, alc861_asus_ch6_init },
7779};
7780
7781/* patch-ALC861 */
7782
7783static struct snd_kcontrol_new alc861_base_mixer[] = {
7784        /* output mixer control */
7785	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
7786	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
7787	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
7788	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
7789	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
7790
7791        /*Input mixer control */
7792	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
7793	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
7794	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
7795	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
7796	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
7797	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
7798	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
7799	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
7800	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
7801	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
7802
7803        /* Capture mixer control */
7804	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7805	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7806	{
7807		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7808		.name = "Capture Source",
7809		.count = 1,
7810		.info = alc_mux_enum_info,
7811		.get = alc_mux_enum_get,
7812		.put = alc_mux_enum_put,
7813	},
7814	{ } /* end */
7815};
7816
7817static struct snd_kcontrol_new alc861_3ST_mixer[] = {
7818        /* output mixer control */
7819	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
7820	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
7821	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
7822	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
7823	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
7824
7825	/* Input mixer control */
7826	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
7827	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
7828	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
7829	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
7830	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
7831	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
7832	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
7833	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
7834	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
7835	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
7836
7837	/* Capture mixer control */
7838	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7839	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7840	{
7841		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7842		.name = "Capture Source",
7843		.count = 1,
7844		.info = alc_mux_enum_info,
7845		.get = alc_mux_enum_get,
7846		.put = alc_mux_enum_put,
7847	},
7848	{
7849		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7850		.name = "Channel Mode",
7851		.info = alc_ch_mode_info,
7852		.get = alc_ch_mode_get,
7853		.put = alc_ch_mode_put,
7854                .private_value = ARRAY_SIZE(alc861_threestack_modes),
7855	},
7856	{ } /* end */
7857};
7858
7859static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
7860        /* output mixer control */
7861	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
7862	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
7863	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
7864
7865        /*Capture mixer control */
7866	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7867	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7868	{
7869		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7870		.name = "Capture Source",
7871		.count = 1,
7872		.info = alc_mux_enum_info,
7873		.get = alc_mux_enum_get,
7874		.put = alc_mux_enum_put,
7875	},
7876
7877	{ } /* end */
7878};
7879
7880static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
7881        /* output mixer control */
7882	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
7883	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
7884	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
7885	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
7886	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
7887
7888	/* Input mixer control */
7889	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
7890	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
7891	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
7892	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
7893	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
7894	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
7895	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
7896	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
7897	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
7898	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
7899
7900	/* Capture mixer control */
7901	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7902	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7903	{
7904		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7905		.name = "Capture Source",
7906		.count = 1,
7907		.info = alc_mux_enum_info,
7908		.get = alc_mux_enum_get,
7909		.put = alc_mux_enum_put,
7910	},
7911	{
7912		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7913		.name = "Channel Mode",
7914		.info = alc_ch_mode_info,
7915		.get = alc_ch_mode_get,
7916		.put = alc_ch_mode_put,
7917                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
7918	},
7919	{ } /* end */
7920};
7921
7922static struct snd_kcontrol_new alc861_asus_mixer[] = {
7923        /* output mixer control */
7924	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
7925	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
7926	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
7927	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
7928	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
7929
7930	/* Input mixer control */
7931	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
7932	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7933	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
7934	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
7935	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
7936	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
7937	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
7938	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
7939	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
7940	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
7941
7942	/* Capture mixer control */
7943	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7944	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7945	{
7946		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7947		.name = "Capture Source",
7948		.count = 1,
7949		.info = alc_mux_enum_info,
7950		.get = alc_mux_enum_get,
7951		.put = alc_mux_enum_put,
7952	},
7953	{
7954		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7955		.name = "Channel Mode",
7956		.info = alc_ch_mode_info,
7957		.get = alc_ch_mode_get,
7958		.put = alc_ch_mode_put,
7959                .private_value = ARRAY_SIZE(alc861_asus_modes),
7960	},
7961	{ }
7962};
7963
7964/* additional mixer */
7965static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
7966	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
7967	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
7968	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
7969	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
7970	{ }
7971};
7972
7973/*
7974 * generic initialization of ADC, input mixers and output mixers
7975 */
7976static struct hda_verb alc861_base_init_verbs[] = {
7977	/*
7978	 * Unmute ADC0 and set the default input to mic-in
7979	 */
7980	/* port-A for surround (rear panel) */
7981	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7982	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
7983	/* port-B for mic-in (rear panel) with vref */
7984	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7985	/* port-C for line-in (rear panel) */
7986	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7987	/* port-D for Front */
7988	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7989	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
7990	/* port-E for HP out (front panel) */
7991	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
7992	/* route front PCM to HP */
7993	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7994	/* port-F for mic-in (front panel) with vref */
7995	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7996	/* port-G for CLFE (rear panel) */
7997	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7998	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7999	/* port-H for side (rear panel) */
8000	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8001	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8002	/* CD-in */
8003	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8004	/* route front mic to ADC1*/
8005	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8006	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8007
8008	/* Unmute DAC0~3 & spdif out*/
8009	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8010	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8011	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8012	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8013	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8014
8015	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8016	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8017        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8018	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8019        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8020
8021	/* Unmute Stereo Mixer 15 */
8022	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8023	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8024	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8025	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8026
8027	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8028	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8029	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8030	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8031	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8032	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8033	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8034	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8035	/* hp used DAC 3 (Front) */
8036	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8037        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8038
8039	{ }
8040};
8041
8042static struct hda_verb alc861_threestack_init_verbs[] = {
8043	/*
8044	 * Unmute ADC0 and set the default input to mic-in
8045	 */
8046	/* port-A for surround (rear panel) */
8047	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8048	/* port-B for mic-in (rear panel) with vref */
8049	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8050	/* port-C for line-in (rear panel) */
8051	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8052	/* port-D for Front */
8053	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8054	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8055	/* port-E for HP out (front panel) */
8056	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8057	/* route front PCM to HP */
8058	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8059	/* port-F for mic-in (front panel) with vref */
8060	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8061	/* port-G for CLFE (rear panel) */
8062	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8063	/* port-H for side (rear panel) */
8064	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8065	/* CD-in */
8066	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8067	/* route front mic to ADC1*/
8068	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8069	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8070	/* Unmute DAC0~3 & spdif out*/
8071	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8072	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8073	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8074	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8075	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8076
8077	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8078	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8079        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8080	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8081        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8082
8083	/* Unmute Stereo Mixer 15 */
8084	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8085	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8086	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8087	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8088
8089	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8090	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8091	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8092	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8093	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8094	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8095	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8096	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8097	/* hp used DAC 3 (Front) */
8098	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8099        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8100	{ }
8101};
8102
8103static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
8104	/*
8105	 * Unmute ADC0 and set the default input to mic-in
8106	 */
8107	/* port-A for surround (rear panel) */
8108	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8109	/* port-B for mic-in (rear panel) with vref */
8110	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8111	/* port-C for line-in (rear panel) */
8112	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8113	/* port-D for Front */
8114	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8115	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8116	/* port-E for HP out (front panel) */
8117	/* this has to be set to VREF80 */
8118	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8119	/* route front PCM to HP */
8120	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8121	/* port-F for mic-in (front panel) with vref */
8122	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8123	/* port-G for CLFE (rear panel) */
8124	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8125	/* port-H for side (rear panel) */
8126	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8127	/* CD-in */
8128	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8129	/* route front mic to ADC1*/
8130	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8131	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8132	/* Unmute DAC0~3 & spdif out*/
8133	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8134	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8135	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8136	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8137	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8138
8139	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8140	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8141        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8142	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8143        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8144
8145	/* Unmute Stereo Mixer 15 */
8146	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8147	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8148	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8149	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8150
8151	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8152	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8153	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8154	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8155	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8156	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8157	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8158	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8159	/* hp used DAC 3 (Front) */
8160	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8161        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8162	{ }
8163};
8164
8165static struct hda_verb alc861_asus_init_verbs[] = {
8166	/*
8167	 * Unmute ADC0 and set the default input to mic-in
8168	 */
8169	/* port-A for surround (rear panel)
8170	 * according to codec#0 this is the HP jack
8171	 */
8172	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
8173	/* route front PCM to HP */
8174	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
8175	/* port-B for mic-in (rear panel) with vref */
8176	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8177	/* port-C for line-in (rear panel) */
8178	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8179	/* port-D for Front */
8180	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8181	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8182	/* port-E for HP out (front panel) */
8183	/* this has to be set to VREF80 */
8184	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8185	/* route front PCM to HP */
8186	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8187	/* port-F for mic-in (front panel) with vref */
8188	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8189	/* port-G for CLFE (rear panel) */
8190	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8191	/* port-H for side (rear panel) */
8192	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8193	/* CD-in */
8194	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8195	/* route front mic to ADC1*/
8196	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8197	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8198	/* Unmute DAC0~3 & spdif out*/
8199	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8200	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8201	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8202	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8203	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8204	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8205	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8206        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8207	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8208        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8209
8210	/* Unmute Stereo Mixer 15 */
8211	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8212	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8213	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8214	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8215
8216	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8217	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8218	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8219	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8220	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8222	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8223	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8224	/* hp used DAC 3 (Front) */
8225	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8226	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8227	{ }
8228};
8229
8230/* additional init verbs for ASUS laptops */
8231static struct hda_verb alc861_asus_laptop_init_verbs[] = {
8232	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
8233	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
8234	{ }
8235};
8236
8237/*
8238 * generic initialization of ADC, input mixers and output mixers
8239 */
8240static struct hda_verb alc861_auto_init_verbs[] = {
8241	/*
8242	 * Unmute ADC0 and set the default input to mic-in
8243	 */
8244	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
8245	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8246
8247	/* Unmute DAC0~3 & spdif out*/
8248	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8249	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8250	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8251	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8252	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8253
8254	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8255	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8256	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8257	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8258	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8259
8260	/* Unmute Stereo Mixer 15 */
8261	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8262	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8263	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8264	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
8265
8266	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8267	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8268	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8269	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8270	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8271	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8272	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8273	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8274
8275	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8276	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8277	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8278	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8279	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8280	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8281	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8282	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8283
8284	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
8285
8286	{ }
8287};
8288
8289static struct hda_verb alc861_toshiba_init_verbs[] = {
8290	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8291
8292	{ }
8293};
8294
8295/* toggle speaker-output according to the hp-jack state */
8296static void alc861_toshiba_automute(struct hda_codec *codec)
8297{
8298	unsigned int present;
8299
8300	present = snd_hda_codec_read(codec, 0x0f, 0,
8301				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8302	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
8303				 0x80, present ? 0x80 : 0);
8304	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
8305				 0x80, present ? 0x80 : 0);
8306	snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
8307				 0x80, present ? 0 : 0x80);
8308	snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
8309				 0x80, present ? 0 : 0x80);
8310}
8311
8312static void alc861_toshiba_unsol_event(struct hda_codec *codec,
8313				       unsigned int res)
8314{
8315	if ((res >> 26) == ALC880_HP_EVENT)
8316		alc861_toshiba_automute(codec);
8317}
8318
8319/* pcm configuration: identiacal with ALC880 */
8320#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
8321#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
8322#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
8323#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
8324
8325
8326#define ALC861_DIGOUT_NID	0x07
8327
8328static struct hda_channel_mode alc861_8ch_modes[1] = {
8329	{ 8, NULL }
8330};
8331
8332static hda_nid_t alc861_dac_nids[4] = {
8333	/* front, surround, clfe, side */
8334	0x03, 0x06, 0x05, 0x04
8335};
8336
8337static hda_nid_t alc660_dac_nids[3] = {
8338	/* front, clfe, surround */
8339	0x03, 0x05, 0x06
8340};
8341
8342static hda_nid_t alc861_adc_nids[1] = {
8343	/* ADC0-2 */
8344	0x08,
8345};
8346
8347static struct hda_input_mux alc861_capture_source = {
8348	.num_items = 5,
8349	.items = {
8350		{ "Mic", 0x0 },
8351		{ "Front Mic", 0x3 },
8352		{ "Line", 0x1 },
8353		{ "CD", 0x4 },
8354		{ "Mixer", 0x5 },
8355	},
8356};
8357
8358/* fill in the dac_nids table from the parsed pin configuration */
8359static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
8360				     const struct auto_pin_cfg *cfg)
8361{
8362	int i;
8363	hda_nid_t nid;
8364
8365	spec->multiout.dac_nids = spec->private_dac_nids;
8366	for (i = 0; i < cfg->line_outs; i++) {
8367		nid = cfg->line_out_pins[i];
8368		if (nid) {
8369			if (i >= ARRAY_SIZE(alc861_dac_nids))
8370				continue;
8371			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
8372		}
8373	}
8374	spec->multiout.num_dacs = cfg->line_outs;
8375	return 0;
8376}
8377
8378/* add playback controls from the parsed DAC table */
8379static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
8380					     const struct auto_pin_cfg *cfg)
8381{
8382	char name[32];
8383	static const char *chname[4] = {
8384		"Front", "Surround", NULL /*CLFE*/, "Side"
8385	};
8386	hda_nid_t nid;
8387	int i, idx, err;
8388
8389	for (i = 0; i < cfg->line_outs; i++) {
8390		nid = spec->multiout.dac_nids[i];
8391		if (!nid)
8392			continue;
8393		if (nid == 0x05) {
8394			/* Center/LFE */
8395			err = add_control(spec, ALC_CTL_BIND_MUTE,
8396					  "Center Playback Switch",
8397					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
8398							      HDA_OUTPUT));
8399			if (err < 0)
8400				return err;
8401			err = add_control(spec, ALC_CTL_BIND_MUTE,
8402					  "LFE Playback Switch",
8403					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8404							      HDA_OUTPUT));
8405			if (err < 0)
8406				return err;
8407		} else {
8408			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
8409			     idx++)
8410				if (nid == alc861_dac_nids[idx])
8411					break;
8412			sprintf(name, "%s Playback Switch", chname[idx]);
8413			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
8414					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8415							      HDA_OUTPUT));
8416			if (err < 0)
8417				return err;
8418		}
8419	}
8420	return 0;
8421}
8422
8423static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
8424{
8425	int err;
8426	hda_nid_t nid;
8427
8428	if (!pin)
8429		return 0;
8430
8431	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
8432		nid = 0x03;
8433		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8434				  "Headphone Playback Switch",
8435				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8436		if (err < 0)
8437			return err;
8438		spec->multiout.hp_nid = nid;
8439	}
8440	return 0;
8441}
8442
8443/* create playback/capture controls for input pins */
8444static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
8445						const struct auto_pin_cfg *cfg)
8446{
8447	struct hda_input_mux *imux = &spec->private_imux;
8448	int i, err, idx, idx1;
8449
8450	for (i = 0; i < AUTO_PIN_LAST; i++) {
8451		switch (cfg->input_pins[i]) {
8452		case 0x0c:
8453			idx1 = 1;
8454			idx = 2;	/* Line In */
8455			break;
8456		case 0x0f:
8457			idx1 = 2;
8458			idx = 2;	/* Line In */
8459			break;
8460		case 0x0d:
8461			idx1 = 0;
8462			idx = 1;	/* Mic In */
8463			break;
8464		case 0x10:
8465			idx1 = 3;
8466			idx = 1;	/* Mic In */
8467			break;
8468		case 0x11:
8469			idx1 = 4;
8470			idx = 0;	/* CD */
8471			break;
8472		default:
8473			continue;
8474		}
8475
8476		err = new_analog_input(spec, cfg->input_pins[i],
8477				       auto_pin_cfg_labels[i], idx, 0x15);
8478		if (err < 0)
8479			return err;
8480
8481		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8482		imux->items[imux->num_items].index = idx1;
8483		imux->num_items++;
8484	}
8485	return 0;
8486}
8487
8488static struct snd_kcontrol_new alc861_capture_mixer[] = {
8489	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8490	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8491
8492	{
8493		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8494		/* .name = "Capture Source", */
8495		.name = "Input Source",
8496		.count = 1,
8497		.info = alc_mux_enum_info,
8498		.get = alc_mux_enum_get,
8499		.put = alc_mux_enum_put,
8500	},
8501	{ } /* end */
8502};
8503
8504static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
8505					      hda_nid_t nid,
8506					      int pin_type, int dac_idx)
8507{
8508	/* set as output */
8509
8510	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8511			    pin_type);
8512	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8513			    AMP_OUT_UNMUTE);
8514
8515}
8516
8517static void alc861_auto_init_multi_out(struct hda_codec *codec)
8518{
8519	struct alc_spec *spec = codec->spec;
8520	int i;
8521
8522	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
8523	for (i = 0; i < spec->autocfg.line_outs; i++) {
8524		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8525		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8526		if (nid)
8527			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
8528							  spec->multiout.dac_nids[i]);
8529	}
8530}
8531
8532static void alc861_auto_init_hp_out(struct hda_codec *codec)
8533{
8534	struct alc_spec *spec = codec->spec;
8535	hda_nid_t pin;
8536
8537	pin = spec->autocfg.hp_pins[0];
8538	if (pin) /* connect to front */
8539		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
8540						  spec->multiout.dac_nids[0]);
8541}
8542
8543static void alc861_auto_init_analog_input(struct hda_codec *codec)
8544{
8545	struct alc_spec *spec = codec->spec;
8546	int i;
8547
8548	for (i = 0; i < AUTO_PIN_LAST; i++) {
8549		hda_nid_t nid = spec->autocfg.input_pins[i];
8550		if (nid >= 0x0c && nid <= 0x11) {
8551			snd_hda_codec_write(codec, nid, 0,
8552					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8553					    i <= AUTO_PIN_FRONT_MIC ?
8554					    PIN_VREF80 : PIN_IN);
8555		}
8556	}
8557}
8558
8559/* parse the BIOS configuration and set up the alc_spec */
8560/* return 1 if successful, 0 if the proper config is not found,
8561 * or a negative error code
8562 */
8563static int alc861_parse_auto_config(struct hda_codec *codec)
8564{
8565	struct alc_spec *spec = codec->spec;
8566	int err;
8567	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
8568
8569	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8570					   alc861_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 = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
8577	if (err < 0)
8578		return err;
8579	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
8580	if (err < 0)
8581		return err;
8582	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
8583	if (err < 0)
8584		return err;
8585	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
8586	if (err < 0)
8587		return err;
8588
8589	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8590
8591	if (spec->autocfg.dig_out_pin)
8592		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
8593
8594	if (spec->kctl_alloc)
8595		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8596
8597	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
8598
8599	spec->num_mux_defs = 1;
8600	spec->input_mux = &spec->private_imux;
8601
8602	spec->adc_nids = alc861_adc_nids;
8603	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
8604	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
8605	spec->num_mixers++;
8606
8607	return 1;
8608}
8609
8610/* additional initialization for auto-configuration model */
8611static void alc861_auto_init(struct hda_codec *codec)
8612{
8613	alc861_auto_init_multi_out(codec);
8614	alc861_auto_init_hp_out(codec);
8615	alc861_auto_init_analog_input(codec);
8616}
8617
8618
8619/*
8620 * configuration and preset
8621 */
8622static const char *alc861_models[ALC861_MODEL_LAST] = {
8623	[ALC861_3ST]		= "3stack",
8624	[ALC660_3ST]		= "3stack-660",
8625	[ALC861_3ST_DIG]	= "3stack-dig",
8626	[ALC861_6ST_DIG]	= "6stack-dig",
8627	[ALC861_UNIWILL_M31]	= "uniwill-m31",
8628	[ALC861_TOSHIBA]	= "toshiba",
8629	[ALC861_ASUS]		= "asus",
8630	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
8631	[ALC861_AUTO]		= "auto",
8632};
8633
8634static struct snd_pci_quirk alc861_cfg_tbl[] = {
8635	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
8636	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
8637	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
8638	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
8639	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
8640	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
8641	SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
8642	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
8643	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
8644	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
8645	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
8646	{}
8647};
8648
8649static struct alc_config_preset alc861_presets[] = {
8650	[ALC861_3ST] = {
8651		.mixers = { alc861_3ST_mixer },
8652		.init_verbs = { alc861_threestack_init_verbs },
8653		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
8654		.dac_nids = alc861_dac_nids,
8655		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
8656		.channel_mode = alc861_threestack_modes,
8657		.need_dac_fix = 1,
8658		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8659		.adc_nids = alc861_adc_nids,
8660		.input_mux = &alc861_capture_source,
8661	},
8662	[ALC861_3ST_DIG] = {
8663		.mixers = { alc861_base_mixer },
8664		.init_verbs = { alc861_threestack_init_verbs },
8665		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
8666		.dac_nids = alc861_dac_nids,
8667		.dig_out_nid = ALC861_DIGOUT_NID,
8668		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
8669		.channel_mode = alc861_threestack_modes,
8670		.need_dac_fix = 1,
8671		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8672		.adc_nids = alc861_adc_nids,
8673		.input_mux = &alc861_capture_source,
8674	},
8675	[ALC861_6ST_DIG] = {
8676		.mixers = { alc861_base_mixer },
8677		.init_verbs = { alc861_base_init_verbs },
8678		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
8679		.dac_nids = alc861_dac_nids,
8680		.dig_out_nid = ALC861_DIGOUT_NID,
8681		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
8682		.channel_mode = alc861_8ch_modes,
8683		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8684		.adc_nids = alc861_adc_nids,
8685		.input_mux = &alc861_capture_source,
8686	},
8687	[ALC660_3ST] = {
8688		.mixers = { alc861_3ST_mixer },
8689		.init_verbs = { alc861_threestack_init_verbs },
8690		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
8691		.dac_nids = alc660_dac_nids,
8692		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
8693		.channel_mode = alc861_threestack_modes,
8694		.need_dac_fix = 1,
8695		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8696		.adc_nids = alc861_adc_nids,
8697		.input_mux = &alc861_capture_source,
8698	},
8699	[ALC861_UNIWILL_M31] = {
8700		.mixers = { alc861_uniwill_m31_mixer },
8701		.init_verbs = { alc861_uniwill_m31_init_verbs },
8702		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
8703		.dac_nids = alc861_dac_nids,
8704		.dig_out_nid = ALC861_DIGOUT_NID,
8705		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
8706		.channel_mode = alc861_uniwill_m31_modes,
8707		.need_dac_fix = 1,
8708		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8709		.adc_nids = alc861_adc_nids,
8710		.input_mux = &alc861_capture_source,
8711	},
8712	[ALC861_TOSHIBA] = {
8713		.mixers = { alc861_toshiba_mixer },
8714		.init_verbs = { alc861_base_init_verbs,
8715				alc861_toshiba_init_verbs },
8716		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
8717		.dac_nids = alc861_dac_nids,
8718		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8719		.channel_mode = alc883_3ST_2ch_modes,
8720		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8721		.adc_nids = alc861_adc_nids,
8722		.input_mux = &alc861_capture_source,
8723		.unsol_event = alc861_toshiba_unsol_event,
8724		.init_hook = alc861_toshiba_automute,
8725	},
8726	[ALC861_ASUS] = {
8727		.mixers = { alc861_asus_mixer },
8728		.init_verbs = { alc861_asus_init_verbs },
8729		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
8730		.dac_nids = alc861_dac_nids,
8731		.dig_out_nid = ALC861_DIGOUT_NID,
8732		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
8733		.channel_mode = alc861_asus_modes,
8734		.need_dac_fix = 1,
8735		.hp_nid = 0x06,
8736		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8737		.adc_nids = alc861_adc_nids,
8738		.input_mux = &alc861_capture_source,
8739	},
8740	[ALC861_ASUS_LAPTOP] = {
8741		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
8742		.init_verbs = { alc861_asus_init_verbs,
8743				alc861_asus_laptop_init_verbs },
8744		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
8745		.dac_nids = alc861_dac_nids,
8746		.dig_out_nid = ALC861_DIGOUT_NID,
8747		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8748		.channel_mode = alc883_3ST_2ch_modes,
8749		.need_dac_fix = 1,
8750		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
8751		.adc_nids = alc861_adc_nids,
8752		.input_mux = &alc861_capture_source,
8753	},
8754};
8755
8756
8757static int patch_alc861(struct hda_codec *codec)
8758{
8759	struct alc_spec *spec;
8760	int board_config;
8761	int err;
8762
8763	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8764	if (spec == NULL)
8765		return -ENOMEM;
8766
8767	codec->spec = spec;
8768
8769        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
8770						  alc861_models,
8771						  alc861_cfg_tbl);
8772
8773	if (board_config < 0) {
8774		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
8775		       "trying auto-probe from BIOS...\n");
8776		board_config = ALC861_AUTO;
8777	}
8778
8779	if (board_config == ALC861_AUTO) {
8780		/* automatic parse from the BIOS config */
8781		err = alc861_parse_auto_config(codec);
8782		if (err < 0) {
8783			alc_free(codec);
8784			return err;
8785		} else if (!err) {
8786			printk(KERN_INFO
8787			       "hda_codec: Cannot set up configuration "
8788			       "from BIOS.  Using base mode...\n");
8789		   board_config = ALC861_3ST_DIG;
8790		}
8791	}
8792
8793	if (board_config != ALC861_AUTO)
8794		setup_preset(spec, &alc861_presets[board_config]);
8795
8796	spec->stream_name_analog = "ALC861 Analog";
8797	spec->stream_analog_playback = &alc861_pcm_analog_playback;
8798	spec->stream_analog_capture = &alc861_pcm_analog_capture;
8799
8800	spec->stream_name_digital = "ALC861 Digital";
8801	spec->stream_digital_playback = &alc861_pcm_digital_playback;
8802	spec->stream_digital_capture = &alc861_pcm_digital_capture;
8803
8804	codec->patch_ops = alc_patch_ops;
8805	if (board_config == ALC861_AUTO)
8806		spec->init_hook = alc861_auto_init;
8807
8808	return 0;
8809}
8810
8811/*
8812 * ALC861-VD support
8813 *
8814 * Based on ALC882
8815 *
8816 * In addition, an independent DAC
8817 */
8818#define ALC861VD_DIGOUT_NID	0x06
8819
8820static hda_nid_t alc861vd_dac_nids[4] = {
8821	/* front, surr, clfe, side surr */
8822	0x02, 0x03, 0x04, 0x05
8823};
8824
8825/* dac_nids for ALC660vd are in a different order - according to
8826 * Realtek's driver.
8827 * This should probably tesult in a different mixer for 6stack models
8828 * of ALC660vd codecs, but for now there is only 3stack mixer
8829 * - and it is the same as in 861vd.
8830 * adc_nids in ALC660vd are (is) the same as in 861vd
8831 */
8832static hda_nid_t alc660vd_dac_nids[3] = {
8833	/* front, rear, clfe, rear_surr */
8834	0x02, 0x04, 0x03
8835};
8836
8837static hda_nid_t alc861vd_adc_nids[1] = {
8838	/* ADC0 */
8839	0x09,
8840};
8841
8842/* input MUX */
8843static struct hda_input_mux alc861vd_capture_source = {
8844	.num_items = 4,
8845	.items = {
8846		{ "Mic", 0x0 },
8847		{ "Front Mic", 0x1 },
8848		{ "Line", 0x2 },
8849		{ "CD", 0x4 },
8850	},
8851};
8852
8853static struct hda_input_mux alc861vd_dallas_capture_source = {
8854	.num_items = 3,
8855	.items = {
8856		{ "Front Mic", 0x0 },
8857		{ "ATAPI Mic", 0x1 },
8858		{ "Line In", 0x5 },
8859	},
8860};
8861
8862#define alc861vd_mux_enum_info alc_mux_enum_info
8863#define alc861vd_mux_enum_get alc_mux_enum_get
8864
8865static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
8866				struct snd_ctl_elem_value *ucontrol)
8867{
8868	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8869	struct alc_spec *spec = codec->spec;
8870	const struct hda_input_mux *imux = spec->input_mux;
8871	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8872	static hda_nid_t capture_mixers[1] = { 0x22 };
8873	hda_nid_t nid = capture_mixers[adc_idx];
8874	unsigned int *cur_val = &spec->cur_mux[adc_idx];
8875	unsigned int i, idx;
8876
8877	idx = ucontrol->value.enumerated.item[0];
8878	if (idx >= imux->num_items)
8879		idx = imux->num_items - 1;
8880	if (*cur_val == idx && !codec->in_resume)
8881		return 0;
8882	for (i = 0; i < imux->num_items; i++) {
8883		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8884		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8885				    v | (imux->items[i].index << 8));
8886	}
8887	*cur_val = idx;
8888	return 1;
8889}
8890
8891/*
8892 * 2ch mode
8893 */
8894static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
8895	{ 2, NULL }
8896};
8897
8898/*
8899 * 6ch mode
8900 */
8901static struct hda_verb alc861vd_6stack_ch6_init[] = {
8902	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8903	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8904	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8905	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8906	{ } /* end */
8907};
8908
8909/*
8910 * 8ch mode
8911 */
8912static struct hda_verb alc861vd_6stack_ch8_init[] = {
8913	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8914	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8915	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8916	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8917	{ } /* end */
8918};
8919
8920static struct hda_channel_mode alc861vd_6stack_modes[2] = {
8921	{ 6, alc861vd_6stack_ch6_init },
8922	{ 8, alc861vd_6stack_ch8_init },
8923};
8924
8925static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
8926	{
8927		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8928		.name = "Channel Mode",
8929		.info = alc_ch_mode_info,
8930		.get = alc_ch_mode_get,
8931		.put = alc_ch_mode_put,
8932	},
8933	{ } /* end */
8934};
8935
8936static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
8937	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
8938	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
8939
8940	{
8941		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8942		/* .name = "Capture Source", */
8943		.name = "Input Source",
8944		.count = 1,
8945		.info = alc861vd_mux_enum_info,
8946		.get = alc861vd_mux_enum_get,
8947		.put = alc861vd_mux_enum_put,
8948	},
8949	{ } /* end */
8950};
8951
8952/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8953 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8954 */
8955static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
8956	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8957	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8958
8959	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8960	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8961
8962	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
8963				HDA_OUTPUT),
8964	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
8965				HDA_OUTPUT),
8966	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8967	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8968
8969	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
8970	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8971
8972	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8973
8974	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8975	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8976	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8977
8978	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8979	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8980	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8981
8982	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8983	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8984
8985	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8986	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8987
8988	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
8989	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
8990
8991	{ } /* end */
8992};
8993
8994static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
8995	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8996	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8997
8998	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8999
9000	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9001	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9002	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9003
9004	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9005	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9006	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9007
9008	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9009	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9010
9011	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9012	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9013
9014	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9015	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9016
9017	{ } /* end */
9018};
9019
9020static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
9021	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9022	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
9023	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9024
9025	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9026
9027	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9028	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9029	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9030
9031	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9032	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9033	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9034
9035	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9036	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9037
9038	{ } /* end */
9039};
9040
9041/* Pin assignment: Front=0x14, HP = 0x15,
9042 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
9043 */
9044static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
9045	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9046	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9047	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9048	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
9049	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9050	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9051	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9052	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9053	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
9054	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
9055	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9056	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9057	{
9058		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9059		/* .name = "Capture Source", */
9060		.name = "Input Source",
9061		.count = 1,
9062		.info = alc882_mux_enum_info,
9063		.get = alc882_mux_enum_get,
9064		.put = alc882_mux_enum_put,
9065	},
9066	{ } /* end */
9067};
9068
9069/*
9070 * generic initialization of ADC, input mixers and output mixers
9071 */
9072static struct hda_verb alc861vd_volume_init_verbs[] = {
9073	/*
9074	 * Unmute ADC0 and set the default input to mic-in
9075	 */
9076	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9077	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9078
9079	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
9080	 * the analog-loopback mixer widget
9081	 */
9082	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9083	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9084	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9085	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9086	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9087	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9088
9089	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
9090	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9091	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9092	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9093	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9094
9095	/*
9096	 * Set up output mixers (0x02 - 0x05)
9097	 */
9098	/* set vol=0 to output mixers */
9099	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9100	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9101	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9102	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9103
9104	/* set up input amps for analog loopback */
9105	/* Amp Indices: DAC = 0, mixer = 1 */
9106	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9107	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9108	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9109	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9110	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9111	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9112	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9113	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9114
9115	{ }
9116};
9117
9118/*
9119 * 3-stack pin configuration:
9120 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
9121 */
9122static struct hda_verb alc861vd_3stack_init_verbs[] = {
9123	/*
9124	 * Set pin mode and muting
9125	 */
9126	/* set front pin widgets 0x14 for output */
9127	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9128	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9129	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9130
9131	/* Mic (rear) pin: input vref at 80% */
9132	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9133	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9134	/* Front Mic pin: input vref at 80% */
9135	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9136	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9137	/* Line In pin: input */
9138	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9139	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9140	/* Line-2 In: Headphone output (output 0 - 0x0c) */
9141	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9142	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9143	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9144	/* CD pin widget for input */
9145	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9146
9147	{ }
9148};
9149
9150/*
9151 * 6-stack pin configuration:
9152 */
9153static struct hda_verb alc861vd_6stack_init_verbs[] = {
9154	/*
9155	 * Set pin mode and muting
9156	 */
9157	/* set front pin widgets 0x14 for output */
9158	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9159	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9160	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9161
9162	/* Rear Pin: output 1 (0x0d) */
9163	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9164	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9165	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9166	/* CLFE Pin: output 2 (0x0e) */
9167	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9168	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9169	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
9170	/* Side Pin: output 3 (0x0f) */
9171	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9172	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9173	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9174
9175	/* Mic (rear) pin: input vref at 80% */
9176	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9177	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9178	/* Front Mic pin: input vref at 80% */
9179	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9180	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9181	/* Line In pin: input */
9182	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9183	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9184	/* Line-2 In: Headphone output (output 0 - 0x0c) */
9185	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9186	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9187	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9188	/* CD pin widget for input */
9189	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9190
9191	{ }
9192};
9193
9194static struct hda_verb alc861vd_eapd_verbs[] = {
9195	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9196	{ }
9197};
9198
9199static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
9200	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9201	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9202	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9203	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9204	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9205	{}
9206};
9207
9208/* toggle speaker-output according to the hp-jack state */
9209static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
9210{
9211	unsigned int present;
9212	unsigned char bits;
9213
9214	present = snd_hda_codec_read(codec, 0x1b, 0,
9215				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9216	bits = present ? 0x80 : 0;
9217	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9218				 0x80, bits);
9219	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9220				 0x80, bits);
9221}
9222
9223static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
9224{
9225	unsigned int present;
9226	unsigned char bits;
9227
9228	present = snd_hda_codec_read(codec, 0x18, 0,
9229				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9230	bits = present ? 0x80 : 0;
9231	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
9232				 0x80, bits);
9233	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
9234				 0x80, bits);
9235}
9236
9237static void alc861vd_lenovo_automute(struct hda_codec *codec)
9238{
9239	alc861vd_lenovo_hp_automute(codec);
9240	alc861vd_lenovo_mic_automute(codec);
9241}
9242
9243static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
9244					unsigned int res)
9245{
9246	switch (res >> 26) {
9247	case ALC880_HP_EVENT:
9248		alc861vd_lenovo_hp_automute(codec);
9249		break;
9250	case ALC880_MIC_EVENT:
9251		alc861vd_lenovo_mic_automute(codec);
9252		break;
9253	}
9254}
9255
9256static struct hda_verb alc861vd_dallas_verbs[] = {
9257	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9258	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9259	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9260	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9261
9262	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9263	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9264	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9265	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9266	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9267	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9268	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9269	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9270
9271	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9272	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9273	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9274	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9275	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9276	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9277	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9278	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9279
9280	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
9281	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9282	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
9283	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9284	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9285	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9286	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9287	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9288
9289	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9290	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9291	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9292	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9293
9294	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9295	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9296	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9297
9298	{ } /* end */
9299};
9300
9301/* toggle speaker-output according to the hp-jack state */
9302static void alc861vd_dallas_automute(struct hda_codec *codec)
9303{
9304	unsigned int present;
9305
9306	present = snd_hda_codec_read(codec, 0x15, 0,
9307				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9308	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9309				 0x80, present ? 0x80 : 0);
9310	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9311				 0x80, present ? 0x80 : 0);
9312}
9313
9314static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
9315{
9316	if ((res >> 26) == ALC880_HP_EVENT)
9317		alc861vd_dallas_automute(codec);
9318}
9319
9320/* pcm configuration: identiacal with ALC880 */
9321#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
9322#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
9323#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
9324#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
9325
9326/*
9327 * configuration and preset
9328 */
9329static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
9330	[ALC660VD_3ST]		= "3stack-660",
9331	[ALC861VD_3ST]		= "3stack",
9332	[ALC861VD_3ST_DIG]	= "3stack-digout",
9333	[ALC861VD_6ST_DIG]	= "6stack-digout",
9334	[ALC861VD_LENOVO]	= "lenovo",
9335	[ALC861VD_DALLAS]	= "dallas",
9336	[ALC861VD_AUTO]		= "auto",
9337};
9338
9339static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
9340	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
9341	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
9342	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST),
9343	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
9344	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
9345
9346	SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
9347	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
9348	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
9349	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
9350	{}
9351};
9352
9353static struct alc_config_preset alc861vd_presets[] = {
9354	[ALC660VD_3ST] = {
9355		.mixers = { alc861vd_3st_mixer },
9356		.init_verbs = { alc861vd_volume_init_verbs,
9357				 alc861vd_3stack_init_verbs },
9358		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
9359		.dac_nids = alc660vd_dac_nids,
9360		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
9361		.adc_nids = alc861vd_adc_nids,
9362		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
9363		.channel_mode = alc861vd_3stack_2ch_modes,
9364		.input_mux = &alc861vd_capture_source,
9365	},
9366	[ALC861VD_3ST] = {
9367		.mixers = { alc861vd_3st_mixer },
9368		.init_verbs = { alc861vd_volume_init_verbs,
9369				 alc861vd_3stack_init_verbs },
9370		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
9371		.dac_nids = alc861vd_dac_nids,
9372		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
9373		.channel_mode = alc861vd_3stack_2ch_modes,
9374		.input_mux = &alc861vd_capture_source,
9375	},
9376	[ALC861VD_3ST_DIG] = {
9377		.mixers = { alc861vd_3st_mixer },
9378		.init_verbs = { alc861vd_volume_init_verbs,
9379		 		 alc861vd_3stack_init_verbs },
9380		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
9381		.dac_nids = alc861vd_dac_nids,
9382		.dig_out_nid = ALC861VD_DIGOUT_NID,
9383		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
9384		.channel_mode = alc861vd_3stack_2ch_modes,
9385		.input_mux = &alc861vd_capture_source,
9386	},
9387	[ALC861VD_6ST_DIG] = {
9388		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
9389		.init_verbs = { alc861vd_volume_init_verbs,
9390				alc861vd_6stack_init_verbs },
9391		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
9392		.dac_nids = alc861vd_dac_nids,
9393		.dig_out_nid = ALC861VD_DIGOUT_NID,
9394		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
9395		.channel_mode = alc861vd_6stack_modes,
9396		.input_mux = &alc861vd_capture_source,
9397	},
9398	[ALC861VD_LENOVO] = {
9399		.mixers = { alc861vd_lenovo_mixer },
9400		.init_verbs = { alc861vd_volume_init_verbs,
9401				alc861vd_3stack_init_verbs,
9402				alc861vd_eapd_verbs,
9403				alc861vd_lenovo_unsol_verbs },
9404		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
9405		.dac_nids = alc660vd_dac_nids,
9406		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
9407		.adc_nids = alc861vd_adc_nids,
9408		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
9409		.channel_mode = alc861vd_3stack_2ch_modes,
9410		.input_mux = &alc861vd_capture_source,
9411		.unsol_event = alc861vd_lenovo_unsol_event,
9412		.init_hook = alc861vd_lenovo_automute,
9413	},
9414	[ALC861VD_DALLAS] = {
9415		.mixers = { alc861vd_dallas_mixer },
9416		.init_verbs = { alc861vd_dallas_verbs },
9417		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
9418		.dac_nids = alc861vd_dac_nids,
9419		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
9420		.adc_nids = alc861vd_adc_nids,
9421		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
9422		.channel_mode = alc861vd_3stack_2ch_modes,
9423		.input_mux = &alc861vd_dallas_capture_source,
9424		.unsol_event = alc861vd_dallas_unsol_event,
9425		.init_hook = alc861vd_dallas_automute,
9426	},
9427};
9428
9429/*
9430 * BIOS auto configuration
9431 */
9432static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
9433				hda_nid_t nid, int pin_type, int dac_idx)
9434{
9435	/* set as output */
9436	snd_hda_codec_write(codec, nid, 0,
9437				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
9438	snd_hda_codec_write(codec, nid, 0,
9439				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
9440}
9441
9442static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
9443{
9444	struct alc_spec *spec = codec->spec;
9445	int i;
9446
9447	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9448	for (i = 0; i <= HDA_SIDE; i++) {
9449		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9450		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9451		if (nid)
9452			alc861vd_auto_set_output_and_unmute(codec, nid,
9453							    pin_type, i);
9454	}
9455}
9456
9457
9458static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
9459{
9460	struct alc_spec *spec = codec->spec;
9461	hda_nid_t pin;
9462
9463	pin = spec->autocfg.hp_pins[0];
9464	if (pin) /* connect to front and  use dac 0 */
9465		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9466}
9467
9468#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
9469#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
9470
9471static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
9472{
9473	struct alc_spec *spec = codec->spec;
9474	int i;
9475
9476	for (i = 0; i < AUTO_PIN_LAST; i++) {
9477		hda_nid_t nid = spec->autocfg.input_pins[i];
9478		if (alc861vd_is_input_pin(nid)) {
9479			snd_hda_codec_write(codec, nid, 0,
9480					AC_VERB_SET_PIN_WIDGET_CONTROL,
9481					i <= AUTO_PIN_FRONT_MIC ?
9482							PIN_VREF80 : PIN_IN);
9483			if (nid != ALC861VD_PIN_CD_NID)
9484				snd_hda_codec_write(codec, nid, 0,
9485						AC_VERB_SET_AMP_GAIN_MUTE,
9486						AMP_OUT_MUTE);
9487		}
9488	}
9489}
9490
9491#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
9492#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
9493
9494/* add playback controls from the parsed DAC table */
9495/* Based on ALC880 version. But ALC861VD has separate,
9496 * different NIDs for mute/unmute switch and volume control */
9497static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
9498					     const struct auto_pin_cfg *cfg)
9499{
9500	char name[32];
9501	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
9502	hda_nid_t nid_v, nid_s;
9503	int i, err;
9504
9505	for (i = 0; i < cfg->line_outs; i++) {
9506		if (!spec->multiout.dac_nids[i])
9507			continue;
9508		nid_v = alc861vd_idx_to_mixer_vol(
9509				alc880_dac_to_idx(
9510					spec->multiout.dac_nids[i]));
9511		nid_s = alc861vd_idx_to_mixer_switch(
9512				alc880_dac_to_idx(
9513					spec->multiout.dac_nids[i]));
9514
9515		if (i == 2) {
9516			/* Center/LFE */
9517			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9518					  "Center Playback Volume",
9519					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
9520							      HDA_OUTPUT));
9521			if (err < 0)
9522				return err;
9523			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9524					  "LFE Playback Volume",
9525					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
9526							      HDA_OUTPUT));
9527			if (err < 0)
9528				return err;
9529			err = add_control(spec, ALC_CTL_BIND_MUTE,
9530					  "Center Playback Switch",
9531					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
9532							      HDA_INPUT));
9533			if (err < 0)
9534				return err;
9535			err = add_control(spec, ALC_CTL_BIND_MUTE,
9536					  "LFE Playback Switch",
9537					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
9538							      HDA_INPUT));
9539			if (err < 0)
9540				return err;
9541		} else {
9542			sprintf(name, "%s Playback Volume", chname[i]);
9543			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9544					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
9545							      HDA_OUTPUT));
9546			if (err < 0)
9547				return err;
9548			sprintf(name, "%s Playback Switch", chname[i]);
9549			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9550					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
9551							      HDA_INPUT));
9552			if (err < 0)
9553				return err;
9554		}
9555	}
9556	return 0;
9557}
9558
9559/* add playback controls for speaker and HP outputs */
9560/* Based on ALC880 version. But ALC861VD has separate,
9561 * different NIDs for mute/unmute switch and volume control */
9562static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
9563					hda_nid_t pin, const char *pfx)
9564{
9565	hda_nid_t nid_v, nid_s;
9566	int err;
9567	char name[32];
9568
9569	if (!pin)
9570		return 0;
9571
9572	if (alc880_is_fixed_pin(pin)) {
9573		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
9574		/* specify the DAC as the extra output */
9575		if (!spec->multiout.hp_nid)
9576			spec->multiout.hp_nid = nid_v;
9577		else
9578			spec->multiout.extra_out_nid[0] = nid_v;
9579		/* control HP volume/switch on the output mixer amp */
9580		nid_v = alc861vd_idx_to_mixer_vol(
9581				alc880_fixed_pin_idx(pin));
9582		nid_s = alc861vd_idx_to_mixer_switch(
9583				alc880_fixed_pin_idx(pin));
9584
9585		sprintf(name, "%s Playback Volume", pfx);
9586		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9587				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
9588		if (err < 0)
9589			return err;
9590		sprintf(name, "%s Playback Switch", pfx);
9591		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9592				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
9593		if (err < 0)
9594			return err;
9595	} else if (alc880_is_multi_pin(pin)) {
9596		/* set manual connection */
9597		/* we have only a switch on HP-out PIN */
9598		sprintf(name, "%s Playback Switch", pfx);
9599		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9600				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
9601		if (err < 0)
9602			return err;
9603	}
9604	return 0;
9605}
9606
9607/* parse the BIOS configuration and set up the alc_spec
9608 * return 1 if successful, 0 if the proper config is not found,
9609 * or a negative error code
9610 * Based on ALC880 version - had to change it to override
9611 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
9612static int alc861vd_parse_auto_config(struct hda_codec *codec)
9613{
9614	struct alc_spec *spec = codec->spec;
9615	int err;
9616	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
9617
9618	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9619					   alc861vd_ignore);
9620	if (err < 0)
9621		return err;
9622	if (!spec->autocfg.line_outs)
9623		return 0; /* can't find valid BIOS pin config */
9624
9625	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
9626	if (err < 0)
9627		return err;
9628	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
9629	if (err < 0)
9630		return err;
9631	err = alc861vd_auto_create_extra_out(spec,
9632					     spec->autocfg.speaker_pins[0],
9633					     "Speaker");
9634	if (err < 0)
9635		return err;
9636	err = alc861vd_auto_create_extra_out(spec,
9637					     spec->autocfg.hp_pins[0],
9638					     "Headphone");
9639	if (err < 0)
9640		return err;
9641	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
9642	if (err < 0)
9643		return err;
9644
9645	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9646
9647	if (spec->autocfg.dig_out_pin)
9648		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
9649
9650	if (spec->kctl_alloc)
9651		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9652
9653	spec->init_verbs[spec->num_init_verbs++]
9654		= alc861vd_volume_init_verbs;
9655
9656	spec->num_mux_defs = 1;
9657	spec->input_mux = &spec->private_imux;
9658
9659	return 1;
9660}
9661
9662/* additional initialization for auto-configuration model */
9663static void alc861vd_auto_init(struct hda_codec *codec)
9664{
9665	alc861vd_auto_init_multi_out(codec);
9666	alc861vd_auto_init_hp_out(codec);
9667	alc861vd_auto_init_analog_input(codec);
9668}
9669
9670static int patch_alc861vd(struct hda_codec *codec)
9671{
9672	struct alc_spec *spec;
9673	int err, board_config;
9674
9675	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9676	if (spec == NULL)
9677		return -ENOMEM;
9678
9679	codec->spec = spec;
9680
9681	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
9682						  alc861vd_models,
9683						  alc861vd_cfg_tbl);
9684
9685	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9686		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
9687			"ALC861VD, trying auto-probe from BIOS...\n");
9688		board_config = ALC861VD_AUTO;
9689	}
9690
9691	if (board_config == ALC861VD_AUTO) {
9692		/* automatic parse from the BIOS config */
9693		err = alc861vd_parse_auto_config(codec);
9694		if (err < 0) {
9695			alc_free(codec);
9696			return err;
9697		} else if (!err) {
9698			printk(KERN_INFO
9699			       "hda_codec: Cannot set up configuration "
9700			       "from BIOS.  Using base mode...\n");
9701			board_config = ALC861VD_3ST;
9702		}
9703	}
9704
9705	if (board_config != ALC861VD_AUTO)
9706		setup_preset(spec, &alc861vd_presets[board_config]);
9707
9708	spec->stream_name_analog = "ALC861VD Analog";
9709	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
9710	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
9711
9712	spec->stream_name_digital = "ALC861VD Digital";
9713	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
9714	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
9715
9716	spec->adc_nids = alc861vd_adc_nids;
9717	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
9718
9719	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
9720	spec->num_mixers++;
9721
9722	codec->patch_ops = alc_patch_ops;
9723
9724	if (board_config == ALC861VD_AUTO)
9725		spec->init_hook = alc861vd_auto_init;
9726
9727	return 0;
9728}
9729
9730/*
9731 * ALC662 support
9732 *
9733 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
9734 * configuration.  Each pin widget can choose any input DACs and a mixer.
9735 * Each ADC is connected from a mixer of all inputs.  This makes possible
9736 * 6-channel independent captures.
9737 *
9738 * In addition, an independent DAC for the multi-playback (not used in this
9739 * driver yet).
9740 */
9741#define ALC662_DIGOUT_NID	0x06
9742#define ALC662_DIGIN_NID	0x0a
9743
9744static hda_nid_t alc662_dac_nids[4] = {
9745	/* front, rear, clfe, rear_surr */
9746	0x02, 0x03, 0x04
9747};
9748
9749static hda_nid_t alc662_adc_nids[1] = {
9750	/* ADC1-2 */
9751	0x09,
9752};
9753/* input MUX */
9754
9755static struct hda_input_mux alc662_capture_source = {
9756	.num_items = 4,
9757	.items = {
9758		{ "Mic", 0x0 },
9759		{ "Front Mic", 0x1 },
9760		{ "Line", 0x2 },
9761		{ "CD", 0x4 },
9762	},
9763};
9764
9765static struct hda_input_mux alc662_lenovo_101e_capture_source = {
9766	.num_items = 2,
9767	.items = {
9768		{ "Mic", 0x1 },
9769		{ "Line", 0x2 },
9770	},
9771};
9772#define alc662_mux_enum_info alc_mux_enum_info
9773#define alc662_mux_enum_get alc_mux_enum_get
9774
9775static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
9776			       struct snd_ctl_elem_value *ucontrol)
9777{
9778	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9779	struct alc_spec *spec = codec->spec;
9780	const struct hda_input_mux *imux = spec->input_mux;
9781	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9782	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
9783	hda_nid_t nid = capture_mixers[adc_idx];
9784	unsigned int *cur_val = &spec->cur_mux[adc_idx];
9785	unsigned int i, idx;
9786
9787	idx = ucontrol->value.enumerated.item[0];
9788	if (idx >= imux->num_items)
9789		idx = imux->num_items - 1;
9790	if (*cur_val == idx && !codec->in_resume)
9791		return 0;
9792	for (i = 0; i < imux->num_items; i++) {
9793		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
9794		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9795				    v | (imux->items[i].index << 8));
9796	}
9797	*cur_val = idx;
9798	return 1;
9799}
9800/*
9801 * 2ch mode
9802 */
9803static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
9804	{ 2, NULL }
9805};
9806
9807/*
9808 * 2ch mode
9809 */
9810static struct hda_verb alc662_3ST_ch2_init[] = {
9811	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9812	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9813	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9814	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9815	{ } /* end */
9816};
9817
9818/*
9819 * 6ch mode
9820 */
9821static struct hda_verb alc662_3ST_ch6_init[] = {
9822	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9823	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9824	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9825	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9826	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9827	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
9828	{ } /* end */
9829};
9830
9831static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
9832	{ 2, alc662_3ST_ch2_init },
9833	{ 6, alc662_3ST_ch6_init },
9834};
9835
9836/*
9837 * 2ch mode
9838 */
9839static struct hda_verb alc662_sixstack_ch6_init[] = {
9840	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9841	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9842	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9843	{ } /* end */
9844};
9845
9846/*
9847 * 6ch mode
9848 */
9849static struct hda_verb alc662_sixstack_ch8_init[] = {
9850	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9851	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9852	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9853	{ } /* end */
9854};
9855
9856static struct hda_channel_mode alc662_5stack_modes[2] = {
9857	{ 2, alc662_sixstack_ch6_init },
9858	{ 6, alc662_sixstack_ch8_init },
9859};
9860
9861/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9862 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9863 */
9864
9865static struct snd_kcontrol_new alc662_base_mixer[] = {
9866	/* output mixer control */
9867	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9868	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
9869	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9870	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9871	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
9872	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
9873	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
9874	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
9875	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9876
9877	/*Input mixer control */
9878	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
9879	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
9880	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
9881	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
9882	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
9883	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
9884	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
9885	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
9886
9887	/* Capture mixer control */
9888	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9889	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9890	{
9891		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9892		.name = "Capture Source",
9893		.count = 1,
9894		.info = alc_mux_enum_info,
9895		.get = alc_mux_enum_get,
9896		.put = alc_mux_enum_put,
9897	},
9898	{ } /* end */
9899};
9900
9901static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
9902	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9903	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
9904	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9905	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9906	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9907	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9908	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9909	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9910	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9911	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9912	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9913	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9914	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9915	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9916	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9917	{
9918		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9919		/* .name = "Capture Source", */
9920		.name = "Input Source",
9921		.count = 1,
9922		.info = alc662_mux_enum_info,
9923		.get = alc662_mux_enum_get,
9924		.put = alc662_mux_enum_put,
9925	},
9926	{ } /* end */
9927};
9928
9929static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
9930	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9931	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
9932	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9933	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
9934	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
9935	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
9936	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
9937	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
9938	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9939	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9940	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9941	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9942	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9943	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9944	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9945	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9946	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9947	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9948	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9949	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9950	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9951	{
9952		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9953		/* .name = "Capture Source", */
9954		.name = "Input Source",
9955		.count = 1,
9956		.info = alc662_mux_enum_info,
9957		.get = alc662_mux_enum_get,
9958		.put = alc662_mux_enum_put,
9959	},
9960	{ } /* end */
9961};
9962
9963static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
9964	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9965	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
9966	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9967	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
9968	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9969	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9970	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9971	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9972	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9973	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9974	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9975	{
9976		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9977		/* .name = "Capture Source", */
9978		.name = "Input Source",
9979		.count = 1,
9980		.info = alc662_mux_enum_info,
9981		.get = alc662_mux_enum_get,
9982		.put = alc662_mux_enum_put,
9983	},
9984	{ } /* end */
9985};
9986
9987static struct snd_kcontrol_new alc662_chmode_mixer[] = {
9988	{
9989		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9990		.name = "Channel Mode",
9991		.info = alc_ch_mode_info,
9992		.get = alc_ch_mode_get,
9993		.put = alc_ch_mode_put,
9994	},
9995	{ } /* end */
9996};
9997
9998static struct hda_verb alc662_init_verbs[] = {
9999	/* ADC: mute amp left and right */
10000	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10001	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10002	/* Front mixer: unmute input/output amp left and right (volume = 0) */
10003
10004	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10005	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10006	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10007	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10008	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10009
10010	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10011	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10012	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10013	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10014	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10015	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10016
10017	/* Front Pin: output 0 (0x0c) */
10018	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10019	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10020
10021	/* Rear Pin: output 1 (0x0d) */
10022	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10023	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10024
10025	/* CLFE Pin: output 2 (0x0e) */
10026	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10027	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10028
10029	/* Mic (rear) pin: input vref at 80% */
10030	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10031	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10032	/* Front Mic pin: input vref at 80% */
10033	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10034	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10035	/* Line In pin: input */
10036	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10037	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10038	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10039	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10040	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10041	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10042	/* CD pin widget for input */
10043	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10044
10045	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10046	/* Input mixer */
10047	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10048	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10049	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10050	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10051	{ }
10052};
10053
10054static struct hda_verb alc662_sue_init_verbs[] = {
10055	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
10056	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
10057        {}
10058};
10059
10060/*
10061 * generic initialization of ADC, input mixers and output mixers
10062 */
10063static struct hda_verb alc662_auto_init_verbs[] = {
10064	/*
10065	 * Unmute ADC and set the default input to mic-in
10066	 */
10067	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10068	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10069
10070	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10071	 * mixer widget
10072	 * Note: PASD motherboards uses the Line In 2 as the input for front
10073	 * panel mic (mic 2)
10074	 */
10075	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10076	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10077	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10078	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10079	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10080	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10081
10082	/*
10083	 * Set up output mixers (0x0c - 0x0f)
10084	 */
10085	/* set vol=0 to output mixers */
10086	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10087	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10088	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10089
10090	/* set up input amps for analog loopback */
10091	/* Amp Indices: DAC = 0, mixer = 1 */
10092	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10093	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10094	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10095	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10096	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10097	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10098
10099
10100	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10101	/* Input mixer */
10102	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10103	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10104	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10105	/*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
10106	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10107
10108	{ }
10109};
10110
10111/* capture mixer elements */
10112static struct snd_kcontrol_new alc662_capture_mixer[] = {
10113	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10114	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10115	{
10116		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10117		/* .name = "Capture Source", */
10118		.name = "Input Source",
10119		.count = 1,
10120		.info = alc882_mux_enum_info,
10121		.get = alc882_mux_enum_get,
10122		.put = alc882_mux_enum_put,
10123	},
10124	{ } /* end */
10125};
10126
10127static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
10128{
10129	unsigned int present;
10130	unsigned char bits;
10131
10132	present = snd_hda_codec_read(codec, 0x14, 0,
10133				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10134	bits = present ? 0x80 : 0;
10135	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
10136				 0x80, bits);
10137	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
10138				 0x80, bits);
10139}
10140
10141static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
10142{
10143	unsigned int present;
10144	unsigned char bits;
10145
10146 	present = snd_hda_codec_read(codec, 0x1b, 0,
10147				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10148	bits = present ? 0x80 : 0;
10149	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
10150				 0x80, bits);
10151	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
10152				 0x80, bits);
10153	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10154				 0x80, bits);
10155	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10156				 0x80, bits);
10157}
10158
10159static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
10160					   unsigned int res)
10161{
10162	if ((res >> 26) == ALC880_HP_EVENT)
10163		alc662_lenovo_101e_all_automute(codec);
10164	if ((res >> 26) == ALC880_FRONT_EVENT)
10165		alc662_lenovo_101e_ispeaker_automute(codec);
10166}
10167
10168
10169/* pcm configuration: identiacal with ALC880 */
10170#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
10171#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
10172#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
10173#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
10174
10175/*
10176 * configuration and preset
10177 */
10178static const char *alc662_models[ALC662_MODEL_LAST] = {
10179	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
10180	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
10181	[ALC662_3ST_6ch]	= "3stack-6ch",
10182	[ALC662_5ST_DIG]	= "6stack-dig",
10183	[ALC662_LENOVO_101E]	= "lenovo-101e",
10184	[ALC662_AUTO]		= "auto",
10185};
10186
10187static struct snd_pci_quirk alc662_cfg_tbl[] = {
10188	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
10189	{}
10190};
10191
10192static struct alc_config_preset alc662_presets[] = {
10193	[ALC662_3ST_2ch_DIG] = {
10194		.mixers = { alc662_3ST_2ch_mixer },
10195		.init_verbs = { alc662_init_verbs },
10196		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
10197		.dac_nids = alc662_dac_nids,
10198		.dig_out_nid = ALC662_DIGOUT_NID,
10199		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10200		.adc_nids = alc662_adc_nids,
10201		.dig_in_nid = ALC662_DIGIN_NID,
10202		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
10203		.channel_mode = alc662_3ST_2ch_modes,
10204		.input_mux = &alc662_capture_source,
10205	},
10206	[ALC662_3ST_6ch_DIG] = {
10207		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
10208		.init_verbs = { alc662_init_verbs },
10209		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
10210		.dac_nids = alc662_dac_nids,
10211		.dig_out_nid = ALC662_DIGOUT_NID,
10212		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10213		.adc_nids = alc662_adc_nids,
10214		.dig_in_nid = ALC662_DIGIN_NID,
10215		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
10216		.channel_mode = alc662_3ST_6ch_modes,
10217		.need_dac_fix = 1,
10218		.input_mux = &alc662_capture_source,
10219	},
10220	[ALC662_3ST_6ch] = {
10221		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
10222		.init_verbs = { alc662_init_verbs },
10223		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
10224		.dac_nids = alc662_dac_nids,
10225		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10226		.adc_nids = alc662_adc_nids,
10227		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
10228		.channel_mode = alc662_3ST_6ch_modes,
10229		.need_dac_fix = 1,
10230		.input_mux = &alc662_capture_source,
10231	},
10232	[ALC662_5ST_DIG] = {
10233		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
10234		.init_verbs = { alc662_init_verbs },
10235		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
10236		.dac_nids = alc662_dac_nids,
10237		.dig_out_nid = ALC662_DIGOUT_NID,
10238		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10239		.adc_nids = alc662_adc_nids,
10240		.dig_in_nid = ALC662_DIGIN_NID,
10241		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
10242		.channel_mode = alc662_5stack_modes,
10243		.input_mux = &alc662_capture_source,
10244	},
10245	[ALC662_LENOVO_101E] = {
10246		.mixers = { alc662_lenovo_101e_mixer },
10247		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
10248		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
10249		.dac_nids = alc662_dac_nids,
10250		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
10251		.adc_nids = alc662_adc_nids,
10252		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
10253		.channel_mode = alc662_3ST_2ch_modes,
10254		.input_mux = &alc662_lenovo_101e_capture_source,
10255		.unsol_event = alc662_lenovo_101e_unsol_event,
10256		.init_hook = alc662_lenovo_101e_all_automute,
10257	},
10258
10259};
10260
10261
10262/*
10263 * BIOS auto configuration
10264 */
10265
10266/* add playback controls from the parsed DAC table */
10267static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
10268					     const struct auto_pin_cfg *cfg)
10269{
10270	char name[32];
10271	static const char *chname[4] = {
10272		"Front", "Surround", NULL /*CLFE*/, "Side"
10273	};
10274	hda_nid_t nid;
10275	int i, err;
10276
10277	for (i = 0; i < cfg->line_outs; i++) {
10278		if (!spec->multiout.dac_nids[i])
10279			continue;
10280		nid = alc880_idx_to_dac(i);
10281		if (i == 2) {
10282			/* Center/LFE */
10283			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10284					  "Center Playback Volume",
10285					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10286							      HDA_OUTPUT));
10287			if (err < 0)
10288				return err;
10289			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10290					  "LFE Playback Volume",
10291					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10292							      HDA_OUTPUT));
10293			if (err < 0)
10294				return err;
10295			err = add_control(spec, ALC_CTL_BIND_MUTE,
10296					  "Center Playback Switch",
10297					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
10298							      HDA_INPUT));
10299			if (err < 0)
10300				return err;
10301			err = add_control(spec, ALC_CTL_BIND_MUTE,
10302					  "LFE Playback Switch",
10303					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
10304							      HDA_INPUT));
10305			if (err < 0)
10306				return err;
10307		} else {
10308			sprintf(name, "%s Playback Volume", chname[i]);
10309			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10310					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10311							      HDA_OUTPUT));
10312			if (err < 0)
10313				return err;
10314			sprintf(name, "%s Playback Switch", chname[i]);
10315			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10316					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
10317							      HDA_INPUT));
10318			if (err < 0)
10319				return err;
10320		}
10321	}
10322	return 0;
10323}
10324
10325/* add playback controls for speaker and HP outputs */
10326static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
10327					const char *pfx)
10328{
10329	hda_nid_t nid;
10330	int err;
10331	char name[32];
10332
10333	if (!pin)
10334		return 0;
10335
10336	if (alc880_is_fixed_pin(pin)) {
10337		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10338                /* printk("DAC nid=%x\n",nid); */
10339		/* specify the DAC as the extra output */
10340		if (!spec->multiout.hp_nid)
10341			spec->multiout.hp_nid = nid;
10342		else
10343			spec->multiout.extra_out_nid[0] = nid;
10344		/* control HP volume/switch on the output mixer amp */
10345		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10346		sprintf(name, "%s Playback Volume", pfx);
10347		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10348				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10349		if (err < 0)
10350			return err;
10351		sprintf(name, "%s Playback Switch", pfx);
10352		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10353				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
10354		if (err < 0)
10355			return err;
10356	} else if (alc880_is_multi_pin(pin)) {
10357		/* set manual connection */
10358		/* we have only a switch on HP-out PIN */
10359		sprintf(name, "%s Playback Switch", pfx);
10360		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10361				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10362		if (err < 0)
10363			return err;
10364	}
10365	return 0;
10366}
10367
10368/* create playback/capture controls for input pins */
10369static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
10370						const struct auto_pin_cfg *cfg)
10371{
10372	struct hda_input_mux *imux = &spec->private_imux;
10373	int i, err, idx;
10374
10375	for (i = 0; i < AUTO_PIN_LAST; i++) {
10376		if (alc880_is_input_pin(cfg->input_pins[i])) {
10377			idx = alc880_input_pin_idx(cfg->input_pins[i]);
10378			err = new_analog_input(spec, cfg->input_pins[i],
10379					       auto_pin_cfg_labels[i],
10380					       idx, 0x0b);
10381			if (err < 0)
10382				return err;
10383			imux->items[imux->num_items].label =
10384				auto_pin_cfg_labels[i];
10385			imux->items[imux->num_items].index =
10386				alc880_input_pin_idx(cfg->input_pins[i]);
10387			imux->num_items++;
10388		}
10389	}
10390	return 0;
10391}
10392
10393static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
10394					      hda_nid_t nid, int pin_type,
10395					      int dac_idx)
10396{
10397	/* set as output */
10398	snd_hda_codec_write(codec, nid, 0,
10399			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10400	snd_hda_codec_write(codec, nid, 0,
10401			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10402	/* need the manual connection? */
10403	if (alc880_is_multi_pin(nid)) {
10404		struct alc_spec *spec = codec->spec;
10405		int idx = alc880_multi_pin_idx(nid);
10406		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
10407				    AC_VERB_SET_CONNECT_SEL,
10408				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
10409	}
10410}
10411
10412static void alc662_auto_init_multi_out(struct hda_codec *codec)
10413{
10414	struct alc_spec *spec = codec->spec;
10415	int i;
10416
10417	for (i = 0; i <= HDA_SIDE; i++) {
10418		hda_nid_t nid = spec->autocfg.line_out_pins[i];
10419		int pin_type = get_pin_type(spec->autocfg.line_out_type);
10420		if (nid)
10421			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
10422							  i);
10423	}
10424}
10425
10426static void alc662_auto_init_hp_out(struct hda_codec *codec)
10427{
10428	struct alc_spec *spec = codec->spec;
10429	hda_nid_t pin;
10430
10431	pin = spec->autocfg.hp_pins[0];
10432	if (pin) /* connect to front */
10433		/* use dac 0 */
10434		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10435}
10436
10437#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
10438#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
10439
10440static void alc662_auto_init_analog_input(struct hda_codec *codec)
10441{
10442	struct alc_spec *spec = codec->spec;
10443	int i;
10444
10445	for (i = 0; i < AUTO_PIN_LAST; i++) {
10446		hda_nid_t nid = spec->autocfg.input_pins[i];
10447		if (alc662_is_input_pin(nid)) {
10448			snd_hda_codec_write(codec, nid, 0,
10449					    AC_VERB_SET_PIN_WIDGET_CONTROL,
10450					    (i <= AUTO_PIN_FRONT_MIC ?
10451					     PIN_VREF80 : PIN_IN));
10452			if (nid != ALC662_PIN_CD_NID)
10453				snd_hda_codec_write(codec, nid, 0,
10454						    AC_VERB_SET_AMP_GAIN_MUTE,
10455						    AMP_OUT_MUTE);
10456		}
10457	}
10458}
10459
10460static int alc662_parse_auto_config(struct hda_codec *codec)
10461{
10462	struct alc_spec *spec = codec->spec;
10463	int err;
10464	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
10465
10466	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10467					   alc662_ignore);
10468	if (err < 0)
10469		return err;
10470	if (!spec->autocfg.line_outs)
10471		return 0; /* can't find valid BIOS pin config */
10472
10473	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10474	if (err < 0)
10475		return err;
10476	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
10477	if (err < 0)
10478		return err;
10479	err = alc662_auto_create_extra_out(spec,
10480					   spec->autocfg.speaker_pins[0],
10481					   "Speaker");
10482	if (err < 0)
10483		return err;
10484	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10485					   "Headphone");
10486	if (err < 0)
10487		return err;
10488	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
10489	if (err < 0)
10490		return err;
10491
10492	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10493
10494	if (spec->autocfg.dig_out_pin)
10495		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
10496
10497	if (spec->kctl_alloc)
10498		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10499
10500	spec->num_mux_defs = 1;
10501	spec->input_mux = &spec->private_imux;
10502
10503	if (err < 0)
10504		return err;
10505	else if (err > 0)
10506		/* hack - override the init verbs */
10507		spec->init_verbs[0] = alc662_auto_init_verbs;
10508	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
10509	spec->num_mixers++;
10510	return err;
10511}
10512
10513/* additional initialization for auto-configuration model */
10514static void alc662_auto_init(struct hda_codec *codec)
10515{
10516	alc662_auto_init_multi_out(codec);
10517	alc662_auto_init_hp_out(codec);
10518	alc662_auto_init_analog_input(codec);
10519}
10520
10521static int patch_alc662(struct hda_codec *codec)
10522{
10523	struct alc_spec *spec;
10524	int err, board_config;
10525
10526	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10527	if (!spec)
10528		return -ENOMEM;
10529
10530	codec->spec = spec;
10531
10532	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
10533						  alc662_models,
10534			  	                  alc662_cfg_tbl);
10535	if (board_config < 0) {
10536		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
10537		       "trying auto-probe from BIOS...\n");
10538		board_config = ALC662_AUTO;
10539	}
10540
10541	if (board_config == ALC662_AUTO) {
10542		/* automatic parse from the BIOS config */
10543		err = alc662_parse_auto_config(codec);
10544		if (err < 0) {
10545			alc_free(codec);
10546			return err;
10547		} else if (err) {
10548			printk(KERN_INFO
10549			       "hda_codec: Cannot set up configuration "
10550			       "from BIOS.  Using base mode...\n");
10551			board_config = ALC662_3ST_2ch_DIG;
10552		}
10553	}
10554
10555	if (board_config != ALC662_AUTO)
10556		setup_preset(spec, &alc662_presets[board_config]);
10557
10558	spec->stream_name_analog = "ALC662 Analog";
10559	spec->stream_analog_playback = &alc662_pcm_analog_playback;
10560	spec->stream_analog_capture = &alc662_pcm_analog_capture;
10561
10562	spec->stream_name_digital = "ALC662 Digital";
10563	spec->stream_digital_playback = &alc662_pcm_digital_playback;
10564	spec->stream_digital_capture = &alc662_pcm_digital_capture;
10565
10566	if (!spec->adc_nids && spec->input_mux) {
10567		spec->adc_nids = alc662_adc_nids;
10568		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
10569	}
10570
10571	codec->patch_ops = alc_patch_ops;
10572	if (board_config == ALC662_AUTO)
10573		spec->init_hook = alc662_auto_init;
10574
10575	return 0;
10576}
10577
10578/*
10579 * patch entries
10580 */
10581struct hda_codec_preset snd_hda_preset_realtek[] = {
10582	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
10583	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
10584	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
10585	  .patch = patch_alc861 },
10586	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
10587	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
10588	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
10589	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
10590	  .patch = patch_alc883 },
10591	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
10592	  .patch = patch_alc662 },
10593	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
10594	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
10595	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
10596	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
10597	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
10598	{} /* terminator */
10599};
10600