patch_realtek.c revision 61dc35de78d2b28e3c28fd7a352ef8c4ff63f42d
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_HP_TC_T5735,
96	ALC262_BENQ_ED8,
97	ALC262_SONY_ASSAMD,
98	ALC262_BENQ_T31,
99	ALC262_ULTRA,
100	ALC262_AUTO,
101	ALC262_MODEL_LAST /* last tag */
102};
103
104/* ALC268 models */
105enum {
106	ALC268_3ST,
107	ALC268_TOSHIBA,
108	ALC268_ACER,
109	ALC268_AUTO,
110	ALC268_MODEL_LAST /* last tag */
111};
112
113/* ALC861 models */
114enum {
115	ALC861_3ST,
116	ALC660_3ST,
117	ALC861_3ST_DIG,
118	ALC861_6ST_DIG,
119	ALC861_UNIWILL_M31,
120	ALC861_TOSHIBA,
121	ALC861_ASUS,
122	ALC861_ASUS_LAPTOP,
123	ALC861_AUTO,
124	ALC861_MODEL_LAST,
125};
126
127/* ALC861-VD models */
128enum {
129	ALC660VD_3ST,
130	ALC660VD_3ST_DIG,
131	ALC861VD_3ST,
132	ALC861VD_3ST_DIG,
133	ALC861VD_6ST_DIG,
134	ALC861VD_LENOVO,
135	ALC861VD_DALLAS,
136	ALC861VD_HP,
137	ALC861VD_AUTO,
138	ALC861VD_MODEL_LAST,
139};
140
141/* ALC662 models */
142enum {
143	ALC662_3ST_2ch_DIG,
144	ALC662_3ST_6ch_DIG,
145	ALC662_3ST_6ch,
146	ALC662_5ST_DIG,
147	ALC662_LENOVO_101E,
148	ALC662_ASUS_EEEPC_P701,
149	ALC662_AUTO,
150	ALC662_MODEL_LAST,
151};
152
153/* ALC882 models */
154enum {
155	ALC882_3ST_DIG,
156	ALC882_6ST_DIG,
157	ALC882_ARIMA,
158	ALC882_W2JC,
159	ALC882_TARGA,
160	ALC882_ASUS_A7J,
161	ALC882_ASUS_A7M,
162	ALC885_MACPRO,
163	ALC885_MBP3,
164	ALC885_IMAC24,
165	ALC882_AUTO,
166	ALC882_MODEL_LAST,
167};
168
169/* ALC883 models */
170enum {
171	ALC883_3ST_2ch_DIG,
172	ALC883_3ST_6ch_DIG,
173	ALC883_3ST_6ch,
174	ALC883_6ST_DIG,
175	ALC883_TARGA_DIG,
176	ALC883_TARGA_2ch_DIG,
177	ALC883_ACER,
178	ALC883_ACER_ASPIRE,
179	ALC883_MEDION,
180	ALC883_MEDION_MD2,
181	ALC883_LAPTOP_EAPD,
182	ALC883_LENOVO_101E_2ch,
183	ALC883_LENOVO_NB0763,
184	ALC888_LENOVO_MS7195_DIG,
185	ALC883_HAIER_W66,
186	ALC888_6ST_HP,
187	ALC888_3ST_HP,
188	ALC883_AUTO,
189	ALC883_MODEL_LAST,
190};
191
192/* for GPIO Poll */
193#define GPIO_MASK	0x03
194
195struct alc_spec {
196	/* codec parameterization */
197	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
198	unsigned int num_mixers;
199
200	const struct hda_verb *init_verbs[5];	/* initialization verbs
201						 * don't forget NULL
202						 * termination!
203						 */
204	unsigned int num_init_verbs;
205
206	char *stream_name_analog;	/* analog PCM stream */
207	struct hda_pcm_stream *stream_analog_playback;
208	struct hda_pcm_stream *stream_analog_capture;
209
210	char *stream_name_digital;	/* digital PCM stream */
211	struct hda_pcm_stream *stream_digital_playback;
212	struct hda_pcm_stream *stream_digital_capture;
213
214	/* playback */
215	struct hda_multi_out multiout;	/* playback set-up
216					 * max_channels, dacs must be set
217					 * dig_out_nid and hp_nid are optional
218					 */
219
220	/* capture */
221	unsigned int num_adc_nids;
222	hda_nid_t *adc_nids;
223	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
224
225	/* capture source */
226	unsigned int num_mux_defs;
227	const struct hda_input_mux *input_mux;
228	unsigned int cur_mux[3];
229
230	/* channel model */
231	const struct hda_channel_mode *channel_mode;
232	int num_channel_mode;
233	int need_dac_fix;
234
235	/* PCM information */
236	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
237
238	/* dynamic controls, init_verbs and input_mux */
239	struct auto_pin_cfg autocfg;
240	unsigned int num_kctl_alloc, num_kctl_used;
241	struct snd_kcontrol_new *kctl_alloc;
242	struct hda_input_mux private_imux;
243	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
244
245	/* hooks */
246	void (*init_hook)(struct hda_codec *codec);
247	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
248
249	/* for pin sensing */
250	unsigned int sense_updated: 1;
251	unsigned int jack_present: 1;
252
253#ifdef CONFIG_SND_HDA_POWER_SAVE
254	struct hda_loopback_check loopback;
255#endif
256};
257
258/*
259 * configuration template - to be copied to the spec instance
260 */
261struct alc_config_preset {
262	struct snd_kcontrol_new *mixers[5]; /* should be identical size
263					     * with spec
264					     */
265	const struct hda_verb *init_verbs[5];
266	unsigned int num_dacs;
267	hda_nid_t *dac_nids;
268	hda_nid_t dig_out_nid;		/* optional */
269	hda_nid_t hp_nid;		/* optional */
270	unsigned int num_adc_nids;
271	hda_nid_t *adc_nids;
272	hda_nid_t dig_in_nid;
273	unsigned int num_channel_mode;
274	const struct hda_channel_mode *channel_mode;
275	int need_dac_fix;
276	unsigned int num_mux_defs;
277	const struct hda_input_mux *input_mux;
278	void (*unsol_event)(struct hda_codec *, unsigned int);
279	void (*init_hook)(struct hda_codec *);
280#ifdef CONFIG_SND_HDA_POWER_SAVE
281	struct hda_amp_list *loopbacks;
282#endif
283};
284
285
286/*
287 * input MUX handling
288 */
289static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
290			     struct snd_ctl_elem_info *uinfo)
291{
292	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
293	struct alc_spec *spec = codec->spec;
294	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
295	if (mux_idx >= spec->num_mux_defs)
296		mux_idx = 0;
297	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
298}
299
300static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
301			    struct snd_ctl_elem_value *ucontrol)
302{
303	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
304	struct alc_spec *spec = codec->spec;
305	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
306
307	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
308	return 0;
309}
310
311static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
312			    struct snd_ctl_elem_value *ucontrol)
313{
314	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
315	struct alc_spec *spec = codec->spec;
316	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
317	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
318	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
319				     spec->adc_nids[adc_idx],
320				     &spec->cur_mux[adc_idx]);
321}
322
323
324/*
325 * channel mode setting
326 */
327static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
328			    struct snd_ctl_elem_info *uinfo)
329{
330	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
331	struct alc_spec *spec = codec->spec;
332	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
333				    spec->num_channel_mode);
334}
335
336static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
337			   struct snd_ctl_elem_value *ucontrol)
338{
339	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
340	struct alc_spec *spec = codec->spec;
341	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
342				   spec->num_channel_mode,
343				   spec->multiout.max_channels);
344}
345
346static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
347			   struct snd_ctl_elem_value *ucontrol)
348{
349	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350	struct alc_spec *spec = codec->spec;
351	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
352				      spec->num_channel_mode,
353				      &spec->multiout.max_channels);
354	if (err >= 0 && spec->need_dac_fix)
355		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
356	return err;
357}
358
359/*
360 * Control the mode of pin widget settings via the mixer.  "pc" is used
361 * instead of "%" to avoid consequences of accidently treating the % as
362 * being part of a format specifier.  Maximum allowed length of a value is
363 * 63 characters plus NULL terminator.
364 *
365 * Note: some retasking pin complexes seem to ignore requests for input
366 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
367 * are requested.  Therefore order this list so that this behaviour will not
368 * cause problems when mixer clients move through the enum sequentially.
369 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
370 * March 2006.
371 */
372static char *alc_pin_mode_names[] = {
373	"Mic 50pc bias", "Mic 80pc bias",
374	"Line in", "Line out", "Headphone out",
375};
376static unsigned char alc_pin_mode_values[] = {
377	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
378};
379/* The control can present all 5 options, or it can limit the options based
380 * in the pin being assumed to be exclusively an input or an output pin.  In
381 * addition, "input" pins may or may not process the mic bias option
382 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
383 * accept requests for bias as of chip versions up to March 2006) and/or
384 * wiring in the computer.
385 */
386#define ALC_PIN_DIR_IN              0x00
387#define ALC_PIN_DIR_OUT             0x01
388#define ALC_PIN_DIR_INOUT           0x02
389#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
390#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
391
392/* Info about the pin modes supported by the different pin direction modes.
393 * For each direction the minimum and maximum values are given.
394 */
395static signed char alc_pin_mode_dir_info[5][2] = {
396	{ 0, 2 },    /* ALC_PIN_DIR_IN */
397	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
398	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
399	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
400	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
401};
402#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
403#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
404#define alc_pin_mode_n_items(_dir) \
405	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
406
407static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
408			     struct snd_ctl_elem_info *uinfo)
409{
410	unsigned int item_num = uinfo->value.enumerated.item;
411	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
412
413	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
414	uinfo->count = 1;
415	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
416
417	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
418		item_num = alc_pin_mode_min(dir);
419	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
420	return 0;
421}
422
423static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
424			    struct snd_ctl_elem_value *ucontrol)
425{
426	unsigned int i;
427	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
428	hda_nid_t nid = kcontrol->private_value & 0xffff;
429	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
430	long *valp = ucontrol->value.integer.value;
431	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
432						 AC_VERB_GET_PIN_WIDGET_CONTROL,
433						 0x00);
434
435	/* Find enumerated value for current pinctl setting */
436	i = alc_pin_mode_min(dir);
437	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
438		i++;
439	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
440	return 0;
441}
442
443static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
444			    struct snd_ctl_elem_value *ucontrol)
445{
446	signed int change;
447	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
448	hda_nid_t nid = kcontrol->private_value & 0xffff;
449	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
450	long val = *ucontrol->value.integer.value;
451	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
452						 AC_VERB_GET_PIN_WIDGET_CONTROL,
453						 0x00);
454
455	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
456		val = alc_pin_mode_min(dir);
457
458	change = pinctl != alc_pin_mode_values[val];
459	if (change) {
460		/* Set pin mode to that requested */
461		snd_hda_codec_write_cache(codec, nid, 0,
462					  AC_VERB_SET_PIN_WIDGET_CONTROL,
463					  alc_pin_mode_values[val]);
464
465		/* Also enable the retasking pin's input/output as required
466		 * for the requested pin mode.  Enum values of 2 or less are
467		 * input modes.
468		 *
469		 * Dynamically switching the input/output buffers probably
470		 * reduces noise slightly (particularly on input) so we'll
471		 * do it.  However, having both input and output buffers
472		 * enabled simultaneously doesn't seem to be problematic if
473		 * this turns out to be necessary in the future.
474		 */
475		if (val <= 2) {
476			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
477						 HDA_AMP_MUTE, HDA_AMP_MUTE);
478			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
479						 HDA_AMP_MUTE, 0);
480		} else {
481			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
482						 HDA_AMP_MUTE, HDA_AMP_MUTE);
483			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
484						 HDA_AMP_MUTE, 0);
485		}
486	}
487	return change;
488}
489
490#define ALC_PIN_MODE(xname, nid, dir) \
491	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
492	  .info = alc_pin_mode_info, \
493	  .get = alc_pin_mode_get, \
494	  .put = alc_pin_mode_put, \
495	  .private_value = nid | (dir<<16) }
496
497/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
498 * together using a mask with more than one bit set.  This control is
499 * currently used only by the ALC260 test model.  At this stage they are not
500 * needed for any "production" models.
501 */
502#ifdef CONFIG_SND_DEBUG
503#define alc_gpio_data_info	snd_ctl_boolean_mono_info
504
505static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
506			     struct snd_ctl_elem_value *ucontrol)
507{
508	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
509	hda_nid_t nid = kcontrol->private_value & 0xffff;
510	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
511	long *valp = ucontrol->value.integer.value;
512	unsigned int val = snd_hda_codec_read(codec, nid, 0,
513					      AC_VERB_GET_GPIO_DATA, 0x00);
514
515	*valp = (val & mask) != 0;
516	return 0;
517}
518static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
519			     struct snd_ctl_elem_value *ucontrol)
520{
521	signed int change;
522	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
523	hda_nid_t nid = kcontrol->private_value & 0xffff;
524	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
525	long val = *ucontrol->value.integer.value;
526	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
527						    AC_VERB_GET_GPIO_DATA,
528						    0x00);
529
530	/* Set/unset the masked GPIO bit(s) as needed */
531	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
532	if (val == 0)
533		gpio_data &= ~mask;
534	else
535		gpio_data |= mask;
536	snd_hda_codec_write_cache(codec, nid, 0,
537				  AC_VERB_SET_GPIO_DATA, gpio_data);
538
539	return change;
540}
541#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
542	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
543	  .info = alc_gpio_data_info, \
544	  .get = alc_gpio_data_get, \
545	  .put = alc_gpio_data_put, \
546	  .private_value = nid | (mask<<16) }
547#endif   /* CONFIG_SND_DEBUG */
548
549/* A switch control to allow the enabling of the digital IO pins on the
550 * ALC260.  This is incredibly simplistic; the intention of this control is
551 * to provide something in the test model allowing digital outputs to be
552 * identified if present.  If models are found which can utilise these
553 * outputs a more complete mixer control can be devised for those models if
554 * necessary.
555 */
556#ifdef CONFIG_SND_DEBUG
557#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
558
559static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
560			      struct snd_ctl_elem_value *ucontrol)
561{
562	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
563	hda_nid_t nid = kcontrol->private_value & 0xffff;
564	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
565	long *valp = ucontrol->value.integer.value;
566	unsigned int val = snd_hda_codec_read(codec, nid, 0,
567					      AC_VERB_GET_DIGI_CONVERT, 0x00);
568
569	*valp = (val & mask) != 0;
570	return 0;
571}
572static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
573			      struct snd_ctl_elem_value *ucontrol)
574{
575	signed int change;
576	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577	hda_nid_t nid = kcontrol->private_value & 0xffff;
578	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
579	long val = *ucontrol->value.integer.value;
580	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
581						    AC_VERB_GET_DIGI_CONVERT,
582						    0x00);
583
584	/* Set/unset the masked control bit(s) as needed */
585	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
586	if (val==0)
587		ctrl_data &= ~mask;
588	else
589		ctrl_data |= mask;
590	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
591				  ctrl_data);
592
593	return change;
594}
595#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
596	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
597	  .info = alc_spdif_ctrl_info, \
598	  .get = alc_spdif_ctrl_get, \
599	  .put = alc_spdif_ctrl_put, \
600	  .private_value = nid | (mask<<16) }
601#endif   /* CONFIG_SND_DEBUG */
602
603/*
604 * set up from the preset table
605 */
606static void setup_preset(struct alc_spec *spec,
607			 const struct alc_config_preset *preset)
608{
609	int i;
610
611	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
612		spec->mixers[spec->num_mixers++] = preset->mixers[i];
613	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
614	     i++)
615		spec->init_verbs[spec->num_init_verbs++] =
616			preset->init_verbs[i];
617
618	spec->channel_mode = preset->channel_mode;
619	spec->num_channel_mode = preset->num_channel_mode;
620	spec->need_dac_fix = preset->need_dac_fix;
621
622	spec->multiout.max_channels = spec->channel_mode[0].channels;
623
624	spec->multiout.num_dacs = preset->num_dacs;
625	spec->multiout.dac_nids = preset->dac_nids;
626	spec->multiout.dig_out_nid = preset->dig_out_nid;
627	spec->multiout.hp_nid = preset->hp_nid;
628
629	spec->num_mux_defs = preset->num_mux_defs;
630	if (!spec->num_mux_defs)
631		spec->num_mux_defs = 1;
632	spec->input_mux = preset->input_mux;
633
634	spec->num_adc_nids = preset->num_adc_nids;
635	spec->adc_nids = preset->adc_nids;
636	spec->dig_in_nid = preset->dig_in_nid;
637
638	spec->unsol_event = preset->unsol_event;
639	spec->init_hook = preset->init_hook;
640#ifdef CONFIG_SND_HDA_POWER_SAVE
641	spec->loopback.amplist = preset->loopbacks;
642#endif
643}
644
645/* Enable GPIO mask and set output */
646static struct hda_verb alc_gpio1_init_verbs[] = {
647	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
648	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
649	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
650	{ }
651};
652
653static struct hda_verb alc_gpio2_init_verbs[] = {
654	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
655	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
656	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
657	{ }
658};
659
660static struct hda_verb alc_gpio3_init_verbs[] = {
661	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
662	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
663	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
664	{ }
665};
666
667static void alc_sku_automute(struct hda_codec *codec)
668{
669	struct alc_spec *spec = codec->spec;
670	unsigned int mute;
671	unsigned int present;
672	unsigned int hp_nid = spec->autocfg.hp_pins[0];
673	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
674
675	/* need to execute and sync at first */
676	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
677	present = snd_hda_codec_read(codec, hp_nid, 0,
678				     AC_VERB_GET_PIN_SENSE, 0);
679	spec->jack_present = (present & 0x80000000) != 0;
680	if (spec->jack_present) {
681		/* mute internal speaker */
682		snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
683					 HDA_AMP_MUTE, HDA_AMP_MUTE);
684	} else {
685		/* unmute internal speaker if necessary */
686		mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
687		snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
688					 HDA_AMP_MUTE, mute);
689	}
690}
691
692/* unsolicited event for HP jack sensing */
693static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
694{
695	if (codec->vendor_id == 0x10ec0880)
696		res >>= 28;
697	else
698		res >>= 26;
699	if (res != ALC880_HP_EVENT)
700		return;
701
702	alc_sku_automute(codec);
703}
704
705/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
706 *	31 ~ 16 :	Manufacture ID
707 *	15 ~ 8	:	SKU ID
708 *	7  ~ 0	:	Assembly ID
709 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
710 */
711static void alc_subsystem_id(struct hda_codec *codec,
712			     unsigned int porta, unsigned int porte,
713			     unsigned int portd)
714{
715	unsigned int ass, tmp, i;
716	unsigned nid;
717	struct alc_spec *spec = codec->spec;
718
719	ass = codec->subsystem_id & 0xffff;
720	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
721		goto do_sku;
722
723	/*
724	 * 31~30	: port conetcivity
725	 * 29~21	: reserve
726	 * 20		: PCBEEP input
727	 * 19~16	: Check sum (15:1)
728	 * 15~1		: Custom
729	 * 0		: override
730	*/
731	nid = 0x1d;
732	if (codec->vendor_id == 0x10ec0260)
733		nid = 0x17;
734	ass = snd_hda_codec_read(codec, nid, 0,
735				 AC_VERB_GET_CONFIG_DEFAULT, 0);
736	if (!(ass & 1) && !(ass & 0x100000))
737		return;
738	if ((ass >> 30) != 1)	/* no physical connection */
739		return;
740
741	/* check sum */
742	tmp = 0;
743	for (i = 1; i < 16; i++) {
744		if ((ass >> i) && 1)
745			tmp++;
746	}
747	if (((ass >> 16) & 0xf) != tmp)
748		return;
749do_sku:
750	/*
751	 * 0 : override
752	 * 1 :	Swap Jack
753	 * 2 : 0 --> Desktop, 1 --> Laptop
754	 * 3~5 : External Amplifier control
755	 * 7~6 : Reserved
756	*/
757	tmp = (ass & 0x38) >> 3;	/* external Amp control */
758	switch (tmp) {
759	case 1:
760		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
761		break;
762	case 3:
763		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
764		break;
765	case 7:
766		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
767		break;
768	case 5:	/* set EAPD output high */
769		switch (codec->vendor_id) {
770		case 0x10ec0260:
771			snd_hda_codec_write(codec, 0x0f, 0,
772					    AC_VERB_SET_EAPD_BTLENABLE, 2);
773			snd_hda_codec_write(codec, 0x10, 0,
774					    AC_VERB_SET_EAPD_BTLENABLE, 2);
775			break;
776		case 0x10ec0262:
777		case 0x10ec0267:
778		case 0x10ec0268:
779		case 0x10ec0269:
780		case 0x10ec0862:
781		case 0x10ec0662:
782			snd_hda_codec_write(codec, 0x14, 0,
783					    AC_VERB_SET_EAPD_BTLENABLE, 2);
784			snd_hda_codec_write(codec, 0x15, 0,
785					    AC_VERB_SET_EAPD_BTLENABLE, 2);
786			break;
787		}
788		switch (codec->vendor_id) {
789		case 0x10ec0260:
790			snd_hda_codec_write(codec, 0x1a, 0,
791					    AC_VERB_SET_COEF_INDEX, 7);
792			tmp = snd_hda_codec_read(codec, 0x1a, 0,
793						 AC_VERB_GET_PROC_COEF, 0);
794			snd_hda_codec_write(codec, 0x1a, 0,
795					    AC_VERB_SET_COEF_INDEX, 7);
796			snd_hda_codec_write(codec, 0x1a, 0,
797					    AC_VERB_SET_PROC_COEF,
798					    tmp | 0x2010);
799			break;
800		case 0x10ec0262:
801		case 0x10ec0880:
802		case 0x10ec0882:
803		case 0x10ec0883:
804		case 0x10ec0885:
805		case 0x10ec0888:
806			snd_hda_codec_write(codec, 0x20, 0,
807					    AC_VERB_SET_COEF_INDEX, 7);
808			tmp = snd_hda_codec_read(codec, 0x20, 0,
809						 AC_VERB_GET_PROC_COEF, 0);
810			snd_hda_codec_write(codec, 0x20, 0,
811					    AC_VERB_SET_COEF_INDEX, 7);
812			snd_hda_codec_write(codec, 0x20, 0,
813					    AC_VERB_SET_PROC_COEF,
814					    tmp | 0x2010);
815			break;
816		case 0x10ec0267:
817		case 0x10ec0268:
818			snd_hda_codec_write(codec, 0x20, 0,
819					    AC_VERB_SET_COEF_INDEX, 7);
820			tmp = snd_hda_codec_read(codec, 0x20, 0,
821						 AC_VERB_GET_PROC_COEF, 0);
822			snd_hda_codec_write(codec, 0x20, 0,
823					    AC_VERB_SET_COEF_INDEX, 7);
824			snd_hda_codec_write(codec, 0x20, 0,
825					    AC_VERB_SET_PROC_COEF,
826					    tmp | 0x3000);
827			break;
828		}
829	default:
830		break;
831	}
832
833	/* is laptop and enable the function "Mute internal speaker
834	 * when the external headphone out jack is plugged"
835	 */
836	if (!(ass & 0x4) || !(ass & 0x8000))
837		return;
838	/*
839	 * 10~8 : Jack location
840	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
841	 * 14~13: Resvered
842	 * 15   : 1 --> enable the function "Mute internal speaker
843	 *	        when the external headphone out jack is plugged"
844	 */
845	if (!spec->autocfg.speaker_pins[0]) {
846		if (spec->multiout.dac_nids[0])
847			spec->autocfg.speaker_pins[0] =
848				spec->multiout.dac_nids[0];
849		else
850			return;
851	}
852
853	if (!spec->autocfg.hp_pins[0]) {
854		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
855		if (tmp == 0)
856			spec->autocfg.hp_pins[0] = porta;
857		else if (tmp == 1)
858			spec->autocfg.hp_pins[0] = porte;
859		else if (tmp == 2)
860			spec->autocfg.hp_pins[0] = portd;
861		else
862			return;
863	}
864
865	snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
866			    AC_VERB_SET_UNSOLICITED_ENABLE,
867			    AC_USRSP_EN | ALC880_HP_EVENT);
868	spec->unsol_event = alc_sku_unsol_event;
869	spec->init_hook = alc_sku_automute;
870}
871
872/*
873 * Fix-up pin default configurations
874 */
875
876struct alc_pincfg {
877	hda_nid_t nid;
878	u32 val;
879};
880
881static void alc_fix_pincfg(struct hda_codec *codec,
882			   const struct snd_pci_quirk *quirk,
883			   const struct alc_pincfg **pinfix)
884{
885	const struct alc_pincfg *cfg;
886
887	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
888	if (!quirk)
889		return;
890
891	cfg = pinfix[quirk->value];
892	for (; cfg->nid; cfg++) {
893		int i;
894		u32 val = cfg->val;
895		for (i = 0; i < 4; i++) {
896			snd_hda_codec_write(codec, cfg->nid, 0,
897				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
898				    val & 0xff);
899			val >>= 8;
900		}
901	}
902}
903
904/*
905 * ALC880 3-stack model
906 *
907 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
908 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
909 *                 F-Mic = 0x1b, HP = 0x19
910 */
911
912static hda_nid_t alc880_dac_nids[4] = {
913	/* front, rear, clfe, rear_surr */
914	0x02, 0x05, 0x04, 0x03
915};
916
917static hda_nid_t alc880_adc_nids[3] = {
918	/* ADC0-2 */
919	0x07, 0x08, 0x09,
920};
921
922/* The datasheet says the node 0x07 is connected from inputs,
923 * but it shows zero connection in the real implementation on some devices.
924 * Note: this is a 915GAV bug, fixed on 915GLV
925 */
926static hda_nid_t alc880_adc_nids_alt[2] = {
927	/* ADC1-2 */
928	0x08, 0x09,
929};
930
931#define ALC880_DIGOUT_NID	0x06
932#define ALC880_DIGIN_NID	0x0a
933
934static struct hda_input_mux alc880_capture_source = {
935	.num_items = 4,
936	.items = {
937		{ "Mic", 0x0 },
938		{ "Front Mic", 0x3 },
939		{ "Line", 0x2 },
940		{ "CD", 0x4 },
941	},
942};
943
944/* channel source setting (2/6 channel selection for 3-stack) */
945/* 2ch mode */
946static struct hda_verb alc880_threestack_ch2_init[] = {
947	/* set line-in to input, mute it */
948	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
949	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
950	/* set mic-in to input vref 80%, mute it */
951	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
952	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
953	{ } /* end */
954};
955
956/* 6ch mode */
957static struct hda_verb alc880_threestack_ch6_init[] = {
958	/* set line-in to output, unmute it */
959	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
960	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
961	/* set mic-in to output, unmute it */
962	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
963	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
964	{ } /* end */
965};
966
967static struct hda_channel_mode alc880_threestack_modes[2] = {
968	{ 2, alc880_threestack_ch2_init },
969	{ 6, alc880_threestack_ch6_init },
970};
971
972static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
973	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
974	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
975	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
976	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
977	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
978	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
979	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
980	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
981	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
982	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
983	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
984	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
985	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
986	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
987	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
988	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
989	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
990	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
991	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
992	{
993		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
994		.name = "Channel Mode",
995		.info = alc_ch_mode_info,
996		.get = alc_ch_mode_get,
997		.put = alc_ch_mode_put,
998	},
999	{ } /* end */
1000};
1001
1002/* capture mixer elements */
1003static struct snd_kcontrol_new alc880_capture_mixer[] = {
1004	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1005	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1006	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1007	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1008	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1009	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1010	{
1011		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1012		/* The multiple "Capture Source" controls confuse alsamixer
1013		 * So call somewhat different..
1014		 * FIXME: the controls appear in the "playback" view!
1015		 */
1016		/* .name = "Capture Source", */
1017		.name = "Input Source",
1018		.count = 3,
1019		.info = alc_mux_enum_info,
1020		.get = alc_mux_enum_get,
1021		.put = alc_mux_enum_put,
1022	},
1023	{ } /* end */
1024};
1025
1026/* capture mixer elements (in case NID 0x07 not available) */
1027static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1028	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1029	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1030	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1031	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1032	{
1033		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1034		/* The multiple "Capture Source" controls confuse alsamixer
1035		 * So call somewhat different..
1036		 * FIXME: the controls appear in the "playback" view!
1037		 */
1038		/* .name = "Capture Source", */
1039		.name = "Input Source",
1040		.count = 2,
1041		.info = alc_mux_enum_info,
1042		.get = alc_mux_enum_get,
1043		.put = alc_mux_enum_put,
1044	},
1045	{ } /* end */
1046};
1047
1048
1049
1050/*
1051 * ALC880 5-stack model
1052 *
1053 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1054 *      Side = 0x02 (0xd)
1055 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1056 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1057 */
1058
1059/* additional mixers to alc880_three_stack_mixer */
1060static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1061	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1062	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1063	{ } /* end */
1064};
1065
1066/* channel source setting (6/8 channel selection for 5-stack) */
1067/* 6ch mode */
1068static struct hda_verb alc880_fivestack_ch6_init[] = {
1069	/* set line-in to input, mute it */
1070	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1071	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1072	{ } /* end */
1073};
1074
1075/* 8ch mode */
1076static struct hda_verb alc880_fivestack_ch8_init[] = {
1077	/* set line-in to output, unmute it */
1078	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1079	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1080	{ } /* end */
1081};
1082
1083static struct hda_channel_mode alc880_fivestack_modes[2] = {
1084	{ 6, alc880_fivestack_ch6_init },
1085	{ 8, alc880_fivestack_ch8_init },
1086};
1087
1088
1089/*
1090 * ALC880 6-stack model
1091 *
1092 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1093 *      Side = 0x05 (0x0f)
1094 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1095 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1096 */
1097
1098static hda_nid_t alc880_6st_dac_nids[4] = {
1099	/* front, rear, clfe, rear_surr */
1100	0x02, 0x03, 0x04, 0x05
1101};
1102
1103static struct hda_input_mux alc880_6stack_capture_source = {
1104	.num_items = 4,
1105	.items = {
1106		{ "Mic", 0x0 },
1107		{ "Front Mic", 0x1 },
1108		{ "Line", 0x2 },
1109		{ "CD", 0x4 },
1110	},
1111};
1112
1113/* fixed 8-channels */
1114static struct hda_channel_mode alc880_sixstack_modes[1] = {
1115	{ 8, NULL },
1116};
1117
1118static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1119	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1120	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1121	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1122	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1123	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1124	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1125	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1126	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1127	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1128	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1129	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1130	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1131	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1132	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1133	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1134	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1135	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1136	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1137	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1138	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1139	{
1140		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1141		.name = "Channel Mode",
1142		.info = alc_ch_mode_info,
1143		.get = alc_ch_mode_get,
1144		.put = alc_ch_mode_put,
1145	},
1146	{ } /* end */
1147};
1148
1149
1150/*
1151 * ALC880 W810 model
1152 *
1153 * W810 has rear IO for:
1154 * Front (DAC 02)
1155 * Surround (DAC 03)
1156 * Center/LFE (DAC 04)
1157 * Digital out (06)
1158 *
1159 * The system also has a pair of internal speakers, and a headphone jack.
1160 * These are both connected to Line2 on the codec, hence to DAC 02.
1161 *
1162 * There is a variable resistor to control the speaker or headphone
1163 * volume. This is a hardware-only device without a software API.
1164 *
1165 * Plugging headphones in will disable the internal speakers. This is
1166 * implemented in hardware, not via the driver using jack sense. In
1167 * a similar fashion, plugging into the rear socket marked "front" will
1168 * disable both the speakers and headphones.
1169 *
1170 * For input, there's a microphone jack, and an "audio in" jack.
1171 * These may not do anything useful with this driver yet, because I
1172 * haven't setup any initialization verbs for these yet...
1173 */
1174
1175static hda_nid_t alc880_w810_dac_nids[3] = {
1176	/* front, rear/surround, clfe */
1177	0x02, 0x03, 0x04
1178};
1179
1180/* fixed 6 channels */
1181static struct hda_channel_mode alc880_w810_modes[1] = {
1182	{ 6, NULL }
1183};
1184
1185/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1186static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1187	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1188	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1189	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1190	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1191	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1192	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1193	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1194	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1195	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1196	{ } /* end */
1197};
1198
1199
1200/*
1201 * Z710V model
1202 *
1203 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1204 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1205 *                 Line = 0x1a
1206 */
1207
1208static hda_nid_t alc880_z71v_dac_nids[1] = {
1209	0x02
1210};
1211#define ALC880_Z71V_HP_DAC	0x03
1212
1213/* fixed 2 channels */
1214static struct hda_channel_mode alc880_2_jack_modes[1] = {
1215	{ 2, NULL }
1216};
1217
1218static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1219	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1220	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1221	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1222	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1223	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1224	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1225	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1226	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1227	{ } /* end */
1228};
1229
1230
1231/* FIXME! */
1232/*
1233 * ALC880 F1734 model
1234 *
1235 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1236 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1237 */
1238
1239static hda_nid_t alc880_f1734_dac_nids[1] = {
1240	0x03
1241};
1242#define ALC880_F1734_HP_DAC	0x02
1243
1244static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1245	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1246	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1247	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1248	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1249	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1250	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1251	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1252	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1253	{ } /* end */
1254};
1255
1256
1257/* FIXME! */
1258/*
1259 * ALC880 ASUS model
1260 *
1261 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1262 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1263 *  Mic = 0x18, Line = 0x1a
1264 */
1265
1266#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1267#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1268
1269static struct snd_kcontrol_new alc880_asus_mixer[] = {
1270	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1271	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1272	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1273	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1274	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1275	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1276	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1277	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1278	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1279	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1280	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1281	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1282	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1283	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1284	{
1285		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1286		.name = "Channel Mode",
1287		.info = alc_ch_mode_info,
1288		.get = alc_ch_mode_get,
1289		.put = alc_ch_mode_put,
1290	},
1291	{ } /* end */
1292};
1293
1294/* FIXME! */
1295/*
1296 * ALC880 ASUS W1V model
1297 *
1298 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1299 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1300 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1301 */
1302
1303/* additional mixers to alc880_asus_mixer */
1304static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1305	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1306	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1307	{ } /* end */
1308};
1309
1310/* additional mixers to alc880_asus_mixer */
1311static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1312	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1313	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1314	{ } /* end */
1315};
1316
1317/* TCL S700 */
1318static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1319	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1320	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1321	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1322	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1323	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1324	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1325	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1326	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1327	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1328	{
1329		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1330		/* The multiple "Capture Source" controls confuse alsamixer
1331		 * So call somewhat different..
1332		 * FIXME: the controls appear in the "playback" view!
1333		 */
1334		/* .name = "Capture Source", */
1335		.name = "Input Source",
1336		.count = 1,
1337		.info = alc_mux_enum_info,
1338		.get = alc_mux_enum_get,
1339		.put = alc_mux_enum_put,
1340	},
1341	{ } /* end */
1342};
1343
1344/* Uniwill */
1345static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1346	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1347	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1348	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1349	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1350	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1351	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1352	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1353	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1354	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1355	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1356	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1357	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1358	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1359	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1360	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1361	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1362	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1363	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1364	{
1365		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1366		.name = "Channel Mode",
1367		.info = alc_ch_mode_info,
1368		.get = alc_ch_mode_get,
1369		.put = alc_ch_mode_put,
1370	},
1371	{ } /* end */
1372};
1373
1374static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1375	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1376	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1377	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1378	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1379	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1380	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1381	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1382	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1383	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1384	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1385	{ } /* end */
1386};
1387
1388static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1389	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1390	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1391	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1392	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1393	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1394	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1395	{ } /* end */
1396};
1397
1398/*
1399 * build control elements
1400 */
1401static int alc_build_controls(struct hda_codec *codec)
1402{
1403	struct alc_spec *spec = codec->spec;
1404	int err;
1405	int i;
1406
1407	for (i = 0; i < spec->num_mixers; i++) {
1408		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1409		if (err < 0)
1410			return err;
1411	}
1412
1413	if (spec->multiout.dig_out_nid) {
1414		err = snd_hda_create_spdif_out_ctls(codec,
1415						    spec->multiout.dig_out_nid);
1416		if (err < 0)
1417			return err;
1418	}
1419	if (spec->dig_in_nid) {
1420		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1421		if (err < 0)
1422			return err;
1423	}
1424	return 0;
1425}
1426
1427
1428/*
1429 * initialize the codec volumes, etc
1430 */
1431
1432/*
1433 * generic initialization of ADC, input mixers and output mixers
1434 */
1435static struct hda_verb alc880_volume_init_verbs[] = {
1436	/*
1437	 * Unmute ADC0-2 and set the default input to mic-in
1438	 */
1439	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1440	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1441	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1442	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1443	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1444	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1445
1446	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1447	 * mixer widget
1448	 * Note: PASD motherboards uses the Line In 2 as the input for front
1449	 * panel mic (mic 2)
1450	 */
1451	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1452	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1453	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1454	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1455	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1456	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1457	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1458	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1459
1460	/*
1461	 * Set up output mixers (0x0c - 0x0f)
1462	 */
1463	/* set vol=0 to output mixers */
1464	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1465	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1466	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1467	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1468	/* set up input amps for analog loopback */
1469	/* Amp Indices: DAC = 0, mixer = 1 */
1470	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1471	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1472	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1473	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1474	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1475	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1476	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1477	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1478
1479	{ }
1480};
1481
1482/*
1483 * 3-stack pin configuration:
1484 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1485 */
1486static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1487	/*
1488	 * preset connection lists of input pins
1489	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1490	 */
1491	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1492	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1493	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1494
1495	/*
1496	 * Set pin mode and muting
1497	 */
1498	/* set front pin widgets 0x14 for output */
1499	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1500	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1501	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1502	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1503	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1504	/* Mic2 (as headphone out) for HP output */
1505	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1506	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1507	/* Line In pin widget for input */
1508	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1509	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1510	/* Line2 (as front mic) pin widget for input and vref at 80% */
1511	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1512	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1513	/* CD pin widget for input */
1514	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1515
1516	{ }
1517};
1518
1519/*
1520 * 5-stack pin configuration:
1521 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1522 * line-in/side = 0x1a, f-mic = 0x1b
1523 */
1524static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1525	/*
1526	 * preset connection lists of input pins
1527	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1528	 */
1529	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1530	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1531
1532	/*
1533	 * Set pin mode and muting
1534	 */
1535	/* set pin widgets 0x14-0x17 for output */
1536	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1537	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1538	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1539	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1540	/* unmute pins for output (no gain on this amp) */
1541	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1542	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1543	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1544	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1545
1546	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1547	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1548	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1549	/* Mic2 (as headphone out) for HP output */
1550	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1551	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1552	/* Line In pin widget for input */
1553	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1554	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1555	/* Line2 (as front mic) pin widget for input and vref at 80% */
1556	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1557	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1558	/* CD pin widget for input */
1559	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1560
1561	{ }
1562};
1563
1564/*
1565 * W810 pin configuration:
1566 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1567 */
1568static struct hda_verb alc880_pin_w810_init_verbs[] = {
1569	/* hphone/speaker input selector: front DAC */
1570	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1571
1572	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1573	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1574	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1575	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1576	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1577	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1578
1579	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1580	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1581
1582	{ }
1583};
1584
1585/*
1586 * Z71V pin configuration:
1587 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1588 */
1589static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1590	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1591	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1592	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1593	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1594
1595	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1596	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1597	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1598	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1599
1600	{ }
1601};
1602
1603/*
1604 * 6-stack pin configuration:
1605 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1606 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1607 */
1608static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1609	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1610
1611	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1612	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1613	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1614	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1615	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1616	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1617	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1618	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1619
1620	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1621	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1622	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1623	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1624	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1625	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1626	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1627	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1629
1630	{ }
1631};
1632
1633/*
1634 * Uniwill pin configuration:
1635 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1636 * line = 0x1a
1637 */
1638static struct hda_verb alc880_uniwill_init_verbs[] = {
1639	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1640
1641	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1642	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1643	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1644	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1645	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1646	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1647	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1648	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1649	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1650	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1651	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1652	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1653	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1654	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1655
1656	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1657	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1658	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1659	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1660	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1661	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1662	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1663	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1664	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1665
1666	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1667	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1668
1669	{ }
1670};
1671
1672/*
1673* Uniwill P53
1674* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1675 */
1676static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1677	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1678
1679	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1680	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1681	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1682	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1683	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1684	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1685	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1686	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1687	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1688	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1689	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1690	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1691
1692	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1693	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1694	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1695	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1696	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1697	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1698
1699	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1700	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1701
1702	{ }
1703};
1704
1705static struct hda_verb alc880_beep_init_verbs[] = {
1706	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1707	{ }
1708};
1709
1710/* toggle speaker-output according to the hp-jack state */
1711static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1712{
1713 	unsigned int present;
1714	unsigned char bits;
1715
1716 	present = snd_hda_codec_read(codec, 0x14, 0,
1717				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1718	bits = present ? HDA_AMP_MUTE : 0;
1719	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1720				 HDA_AMP_MUTE, bits);
1721	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1722				 HDA_AMP_MUTE, bits);
1723}
1724
1725/* auto-toggle front mic */
1726static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1727{
1728 	unsigned int present;
1729	unsigned char bits;
1730
1731	present = snd_hda_codec_read(codec, 0x18, 0,
1732				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1733	bits = present ? HDA_AMP_MUTE : 0;
1734	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1735}
1736
1737static void alc880_uniwill_automute(struct hda_codec *codec)
1738{
1739	alc880_uniwill_hp_automute(codec);
1740	alc880_uniwill_mic_automute(codec);
1741}
1742
1743static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1744				       unsigned int res)
1745{
1746	/* Looks like the unsol event is incompatible with the standard
1747	 * definition.  4bit tag is placed at 28 bit!
1748	 */
1749	switch (res >> 28) {
1750	case ALC880_HP_EVENT:
1751		alc880_uniwill_hp_automute(codec);
1752		break;
1753	case ALC880_MIC_EVENT:
1754		alc880_uniwill_mic_automute(codec);
1755		break;
1756	}
1757}
1758
1759static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1760{
1761 	unsigned int present;
1762	unsigned char bits;
1763
1764 	present = snd_hda_codec_read(codec, 0x14, 0,
1765				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1766	bits = present ? HDA_AMP_MUTE : 0;
1767	snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1768}
1769
1770static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1771{
1772	unsigned int present;
1773
1774	present = snd_hda_codec_read(codec, 0x21, 0,
1775				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1776	present &= HDA_AMP_VOLMASK;
1777	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1778				 HDA_AMP_VOLMASK, present);
1779	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1780				 HDA_AMP_VOLMASK, present);
1781}
1782
1783static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1784					   unsigned int res)
1785{
1786	/* Looks like the unsol event is incompatible with the standard
1787	 * definition.  4bit tag is placed at 28 bit!
1788	 */
1789	if ((res >> 28) == ALC880_HP_EVENT)
1790		alc880_uniwill_p53_hp_automute(codec);
1791	if ((res >> 28) == ALC880_DCVOL_EVENT)
1792		alc880_uniwill_p53_dcvol_automute(codec);
1793}
1794
1795/* FIXME! */
1796/*
1797 * F1734 pin configuration:
1798 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1799 */
1800static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1801	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1802	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1803	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1804	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1805
1806	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1807	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1808	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1809	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1810
1811	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1812	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1813	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1814	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1815	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1816	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1817	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1818	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1819	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1820
1821	{ }
1822};
1823
1824/* FIXME! */
1825/*
1826 * ASUS pin configuration:
1827 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1828 */
1829static struct hda_verb alc880_pin_asus_init_verbs[] = {
1830	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1831	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1832	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1833	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1834
1835	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1836	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1837	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1838	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1839	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1840	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1841	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1842	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1843
1844	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1845	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1846	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1847	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1848	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1849	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1850	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1851	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1852	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1853
1854	{ }
1855};
1856
1857/* Enable GPIO mask and set output */
1858#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1859#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1860
1861/* Clevo m520g init */
1862static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1863	/* headphone output */
1864	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1865	/* line-out */
1866	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1867	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1868	/* Line-in */
1869	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1870	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1871	/* CD */
1872	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1873	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874	/* Mic1 (rear panel) */
1875	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1876	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1877	/* Mic2 (front panel) */
1878	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1879	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1880	/* headphone */
1881	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1882	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1883        /* change to EAPD mode */
1884	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1885	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1886
1887	{ }
1888};
1889
1890static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1891	/* change to EAPD mode */
1892	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1893	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1894
1895	/* Headphone output */
1896	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1897	/* Front output*/
1898	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1899	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1900
1901	/* Line In pin widget for input */
1902	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1903	/* CD pin widget for input */
1904	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1905	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1906	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1907
1908	/* change to EAPD mode */
1909	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1910	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1911
1912	{ }
1913};
1914
1915/*
1916 * LG m1 express dual
1917 *
1918 * Pin assignment:
1919 *   Rear Line-In/Out (blue): 0x14
1920 *   Build-in Mic-In: 0x15
1921 *   Speaker-out: 0x17
1922 *   HP-Out (green): 0x1b
1923 *   Mic-In/Out (red): 0x19
1924 *   SPDIF-Out: 0x1e
1925 */
1926
1927/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1928static hda_nid_t alc880_lg_dac_nids[3] = {
1929	0x05, 0x02, 0x03
1930};
1931
1932/* seems analog CD is not working */
1933static struct hda_input_mux alc880_lg_capture_source = {
1934	.num_items = 3,
1935	.items = {
1936		{ "Mic", 0x1 },
1937		{ "Line", 0x5 },
1938		{ "Internal Mic", 0x6 },
1939	},
1940};
1941
1942/* 2,4,6 channel modes */
1943static struct hda_verb alc880_lg_ch2_init[] = {
1944	/* set line-in and mic-in to input */
1945	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1946	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1947	{ }
1948};
1949
1950static struct hda_verb alc880_lg_ch4_init[] = {
1951	/* set line-in to out and mic-in to input */
1952	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1953	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1954	{ }
1955};
1956
1957static struct hda_verb alc880_lg_ch6_init[] = {
1958	/* set line-in and mic-in to output */
1959	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1960	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1961	{ }
1962};
1963
1964static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1965	{ 2, alc880_lg_ch2_init },
1966	{ 4, alc880_lg_ch4_init },
1967	{ 6, alc880_lg_ch6_init },
1968};
1969
1970static struct snd_kcontrol_new alc880_lg_mixer[] = {
1971	/* FIXME: it's not really "master" but front channels */
1972	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1973	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1974	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1975	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1976	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1977	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1978	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1979	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1980	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1981	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1982	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1983	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1984	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1985	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1986	{
1987		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1988		.name = "Channel Mode",
1989		.info = alc_ch_mode_info,
1990		.get = alc_ch_mode_get,
1991		.put = alc_ch_mode_put,
1992	},
1993	{ } /* end */
1994};
1995
1996static struct hda_verb alc880_lg_init_verbs[] = {
1997	/* set capture source to mic-in */
1998	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1999	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2000	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2001	/* mute all amp mixer inputs */
2002	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2003	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2004	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2005	/* line-in to input */
2006	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2007	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008	/* built-in mic */
2009	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2010	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2011	/* speaker-out */
2012	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2013	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2014	/* mic-in to input */
2015	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2016	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2017	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2018	/* HP-out */
2019	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2020	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2021	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2022	/* jack sense */
2023	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2024	{ }
2025};
2026
2027/* toggle speaker-output according to the hp-jack state */
2028static void alc880_lg_automute(struct hda_codec *codec)
2029{
2030	unsigned int present;
2031	unsigned char bits;
2032
2033	present = snd_hda_codec_read(codec, 0x1b, 0,
2034				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2035	bits = present ? HDA_AMP_MUTE : 0;
2036	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2037				 HDA_AMP_MUTE, bits);
2038}
2039
2040static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2041{
2042	/* Looks like the unsol event is incompatible with the standard
2043	 * definition.  4bit tag is placed at 28 bit!
2044	 */
2045	if ((res >> 28) == 0x01)
2046		alc880_lg_automute(codec);
2047}
2048
2049/*
2050 * LG LW20
2051 *
2052 * Pin assignment:
2053 *   Speaker-out: 0x14
2054 *   Mic-In: 0x18
2055 *   Built-in Mic-In: 0x19
2056 *   Line-In: 0x1b
2057 *   HP-Out: 0x1a
2058 *   SPDIF-Out: 0x1e
2059 */
2060
2061static struct hda_input_mux alc880_lg_lw_capture_source = {
2062	.num_items = 3,
2063	.items = {
2064		{ "Mic", 0x0 },
2065		{ "Internal Mic", 0x1 },
2066		{ "Line In", 0x2 },
2067	},
2068};
2069
2070#define alc880_lg_lw_modes alc880_threestack_modes
2071
2072static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2073	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2074	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2075	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2076	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2077	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2078	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2079	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2080	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2081	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2082	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2083	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2084	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2085	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2086	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2087	{
2088		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2089		.name = "Channel Mode",
2090		.info = alc_ch_mode_info,
2091		.get = alc_ch_mode_get,
2092		.put = alc_ch_mode_put,
2093	},
2094	{ } /* end */
2095};
2096
2097static struct hda_verb alc880_lg_lw_init_verbs[] = {
2098	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2099	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2100	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2101
2102	/* set capture source to mic-in */
2103	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2104	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2105	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2106	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2107	/* speaker-out */
2108	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2109	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2110	/* HP-out */
2111	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2112	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2113	/* mic-in to input */
2114	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2115	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2116	/* built-in mic */
2117	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2118	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2119	/* jack sense */
2120	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2121	{ }
2122};
2123
2124/* toggle speaker-output according to the hp-jack state */
2125static void alc880_lg_lw_automute(struct hda_codec *codec)
2126{
2127	unsigned int present;
2128	unsigned char bits;
2129
2130	present = snd_hda_codec_read(codec, 0x1b, 0,
2131				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2132	bits = present ? HDA_AMP_MUTE : 0;
2133	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2134				 HDA_AMP_MUTE, bits);
2135}
2136
2137static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2138{
2139	/* Looks like the unsol event is incompatible with the standard
2140	 * definition.  4bit tag is placed at 28 bit!
2141	 */
2142	if ((res >> 28) == 0x01)
2143		alc880_lg_lw_automute(codec);
2144}
2145
2146#ifdef CONFIG_SND_HDA_POWER_SAVE
2147static struct hda_amp_list alc880_loopbacks[] = {
2148	{ 0x0b, HDA_INPUT, 0 },
2149	{ 0x0b, HDA_INPUT, 1 },
2150	{ 0x0b, HDA_INPUT, 2 },
2151	{ 0x0b, HDA_INPUT, 3 },
2152	{ 0x0b, HDA_INPUT, 4 },
2153	{ } /* end */
2154};
2155
2156static struct hda_amp_list alc880_lg_loopbacks[] = {
2157	{ 0x0b, HDA_INPUT, 1 },
2158	{ 0x0b, HDA_INPUT, 6 },
2159	{ 0x0b, HDA_INPUT, 7 },
2160	{ } /* end */
2161};
2162#endif
2163
2164/*
2165 * Common callbacks
2166 */
2167
2168static int alc_init(struct hda_codec *codec)
2169{
2170	struct alc_spec *spec = codec->spec;
2171	unsigned int i;
2172
2173	for (i = 0; i < spec->num_init_verbs; i++)
2174		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2175
2176	if (spec->init_hook)
2177		spec->init_hook(codec);
2178
2179	return 0;
2180}
2181
2182static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2183{
2184	struct alc_spec *spec = codec->spec;
2185
2186	if (spec->unsol_event)
2187		spec->unsol_event(codec, res);
2188}
2189
2190#ifdef CONFIG_SND_HDA_POWER_SAVE
2191static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2192{
2193	struct alc_spec *spec = codec->spec;
2194	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2195}
2196#endif
2197
2198/*
2199 * Analog playback callbacks
2200 */
2201static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2202				    struct hda_codec *codec,
2203				    struct snd_pcm_substream *substream)
2204{
2205	struct alc_spec *spec = codec->spec;
2206	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2207}
2208
2209static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2210				       struct hda_codec *codec,
2211				       unsigned int stream_tag,
2212				       unsigned int format,
2213				       struct snd_pcm_substream *substream)
2214{
2215	struct alc_spec *spec = codec->spec;
2216	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2217						stream_tag, format, substream);
2218}
2219
2220static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2221				       struct hda_codec *codec,
2222				       struct snd_pcm_substream *substream)
2223{
2224	struct alc_spec *spec = codec->spec;
2225	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2226}
2227
2228/*
2229 * Digital out
2230 */
2231static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2232					struct hda_codec *codec,
2233					struct snd_pcm_substream *substream)
2234{
2235	struct alc_spec *spec = codec->spec;
2236	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2237}
2238
2239static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2240					   struct hda_codec *codec,
2241					   unsigned int stream_tag,
2242					   unsigned int format,
2243					   struct snd_pcm_substream *substream)
2244{
2245	struct alc_spec *spec = codec->spec;
2246	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2247					     stream_tag, format, substream);
2248}
2249
2250static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2251					 struct hda_codec *codec,
2252					 struct snd_pcm_substream *substream)
2253{
2254	struct alc_spec *spec = codec->spec;
2255	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2256}
2257
2258/*
2259 * Analog capture
2260 */
2261static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2262				      struct hda_codec *codec,
2263				      unsigned int stream_tag,
2264				      unsigned int format,
2265				      struct snd_pcm_substream *substream)
2266{
2267	struct alc_spec *spec = codec->spec;
2268
2269	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2270				   stream_tag, 0, format);
2271	return 0;
2272}
2273
2274static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2275				      struct hda_codec *codec,
2276				      struct snd_pcm_substream *substream)
2277{
2278	struct alc_spec *spec = codec->spec;
2279
2280	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2281				   0, 0, 0);
2282	return 0;
2283}
2284
2285
2286/*
2287 */
2288static struct hda_pcm_stream alc880_pcm_analog_playback = {
2289	.substreams = 1,
2290	.channels_min = 2,
2291	.channels_max = 8,
2292	/* NID is set in alc_build_pcms */
2293	.ops = {
2294		.open = alc880_playback_pcm_open,
2295		.prepare = alc880_playback_pcm_prepare,
2296		.cleanup = alc880_playback_pcm_cleanup
2297	},
2298};
2299
2300static struct hda_pcm_stream alc880_pcm_analog_capture = {
2301	.substreams = 2,
2302	.channels_min = 2,
2303	.channels_max = 2,
2304	/* NID is set in alc_build_pcms */
2305	.ops = {
2306		.prepare = alc880_capture_pcm_prepare,
2307		.cleanup = alc880_capture_pcm_cleanup
2308	},
2309};
2310
2311static struct hda_pcm_stream alc880_pcm_digital_playback = {
2312	.substreams = 1,
2313	.channels_min = 2,
2314	.channels_max = 2,
2315	/* NID is set in alc_build_pcms */
2316	.ops = {
2317		.open = alc880_dig_playback_pcm_open,
2318		.close = alc880_dig_playback_pcm_close,
2319		.prepare = alc880_dig_playback_pcm_prepare
2320	},
2321};
2322
2323static struct hda_pcm_stream alc880_pcm_digital_capture = {
2324	.substreams = 1,
2325	.channels_min = 2,
2326	.channels_max = 2,
2327	/* NID is set in alc_build_pcms */
2328};
2329
2330/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2331static struct hda_pcm_stream alc_pcm_null_playback = {
2332	.substreams = 0,
2333	.channels_min = 0,
2334	.channels_max = 0,
2335};
2336
2337static int alc_build_pcms(struct hda_codec *codec)
2338{
2339	struct alc_spec *spec = codec->spec;
2340	struct hda_pcm *info = spec->pcm_rec;
2341	int i;
2342
2343	codec->num_pcms = 1;
2344	codec->pcm_info = info;
2345
2346	info->name = spec->stream_name_analog;
2347	if (spec->stream_analog_playback) {
2348		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2349		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2350		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2351	}
2352	if (spec->stream_analog_capture) {
2353		snd_assert(spec->adc_nids, return -EINVAL);
2354		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2355		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2356	}
2357
2358	if (spec->channel_mode) {
2359		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2360		for (i = 0; i < spec->num_channel_mode; i++) {
2361			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2362				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2363			}
2364		}
2365	}
2366
2367	/* SPDIF for stream index #1 */
2368	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2369		codec->num_pcms = 2;
2370		info = spec->pcm_rec + 1;
2371		info->name = spec->stream_name_digital;
2372		if (spec->multiout.dig_out_nid &&
2373		    spec->stream_digital_playback) {
2374			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2375			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2376		}
2377		if (spec->dig_in_nid &&
2378		    spec->stream_digital_capture) {
2379			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2380			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2381		}
2382	}
2383
2384	/* If the use of more than one ADC is requested for the current
2385	 * model, configure a second analog capture-only PCM.
2386	 */
2387	/* Additional Analaog capture for index #2 */
2388	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2389	    spec->adc_nids) {
2390		codec->num_pcms = 3;
2391		info = spec->pcm_rec + 2;
2392		info->name = spec->stream_name_analog;
2393		/* No playback stream for second PCM */
2394		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2395		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2396		if (spec->stream_analog_capture) {
2397			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2398			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2399		}
2400	}
2401
2402	return 0;
2403}
2404
2405static void alc_free(struct hda_codec *codec)
2406{
2407	struct alc_spec *spec = codec->spec;
2408	unsigned int i;
2409
2410	if (!spec)
2411		return;
2412
2413	if (spec->kctl_alloc) {
2414		for (i = 0; i < spec->num_kctl_used; i++)
2415			kfree(spec->kctl_alloc[i].name);
2416		kfree(spec->kctl_alloc);
2417	}
2418	kfree(spec);
2419}
2420
2421/*
2422 */
2423static struct hda_codec_ops alc_patch_ops = {
2424	.build_controls = alc_build_controls,
2425	.build_pcms = alc_build_pcms,
2426	.init = alc_init,
2427	.free = alc_free,
2428	.unsol_event = alc_unsol_event,
2429#ifdef CONFIG_SND_HDA_POWER_SAVE
2430	.check_power_status = alc_check_power_status,
2431#endif
2432};
2433
2434
2435/*
2436 * Test configuration for debugging
2437 *
2438 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2439 * enum controls.
2440 */
2441#ifdef CONFIG_SND_DEBUG
2442static hda_nid_t alc880_test_dac_nids[4] = {
2443	0x02, 0x03, 0x04, 0x05
2444};
2445
2446static struct hda_input_mux alc880_test_capture_source = {
2447	.num_items = 7,
2448	.items = {
2449		{ "In-1", 0x0 },
2450		{ "In-2", 0x1 },
2451		{ "In-3", 0x2 },
2452		{ "In-4", 0x3 },
2453		{ "CD", 0x4 },
2454		{ "Front", 0x5 },
2455		{ "Surround", 0x6 },
2456	},
2457};
2458
2459static struct hda_channel_mode alc880_test_modes[4] = {
2460	{ 2, NULL },
2461	{ 4, NULL },
2462	{ 6, NULL },
2463	{ 8, NULL },
2464};
2465
2466static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2467				 struct snd_ctl_elem_info *uinfo)
2468{
2469	static char *texts[] = {
2470		"N/A", "Line Out", "HP Out",
2471		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2472	};
2473	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2474	uinfo->count = 1;
2475	uinfo->value.enumerated.items = 8;
2476	if (uinfo->value.enumerated.item >= 8)
2477		uinfo->value.enumerated.item = 7;
2478	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2479	return 0;
2480}
2481
2482static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2483				struct snd_ctl_elem_value *ucontrol)
2484{
2485	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2486	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2487	unsigned int pin_ctl, item = 0;
2488
2489	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2490				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2491	if (pin_ctl & AC_PINCTL_OUT_EN) {
2492		if (pin_ctl & AC_PINCTL_HP_EN)
2493			item = 2;
2494		else
2495			item = 1;
2496	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2497		switch (pin_ctl & AC_PINCTL_VREFEN) {
2498		case AC_PINCTL_VREF_HIZ: item = 3; break;
2499		case AC_PINCTL_VREF_50:  item = 4; break;
2500		case AC_PINCTL_VREF_GRD: item = 5; break;
2501		case AC_PINCTL_VREF_80:  item = 6; break;
2502		case AC_PINCTL_VREF_100: item = 7; break;
2503		}
2504	}
2505	ucontrol->value.enumerated.item[0] = item;
2506	return 0;
2507}
2508
2509static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2510				struct snd_ctl_elem_value *ucontrol)
2511{
2512	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2513	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2514	static unsigned int ctls[] = {
2515		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2516		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2517		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2518		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2519		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2520		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2521	};
2522	unsigned int old_ctl, new_ctl;
2523
2524	old_ctl = snd_hda_codec_read(codec, nid, 0,
2525				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2526	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2527	if (old_ctl != new_ctl) {
2528		int val;
2529		snd_hda_codec_write_cache(codec, nid, 0,
2530					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2531					  new_ctl);
2532		val = ucontrol->value.enumerated.item[0] >= 3 ?
2533			HDA_AMP_MUTE : 0;
2534		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2535					 HDA_AMP_MUTE, val);
2536		return 1;
2537	}
2538	return 0;
2539}
2540
2541static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2542				 struct snd_ctl_elem_info *uinfo)
2543{
2544	static char *texts[] = {
2545		"Front", "Surround", "CLFE", "Side"
2546	};
2547	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2548	uinfo->count = 1;
2549	uinfo->value.enumerated.items = 4;
2550	if (uinfo->value.enumerated.item >= 4)
2551		uinfo->value.enumerated.item = 3;
2552	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2553	return 0;
2554}
2555
2556static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2557				struct snd_ctl_elem_value *ucontrol)
2558{
2559	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2560	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2561	unsigned int sel;
2562
2563	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2564	ucontrol->value.enumerated.item[0] = sel & 3;
2565	return 0;
2566}
2567
2568static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2569				struct snd_ctl_elem_value *ucontrol)
2570{
2571	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2572	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2573	unsigned int sel;
2574
2575	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2576	if (ucontrol->value.enumerated.item[0] != sel) {
2577		sel = ucontrol->value.enumerated.item[0] & 3;
2578		snd_hda_codec_write_cache(codec, nid, 0,
2579					  AC_VERB_SET_CONNECT_SEL, sel);
2580		return 1;
2581	}
2582	return 0;
2583}
2584
2585#define PIN_CTL_TEST(xname,nid) {			\
2586		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2587			.name = xname,		       \
2588			.info = alc_test_pin_ctl_info, \
2589			.get = alc_test_pin_ctl_get,   \
2590			.put = alc_test_pin_ctl_put,   \
2591			.private_value = nid	       \
2592			}
2593
2594#define PIN_SRC_TEST(xname,nid) {			\
2595		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2596			.name = xname,		       \
2597			.info = alc_test_pin_src_info, \
2598			.get = alc_test_pin_src_get,   \
2599			.put = alc_test_pin_src_put,   \
2600			.private_value = nid	       \
2601			}
2602
2603static struct snd_kcontrol_new alc880_test_mixer[] = {
2604	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2605	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2606	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2607	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2608	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2609	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2610	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2611	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2612	PIN_CTL_TEST("Front Pin Mode", 0x14),
2613	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2614	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2615	PIN_CTL_TEST("Side Pin Mode", 0x17),
2616	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2617	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2618	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2619	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2620	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2621	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2622	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2623	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2624	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2625	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2626	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2627	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2628	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2629	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2630	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2631	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2632	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2633	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2634	{
2635		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2636		.name = "Channel Mode",
2637		.info = alc_ch_mode_info,
2638		.get = alc_ch_mode_get,
2639		.put = alc_ch_mode_put,
2640	},
2641	{ } /* end */
2642};
2643
2644static struct hda_verb alc880_test_init_verbs[] = {
2645	/* Unmute inputs of 0x0c - 0x0f */
2646	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2647	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2648	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2649	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2650	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2651	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2652	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2653	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2654	/* Vol output for 0x0c-0x0f */
2655	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2656	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2657	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2658	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2659	/* Set output pins 0x14-0x17 */
2660	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2661	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2662	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2663	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2664	/* Unmute output pins 0x14-0x17 */
2665	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2666	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2667	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2668	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2669	/* Set input pins 0x18-0x1c */
2670	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2671	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2672	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2673	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2674	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2675	/* Mute input pins 0x18-0x1b */
2676	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2677	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2678	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2679	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2680	/* ADC set up */
2681	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2682	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2683	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2684	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2685	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2686	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2687	/* Analog input/passthru */
2688	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2689	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2690	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2691	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2692	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2693	{ }
2694};
2695#endif
2696
2697/*
2698 */
2699
2700static const char *alc880_models[ALC880_MODEL_LAST] = {
2701	[ALC880_3ST]		= "3stack",
2702	[ALC880_TCL_S700]	= "tcl",
2703	[ALC880_3ST_DIG]	= "3stack-digout",
2704	[ALC880_CLEVO]		= "clevo",
2705	[ALC880_5ST]		= "5stack",
2706	[ALC880_5ST_DIG]	= "5stack-digout",
2707	[ALC880_W810]		= "w810",
2708	[ALC880_Z71V]		= "z71v",
2709	[ALC880_6ST]		= "6stack",
2710	[ALC880_6ST_DIG]	= "6stack-digout",
2711	[ALC880_ASUS]		= "asus",
2712	[ALC880_ASUS_W1V]	= "asus-w1v",
2713	[ALC880_ASUS_DIG]	= "asus-dig",
2714	[ALC880_ASUS_DIG2]	= "asus-dig2",
2715	[ALC880_UNIWILL_DIG]	= "uniwill",
2716	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2717	[ALC880_FUJITSU]	= "fujitsu",
2718	[ALC880_F1734]		= "F1734",
2719	[ALC880_LG]		= "lg",
2720	[ALC880_LG_LW]		= "lg-lw",
2721#ifdef CONFIG_SND_DEBUG
2722	[ALC880_TEST]		= "test",
2723#endif
2724	[ALC880_AUTO]		= "auto",
2725};
2726
2727static struct snd_pci_quirk alc880_cfg_tbl[] = {
2728	/* Broken BIOS configuration */
2729	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2730	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2731
2732	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2733	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2734	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2735	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2736	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2737	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2738	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2739	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2740	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2741
2742	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2743	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2744
2745	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2746	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2747	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2748	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2749	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2750	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2751	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2752	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2753	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2754	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2755	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2756	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2757	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2758	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2759	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2760
2761	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2762	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2763	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2764	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2765	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2766	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2767	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2768	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2769	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2770	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2771	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2772	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2773	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2774	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2775	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2776	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2777	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2778	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2779
2780	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2781	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2782	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2783	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2784
2785	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2786	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2787	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2788	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2789
2790	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2791	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2792	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2793	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2794
2795	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2796	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2797	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2798	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2799	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2800	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2801	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2802	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2803	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2804	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2805	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2806
2807	{}
2808};
2809
2810/*
2811 * ALC880 codec presets
2812 */
2813static struct alc_config_preset alc880_presets[] = {
2814	[ALC880_3ST] = {
2815		.mixers = { alc880_three_stack_mixer },
2816		.init_verbs = { alc880_volume_init_verbs,
2817				alc880_pin_3stack_init_verbs },
2818		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2819		.dac_nids = alc880_dac_nids,
2820		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2821		.channel_mode = alc880_threestack_modes,
2822		.need_dac_fix = 1,
2823		.input_mux = &alc880_capture_source,
2824	},
2825	[ALC880_3ST_DIG] = {
2826		.mixers = { alc880_three_stack_mixer },
2827		.init_verbs = { alc880_volume_init_verbs,
2828				alc880_pin_3stack_init_verbs },
2829		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2830		.dac_nids = alc880_dac_nids,
2831		.dig_out_nid = ALC880_DIGOUT_NID,
2832		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2833		.channel_mode = alc880_threestack_modes,
2834		.need_dac_fix = 1,
2835		.input_mux = &alc880_capture_source,
2836	},
2837	[ALC880_TCL_S700] = {
2838		.mixers = { alc880_tcl_s700_mixer },
2839		.init_verbs = { alc880_volume_init_verbs,
2840				alc880_pin_tcl_S700_init_verbs,
2841				alc880_gpio2_init_verbs },
2842		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2843		.dac_nids = alc880_dac_nids,
2844		.hp_nid = 0x03,
2845		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2846		.channel_mode = alc880_2_jack_modes,
2847		.input_mux = &alc880_capture_source,
2848	},
2849	[ALC880_5ST] = {
2850		.mixers = { alc880_three_stack_mixer,
2851			    alc880_five_stack_mixer},
2852		.init_verbs = { alc880_volume_init_verbs,
2853				alc880_pin_5stack_init_verbs },
2854		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2855		.dac_nids = alc880_dac_nids,
2856		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2857		.channel_mode = alc880_fivestack_modes,
2858		.input_mux = &alc880_capture_source,
2859	},
2860	[ALC880_5ST_DIG] = {
2861		.mixers = { alc880_three_stack_mixer,
2862			    alc880_five_stack_mixer },
2863		.init_verbs = { alc880_volume_init_verbs,
2864				alc880_pin_5stack_init_verbs },
2865		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2866		.dac_nids = alc880_dac_nids,
2867		.dig_out_nid = ALC880_DIGOUT_NID,
2868		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2869		.channel_mode = alc880_fivestack_modes,
2870		.input_mux = &alc880_capture_source,
2871	},
2872	[ALC880_6ST] = {
2873		.mixers = { alc880_six_stack_mixer },
2874		.init_verbs = { alc880_volume_init_verbs,
2875				alc880_pin_6stack_init_verbs },
2876		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2877		.dac_nids = alc880_6st_dac_nids,
2878		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2879		.channel_mode = alc880_sixstack_modes,
2880		.input_mux = &alc880_6stack_capture_source,
2881	},
2882	[ALC880_6ST_DIG] = {
2883		.mixers = { alc880_six_stack_mixer },
2884		.init_verbs = { alc880_volume_init_verbs,
2885				alc880_pin_6stack_init_verbs },
2886		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2887		.dac_nids = alc880_6st_dac_nids,
2888		.dig_out_nid = ALC880_DIGOUT_NID,
2889		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2890		.channel_mode = alc880_sixstack_modes,
2891		.input_mux = &alc880_6stack_capture_source,
2892	},
2893	[ALC880_W810] = {
2894		.mixers = { alc880_w810_base_mixer },
2895		.init_verbs = { alc880_volume_init_verbs,
2896				alc880_pin_w810_init_verbs,
2897				alc880_gpio2_init_verbs },
2898		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2899		.dac_nids = alc880_w810_dac_nids,
2900		.dig_out_nid = ALC880_DIGOUT_NID,
2901		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2902		.channel_mode = alc880_w810_modes,
2903		.input_mux = &alc880_capture_source,
2904	},
2905	[ALC880_Z71V] = {
2906		.mixers = { alc880_z71v_mixer },
2907		.init_verbs = { alc880_volume_init_verbs,
2908				alc880_pin_z71v_init_verbs },
2909		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2910		.dac_nids = alc880_z71v_dac_nids,
2911		.dig_out_nid = ALC880_DIGOUT_NID,
2912		.hp_nid = 0x03,
2913		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2914		.channel_mode = alc880_2_jack_modes,
2915		.input_mux = &alc880_capture_source,
2916	},
2917	[ALC880_F1734] = {
2918		.mixers = { alc880_f1734_mixer },
2919		.init_verbs = { alc880_volume_init_verbs,
2920				alc880_pin_f1734_init_verbs },
2921		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2922		.dac_nids = alc880_f1734_dac_nids,
2923		.hp_nid = 0x02,
2924		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2925		.channel_mode = alc880_2_jack_modes,
2926		.input_mux = &alc880_capture_source,
2927	},
2928	[ALC880_ASUS] = {
2929		.mixers = { alc880_asus_mixer },
2930		.init_verbs = { alc880_volume_init_verbs,
2931				alc880_pin_asus_init_verbs,
2932				alc880_gpio1_init_verbs },
2933		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2934		.dac_nids = alc880_asus_dac_nids,
2935		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2936		.channel_mode = alc880_asus_modes,
2937		.need_dac_fix = 1,
2938		.input_mux = &alc880_capture_source,
2939	},
2940	[ALC880_ASUS_DIG] = {
2941		.mixers = { alc880_asus_mixer },
2942		.init_verbs = { alc880_volume_init_verbs,
2943				alc880_pin_asus_init_verbs,
2944				alc880_gpio1_init_verbs },
2945		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2946		.dac_nids = alc880_asus_dac_nids,
2947		.dig_out_nid = ALC880_DIGOUT_NID,
2948		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2949		.channel_mode = alc880_asus_modes,
2950		.need_dac_fix = 1,
2951		.input_mux = &alc880_capture_source,
2952	},
2953	[ALC880_ASUS_DIG2] = {
2954		.mixers = { alc880_asus_mixer },
2955		.init_verbs = { alc880_volume_init_verbs,
2956				alc880_pin_asus_init_verbs,
2957				alc880_gpio2_init_verbs }, /* use GPIO2 */
2958		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2959		.dac_nids = alc880_asus_dac_nids,
2960		.dig_out_nid = ALC880_DIGOUT_NID,
2961		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2962		.channel_mode = alc880_asus_modes,
2963		.need_dac_fix = 1,
2964		.input_mux = &alc880_capture_source,
2965	},
2966	[ALC880_ASUS_W1V] = {
2967		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2968		.init_verbs = { alc880_volume_init_verbs,
2969				alc880_pin_asus_init_verbs,
2970				alc880_gpio1_init_verbs },
2971		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2972		.dac_nids = alc880_asus_dac_nids,
2973		.dig_out_nid = ALC880_DIGOUT_NID,
2974		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2975		.channel_mode = alc880_asus_modes,
2976		.need_dac_fix = 1,
2977		.input_mux = &alc880_capture_source,
2978	},
2979	[ALC880_UNIWILL_DIG] = {
2980		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2981		.init_verbs = { alc880_volume_init_verbs,
2982				alc880_pin_asus_init_verbs },
2983		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2984		.dac_nids = alc880_asus_dac_nids,
2985		.dig_out_nid = ALC880_DIGOUT_NID,
2986		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2987		.channel_mode = alc880_asus_modes,
2988		.need_dac_fix = 1,
2989		.input_mux = &alc880_capture_source,
2990	},
2991	[ALC880_UNIWILL] = {
2992		.mixers = { alc880_uniwill_mixer },
2993		.init_verbs = { alc880_volume_init_verbs,
2994				alc880_uniwill_init_verbs },
2995		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2996		.dac_nids = alc880_asus_dac_nids,
2997		.dig_out_nid = ALC880_DIGOUT_NID,
2998		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2999		.channel_mode = alc880_threestack_modes,
3000		.need_dac_fix = 1,
3001		.input_mux = &alc880_capture_source,
3002		.unsol_event = alc880_uniwill_unsol_event,
3003		.init_hook = alc880_uniwill_automute,
3004	},
3005	[ALC880_UNIWILL_P53] = {
3006		.mixers = { alc880_uniwill_p53_mixer },
3007		.init_verbs = { alc880_volume_init_verbs,
3008				alc880_uniwill_p53_init_verbs },
3009		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3010		.dac_nids = alc880_asus_dac_nids,
3011		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3012		.channel_mode = alc880_threestack_modes,
3013		.input_mux = &alc880_capture_source,
3014		.unsol_event = alc880_uniwill_p53_unsol_event,
3015		.init_hook = alc880_uniwill_p53_hp_automute,
3016	},
3017	[ALC880_FUJITSU] = {
3018		.mixers = { alc880_fujitsu_mixer,
3019			    alc880_pcbeep_mixer, },
3020		.init_verbs = { alc880_volume_init_verbs,
3021				alc880_uniwill_p53_init_verbs,
3022	       			alc880_beep_init_verbs },
3023		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3024		.dac_nids = alc880_dac_nids,
3025		.dig_out_nid = ALC880_DIGOUT_NID,
3026		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3027		.channel_mode = alc880_2_jack_modes,
3028		.input_mux = &alc880_capture_source,
3029		.unsol_event = alc880_uniwill_p53_unsol_event,
3030		.init_hook = alc880_uniwill_p53_hp_automute,
3031	},
3032	[ALC880_CLEVO] = {
3033		.mixers = { alc880_three_stack_mixer },
3034		.init_verbs = { alc880_volume_init_verbs,
3035				alc880_pin_clevo_init_verbs },
3036		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3037		.dac_nids = alc880_dac_nids,
3038		.hp_nid = 0x03,
3039		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3040		.channel_mode = alc880_threestack_modes,
3041		.need_dac_fix = 1,
3042		.input_mux = &alc880_capture_source,
3043	},
3044	[ALC880_LG] = {
3045		.mixers = { alc880_lg_mixer },
3046		.init_verbs = { alc880_volume_init_verbs,
3047				alc880_lg_init_verbs },
3048		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3049		.dac_nids = alc880_lg_dac_nids,
3050		.dig_out_nid = ALC880_DIGOUT_NID,
3051		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3052		.channel_mode = alc880_lg_ch_modes,
3053		.need_dac_fix = 1,
3054		.input_mux = &alc880_lg_capture_source,
3055		.unsol_event = alc880_lg_unsol_event,
3056		.init_hook = alc880_lg_automute,
3057#ifdef CONFIG_SND_HDA_POWER_SAVE
3058		.loopbacks = alc880_lg_loopbacks,
3059#endif
3060	},
3061	[ALC880_LG_LW] = {
3062		.mixers = { alc880_lg_lw_mixer },
3063		.init_verbs = { alc880_volume_init_verbs,
3064				alc880_lg_lw_init_verbs },
3065		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3066		.dac_nids = alc880_dac_nids,
3067		.dig_out_nid = ALC880_DIGOUT_NID,
3068		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3069		.channel_mode = alc880_lg_lw_modes,
3070		.input_mux = &alc880_lg_lw_capture_source,
3071		.unsol_event = alc880_lg_lw_unsol_event,
3072		.init_hook = alc880_lg_lw_automute,
3073	},
3074#ifdef CONFIG_SND_DEBUG
3075	[ALC880_TEST] = {
3076		.mixers = { alc880_test_mixer },
3077		.init_verbs = { alc880_test_init_verbs },
3078		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3079		.dac_nids = alc880_test_dac_nids,
3080		.dig_out_nid = ALC880_DIGOUT_NID,
3081		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3082		.channel_mode = alc880_test_modes,
3083		.input_mux = &alc880_test_capture_source,
3084	},
3085#endif
3086};
3087
3088/*
3089 * Automatic parse of I/O pins from the BIOS configuration
3090 */
3091
3092#define NUM_CONTROL_ALLOC	32
3093#define NUM_VERB_ALLOC		32
3094
3095enum {
3096	ALC_CTL_WIDGET_VOL,
3097	ALC_CTL_WIDGET_MUTE,
3098	ALC_CTL_BIND_MUTE,
3099};
3100static struct snd_kcontrol_new alc880_control_templates[] = {
3101	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3102	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3103	HDA_BIND_MUTE(NULL, 0, 0, 0),
3104};
3105
3106/* add dynamic controls */
3107static int add_control(struct alc_spec *spec, int type, const char *name,
3108		       unsigned long val)
3109{
3110	struct snd_kcontrol_new *knew;
3111
3112	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3113		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3114
3115		/* array + terminator */
3116		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3117		if (!knew)
3118			return -ENOMEM;
3119		if (spec->kctl_alloc) {
3120			memcpy(knew, spec->kctl_alloc,
3121			       sizeof(*knew) * spec->num_kctl_alloc);
3122			kfree(spec->kctl_alloc);
3123		}
3124		spec->kctl_alloc = knew;
3125		spec->num_kctl_alloc = num;
3126	}
3127
3128	knew = &spec->kctl_alloc[spec->num_kctl_used];
3129	*knew = alc880_control_templates[type];
3130	knew->name = kstrdup(name, GFP_KERNEL);
3131	if (!knew->name)
3132		return -ENOMEM;
3133	knew->private_value = val;
3134	spec->num_kctl_used++;
3135	return 0;
3136}
3137
3138#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3139#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3140#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3141#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3142#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3143#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3144#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3145#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3146#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3147#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3148#define ALC880_PIN_CD_NID		0x1c
3149
3150/* fill in the dac_nids table from the parsed pin configuration */
3151static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3152				     const struct auto_pin_cfg *cfg)
3153{
3154	hda_nid_t nid;
3155	int assigned[4];
3156	int i, j;
3157
3158	memset(assigned, 0, sizeof(assigned));
3159	spec->multiout.dac_nids = spec->private_dac_nids;
3160
3161	/* check the pins hardwired to audio widget */
3162	for (i = 0; i < cfg->line_outs; i++) {
3163		nid = cfg->line_out_pins[i];
3164		if (alc880_is_fixed_pin(nid)) {
3165			int idx = alc880_fixed_pin_idx(nid);
3166			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3167			assigned[idx] = 1;
3168		}
3169	}
3170	/* left pins can be connect to any audio widget */
3171	for (i = 0; i < cfg->line_outs; i++) {
3172		nid = cfg->line_out_pins[i];
3173		if (alc880_is_fixed_pin(nid))
3174			continue;
3175		/* search for an empty channel */
3176		for (j = 0; j < cfg->line_outs; j++) {
3177			if (!assigned[j]) {
3178				spec->multiout.dac_nids[i] =
3179					alc880_idx_to_dac(j);
3180				assigned[j] = 1;
3181				break;
3182			}
3183		}
3184	}
3185	spec->multiout.num_dacs = cfg->line_outs;
3186	return 0;
3187}
3188
3189/* add playback controls from the parsed DAC table */
3190static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3191					     const struct auto_pin_cfg *cfg)
3192{
3193	char name[32];
3194	static const char *chname[4] = {
3195		"Front", "Surround", NULL /*CLFE*/, "Side"
3196	};
3197	hda_nid_t nid;
3198	int i, err;
3199
3200	for (i = 0; i < cfg->line_outs; i++) {
3201		if (!spec->multiout.dac_nids[i])
3202			continue;
3203		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3204		if (i == 2) {
3205			/* Center/LFE */
3206			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3207					  "Center Playback Volume",
3208					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3209							      HDA_OUTPUT));
3210			if (err < 0)
3211				return err;
3212			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3213					  "LFE Playback Volume",
3214					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3215							      HDA_OUTPUT));
3216			if (err < 0)
3217				return err;
3218			err = add_control(spec, ALC_CTL_BIND_MUTE,
3219					  "Center Playback Switch",
3220					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3221							      HDA_INPUT));
3222			if (err < 0)
3223				return err;
3224			err = add_control(spec, ALC_CTL_BIND_MUTE,
3225					  "LFE Playback Switch",
3226					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3227							      HDA_INPUT));
3228			if (err < 0)
3229				return err;
3230		} else {
3231			sprintf(name, "%s Playback Volume", chname[i]);
3232			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3233					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3234							      HDA_OUTPUT));
3235			if (err < 0)
3236				return err;
3237			sprintf(name, "%s Playback Switch", chname[i]);
3238			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3239					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3240							      HDA_INPUT));
3241			if (err < 0)
3242				return err;
3243		}
3244	}
3245	return 0;
3246}
3247
3248/* add playback controls for speaker and HP outputs */
3249static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3250					const char *pfx)
3251{
3252	hda_nid_t nid;
3253	int err;
3254	char name[32];
3255
3256	if (!pin)
3257		return 0;
3258
3259	if (alc880_is_fixed_pin(pin)) {
3260		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3261		/* specify the DAC as the extra output */
3262		if (!spec->multiout.hp_nid)
3263			spec->multiout.hp_nid = nid;
3264		else
3265			spec->multiout.extra_out_nid[0] = nid;
3266		/* control HP volume/switch on the output mixer amp */
3267		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3268		sprintf(name, "%s Playback Volume", pfx);
3269		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3270				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3271		if (err < 0)
3272			return err;
3273		sprintf(name, "%s Playback Switch", pfx);
3274		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3275				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3276		if (err < 0)
3277			return err;
3278	} else if (alc880_is_multi_pin(pin)) {
3279		/* set manual connection */
3280		/* we have only a switch on HP-out PIN */
3281		sprintf(name, "%s Playback Switch", pfx);
3282		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3283				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3284		if (err < 0)
3285			return err;
3286	}
3287	return 0;
3288}
3289
3290/* create input playback/capture controls for the given pin */
3291static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3292			    const char *ctlname,
3293			    int idx, hda_nid_t mix_nid)
3294{
3295	char name[32];
3296	int err;
3297
3298	sprintf(name, "%s Playback Volume", ctlname);
3299	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3300			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3301	if (err < 0)
3302		return err;
3303	sprintf(name, "%s Playback Switch", ctlname);
3304	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3305			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3306	if (err < 0)
3307		return err;
3308	return 0;
3309}
3310
3311/* create playback/capture controls for input pins */
3312static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3313						const struct auto_pin_cfg *cfg)
3314{
3315	struct hda_input_mux *imux = &spec->private_imux;
3316	int i, err, idx;
3317
3318	for (i = 0; i < AUTO_PIN_LAST; i++) {
3319		if (alc880_is_input_pin(cfg->input_pins[i])) {
3320			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3321			err = new_analog_input(spec, cfg->input_pins[i],
3322					       auto_pin_cfg_labels[i],
3323					       idx, 0x0b);
3324			if (err < 0)
3325				return err;
3326			imux->items[imux->num_items].label =
3327				auto_pin_cfg_labels[i];
3328			imux->items[imux->num_items].index =
3329				alc880_input_pin_idx(cfg->input_pins[i]);
3330			imux->num_items++;
3331		}
3332	}
3333	return 0;
3334}
3335
3336static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3337					      hda_nid_t nid, int pin_type,
3338					      int dac_idx)
3339{
3340	/* set as output */
3341	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3342			    pin_type);
3343	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3344			    AMP_OUT_UNMUTE);
3345	/* need the manual connection? */
3346	if (alc880_is_multi_pin(nid)) {
3347		struct alc_spec *spec = codec->spec;
3348		int idx = alc880_multi_pin_idx(nid);
3349		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3350				    AC_VERB_SET_CONNECT_SEL,
3351				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3352	}
3353}
3354
3355static int get_pin_type(int line_out_type)
3356{
3357	if (line_out_type == AUTO_PIN_HP_OUT)
3358		return PIN_HP;
3359	else
3360		return PIN_OUT;
3361}
3362
3363static void alc880_auto_init_multi_out(struct hda_codec *codec)
3364{
3365	struct alc_spec *spec = codec->spec;
3366	int i;
3367
3368	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3369	for (i = 0; i < spec->autocfg.line_outs; i++) {
3370		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3371		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3372		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3373	}
3374}
3375
3376static void alc880_auto_init_extra_out(struct hda_codec *codec)
3377{
3378	struct alc_spec *spec = codec->spec;
3379	hda_nid_t pin;
3380
3381	pin = spec->autocfg.speaker_pins[0];
3382	if (pin) /* connect to front */
3383		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3384	pin = spec->autocfg.hp_pins[0];
3385	if (pin) /* connect to front */
3386		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3387}
3388
3389static void alc880_auto_init_analog_input(struct hda_codec *codec)
3390{
3391	struct alc_spec *spec = codec->spec;
3392	int i;
3393
3394	for (i = 0; i < AUTO_PIN_LAST; i++) {
3395		hda_nid_t nid = spec->autocfg.input_pins[i];
3396		if (alc880_is_input_pin(nid)) {
3397			snd_hda_codec_write(codec, nid, 0,
3398					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3399					    i <= AUTO_PIN_FRONT_MIC ?
3400					    PIN_VREF80 : PIN_IN);
3401			if (nid != ALC880_PIN_CD_NID)
3402				snd_hda_codec_write(codec, nid, 0,
3403						    AC_VERB_SET_AMP_GAIN_MUTE,
3404						    AMP_OUT_MUTE);
3405		}
3406	}
3407}
3408
3409/* parse the BIOS configuration and set up the alc_spec */
3410/* return 1 if successful, 0 if the proper config is not found,
3411 * or a negative error code
3412 */
3413static int alc880_parse_auto_config(struct hda_codec *codec)
3414{
3415	struct alc_spec *spec = codec->spec;
3416	int err;
3417	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3418
3419	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3420					   alc880_ignore);
3421	if (err < 0)
3422		return err;
3423	if (!spec->autocfg.line_outs)
3424		return 0; /* can't find valid BIOS pin config */
3425
3426	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3427	if (err < 0)
3428		return err;
3429	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3430	if (err < 0)
3431		return err;
3432	err = alc880_auto_create_extra_out(spec,
3433					   spec->autocfg.speaker_pins[0],
3434					   "Speaker");
3435	if (err < 0)
3436		return err;
3437	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3438					   "Headphone");
3439	if (err < 0)
3440		return err;
3441	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3442	if (err < 0)
3443		return err;
3444
3445	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3446
3447	if (spec->autocfg.dig_out_pin)
3448		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3449	if (spec->autocfg.dig_in_pin)
3450		spec->dig_in_nid = ALC880_DIGIN_NID;
3451
3452	if (spec->kctl_alloc)
3453		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3454
3455	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3456
3457	spec->num_mux_defs = 1;
3458	spec->input_mux = &spec->private_imux;
3459
3460	return 1;
3461}
3462
3463/* additional initialization for auto-configuration model */
3464static void alc880_auto_init(struct hda_codec *codec)
3465{
3466	alc880_auto_init_multi_out(codec);
3467	alc880_auto_init_extra_out(codec);
3468	alc880_auto_init_analog_input(codec);
3469}
3470
3471/*
3472 * OK, here we have finally the patch for ALC880
3473 */
3474
3475static int patch_alc880(struct hda_codec *codec)
3476{
3477	struct alc_spec *spec;
3478	int board_config;
3479	int err;
3480
3481	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3482	if (spec == NULL)
3483		return -ENOMEM;
3484
3485	codec->spec = spec;
3486
3487	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3488						  alc880_models,
3489						  alc880_cfg_tbl);
3490	if (board_config < 0) {
3491		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3492		       "trying auto-probe from BIOS...\n");
3493		board_config = ALC880_AUTO;
3494	}
3495
3496	if (board_config == ALC880_AUTO) {
3497		/* automatic parse from the BIOS config */
3498		err = alc880_parse_auto_config(codec);
3499		if (err < 0) {
3500			alc_free(codec);
3501			return err;
3502		} else if (!err) {
3503			printk(KERN_INFO
3504			       "hda_codec: Cannot set up configuration "
3505			       "from BIOS.  Using 3-stack mode...\n");
3506			board_config = ALC880_3ST;
3507		}
3508	}
3509
3510	if (board_config != ALC880_AUTO)
3511		setup_preset(spec, &alc880_presets[board_config]);
3512
3513	spec->stream_name_analog = "ALC880 Analog";
3514	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3515	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3516
3517	spec->stream_name_digital = "ALC880 Digital";
3518	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3519	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3520
3521	if (!spec->adc_nids && spec->input_mux) {
3522		/* check whether NID 0x07 is valid */
3523		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3524		/* get type */
3525		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3526		if (wcap != AC_WID_AUD_IN) {
3527			spec->adc_nids = alc880_adc_nids_alt;
3528			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3529			spec->mixers[spec->num_mixers] =
3530				alc880_capture_alt_mixer;
3531			spec->num_mixers++;
3532		} else {
3533			spec->adc_nids = alc880_adc_nids;
3534			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3535			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3536			spec->num_mixers++;
3537		}
3538	}
3539
3540	codec->patch_ops = alc_patch_ops;
3541	if (board_config == ALC880_AUTO)
3542		spec->init_hook = alc880_auto_init;
3543#ifdef CONFIG_SND_HDA_POWER_SAVE
3544	if (!spec->loopback.amplist)
3545		spec->loopback.amplist = alc880_loopbacks;
3546#endif
3547
3548	return 0;
3549}
3550
3551
3552/*
3553 * ALC260 support
3554 */
3555
3556static hda_nid_t alc260_dac_nids[1] = {
3557	/* front */
3558	0x02,
3559};
3560
3561static hda_nid_t alc260_adc_nids[1] = {
3562	/* ADC0 */
3563	0x04,
3564};
3565
3566static hda_nid_t alc260_adc_nids_alt[1] = {
3567	/* ADC1 */
3568	0x05,
3569};
3570
3571static hda_nid_t alc260_hp_adc_nids[2] = {
3572	/* ADC1, 0 */
3573	0x05, 0x04
3574};
3575
3576/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3577 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3578 */
3579static hda_nid_t alc260_dual_adc_nids[2] = {
3580	/* ADC0, ADC1 */
3581	0x04, 0x05
3582};
3583
3584#define ALC260_DIGOUT_NID	0x03
3585#define ALC260_DIGIN_NID	0x06
3586
3587static struct hda_input_mux alc260_capture_source = {
3588	.num_items = 4,
3589	.items = {
3590		{ "Mic", 0x0 },
3591		{ "Front Mic", 0x1 },
3592		{ "Line", 0x2 },
3593		{ "CD", 0x4 },
3594	},
3595};
3596
3597/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3598 * headphone jack and the internal CD lines since these are the only pins at
3599 * which audio can appear.  For flexibility, also allow the option of
3600 * recording the mixer output on the second ADC (ADC0 doesn't have a
3601 * connection to the mixer output).
3602 */
3603static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3604	{
3605		.num_items = 3,
3606		.items = {
3607			{ "Mic/Line", 0x0 },
3608			{ "CD", 0x4 },
3609			{ "Headphone", 0x2 },
3610		},
3611	},
3612	{
3613		.num_items = 4,
3614		.items = {
3615			{ "Mic/Line", 0x0 },
3616			{ "CD", 0x4 },
3617			{ "Headphone", 0x2 },
3618			{ "Mixer", 0x5 },
3619		},
3620	},
3621
3622};
3623
3624/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3625 * the Fujitsu S702x, but jacks are marked differently.
3626 */
3627static struct hda_input_mux alc260_acer_capture_sources[2] = {
3628	{
3629		.num_items = 4,
3630		.items = {
3631			{ "Mic", 0x0 },
3632			{ "Line", 0x2 },
3633			{ "CD", 0x4 },
3634			{ "Headphone", 0x5 },
3635		},
3636	},
3637	{
3638		.num_items = 5,
3639		.items = {
3640			{ "Mic", 0x0 },
3641			{ "Line", 0x2 },
3642			{ "CD", 0x4 },
3643			{ "Headphone", 0x6 },
3644			{ "Mixer", 0x5 },
3645		},
3646	},
3647};
3648/*
3649 * This is just place-holder, so there's something for alc_build_pcms to look
3650 * at when it calculates the maximum number of channels. ALC260 has no mixer
3651 * element which allows changing the channel mode, so the verb list is
3652 * never used.
3653 */
3654static struct hda_channel_mode alc260_modes[1] = {
3655	{ 2, NULL },
3656};
3657
3658
3659/* Mixer combinations
3660 *
3661 * basic: base_output + input + pc_beep + capture
3662 * HP: base_output + input + capture_alt
3663 * HP_3013: hp_3013 + input + capture
3664 * fujitsu: fujitsu + capture
3665 * acer: acer + capture
3666 */
3667
3668static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3669	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3670	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3671	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3672	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3673	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3674	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3675	{ } /* end */
3676};
3677
3678static struct snd_kcontrol_new alc260_input_mixer[] = {
3679	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3680	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3681	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3682	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3683	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3684	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3685	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3686	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3687	{ } /* end */
3688};
3689
3690static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3691	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3692	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3693	{ } /* end */
3694};
3695
3696static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3697	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3698	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3699	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3700	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3701	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3702	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3703	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3704	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3705	{ } /* end */
3706};
3707
3708/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3709 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3710 */
3711static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3712	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3713	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3714	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3715	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3716	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3717	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3718	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3719	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3720	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3721	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3722	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3723	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3724	{ } /* end */
3725};
3726
3727/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3728 * versions of the ALC260 don't act on requests to enable mic bias from NID
3729 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3730 * datasheet doesn't mention this restriction.  At this stage it's not clear
3731 * whether this behaviour is intentional or is a hardware bug in chip
3732 * revisions available in early 2006.  Therefore for now allow the
3733 * "Headphone Jack Mode" control to span all choices, but if it turns out
3734 * that the lack of mic bias for this NID is intentional we could change the
3735 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3736 *
3737 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3738 * don't appear to make the mic bias available from the "line" jack, even
3739 * though the NID used for this jack (0x14) can supply it.  The theory is
3740 * that perhaps Acer have included blocking capacitors between the ALC260
3741 * and the output jack.  If this turns out to be the case for all such
3742 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3743 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3744 *
3745 * The C20x Tablet series have a mono internal speaker which is controlled
3746 * via the chip's Mono sum widget and pin complex, so include the necessary
3747 * controls for such models.  On models without a "mono speaker" the control
3748 * won't do anything.
3749 */
3750static struct snd_kcontrol_new alc260_acer_mixer[] = {
3751	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3752	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3753	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3754	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3755			      HDA_OUTPUT),
3756	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3757			   HDA_INPUT),
3758	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3759	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3760	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3761	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3762	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3763	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3764	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3765	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3766	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3767	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3768	{ } /* end */
3769};
3770
3771/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3772 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3773 */
3774static struct snd_kcontrol_new alc260_will_mixer[] = {
3775	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3776	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3777	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3778	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3779	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3780	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3781	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3782	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3783	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3784	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3785	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3786	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3787	{ } /* end */
3788};
3789
3790/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3791 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3792 */
3793static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3794	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3795	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3796	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3797	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3798	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3799	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3800	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3801	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3802	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3803	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3804	{ } /* end */
3805};
3806
3807/* capture mixer elements */
3808static struct snd_kcontrol_new alc260_capture_mixer[] = {
3809	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3810	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3811	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3812	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3813	{
3814		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3815		/* The multiple "Capture Source" controls confuse alsamixer
3816		 * So call somewhat different..
3817		 * FIXME: the controls appear in the "playback" view!
3818		 */
3819		/* .name = "Capture Source", */
3820		.name = "Input Source",
3821		.count = 2,
3822		.info = alc_mux_enum_info,
3823		.get = alc_mux_enum_get,
3824		.put = alc_mux_enum_put,
3825	},
3826	{ } /* end */
3827};
3828
3829static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3830	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3831	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3832	{
3833		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3834		/* The multiple "Capture Source" controls confuse alsamixer
3835		 * So call somewhat different..
3836		 * FIXME: the controls appear in the "playback" view!
3837		 */
3838		/* .name = "Capture Source", */
3839		.name = "Input Source",
3840		.count = 1,
3841		.info = alc_mux_enum_info,
3842		.get = alc_mux_enum_get,
3843		.put = alc_mux_enum_put,
3844	},
3845	{ } /* end */
3846};
3847
3848/*
3849 * initialization verbs
3850 */
3851static struct hda_verb alc260_init_verbs[] = {
3852	/* Line In pin widget for input */
3853	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3854	/* CD pin widget for input */
3855	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3856	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3857	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3858	/* Mic2 (front panel) pin widget for input and vref at 80% */
3859	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3860	/* LINE-2 is used for line-out in rear */
3861	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3862	/* select line-out */
3863	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3864	/* LINE-OUT pin */
3865	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3866	/* enable HP */
3867	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3868	/* enable Mono */
3869	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3870	/* mute capture amp left and right */
3871	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3872	/* set connection select to line in (default select for this ADC) */
3873	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3874	/* mute capture amp left and right */
3875	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3876	/* set connection select to line in (default select for this ADC) */
3877	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3878	/* set vol=0 Line-Out mixer amp left and right */
3879	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3880	/* unmute pin widget amp left and right (no gain on this amp) */
3881	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3882	/* set vol=0 HP mixer amp left and right */
3883	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3884	/* unmute pin widget amp left and right (no gain on this amp) */
3885	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3886	/* set vol=0 Mono mixer amp left and right */
3887	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3888	/* unmute pin widget amp left and right (no gain on this amp) */
3889	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3890	/* unmute LINE-2 out pin */
3891	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3892	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3893	 * Line In 2 = 0x03
3894	 */
3895	/* mute analog inputs */
3896	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3897	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3898	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3899	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3900	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3901	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3902	/* mute Front out path */
3903	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3904	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3905	/* mute Headphone out path */
3906	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3907	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3908	/* mute Mono out path */
3909	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3910	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3911	{ }
3912};
3913
3914#if 0 /* should be identical with alc260_init_verbs? */
3915static struct hda_verb alc260_hp_init_verbs[] = {
3916	/* Headphone and output */
3917	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3918	/* mono output */
3919	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3920	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3921	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3922	/* Mic2 (front panel) pin widget for input and vref at 80% */
3923	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3924	/* Line In pin widget for input */
3925	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3926	/* Line-2 pin widget for output */
3927	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3928	/* CD pin widget for input */
3929	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3930	/* unmute amp left and right */
3931	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3932	/* set connection select to line in (default select for this ADC) */
3933	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3934	/* unmute Line-Out mixer amp left and right (volume = 0) */
3935	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3936	/* mute pin widget amp left and right (no gain on this amp) */
3937	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3938	/* unmute HP mixer amp left and right (volume = 0) */
3939	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3940	/* mute pin widget amp left and right (no gain on this amp) */
3941	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3942	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3943	 * Line In 2 = 0x03
3944	 */
3945	/* mute analog inputs */
3946	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3947	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3948	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3949	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3950	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3951	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3952	/* Unmute Front out path */
3953	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3954	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3955	/* Unmute Headphone out path */
3956	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3957	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3958	/* Unmute Mono out path */
3959	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3960	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3961	{ }
3962};
3963#endif
3964
3965static struct hda_verb alc260_hp_3013_init_verbs[] = {
3966	/* Line out and output */
3967	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3968	/* mono output */
3969	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3970	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3971	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3972	/* Mic2 (front panel) pin widget for input and vref at 80% */
3973	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3974	/* Line In pin widget for input */
3975	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3976	/* Headphone pin widget for output */
3977	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3978	/* CD pin widget for input */
3979	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3980	/* unmute amp left and right */
3981	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3982	/* set connection select to line in (default select for this ADC) */
3983	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3984	/* unmute Line-Out mixer amp left and right (volume = 0) */
3985	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3986	/* mute pin widget amp left and right (no gain on this amp) */
3987	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3988	/* unmute HP mixer amp left and right (volume = 0) */
3989	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3990	/* mute pin widget amp left and right (no gain on this amp) */
3991	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3992	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3993	 * Line In 2 = 0x03
3994	 */
3995	/* mute analog inputs */
3996	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3997	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3998	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3999	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4000	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4001	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4002	/* Unmute Front out path */
4003	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4004	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4005	/* Unmute Headphone out path */
4006	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4007	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4008	/* Unmute Mono out path */
4009	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4010	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4011	{ }
4012};
4013
4014/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4015 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4016 * audio = 0x16, internal speaker = 0x10.
4017 */
4018static struct hda_verb alc260_fujitsu_init_verbs[] = {
4019	/* Disable all GPIOs */
4020	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4021	/* Internal speaker is connected to headphone pin */
4022	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4023	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4024	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4025	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4026	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4027	/* Ensure all other unused pins are disabled and muted. */
4028	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4029	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4030	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4031	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4032	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4033	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4034	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4035	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4036
4037	/* Disable digital (SPDIF) pins */
4038	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4039	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4040
4041	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4042	 * when acting as an output.
4043	 */
4044	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4045
4046	/* Start with output sum widgets muted and their output gains at min */
4047	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4048	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4049	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4050	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4051	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4052	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4053	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4054	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4055	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4056
4057	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4058	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4059	/* Unmute Line1 pin widget output buffer since it starts as an output.
4060	 * If the pin mode is changed by the user the pin mode control will
4061	 * take care of enabling the pin's input/output buffers as needed.
4062	 * Therefore there's no need to enable the input buffer at this
4063	 * stage.
4064	 */
4065	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4066	/* Unmute input buffer of pin widget used for Line-in (no equiv
4067	 * mixer ctrl)
4068	 */
4069	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4070
4071	/* Mute capture amp left and right */
4072	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4073	/* Set ADC connection select to match default mixer setting - line
4074	 * in (on mic1 pin)
4075	 */
4076	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4077
4078	/* Do the same for the second ADC: mute capture input amp and
4079	 * set ADC connection to line in (on mic1 pin)
4080	 */
4081	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4082	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4083
4084	/* Mute all inputs to mixer widget (even unconnected ones) */
4085	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4086	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4087	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4088	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4089	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4090	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4091	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4092	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4093
4094	{ }
4095};
4096
4097/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4098 * similar laptops (adapted from Fujitsu init verbs).
4099 */
4100static struct hda_verb alc260_acer_init_verbs[] = {
4101	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4102	 * the headphone jack.  Turn this on and rely on the standard mute
4103	 * methods whenever the user wants to turn these outputs off.
4104	 */
4105	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4106	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4107	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4108	/* Internal speaker/Headphone jack is connected to Line-out pin */
4109	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4110	/* Internal microphone/Mic jack is connected to Mic1 pin */
4111	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4112	/* Line In jack is connected to Line1 pin */
4113	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4114	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4115	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4116	/* Ensure all other unused pins are disabled and muted. */
4117	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4118	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4119	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4120	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4121	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4122	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4123	/* Disable digital (SPDIF) pins */
4124	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4125	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4126
4127	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4128	 * bus when acting as outputs.
4129	 */
4130	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4131	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4132
4133	/* Start with output sum widgets muted and their output gains at min */
4134	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4135	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4136	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4137	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4138	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4139	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4140	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4141	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4142	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4143
4144	/* Unmute Line-out pin widget amp left and right
4145	 * (no equiv mixer ctrl)
4146	 */
4147	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4148	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4149	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4150	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4151	 * inputs. If the pin mode is changed by the user the pin mode control
4152	 * will take care of enabling the pin's input/output buffers as needed.
4153	 * Therefore there's no need to enable the input buffer at this
4154	 * stage.
4155	 */
4156	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4157	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4158
4159	/* Mute capture amp left and right */
4160	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4161	/* Set ADC connection select to match default mixer setting - mic
4162	 * (on mic1 pin)
4163	 */
4164	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4165
4166	/* Do similar with the second ADC: mute capture input amp and
4167	 * set ADC connection to mic to match ALSA's default state.
4168	 */
4169	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4170	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4171
4172	/* Mute all inputs to mixer widget (even unconnected ones) */
4173	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4174	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4175	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4176	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4177	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4178	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4179	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4180	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4181
4182	{ }
4183};
4184
4185static struct hda_verb alc260_will_verbs[] = {
4186	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4187	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4188	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4189	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4190	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4191	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4192	{}
4193};
4194
4195static struct hda_verb alc260_replacer_672v_verbs[] = {
4196	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4197	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4198	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4199
4200	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4201	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4202	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4203
4204	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4205	{}
4206};
4207
4208/* toggle speaker-output according to the hp-jack state */
4209static void alc260_replacer_672v_automute(struct hda_codec *codec)
4210{
4211        unsigned int present;
4212
4213	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4214        present = snd_hda_codec_read(codec, 0x0f, 0,
4215                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4216	if (present) {
4217		snd_hda_codec_write_cache(codec, 0x01, 0,
4218					  AC_VERB_SET_GPIO_DATA, 1);
4219		snd_hda_codec_write_cache(codec, 0x0f, 0,
4220					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4221					  PIN_HP);
4222	} else {
4223		snd_hda_codec_write_cache(codec, 0x01, 0,
4224					  AC_VERB_SET_GPIO_DATA, 0);
4225		snd_hda_codec_write_cache(codec, 0x0f, 0,
4226					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4227					  PIN_OUT);
4228	}
4229}
4230
4231static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4232                                       unsigned int res)
4233{
4234        if ((res >> 26) == ALC880_HP_EVENT)
4235                alc260_replacer_672v_automute(codec);
4236}
4237
4238/* Test configuration for debugging, modelled after the ALC880 test
4239 * configuration.
4240 */
4241#ifdef CONFIG_SND_DEBUG
4242static hda_nid_t alc260_test_dac_nids[1] = {
4243	0x02,
4244};
4245static hda_nid_t alc260_test_adc_nids[2] = {
4246	0x04, 0x05,
4247};
4248/* For testing the ALC260, each input MUX needs its own definition since
4249 * the signal assignments are different.  This assumes that the first ADC
4250 * is NID 0x04.
4251 */
4252static struct hda_input_mux alc260_test_capture_sources[2] = {
4253	{
4254		.num_items = 7,
4255		.items = {
4256			{ "MIC1 pin", 0x0 },
4257			{ "MIC2 pin", 0x1 },
4258			{ "LINE1 pin", 0x2 },
4259			{ "LINE2 pin", 0x3 },
4260			{ "CD pin", 0x4 },
4261			{ "LINE-OUT pin", 0x5 },
4262			{ "HP-OUT pin", 0x6 },
4263		},
4264        },
4265	{
4266		.num_items = 8,
4267		.items = {
4268			{ "MIC1 pin", 0x0 },
4269			{ "MIC2 pin", 0x1 },
4270			{ "LINE1 pin", 0x2 },
4271			{ "LINE2 pin", 0x3 },
4272			{ "CD pin", 0x4 },
4273			{ "Mixer", 0x5 },
4274			{ "LINE-OUT pin", 0x6 },
4275			{ "HP-OUT pin", 0x7 },
4276		},
4277        },
4278};
4279static struct snd_kcontrol_new alc260_test_mixer[] = {
4280	/* Output driver widgets */
4281	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4282	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4283	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4284	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4285	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4286	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4287
4288	/* Modes for retasking pin widgets
4289	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4290         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4291         * mention this restriction.  At this stage it's not clear whether
4292         * this behaviour is intentional or is a hardware bug in chip
4293         * revisions available at least up until early 2006.  Therefore for
4294         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4295         * choices, but if it turns out that the lack of mic bias for these
4296         * NIDs is intentional we could change their modes from
4297         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4298	 */
4299	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4300	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4301	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4302	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4303	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4304	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4305
4306	/* Loopback mixer controls */
4307	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4308	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4309	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4310	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4311	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4312	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4313	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4314	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4315	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4316	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4317	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4318	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4319	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4320	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4321	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4322	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4323
4324	/* Controls for GPIO pins, assuming they are configured as outputs */
4325	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4326	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4327	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4328	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4329
4330	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4331	 * is ambigious as to which NID is which; testing on laptops which
4332	 * make this output available should provide clarification.
4333	 */
4334	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4335	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4336
4337	{ } /* end */
4338};
4339static struct hda_verb alc260_test_init_verbs[] = {
4340	/* Enable all GPIOs as outputs with an initial value of 0 */
4341	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4342	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4343	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4344
4345	/* Enable retasking pins as output, initially without power amp */
4346	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4347	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4348	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4349	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4350	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4351	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4352
4353	/* Disable digital (SPDIF) pins initially, but users can enable
4354	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4355	 * payload also sets the generation to 0, output to be in "consumer"
4356	 * PCM format, copyright asserted, no pre-emphasis and no validity
4357	 * control.
4358	 */
4359	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4360	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4361
4362	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4363	 * OUT1 sum bus when acting as an output.
4364	 */
4365	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4366	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4367	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4368	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4369
4370	/* Start with output sum widgets muted and their output gains at min */
4371	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4372	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4373	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4374	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4375	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4376	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4377	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4378	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4379	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4380
4381	/* Unmute retasking pin widget output buffers since the default
4382	 * state appears to be output.  As the pin mode is changed by the
4383	 * user the pin mode control will take care of enabling the pin's
4384	 * input/output buffers as needed.
4385	 */
4386	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4387	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4388	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4389	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4390	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4391	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4392	/* Also unmute the mono-out pin widget */
4393	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4394
4395	/* Mute capture amp left and right */
4396	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4397	/* Set ADC connection select to match default mixer setting (mic1
4398	 * pin)
4399	 */
4400	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4401
4402	/* Do the same for the second ADC: mute capture input amp and
4403	 * set ADC connection to mic1 pin
4404	 */
4405	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4406	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4407
4408	/* Mute all inputs to mixer widget (even unconnected ones) */
4409	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4410	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4411	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4412	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4413	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4414	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4415	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4416	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4417
4418	{ }
4419};
4420#endif
4421
4422static struct hda_pcm_stream alc260_pcm_analog_playback = {
4423	.substreams = 1,
4424	.channels_min = 2,
4425	.channels_max = 2,
4426};
4427
4428static struct hda_pcm_stream alc260_pcm_analog_capture = {
4429	.substreams = 1,
4430	.channels_min = 2,
4431	.channels_max = 2,
4432};
4433
4434#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4435#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4436
4437/*
4438 * for BIOS auto-configuration
4439 */
4440
4441static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4442					const char *pfx)
4443{
4444	hda_nid_t nid_vol;
4445	unsigned long vol_val, sw_val;
4446	char name[32];
4447	int err;
4448
4449	if (nid >= 0x0f && nid < 0x11) {
4450		nid_vol = nid - 0x7;
4451		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4452		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4453	} else if (nid == 0x11) {
4454		nid_vol = nid - 0x7;
4455		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4456		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4457	} else if (nid >= 0x12 && nid <= 0x15) {
4458		nid_vol = 0x08;
4459		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4460		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4461	} else
4462		return 0; /* N/A */
4463
4464	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4465	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4466	if (err < 0)
4467		return err;
4468	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4469	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4470	if (err < 0)
4471		return err;
4472	return 1;
4473}
4474
4475/* add playback controls from the parsed DAC table */
4476static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4477					     const struct auto_pin_cfg *cfg)
4478{
4479	hda_nid_t nid;
4480	int err;
4481
4482	spec->multiout.num_dacs = 1;
4483	spec->multiout.dac_nids = spec->private_dac_nids;
4484	spec->multiout.dac_nids[0] = 0x02;
4485
4486	nid = cfg->line_out_pins[0];
4487	if (nid) {
4488		err = alc260_add_playback_controls(spec, nid, "Front");
4489		if (err < 0)
4490			return err;
4491	}
4492
4493	nid = cfg->speaker_pins[0];
4494	if (nid) {
4495		err = alc260_add_playback_controls(spec, nid, "Speaker");
4496		if (err < 0)
4497			return err;
4498	}
4499
4500	nid = cfg->hp_pins[0];
4501	if (nid) {
4502		err = alc260_add_playback_controls(spec, nid, "Headphone");
4503		if (err < 0)
4504			return err;
4505	}
4506	return 0;
4507}
4508
4509/* create playback/capture controls for input pins */
4510static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4511						const struct auto_pin_cfg *cfg)
4512{
4513	struct hda_input_mux *imux = &spec->private_imux;
4514	int i, err, idx;
4515
4516	for (i = 0; i < AUTO_PIN_LAST; i++) {
4517		if (cfg->input_pins[i] >= 0x12) {
4518			idx = cfg->input_pins[i] - 0x12;
4519			err = new_analog_input(spec, cfg->input_pins[i],
4520					       auto_pin_cfg_labels[i], idx,
4521					       0x07);
4522			if (err < 0)
4523				return err;
4524			imux->items[imux->num_items].label =
4525				auto_pin_cfg_labels[i];
4526			imux->items[imux->num_items].index = idx;
4527			imux->num_items++;
4528		}
4529		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4530			idx = cfg->input_pins[i] - 0x09;
4531			err = new_analog_input(spec, cfg->input_pins[i],
4532					       auto_pin_cfg_labels[i], idx,
4533					       0x07);
4534			if (err < 0)
4535				return err;
4536			imux->items[imux->num_items].label =
4537				auto_pin_cfg_labels[i];
4538			imux->items[imux->num_items].index = idx;
4539			imux->num_items++;
4540		}
4541	}
4542	return 0;
4543}
4544
4545static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4546					      hda_nid_t nid, int pin_type,
4547					      int sel_idx)
4548{
4549	/* set as output */
4550	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4551			    pin_type);
4552	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4553			    AMP_OUT_UNMUTE);
4554	/* need the manual connection? */
4555	if (nid >= 0x12) {
4556		int idx = nid - 0x12;
4557		snd_hda_codec_write(codec, idx + 0x0b, 0,
4558				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4559	}
4560}
4561
4562static void alc260_auto_init_multi_out(struct hda_codec *codec)
4563{
4564	struct alc_spec *spec = codec->spec;
4565	hda_nid_t nid;
4566
4567	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4568	nid = spec->autocfg.line_out_pins[0];
4569	if (nid) {
4570		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4571		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4572	}
4573
4574	nid = spec->autocfg.speaker_pins[0];
4575	if (nid)
4576		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4577
4578	nid = spec->autocfg.hp_pins[0];
4579	if (nid)
4580		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4581}
4582
4583#define ALC260_PIN_CD_NID		0x16
4584static void alc260_auto_init_analog_input(struct hda_codec *codec)
4585{
4586	struct alc_spec *spec = codec->spec;
4587	int i;
4588
4589	for (i = 0; i < AUTO_PIN_LAST; i++) {
4590		hda_nid_t nid = spec->autocfg.input_pins[i];
4591		if (nid >= 0x12) {
4592			snd_hda_codec_write(codec, nid, 0,
4593					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4594					    i <= AUTO_PIN_FRONT_MIC ?
4595					    PIN_VREF80 : PIN_IN);
4596			if (nid != ALC260_PIN_CD_NID)
4597				snd_hda_codec_write(codec, nid, 0,
4598						    AC_VERB_SET_AMP_GAIN_MUTE,
4599						    AMP_OUT_MUTE);
4600		}
4601	}
4602}
4603
4604/*
4605 * generic initialization of ADC, input mixers and output mixers
4606 */
4607static struct hda_verb alc260_volume_init_verbs[] = {
4608	/*
4609	 * Unmute ADC0-1 and set the default input to mic-in
4610	 */
4611	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4612	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4613	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4614	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4615
4616	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4617	 * mixer widget
4618	 * Note: PASD motherboards uses the Line In 2 as the input for
4619	 * front panel mic (mic 2)
4620	 */
4621	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4622	/* mute analog inputs */
4623	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4624	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4625	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4626	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4627	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4628
4629	/*
4630	 * Set up output mixers (0x08 - 0x0a)
4631	 */
4632	/* set vol=0 to output mixers */
4633	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4634	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4635	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4636	/* set up input amps for analog loopback */
4637	/* Amp Indices: DAC = 0, mixer = 1 */
4638	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4639	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4640	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4641	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4642	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4643	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4644
4645	{ }
4646};
4647
4648static int alc260_parse_auto_config(struct hda_codec *codec)
4649{
4650	struct alc_spec *spec = codec->spec;
4651	unsigned int wcap;
4652	int err;
4653	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4654
4655	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4656					   alc260_ignore);
4657	if (err < 0)
4658		return err;
4659	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4660	if (err < 0)
4661		return err;
4662	if (!spec->kctl_alloc)
4663		return 0; /* can't find valid BIOS pin config */
4664	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4665	if (err < 0)
4666		return err;
4667
4668	spec->multiout.max_channels = 2;
4669
4670	if (spec->autocfg.dig_out_pin)
4671		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4672	if (spec->kctl_alloc)
4673		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4674
4675	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4676
4677	spec->num_mux_defs = 1;
4678	spec->input_mux = &spec->private_imux;
4679
4680	/* check whether NID 0x04 is valid */
4681	wcap = get_wcaps(codec, 0x04);
4682	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4683	if (wcap != AC_WID_AUD_IN) {
4684		spec->adc_nids = alc260_adc_nids_alt;
4685		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4686		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4687	} else {
4688		spec->adc_nids = alc260_adc_nids;
4689		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4690		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4691	}
4692	spec->num_mixers++;
4693
4694	return 1;
4695}
4696
4697/* additional initialization for auto-configuration model */
4698static void alc260_auto_init(struct hda_codec *codec)
4699{
4700	alc260_auto_init_multi_out(codec);
4701	alc260_auto_init_analog_input(codec);
4702}
4703
4704#ifdef CONFIG_SND_HDA_POWER_SAVE
4705static struct hda_amp_list alc260_loopbacks[] = {
4706	{ 0x07, HDA_INPUT, 0 },
4707	{ 0x07, HDA_INPUT, 1 },
4708	{ 0x07, HDA_INPUT, 2 },
4709	{ 0x07, HDA_INPUT, 3 },
4710	{ 0x07, HDA_INPUT, 4 },
4711	{ } /* end */
4712};
4713#endif
4714
4715/*
4716 * ALC260 configurations
4717 */
4718static const char *alc260_models[ALC260_MODEL_LAST] = {
4719	[ALC260_BASIC]		= "basic",
4720	[ALC260_HP]		= "hp",
4721	[ALC260_HP_3013]	= "hp-3013",
4722	[ALC260_FUJITSU_S702X]	= "fujitsu",
4723	[ALC260_ACER]		= "acer",
4724	[ALC260_WILL]		= "will",
4725	[ALC260_REPLACER_672V]	= "replacer",
4726#ifdef CONFIG_SND_DEBUG
4727	[ALC260_TEST]		= "test",
4728#endif
4729	[ALC260_AUTO]		= "auto",
4730};
4731
4732static struct snd_pci_quirk alc260_cfg_tbl[] = {
4733	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4734	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4735	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4736	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4737	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4738	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4739	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4740	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4741	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4742	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4743	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4744	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4745	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4746	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4747	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4748	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4749	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4750	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4751	{}
4752};
4753
4754static struct alc_config_preset alc260_presets[] = {
4755	[ALC260_BASIC] = {
4756		.mixers = { alc260_base_output_mixer,
4757			    alc260_input_mixer,
4758			    alc260_pc_beep_mixer,
4759			    alc260_capture_mixer },
4760		.init_verbs = { alc260_init_verbs },
4761		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4762		.dac_nids = alc260_dac_nids,
4763		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4764		.adc_nids = alc260_adc_nids,
4765		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4766		.channel_mode = alc260_modes,
4767		.input_mux = &alc260_capture_source,
4768	},
4769	[ALC260_HP] = {
4770		.mixers = { alc260_base_output_mixer,
4771			    alc260_input_mixer,
4772			    alc260_capture_alt_mixer },
4773		.init_verbs = { alc260_init_verbs },
4774		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4775		.dac_nids = alc260_dac_nids,
4776		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4777		.adc_nids = alc260_hp_adc_nids,
4778		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4779		.channel_mode = alc260_modes,
4780		.input_mux = &alc260_capture_source,
4781	},
4782	[ALC260_HP_3013] = {
4783		.mixers = { alc260_hp_3013_mixer,
4784			    alc260_input_mixer,
4785			    alc260_capture_alt_mixer },
4786		.init_verbs = { alc260_hp_3013_init_verbs },
4787		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4788		.dac_nids = alc260_dac_nids,
4789		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4790		.adc_nids = alc260_hp_adc_nids,
4791		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4792		.channel_mode = alc260_modes,
4793		.input_mux = &alc260_capture_source,
4794	},
4795	[ALC260_FUJITSU_S702X] = {
4796		.mixers = { alc260_fujitsu_mixer,
4797			    alc260_capture_mixer },
4798		.init_verbs = { alc260_fujitsu_init_verbs },
4799		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4800		.dac_nids = alc260_dac_nids,
4801		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4802		.adc_nids = alc260_dual_adc_nids,
4803		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4804		.channel_mode = alc260_modes,
4805		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4806		.input_mux = alc260_fujitsu_capture_sources,
4807	},
4808	[ALC260_ACER] = {
4809		.mixers = { alc260_acer_mixer,
4810			    alc260_capture_mixer },
4811		.init_verbs = { alc260_acer_init_verbs },
4812		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4813		.dac_nids = alc260_dac_nids,
4814		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4815		.adc_nids = alc260_dual_adc_nids,
4816		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4817		.channel_mode = alc260_modes,
4818		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4819		.input_mux = alc260_acer_capture_sources,
4820	},
4821	[ALC260_WILL] = {
4822		.mixers = { alc260_will_mixer,
4823			    alc260_capture_mixer },
4824		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4825		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4826		.dac_nids = alc260_dac_nids,
4827		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4828		.adc_nids = alc260_adc_nids,
4829		.dig_out_nid = ALC260_DIGOUT_NID,
4830		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4831		.channel_mode = alc260_modes,
4832		.input_mux = &alc260_capture_source,
4833	},
4834	[ALC260_REPLACER_672V] = {
4835		.mixers = { alc260_replacer_672v_mixer,
4836			    alc260_capture_mixer },
4837		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4838		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4839		.dac_nids = alc260_dac_nids,
4840		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4841		.adc_nids = alc260_adc_nids,
4842		.dig_out_nid = ALC260_DIGOUT_NID,
4843		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4844		.channel_mode = alc260_modes,
4845		.input_mux = &alc260_capture_source,
4846		.unsol_event = alc260_replacer_672v_unsol_event,
4847		.init_hook = alc260_replacer_672v_automute,
4848	},
4849#ifdef CONFIG_SND_DEBUG
4850	[ALC260_TEST] = {
4851		.mixers = { alc260_test_mixer,
4852			    alc260_capture_mixer },
4853		.init_verbs = { alc260_test_init_verbs },
4854		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4855		.dac_nids = alc260_test_dac_nids,
4856		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4857		.adc_nids = alc260_test_adc_nids,
4858		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4859		.channel_mode = alc260_modes,
4860		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4861		.input_mux = alc260_test_capture_sources,
4862	},
4863#endif
4864};
4865
4866static int patch_alc260(struct hda_codec *codec)
4867{
4868	struct alc_spec *spec;
4869	int err, board_config;
4870
4871	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4872	if (spec == NULL)
4873		return -ENOMEM;
4874
4875	codec->spec = spec;
4876
4877	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4878						  alc260_models,
4879						  alc260_cfg_tbl);
4880	if (board_config < 0) {
4881		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4882			   "trying auto-probe from BIOS...\n");
4883		board_config = ALC260_AUTO;
4884	}
4885
4886	if (board_config == ALC260_AUTO) {
4887		/* automatic parse from the BIOS config */
4888		err = alc260_parse_auto_config(codec);
4889		if (err < 0) {
4890			alc_free(codec);
4891			return err;
4892		} else if (!err) {
4893			printk(KERN_INFO
4894			       "hda_codec: Cannot set up configuration "
4895			       "from BIOS.  Using base mode...\n");
4896			board_config = ALC260_BASIC;
4897		}
4898	}
4899
4900	if (board_config != ALC260_AUTO)
4901		setup_preset(spec, &alc260_presets[board_config]);
4902
4903	spec->stream_name_analog = "ALC260 Analog";
4904	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4905	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4906
4907	spec->stream_name_digital = "ALC260 Digital";
4908	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4909	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4910
4911	codec->patch_ops = alc_patch_ops;
4912	if (board_config == ALC260_AUTO)
4913		spec->init_hook = alc260_auto_init;
4914#ifdef CONFIG_SND_HDA_POWER_SAVE
4915	if (!spec->loopback.amplist)
4916		spec->loopback.amplist = alc260_loopbacks;
4917#endif
4918
4919	return 0;
4920}
4921
4922
4923/*
4924 * ALC882 support
4925 *
4926 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4927 * configuration.  Each pin widget can choose any input DACs and a mixer.
4928 * Each ADC is connected from a mixer of all inputs.  This makes possible
4929 * 6-channel independent captures.
4930 *
4931 * In addition, an independent DAC for the multi-playback (not used in this
4932 * driver yet).
4933 */
4934#define ALC882_DIGOUT_NID	0x06
4935#define ALC882_DIGIN_NID	0x0a
4936
4937static struct hda_channel_mode alc882_ch_modes[1] = {
4938	{ 8, NULL }
4939};
4940
4941static hda_nid_t alc882_dac_nids[4] = {
4942	/* front, rear, clfe, rear_surr */
4943	0x02, 0x03, 0x04, 0x05
4944};
4945
4946/* identical with ALC880 */
4947#define alc882_adc_nids		alc880_adc_nids
4948#define alc882_adc_nids_alt	alc880_adc_nids_alt
4949
4950/* input MUX */
4951/* FIXME: should be a matrix-type input source selection */
4952
4953static struct hda_input_mux alc882_capture_source = {
4954	.num_items = 4,
4955	.items = {
4956		{ "Mic", 0x0 },
4957		{ "Front Mic", 0x1 },
4958		{ "Line", 0x2 },
4959		{ "CD", 0x4 },
4960	},
4961};
4962#define alc882_mux_enum_info alc_mux_enum_info
4963#define alc882_mux_enum_get alc_mux_enum_get
4964
4965static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4966			       struct snd_ctl_elem_value *ucontrol)
4967{
4968	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4969	struct alc_spec *spec = codec->spec;
4970	const struct hda_input_mux *imux = spec->input_mux;
4971	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4972	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4973	hda_nid_t nid = capture_mixers[adc_idx];
4974	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4975	unsigned int i, idx;
4976
4977	idx = ucontrol->value.enumerated.item[0];
4978	if (idx >= imux->num_items)
4979		idx = imux->num_items - 1;
4980	if (*cur_val == idx)
4981		return 0;
4982	for (i = 0; i < imux->num_items; i++) {
4983		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4984		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4985					 imux->items[i].index,
4986					 HDA_AMP_MUTE, v);
4987	}
4988	*cur_val = idx;
4989	return 1;
4990}
4991
4992/*
4993 * 2ch mode
4994 */
4995static struct hda_verb alc882_3ST_ch2_init[] = {
4996	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4997	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4998	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4999	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5000	{ } /* end */
5001};
5002
5003/*
5004 * 6ch mode
5005 */
5006static struct hda_verb alc882_3ST_ch6_init[] = {
5007	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5008	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5009	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5010	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5011	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5012	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5013	{ } /* end */
5014};
5015
5016static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5017	{ 2, alc882_3ST_ch2_init },
5018	{ 6, alc882_3ST_ch6_init },
5019};
5020
5021/*
5022 * 6ch mode
5023 */
5024static struct hda_verb alc882_sixstack_ch6_init[] = {
5025	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5026	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5027	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5028	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5029	{ } /* end */
5030};
5031
5032/*
5033 * 8ch mode
5034 */
5035static struct hda_verb alc882_sixstack_ch8_init[] = {
5036	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5037	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5038	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5039	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5040	{ } /* end */
5041};
5042
5043static struct hda_channel_mode alc882_sixstack_modes[2] = {
5044	{ 6, alc882_sixstack_ch6_init },
5045	{ 8, alc882_sixstack_ch8_init },
5046};
5047
5048/*
5049 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5050 */
5051
5052/*
5053 * 2ch mode
5054 */
5055static struct hda_verb alc885_mbp_ch2_init[] = {
5056	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5057	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5058	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5059	{ } /* end */
5060};
5061
5062/*
5063 * 6ch mode
5064 */
5065static struct hda_verb alc885_mbp_ch6_init[] = {
5066	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5067	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5068	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5069	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5070	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5071	{ } /* end */
5072};
5073
5074static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5075	{ 2, alc885_mbp_ch2_init },
5076	{ 6, alc885_mbp_ch6_init },
5077};
5078
5079
5080/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5081 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5082 */
5083static struct snd_kcontrol_new alc882_base_mixer[] = {
5084	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5085	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5086	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5087	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5088	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5089	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5090	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5091	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5092	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5093	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5094	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5095	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5096	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5097	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5098	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5099	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5100	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5101	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5102	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5103	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5104	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5105	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5106	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5107	{ } /* end */
5108};
5109
5110static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5111	HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5112	HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5113	HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5114	HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5115	HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5116	HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5117	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5118	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5119	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5120	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5121	{ } /* end */
5122};
5123static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5124	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5125	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5126	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5127	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5128	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5129	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5130	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5131	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5132	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5133	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5134	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5135	{ } /* end */
5136};
5137
5138static struct snd_kcontrol_new alc882_targa_mixer[] = {
5139	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5140	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5141	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5142	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5143	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5144	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5145	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5146	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5147	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5148	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5149	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5150	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5151	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5152	{ } /* end */
5153};
5154
5155/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5156 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5157 */
5158static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5159	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5160	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5161	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5162	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5163	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5164	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5165	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5166	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5167	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5168	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5169	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5170	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5171	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5172	{ } /* end */
5173};
5174
5175static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5176	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5177	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5178	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5179	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5180	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5181	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5182	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5183	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5184	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5185	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5186	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5187	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5188	{ } /* end */
5189};
5190
5191static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5192	{
5193		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5194		.name = "Channel Mode",
5195		.info = alc_ch_mode_info,
5196		.get = alc_ch_mode_get,
5197		.put = alc_ch_mode_put,
5198	},
5199	{ } /* end */
5200};
5201
5202static struct hda_verb alc882_init_verbs[] = {
5203	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5204	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5205	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5206	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5207	/* Rear mixer */
5208	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5209	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5210	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5211	/* CLFE mixer */
5212	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5213	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5214	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5215	/* Side mixer */
5216	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5217	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5218	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5219
5220	/* Front Pin: output 0 (0x0c) */
5221	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5222	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5223	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5224	/* Rear Pin: output 1 (0x0d) */
5225	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5226	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5227	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5228	/* CLFE Pin: output 2 (0x0e) */
5229	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5230	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5231	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5232	/* Side Pin: output 3 (0x0f) */
5233	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5234	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5235	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5236	/* Mic (rear) pin: input vref at 80% */
5237	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5238	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5239	/* Front Mic pin: input vref at 80% */
5240	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5241	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5242	/* Line In pin: input */
5243	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5244	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5245	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5246	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5247	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5248	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5249	/* CD pin widget for input */
5250	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5251
5252	/* FIXME: use matrix-type input source selection */
5253	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5254	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5255	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5256	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5257	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5258	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5259	/* Input mixer2 */
5260	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5261	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5262	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5263	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5264	/* Input mixer3 */
5265	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5266	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5267	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5268	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5269	/* ADC1: mute amp left and right */
5270	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5271	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5272	/* ADC2: mute amp left and right */
5273	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5274	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5275	/* ADC3: mute amp left and right */
5276	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5277	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5278
5279	{ }
5280};
5281
5282static struct hda_verb alc882_eapd_verbs[] = {
5283	/* change to EAPD mode */
5284	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5285	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5286	{ }
5287};
5288
5289/* Mac Pro test */
5290static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5291	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5292	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5293	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5294	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5295	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5296	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5297	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5298	{ } /* end */
5299};
5300
5301static struct hda_verb alc882_macpro_init_verbs[] = {
5302	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5303	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5304	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5305	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5306	/* Front Pin: output 0 (0x0c) */
5307	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5308	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5309	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5310	/* Front Mic pin: input vref at 80% */
5311	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5312	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5313	/* Speaker:  output */
5314	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5315	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5316	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5317	/* Headphone output (output 0 - 0x0c) */
5318	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5319	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5320	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5321
5322	/* FIXME: use matrix-type input source selection */
5323	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5324	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5325	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5326	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5327	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5328	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5329	/* Input mixer2 */
5330	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5331	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5332	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5333	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5334	/* Input mixer3 */
5335	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5336	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5337	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5338	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5339	/* ADC1: mute amp left and right */
5340	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5341	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5342	/* ADC2: mute amp left and right */
5343	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5344	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5345	/* ADC3: mute amp left and right */
5346	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5347	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5348
5349	{ }
5350};
5351
5352/* Macbook Pro rev3 */
5353static struct hda_verb alc885_mbp3_init_verbs[] = {
5354	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5355	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5356	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5357	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5358	/* Rear mixer */
5359	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5360	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5361	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5362	/* Front Pin: output 0 (0x0c) */
5363	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5364	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5365	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5366	/* HP Pin: output 0 (0x0d) */
5367	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5368	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5369	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5370	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5371	/* Mic (rear) pin: input vref at 80% */
5372	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5373	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5374	/* Front Mic pin: input vref at 80% */
5375	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5376	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5377	/* Line In pin: use output 1 when in LineOut mode */
5378	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5379	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5380	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5381
5382	/* FIXME: use matrix-type input source selection */
5383	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5384	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5385	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5386	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5387	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5388	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5389	/* Input mixer2 */
5390	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5391	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5392	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5393	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5394	/* Input mixer3 */
5395	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5396	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5397	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5398	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5399	/* ADC1: mute amp left and right */
5400	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5401	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5402	/* ADC2: mute amp left and right */
5403	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5404	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5405	/* ADC3: mute amp left and right */
5406	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5407	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5408
5409	{ }
5410};
5411
5412/* iMac 24 mixer. */
5413static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5414	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5415	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5416	{ } /* end */
5417};
5418
5419/* iMac 24 init verbs. */
5420static struct hda_verb alc885_imac24_init_verbs[] = {
5421	/* Internal speakers: output 0 (0x0c) */
5422	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5423	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5424	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5425	/* Internal speakers: output 0 (0x0c) */
5426	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5427	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5428	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5429	/* Headphone: output 0 (0x0c) */
5430	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5431	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5432	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5433	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5434	/* Front Mic: input vref at 80% */
5435	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5436	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5437	{ }
5438};
5439
5440/* Toggle speaker-output according to the hp-jack state */
5441static void alc885_imac24_automute(struct hda_codec *codec)
5442{
5443 	unsigned int present;
5444
5445 	present = snd_hda_codec_read(codec, 0x14, 0,
5446				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5447	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5448				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5449	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5450				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5451}
5452
5453/* Processes unsolicited events. */
5454static void alc885_imac24_unsol_event(struct hda_codec *codec,
5455				      unsigned int res)
5456{
5457	/* Headphone insertion or removal. */
5458	if ((res >> 26) == ALC880_HP_EVENT)
5459		alc885_imac24_automute(codec);
5460}
5461
5462static void alc885_mbp3_automute(struct hda_codec *codec)
5463{
5464 	unsigned int present;
5465
5466 	present = snd_hda_codec_read(codec, 0x15, 0,
5467				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5468	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5469				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5470	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5471				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5472
5473}
5474static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5475				    unsigned int res)
5476{
5477	/* Headphone insertion or removal. */
5478	if ((res >> 26) == ALC880_HP_EVENT)
5479		alc885_mbp3_automute(codec);
5480}
5481
5482
5483static struct hda_verb alc882_targa_verbs[] = {
5484	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5485	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5486
5487	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5488	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5489
5490	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5491	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5492	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5493
5494	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5495	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5496	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5497	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5498	{ } /* end */
5499};
5500
5501/* toggle speaker-output according to the hp-jack state */
5502static void alc882_targa_automute(struct hda_codec *codec)
5503{
5504 	unsigned int present;
5505
5506 	present = snd_hda_codec_read(codec, 0x14, 0,
5507				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5508	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5509				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5510	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5511				  present ? 1 : 3);
5512}
5513
5514static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5515{
5516	/* Looks like the unsol event is incompatible with the standard
5517	 * definition.  4bit tag is placed at 26 bit!
5518	 */
5519	if (((res >> 26) == ALC880_HP_EVENT)) {
5520		alc882_targa_automute(codec);
5521	}
5522}
5523
5524static struct hda_verb alc882_asus_a7j_verbs[] = {
5525	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5526	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5527
5528	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5529	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5530	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5531
5532	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5533	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5534	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5535
5536	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5537	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5538	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5539	{ } /* end */
5540};
5541
5542static struct hda_verb alc882_asus_a7m_verbs[] = {
5543	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5544	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5545
5546	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5547	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5548	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5549
5550	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5551	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5552	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5553
5554	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5555	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5556	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5557 	{ } /* end */
5558};
5559
5560static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5561{
5562	unsigned int gpiostate, gpiomask, gpiodir;
5563
5564	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5565				       AC_VERB_GET_GPIO_DATA, 0);
5566
5567	if (!muted)
5568		gpiostate |= (1 << pin);
5569	else
5570		gpiostate &= ~(1 << pin);
5571
5572	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5573				      AC_VERB_GET_GPIO_MASK, 0);
5574	gpiomask |= (1 << pin);
5575
5576	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5577				     AC_VERB_GET_GPIO_DIRECTION, 0);
5578	gpiodir |= (1 << pin);
5579
5580
5581	snd_hda_codec_write(codec, codec->afg, 0,
5582			    AC_VERB_SET_GPIO_MASK, gpiomask);
5583	snd_hda_codec_write(codec, codec->afg, 0,
5584			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5585
5586	msleep(1);
5587
5588	snd_hda_codec_write(codec, codec->afg, 0,
5589			    AC_VERB_SET_GPIO_DATA, gpiostate);
5590}
5591
5592/* set up GPIO at initialization */
5593static void alc885_macpro_init_hook(struct hda_codec *codec)
5594{
5595	alc882_gpio_mute(codec, 0, 0);
5596	alc882_gpio_mute(codec, 1, 0);
5597}
5598
5599/* set up GPIO and update auto-muting at initialization */
5600static void alc885_imac24_init_hook(struct hda_codec *codec)
5601{
5602	alc885_macpro_init_hook(codec);
5603	alc885_imac24_automute(codec);
5604}
5605
5606/*
5607 * generic initialization of ADC, input mixers and output mixers
5608 */
5609static struct hda_verb alc882_auto_init_verbs[] = {
5610	/*
5611	 * Unmute ADC0-2 and set the default input to mic-in
5612	 */
5613	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5614	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5615	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5616	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5617	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5618	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5619
5620	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5621	 * mixer widget
5622	 * Note: PASD motherboards uses the Line In 2 as the input for
5623	 * front panel mic (mic 2)
5624	 */
5625	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5626	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5627	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5628	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5629	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5630	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5631
5632	/*
5633	 * Set up output mixers (0x0c - 0x0f)
5634	 */
5635	/* set vol=0 to output mixers */
5636	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5637	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5638	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5639	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5640	/* set up input amps for analog loopback */
5641	/* Amp Indices: DAC = 0, mixer = 1 */
5642	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5643	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5644	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5645	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5646	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5647	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5648	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5649	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5650	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5651	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5652
5653	/* FIXME: use matrix-type input source selection */
5654	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5655	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5656	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5657	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5658	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5659	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5660	/* Input mixer2 */
5661	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5662	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5663	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5664	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5665	/* Input mixer3 */
5666	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5667	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5668	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5669	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5670
5671	{ }
5672};
5673
5674/* capture mixer elements */
5675static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5676	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5677	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5678	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5679	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5680	{
5681		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5682		/* The multiple "Capture Source" controls confuse alsamixer
5683		 * So call somewhat different..
5684		 * FIXME: the controls appear in the "playback" view!
5685		 */
5686		/* .name = "Capture Source", */
5687		.name = "Input Source",
5688		.count = 2,
5689		.info = alc882_mux_enum_info,
5690		.get = alc882_mux_enum_get,
5691		.put = alc882_mux_enum_put,
5692	},
5693	{ } /* end */
5694};
5695
5696static struct snd_kcontrol_new alc882_capture_mixer[] = {
5697	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5698	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5699	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5700	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5701	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5702	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5703	{
5704		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5705		/* The multiple "Capture Source" controls confuse alsamixer
5706		 * So call somewhat different..
5707		 * FIXME: the controls appear in the "playback" view!
5708		 */
5709		/* .name = "Capture Source", */
5710		.name = "Input Source",
5711		.count = 3,
5712		.info = alc882_mux_enum_info,
5713		.get = alc882_mux_enum_get,
5714		.put = alc882_mux_enum_put,
5715	},
5716	{ } /* end */
5717};
5718
5719#ifdef CONFIG_SND_HDA_POWER_SAVE
5720#define alc882_loopbacks	alc880_loopbacks
5721#endif
5722
5723/* pcm configuration: identiacal with ALC880 */
5724#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5725#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5726#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5727#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5728
5729/*
5730 * configuration and preset
5731 */
5732static const char *alc882_models[ALC882_MODEL_LAST] = {
5733	[ALC882_3ST_DIG]	= "3stack-dig",
5734	[ALC882_6ST_DIG]	= "6stack-dig",
5735	[ALC882_ARIMA]		= "arima",
5736	[ALC882_W2JC]		= "w2jc",
5737	[ALC882_TARGA]		= "targa",
5738	[ALC882_ASUS_A7J]	= "asus-a7j",
5739	[ALC882_ASUS_A7M]	= "asus-a7m",
5740	[ALC885_MACPRO]		= "macpro",
5741	[ALC885_MBP3]		= "mbp3",
5742	[ALC885_IMAC24]		= "imac24",
5743	[ALC882_AUTO]		= "auto",
5744};
5745
5746static struct snd_pci_quirk alc882_cfg_tbl[] = {
5747	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5748	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5749	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5750	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5751	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5752	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5753	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5754	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5755	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5756	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5757	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5758	{}
5759};
5760
5761static struct alc_config_preset alc882_presets[] = {
5762	[ALC882_3ST_DIG] = {
5763		.mixers = { alc882_base_mixer },
5764		.init_verbs = { alc882_init_verbs },
5765		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5766		.dac_nids = alc882_dac_nids,
5767		.dig_out_nid = ALC882_DIGOUT_NID,
5768		.dig_in_nid = ALC882_DIGIN_NID,
5769		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5770		.channel_mode = alc882_ch_modes,
5771		.need_dac_fix = 1,
5772		.input_mux = &alc882_capture_source,
5773	},
5774	[ALC882_6ST_DIG] = {
5775		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5776		.init_verbs = { alc882_init_verbs },
5777		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5778		.dac_nids = alc882_dac_nids,
5779		.dig_out_nid = ALC882_DIGOUT_NID,
5780		.dig_in_nid = ALC882_DIGIN_NID,
5781		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5782		.channel_mode = alc882_sixstack_modes,
5783		.input_mux = &alc882_capture_source,
5784	},
5785	[ALC882_ARIMA] = {
5786		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5787		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5788		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5789		.dac_nids = alc882_dac_nids,
5790		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5791		.channel_mode = alc882_sixstack_modes,
5792		.input_mux = &alc882_capture_source,
5793	},
5794	[ALC882_W2JC] = {
5795		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5796		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5797				alc880_gpio1_init_verbs },
5798		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5799		.dac_nids = alc882_dac_nids,
5800		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5801		.channel_mode = alc880_threestack_modes,
5802		.need_dac_fix = 1,
5803		.input_mux = &alc882_capture_source,
5804		.dig_out_nid = ALC882_DIGOUT_NID,
5805	},
5806	[ALC885_MBP3] = {
5807		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5808		.init_verbs = { alc885_mbp3_init_verbs,
5809				alc880_gpio1_init_verbs },
5810		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5811		.dac_nids = alc882_dac_nids,
5812		.channel_mode = alc885_mbp_6ch_modes,
5813		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5814		.input_mux = &alc882_capture_source,
5815		.dig_out_nid = ALC882_DIGOUT_NID,
5816		.dig_in_nid = ALC882_DIGIN_NID,
5817		.unsol_event = alc885_mbp3_unsol_event,
5818		.init_hook = alc885_mbp3_automute,
5819	},
5820	[ALC885_MACPRO] = {
5821		.mixers = { alc882_macpro_mixer },
5822		.init_verbs = { alc882_macpro_init_verbs },
5823		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5824		.dac_nids = alc882_dac_nids,
5825		.dig_out_nid = ALC882_DIGOUT_NID,
5826		.dig_in_nid = ALC882_DIGIN_NID,
5827		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5828		.channel_mode = alc882_ch_modes,
5829		.input_mux = &alc882_capture_source,
5830		.init_hook = alc885_macpro_init_hook,
5831	},
5832	[ALC885_IMAC24] = {
5833		.mixers = { alc885_imac24_mixer },
5834		.init_verbs = { alc885_imac24_init_verbs },
5835		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5836		.dac_nids = alc882_dac_nids,
5837		.dig_out_nid = ALC882_DIGOUT_NID,
5838		.dig_in_nid = ALC882_DIGIN_NID,
5839		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5840		.channel_mode = alc882_ch_modes,
5841		.input_mux = &alc882_capture_source,
5842		.unsol_event = alc885_imac24_unsol_event,
5843		.init_hook = alc885_imac24_init_hook,
5844	},
5845	[ALC882_TARGA] = {
5846		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5847			    alc882_capture_mixer },
5848		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5849		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5850		.dac_nids = alc882_dac_nids,
5851		.dig_out_nid = ALC882_DIGOUT_NID,
5852		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5853		.adc_nids = alc882_adc_nids,
5854		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5855		.channel_mode = alc882_3ST_6ch_modes,
5856		.need_dac_fix = 1,
5857		.input_mux = &alc882_capture_source,
5858		.unsol_event = alc882_targa_unsol_event,
5859		.init_hook = alc882_targa_automute,
5860	},
5861	[ALC882_ASUS_A7J] = {
5862		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5863			    alc882_capture_mixer },
5864		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5865		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5866		.dac_nids = alc882_dac_nids,
5867		.dig_out_nid = ALC882_DIGOUT_NID,
5868		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5869		.adc_nids = alc882_adc_nids,
5870		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5871		.channel_mode = alc882_3ST_6ch_modes,
5872		.need_dac_fix = 1,
5873		.input_mux = &alc882_capture_source,
5874	},
5875	[ALC882_ASUS_A7M] = {
5876		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5877		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5878				alc880_gpio1_init_verbs,
5879				alc882_asus_a7m_verbs },
5880		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5881		.dac_nids = alc882_dac_nids,
5882		.dig_out_nid = ALC882_DIGOUT_NID,
5883		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5884		.channel_mode = alc880_threestack_modes,
5885		.need_dac_fix = 1,
5886		.input_mux = &alc882_capture_source,
5887	},
5888};
5889
5890
5891/*
5892 * Pin config fixes
5893 */
5894enum {
5895	PINFIX_ABIT_AW9D_MAX
5896};
5897
5898static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5899	{ 0x15, 0x01080104 }, /* side */
5900	{ 0x16, 0x01011012 }, /* rear */
5901	{ 0x17, 0x01016011 }, /* clfe */
5902	{ }
5903};
5904
5905static const struct alc_pincfg *alc882_pin_fixes[] = {
5906	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5907};
5908
5909static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5910	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5911	{}
5912};
5913
5914/*
5915 * BIOS auto configuration
5916 */
5917static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5918					      hda_nid_t nid, int pin_type,
5919					      int dac_idx)
5920{
5921	/* set as output */
5922	struct alc_spec *spec = codec->spec;
5923	int idx;
5924
5925	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5926		idx = 4;
5927	else
5928		idx = spec->multiout.dac_nids[dac_idx] - 2;
5929
5930	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5931			    pin_type);
5932	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5933			    AMP_OUT_UNMUTE);
5934	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5935
5936}
5937
5938static void alc882_auto_init_multi_out(struct hda_codec *codec)
5939{
5940	struct alc_spec *spec = codec->spec;
5941	int i;
5942
5943	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5944	for (i = 0; i <= HDA_SIDE; i++) {
5945		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5946		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5947		if (nid)
5948			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5949							  i);
5950	}
5951}
5952
5953static void alc882_auto_init_hp_out(struct hda_codec *codec)
5954{
5955	struct alc_spec *spec = codec->spec;
5956	hda_nid_t pin;
5957
5958	pin = spec->autocfg.hp_pins[0];
5959	if (pin) /* connect to front */
5960		/* use dac 0 */
5961		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5962}
5963
5964#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
5965#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
5966
5967static void alc882_auto_init_analog_input(struct hda_codec *codec)
5968{
5969	struct alc_spec *spec = codec->spec;
5970	int i;
5971
5972	for (i = 0; i < AUTO_PIN_LAST; i++) {
5973		hda_nid_t nid = spec->autocfg.input_pins[i];
5974		if (alc882_is_input_pin(nid)) {
5975			snd_hda_codec_write(codec, nid, 0,
5976					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5977					    i <= AUTO_PIN_FRONT_MIC ?
5978					    PIN_VREF80 : PIN_IN);
5979			if (nid != ALC882_PIN_CD_NID)
5980				snd_hda_codec_write(codec, nid, 0,
5981						    AC_VERB_SET_AMP_GAIN_MUTE,
5982						    AMP_OUT_MUTE);
5983		}
5984	}
5985}
5986
5987/* add mic boosts if needed */
5988static int alc_auto_add_mic_boost(struct hda_codec *codec)
5989{
5990	struct alc_spec *spec = codec->spec;
5991	int err;
5992	hda_nid_t nid;
5993
5994	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
5995	if (nid) {
5996		err = add_control(spec, ALC_CTL_WIDGET_VOL,
5997				  "Mic Boost",
5998				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
5999		if (err < 0)
6000			return err;
6001	}
6002	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6003	if (nid) {
6004		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6005				  "Front Mic Boost",
6006				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6007		if (err < 0)
6008			return err;
6009	}
6010	return 0;
6011}
6012
6013/* almost identical with ALC880 parser... */
6014static int alc882_parse_auto_config(struct hda_codec *codec)
6015{
6016	struct alc_spec *spec = codec->spec;
6017	int err = alc880_parse_auto_config(codec);
6018
6019	if (err < 0)
6020		return err;
6021	else if (!err)
6022		return 0; /* no config found */
6023
6024	err = alc_auto_add_mic_boost(codec);
6025	if (err < 0)
6026		return err;
6027
6028	/* hack - override the init verbs */
6029	spec->init_verbs[0] = alc882_auto_init_verbs;
6030
6031	return 1; /* config found */
6032}
6033
6034/* additional initialization for auto-configuration model */
6035static void alc882_auto_init(struct hda_codec *codec)
6036{
6037	alc882_auto_init_multi_out(codec);
6038	alc882_auto_init_hp_out(codec);
6039	alc882_auto_init_analog_input(codec);
6040}
6041
6042static int patch_alc882(struct hda_codec *codec)
6043{
6044	struct alc_spec *spec;
6045	int err, board_config;
6046
6047	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6048	if (spec == NULL)
6049		return -ENOMEM;
6050
6051	codec->spec = spec;
6052
6053	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6054						  alc882_models,
6055						  alc882_cfg_tbl);
6056
6057	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6058		/* Pick up systems that don't supply PCI SSID */
6059		switch (codec->subsystem_id) {
6060		case 0x106b0c00: /* Mac Pro */
6061			board_config = ALC885_MACPRO;
6062			break;
6063		case 0x106b1000: /* iMac 24 */
6064			board_config = ALC885_IMAC24;
6065			break;
6066		case 0x106b2c00: /* Macbook Pro rev3 */
6067			board_config = ALC885_MBP3;
6068			break;
6069		default:
6070			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6071		       			 "trying auto-probe from BIOS...\n");
6072			board_config = ALC882_AUTO;
6073		}
6074	}
6075
6076	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6077
6078	if (board_config == ALC882_AUTO) {
6079		/* automatic parse from the BIOS config */
6080		err = alc882_parse_auto_config(codec);
6081		if (err < 0) {
6082			alc_free(codec);
6083			return err;
6084		} else if (!err) {
6085			printk(KERN_INFO
6086			       "hda_codec: Cannot set up configuration "
6087			       "from BIOS.  Using base mode...\n");
6088			board_config = ALC882_3ST_DIG;
6089		}
6090	}
6091
6092	if (board_config != ALC882_AUTO)
6093		setup_preset(spec, &alc882_presets[board_config]);
6094
6095	spec->stream_name_analog = "ALC882 Analog";
6096	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6097	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6098
6099	spec->stream_name_digital = "ALC882 Digital";
6100	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6101	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6102
6103	if (!spec->adc_nids && spec->input_mux) {
6104		/* check whether NID 0x07 is valid */
6105		unsigned int wcap = get_wcaps(codec, 0x07);
6106		/* get type */
6107		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6108		if (wcap != AC_WID_AUD_IN) {
6109			spec->adc_nids = alc882_adc_nids_alt;
6110			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6111			spec->mixers[spec->num_mixers] =
6112				alc882_capture_alt_mixer;
6113			spec->num_mixers++;
6114		} else {
6115			spec->adc_nids = alc882_adc_nids;
6116			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6117			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6118			spec->num_mixers++;
6119		}
6120	}
6121
6122	codec->patch_ops = alc_patch_ops;
6123	if (board_config == ALC882_AUTO)
6124		spec->init_hook = alc882_auto_init;
6125#ifdef CONFIG_SND_HDA_POWER_SAVE
6126	if (!spec->loopback.amplist)
6127		spec->loopback.amplist = alc882_loopbacks;
6128#endif
6129
6130	return 0;
6131}
6132
6133/*
6134 * ALC883 support
6135 *
6136 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6137 * configuration.  Each pin widget can choose any input DACs and a mixer.
6138 * Each ADC is connected from a mixer of all inputs.  This makes possible
6139 * 6-channel independent captures.
6140 *
6141 * In addition, an independent DAC for the multi-playback (not used in this
6142 * driver yet).
6143 */
6144#define ALC883_DIGOUT_NID	0x06
6145#define ALC883_DIGIN_NID	0x0a
6146
6147static hda_nid_t alc883_dac_nids[4] = {
6148	/* front, rear, clfe, rear_surr */
6149	0x02, 0x04, 0x03, 0x05
6150};
6151
6152static hda_nid_t alc883_adc_nids[2] = {
6153	/* ADC1-2 */
6154	0x08, 0x09,
6155};
6156
6157/* input MUX */
6158/* FIXME: should be a matrix-type input source selection */
6159
6160static struct hda_input_mux alc883_capture_source = {
6161	.num_items = 4,
6162	.items = {
6163		{ "Mic", 0x0 },
6164		{ "Front Mic", 0x1 },
6165		{ "Line", 0x2 },
6166		{ "CD", 0x4 },
6167	},
6168};
6169
6170static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6171	.num_items = 2,
6172	.items = {
6173		{ "Mic", 0x1 },
6174		{ "Line", 0x2 },
6175	},
6176};
6177
6178static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6179	.num_items = 4,
6180	.items = {
6181		{ "Mic", 0x0 },
6182		{ "iMic", 0x1 },
6183		{ "Line", 0x2 },
6184		{ "CD", 0x4 },
6185	},
6186};
6187
6188#define alc883_mux_enum_info alc_mux_enum_info
6189#define alc883_mux_enum_get alc_mux_enum_get
6190
6191static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6192			       struct snd_ctl_elem_value *ucontrol)
6193{
6194	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6195	struct alc_spec *spec = codec->spec;
6196	const struct hda_input_mux *imux = spec->input_mux;
6197	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6198	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6199	hda_nid_t nid = capture_mixers[adc_idx];
6200	unsigned int *cur_val = &spec->cur_mux[adc_idx];
6201	unsigned int i, idx;
6202
6203	idx = ucontrol->value.enumerated.item[0];
6204	if (idx >= imux->num_items)
6205		idx = imux->num_items - 1;
6206	if (*cur_val == idx)
6207		return 0;
6208	for (i = 0; i < imux->num_items; i++) {
6209		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6210		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6211					 imux->items[i].index,
6212					 HDA_AMP_MUTE, v);
6213	}
6214	*cur_val = idx;
6215	return 1;
6216}
6217
6218/*
6219 * 2ch mode
6220 */
6221static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6222	{ 2, NULL }
6223};
6224
6225/*
6226 * 2ch mode
6227 */
6228static struct hda_verb alc883_3ST_ch2_init[] = {
6229	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6230	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6231	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6232	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6233	{ } /* end */
6234};
6235
6236/*
6237 * 4ch mode
6238 */
6239static struct hda_verb alc883_3ST_ch4_init[] = {
6240	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6241	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6242	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6243	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6244	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6245	{ } /* end */
6246};
6247
6248/*
6249 * 6ch mode
6250 */
6251static struct hda_verb alc883_3ST_ch6_init[] = {
6252	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6253	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6254	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6255	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6256	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6257	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6258	{ } /* end */
6259};
6260
6261static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6262	{ 2, alc883_3ST_ch2_init },
6263	{ 4, alc883_3ST_ch4_init },
6264	{ 6, alc883_3ST_ch6_init },
6265};
6266
6267/*
6268 * 6ch mode
6269 */
6270static struct hda_verb alc883_sixstack_ch6_init[] = {
6271	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6272	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6273	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6274	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6275	{ } /* end */
6276};
6277
6278/*
6279 * 8ch mode
6280 */
6281static struct hda_verb alc883_sixstack_ch8_init[] = {
6282	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6283	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6284	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6285	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6286	{ } /* end */
6287};
6288
6289static struct hda_channel_mode alc883_sixstack_modes[2] = {
6290	{ 6, alc883_sixstack_ch6_init },
6291	{ 8, alc883_sixstack_ch8_init },
6292};
6293
6294static struct hda_verb alc883_medion_eapd_verbs[] = {
6295        /* eanable EAPD on medion laptop */
6296	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6297	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6298	{ }
6299};
6300
6301/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6302 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6303 */
6304
6305static struct snd_kcontrol_new alc883_base_mixer[] = {
6306	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6307	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6308	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6309	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6310	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6311	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6312	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6313	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6314	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6315	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6316	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6317	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6318	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6319	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6320	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6321	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6322	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6323	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6324	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6325	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6326	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6327	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6328	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6329	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6330	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6331	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6332	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6333	{
6334		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6335		/* .name = "Capture Source", */
6336		.name = "Input Source",
6337		.count = 2,
6338		.info = alc883_mux_enum_info,
6339		.get = alc883_mux_enum_get,
6340		.put = alc883_mux_enum_put,
6341	},
6342	{ } /* end */
6343};
6344
6345static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6346	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6347	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6348	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6349	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6350	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6351	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6352	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6353	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6354	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6355	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6356	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6357	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6358	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6359	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6360	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6361	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6362	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6363	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6364	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6365	{
6366		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6367		/* .name = "Capture Source", */
6368		.name = "Input Source",
6369		.count = 2,
6370		.info = alc883_mux_enum_info,
6371		.get = alc883_mux_enum_get,
6372		.put = alc883_mux_enum_put,
6373	},
6374	{ } /* end */
6375};
6376
6377static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6378	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6379	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6380	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6381	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6382	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6383	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6384	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6385	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6386	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6387	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6388	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6389	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6390	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6391	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6392	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6393	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6394	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6395	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6396	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6397	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6398	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6399	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6400	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6401	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6402	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6403	{
6404		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6405		/* .name = "Capture Source", */
6406		.name = "Input Source",
6407		.count = 2,
6408		.info = alc883_mux_enum_info,
6409		.get = alc883_mux_enum_get,
6410		.put = alc883_mux_enum_put,
6411	},
6412	{ } /* end */
6413};
6414
6415static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6416	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6417	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6418	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6419	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6420	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6421	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6422	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6423	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6424	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6425	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6426	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6427	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6428	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6429	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6430	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6431	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6432	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6433	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6434	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6435	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6436	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6437	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6438	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6439
6440	{
6441		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6442		/* .name = "Capture Source", */
6443		.name = "Input Source",
6444		.count = 1,
6445		.info = alc883_mux_enum_info,
6446		.get = alc883_mux_enum_get,
6447		.put = alc883_mux_enum_put,
6448	},
6449	{ } /* end */
6450};
6451
6452static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6453	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6454	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6455	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6456	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6457	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6458	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6459	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6460	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6461	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6462	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6463	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6464	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6465	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6466	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6467	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6468	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6469	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6470	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6471	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6472	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6473	{
6474		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6475		/* .name = "Capture Source", */
6476		.name = "Input Source",
6477		.count = 2,
6478		.info = alc883_mux_enum_info,
6479		.get = alc883_mux_enum_get,
6480		.put = alc883_mux_enum_put,
6481	},
6482	{ } /* end */
6483};
6484
6485static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6486	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6487	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6488	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6489	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6490	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6491	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6492	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6493	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6494	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6495	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6496	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6497	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6498	{
6499		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6500		/* .name = "Capture Source", */
6501		.name = "Input Source",
6502		.count = 2,
6503		.info = alc883_mux_enum_info,
6504		.get = alc883_mux_enum_get,
6505		.put = alc883_mux_enum_put,
6506	},
6507	{ } /* end */
6508};
6509
6510static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6511	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6512	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6513	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6514	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6515	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6516	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6517	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6518	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6519	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6520	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6521	{
6522		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6523		/* .name = "Capture Source", */
6524		.name = "Input Source",
6525		.count = 1,
6526		.info = alc883_mux_enum_info,
6527		.get = alc883_mux_enum_get,
6528		.put = alc883_mux_enum_put,
6529	},
6530	{ } /* end */
6531};
6532
6533static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6534	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6535	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6536	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6537	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6538	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6539	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6540	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6541	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6542	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6543	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6544	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6545	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6546	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6547	{
6548		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6549		/* .name = "Capture Source", */
6550		.name = "Input Source",
6551		.count = 2,
6552		.info = alc883_mux_enum_info,
6553		.get = alc883_mux_enum_get,
6554		.put = alc883_mux_enum_put,
6555	},
6556	{ } /* end */
6557};
6558
6559static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6560	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6561	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6562	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6563	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6564	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6565	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6566	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6567	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6568	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6569	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6570	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6571	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6572	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6573	{
6574		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6575		/* .name = "Capture Source", */
6576		.name = "Input Source",
6577		.count = 2,
6578		.info = alc883_mux_enum_info,
6579		.get = alc883_mux_enum_get,
6580		.put = alc883_mux_enum_put,
6581	},
6582	{ } /* end */
6583};
6584
6585static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6586	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6587	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6588	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6589	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6590	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6591	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6592	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6593	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6594	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6595	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6596	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6597	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6598	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6599	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6600	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6601	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6602	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6603	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6604	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6605	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6606	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6607	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6608	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6609	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6610	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6611	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6612	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6613	{
6614		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6615		/* .name = "Capture Source", */
6616		.name = "Input Source",
6617		.count = 2,
6618		.info = alc883_mux_enum_info,
6619		.get = alc883_mux_enum_get,
6620		.put = alc883_mux_enum_put,
6621	},
6622	{ } /* end */
6623};
6624
6625static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6626	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6627	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6628	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6629	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6630	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6631	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6632	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6633	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6634	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6635	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6636	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6637	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6638	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6639	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6640	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6641	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6642	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6643	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6644	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6645	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6646	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6647	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6648	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6649	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6650	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6651	{
6652		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6653		/* .name = "Capture Source", */
6654		.name = "Input Source",
6655		.count = 2,
6656		.info = alc883_mux_enum_info,
6657		.get = alc883_mux_enum_get,
6658		.put = alc883_mux_enum_put,
6659	},
6660	{ } /* end */
6661};
6662
6663static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6664	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6665	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6666	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6667	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6668	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6669	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6670	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6671	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6672	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6673	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6674	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6675	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6676	{
6677		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6678		/* .name = "Capture Source", */
6679		.name = "Input Source",
6680		.count = 2,
6681		.info = alc883_mux_enum_info,
6682		.get = alc883_mux_enum_get,
6683		.put = alc883_mux_enum_put,
6684	},
6685	{ } /* end */
6686};
6687
6688static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6689	{
6690		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6691		.name = "Channel Mode",
6692		.info = alc_ch_mode_info,
6693		.get = alc_ch_mode_get,
6694		.put = alc_ch_mode_put,
6695	},
6696	{ } /* end */
6697};
6698
6699static struct hda_verb alc883_init_verbs[] = {
6700	/* ADC1: mute amp left and right */
6701	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6702	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6703	/* ADC2: mute amp left and right */
6704	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6705	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6706	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6707	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6708	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6709	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6710	/* Rear mixer */
6711	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6712	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6713	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6714	/* CLFE mixer */
6715	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6716	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6717	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6718	/* Side mixer */
6719	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6720	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6721	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6722
6723	/* mute analog input loopbacks */
6724	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6725	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6726	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6727	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6728	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6729
6730	/* Front Pin: output 0 (0x0c) */
6731	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6732	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6733	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6734	/* Rear Pin: output 1 (0x0d) */
6735	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6736	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6737	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6738	/* CLFE Pin: output 2 (0x0e) */
6739	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6740	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6741	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6742	/* Side Pin: output 3 (0x0f) */
6743	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6744	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6745	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6746	/* Mic (rear) pin: input vref at 80% */
6747	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6748	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6749	/* Front Mic pin: input vref at 80% */
6750	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6751	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6752	/* Line In pin: input */
6753	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6754	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6755	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6756	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6757	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6758	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6759	/* CD pin widget for input */
6760	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6761
6762	/* FIXME: use matrix-type input source selection */
6763	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6764	/* Input mixer2 */
6765	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6766	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6767	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6768	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6769	/* Input mixer3 */
6770	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6771	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6772	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6773	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6774	{ }
6775};
6776
6777static struct hda_verb alc883_tagra_verbs[] = {
6778	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6779	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6780
6781	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6782	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6783
6784	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6785	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6786	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6787
6788	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6789	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6790	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6791	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6792
6793	{ } /* end */
6794};
6795
6796static struct hda_verb alc883_lenovo_101e_verbs[] = {
6797	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6798	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6799        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6800	{ } /* end */
6801};
6802
6803static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6804        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6805	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6806        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6807        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6808	{ } /* end */
6809};
6810
6811static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6812	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6813	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6814	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6815	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6816	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6817	{ } /* end */
6818};
6819
6820static struct hda_verb alc883_haier_w66_verbs[] = {
6821	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6822	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6823
6824	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6825
6826	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6827	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6828	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6829	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6830	{ } /* end */
6831};
6832
6833static struct hda_verb alc888_6st_hp_verbs[] = {
6834	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6835	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},	/* Rear : output 2 (0x0e) */
6836	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* CLFE : output 1 (0x0d) */
6837	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},	/* Side : output 3 (0x0f) */
6838	{ }
6839};
6840
6841static struct hda_verb alc888_3st_hp_verbs[] = {
6842	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6843	{0x18, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
6844	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
6845	{ }
6846};
6847
6848static struct hda_verb alc888_3st_hp_2ch_init[] = {
6849	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6850	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6851	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6852	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6853	{ }
6854};
6855
6856static struct hda_verb alc888_3st_hp_6ch_init[] = {
6857	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6858	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6859	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6860	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6861	{ }
6862};
6863
6864static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6865	{ 2, alc888_3st_hp_2ch_init },
6866	{ 6, alc888_3st_hp_6ch_init },
6867};
6868
6869/* toggle front-jack and RCA according to the hp-jack state */
6870static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6871{
6872 	unsigned int present;
6873
6874 	present = snd_hda_codec_read(codec, 0x1b, 0,
6875				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6876	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6877				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6878	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6879				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6880}
6881
6882/* toggle RCA according to the front-jack state */
6883static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6884{
6885 	unsigned int present;
6886
6887 	present = snd_hda_codec_read(codec, 0x14, 0,
6888				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6889	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6890				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6891}
6892
6893static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6894					     unsigned int res)
6895{
6896	if ((res >> 26) == ALC880_HP_EVENT)
6897		alc888_lenovo_ms7195_front_automute(codec);
6898	if ((res >> 26) == ALC880_FRONT_EVENT)
6899		alc888_lenovo_ms7195_rca_automute(codec);
6900}
6901
6902static struct hda_verb alc883_medion_md2_verbs[] = {
6903	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6904	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6905
6906	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6907
6908	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6909	{ } /* end */
6910};
6911
6912/* toggle speaker-output according to the hp-jack state */
6913static void alc883_medion_md2_automute(struct hda_codec *codec)
6914{
6915 	unsigned int present;
6916
6917 	present = snd_hda_codec_read(codec, 0x14, 0,
6918				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6919	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6920				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6921}
6922
6923static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6924					  unsigned int res)
6925{
6926	if ((res >> 26) == ALC880_HP_EVENT)
6927		alc883_medion_md2_automute(codec);
6928}
6929
6930/* toggle speaker-output according to the hp-jack state */
6931static void alc883_tagra_automute(struct hda_codec *codec)
6932{
6933 	unsigned int present;
6934	unsigned char bits;
6935
6936 	present = snd_hda_codec_read(codec, 0x14, 0,
6937				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6938	bits = present ? HDA_AMP_MUTE : 0;
6939	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6940				 HDA_AMP_MUTE, bits);
6941	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6942				  present ? 1 : 3);
6943}
6944
6945static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6946{
6947	if ((res >> 26) == ALC880_HP_EVENT)
6948		alc883_tagra_automute(codec);
6949}
6950
6951static void alc883_haier_w66_automute(struct hda_codec *codec)
6952{
6953	unsigned int present;
6954	unsigned char bits;
6955
6956	present = snd_hda_codec_read(codec, 0x1b, 0,
6957				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6958	bits = present ? 0x80 : 0;
6959	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6960				 0x80, bits);
6961}
6962
6963static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
6964					 unsigned int res)
6965{
6966	if ((res >> 26) == ALC880_HP_EVENT)
6967		alc883_haier_w66_automute(codec);
6968}
6969
6970static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6971{
6972 	unsigned int present;
6973	unsigned char bits;
6974
6975 	present = snd_hda_codec_read(codec, 0x14, 0,
6976				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6977	bits = present ? HDA_AMP_MUTE : 0;
6978	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6979				 HDA_AMP_MUTE, bits);
6980}
6981
6982static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6983{
6984 	unsigned int present;
6985	unsigned char bits;
6986
6987 	present = snd_hda_codec_read(codec, 0x1b, 0,
6988				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6989	bits = present ? HDA_AMP_MUTE : 0;
6990	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6991				 HDA_AMP_MUTE, bits);
6992	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6993				 HDA_AMP_MUTE, bits);
6994}
6995
6996static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6997					   unsigned int res)
6998{
6999	if ((res >> 26) == ALC880_HP_EVENT)
7000		alc883_lenovo_101e_all_automute(codec);
7001	if ((res >> 26) == ALC880_FRONT_EVENT)
7002		alc883_lenovo_101e_ispeaker_automute(codec);
7003}
7004
7005/* toggle speaker-output according to the hp-jack state */
7006static void alc883_acer_aspire_automute(struct hda_codec *codec)
7007{
7008 	unsigned int present;
7009
7010 	present = snd_hda_codec_read(codec, 0x14, 0,
7011				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7012	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7013				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7014	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7015				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7016}
7017
7018static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7019					   unsigned int res)
7020{
7021	if ((res >> 26) == ALC880_HP_EVENT)
7022		alc883_acer_aspire_automute(codec);
7023}
7024
7025static struct hda_verb alc883_acer_eapd_verbs[] = {
7026	/* HP Pin: output 0 (0x0c) */
7027	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7028	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7029	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7030	/* Front Pin: output 0 (0x0c) */
7031	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7032	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7033	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7034	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7035        /* eanable EAPD on medion laptop */
7036	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7037	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7038	/* enable unsolicited event */
7039	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7040	{ }
7041};
7042
7043/*
7044 * generic initialization of ADC, input mixers and output mixers
7045 */
7046static struct hda_verb alc883_auto_init_verbs[] = {
7047	/*
7048	 * Unmute ADC0-2 and set the default input to mic-in
7049	 */
7050	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7051	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7052	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7053	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7054
7055	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7056	 * mixer widget
7057	 * Note: PASD motherboards uses the Line In 2 as the input for
7058	 * front panel mic (mic 2)
7059	 */
7060	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7061	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7062	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7063	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7064	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7065	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7066
7067	/*
7068	 * Set up output mixers (0x0c - 0x0f)
7069	 */
7070	/* set vol=0 to output mixers */
7071	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7072	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7073	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7074	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7075	/* set up input amps for analog loopback */
7076	/* Amp Indices: DAC = 0, mixer = 1 */
7077	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7078	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7079	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7080	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7081	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7082	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7083	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7084	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7085	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7086	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7087
7088	/* FIXME: use matrix-type input source selection */
7089	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7090	/* Input mixer1 */
7091	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7092	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7093	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7094	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7095	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7096	/* Input mixer2 */
7097	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7098	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7099	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7100	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7101	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7102
7103	{ }
7104};
7105
7106/* capture mixer elements */
7107static struct snd_kcontrol_new alc883_capture_mixer[] = {
7108	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7109	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7110	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7111	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7112	{
7113		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7114		/* The multiple "Capture Source" controls confuse alsamixer
7115		 * So call somewhat different..
7116		 * FIXME: the controls appear in the "playback" view!
7117		 */
7118		/* .name = "Capture Source", */
7119		.name = "Input Source",
7120		.count = 2,
7121		.info = alc882_mux_enum_info,
7122		.get = alc882_mux_enum_get,
7123		.put = alc882_mux_enum_put,
7124	},
7125	{ } /* end */
7126};
7127
7128#ifdef CONFIG_SND_HDA_POWER_SAVE
7129#define alc883_loopbacks	alc880_loopbacks
7130#endif
7131
7132/* pcm configuration: identiacal with ALC880 */
7133#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
7134#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
7135#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
7136#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
7137
7138/*
7139 * configuration and preset
7140 */
7141static const char *alc883_models[ALC883_MODEL_LAST] = {
7142	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
7143	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
7144	[ALC883_3ST_6ch]	= "3stack-6ch",
7145	[ALC883_6ST_DIG]	= "6stack-dig",
7146	[ALC883_TARGA_DIG]	= "targa-dig",
7147	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
7148	[ALC883_ACER]		= "acer",
7149	[ALC883_ACER_ASPIRE]	= "acer-aspire",
7150	[ALC883_MEDION]		= "medion",
7151	[ALC883_MEDION_MD2]	= "medion-md2",
7152	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
7153	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7154	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
7155	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7156	[ALC883_HAIER_W66] 	= "haier-w66",
7157	[ALC888_6ST_HP]		= "6stack-hp",
7158	[ALC888_3ST_HP]		= "3stack-hp",
7159	[ALC883_AUTO]		= "auto",
7160};
7161
7162static struct snd_pci_quirk alc883_cfg_tbl[] = {
7163	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7164	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7165	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7166	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7167	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7168	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7169	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7170	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7171	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7172	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7173	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7174	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7175	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7176	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7177	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7178	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7179	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7180	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7181	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7182	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7183	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7184	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7185	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7186	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7187	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7188	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7189	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7190	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
7191	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7192	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7193	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7194	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7195	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7196	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7197	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7198	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7199	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7200	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7201	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7202	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7203	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7204	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7205	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7206	{}
7207};
7208
7209static struct alc_config_preset alc883_presets[] = {
7210	[ALC883_3ST_2ch_DIG] = {
7211		.mixers = { alc883_3ST_2ch_mixer },
7212		.init_verbs = { alc883_init_verbs },
7213		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7214		.dac_nids = alc883_dac_nids,
7215		.dig_out_nid = ALC883_DIGOUT_NID,
7216		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7217		.adc_nids = alc883_adc_nids,
7218		.dig_in_nid = ALC883_DIGIN_NID,
7219		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7220		.channel_mode = alc883_3ST_2ch_modes,
7221		.input_mux = &alc883_capture_source,
7222	},
7223	[ALC883_3ST_6ch_DIG] = {
7224		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7225		.init_verbs = { alc883_init_verbs },
7226		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7227		.dac_nids = alc883_dac_nids,
7228		.dig_out_nid = ALC883_DIGOUT_NID,
7229		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7230		.adc_nids = alc883_adc_nids,
7231		.dig_in_nid = ALC883_DIGIN_NID,
7232		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7233		.channel_mode = alc883_3ST_6ch_modes,
7234		.need_dac_fix = 1,
7235		.input_mux = &alc883_capture_source,
7236	},
7237	[ALC883_3ST_6ch] = {
7238		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7239		.init_verbs = { alc883_init_verbs },
7240		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7241		.dac_nids = alc883_dac_nids,
7242		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7243		.adc_nids = alc883_adc_nids,
7244		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7245		.channel_mode = alc883_3ST_6ch_modes,
7246		.need_dac_fix = 1,
7247		.input_mux = &alc883_capture_source,
7248	},
7249	[ALC883_6ST_DIG] = {
7250		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
7251		.init_verbs = { alc883_init_verbs },
7252		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7253		.dac_nids = alc883_dac_nids,
7254		.dig_out_nid = ALC883_DIGOUT_NID,
7255		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7256		.adc_nids = alc883_adc_nids,
7257		.dig_in_nid = ALC883_DIGIN_NID,
7258		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7259		.channel_mode = alc883_sixstack_modes,
7260		.input_mux = &alc883_capture_source,
7261	},
7262	[ALC883_TARGA_DIG] = {
7263		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7264		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7265		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7266		.dac_nids = alc883_dac_nids,
7267		.dig_out_nid = ALC883_DIGOUT_NID,
7268		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7269		.adc_nids = alc883_adc_nids,
7270		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7271		.channel_mode = alc883_3ST_6ch_modes,
7272		.need_dac_fix = 1,
7273		.input_mux = &alc883_capture_source,
7274		.unsol_event = alc883_tagra_unsol_event,
7275		.init_hook = alc883_tagra_automute,
7276	},
7277	[ALC883_TARGA_2ch_DIG] = {
7278		.mixers = { alc883_tagra_2ch_mixer},
7279		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7280		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7281		.dac_nids = alc883_dac_nids,
7282		.dig_out_nid = ALC883_DIGOUT_NID,
7283		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7284		.adc_nids = alc883_adc_nids,
7285		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7286		.channel_mode = alc883_3ST_2ch_modes,
7287		.input_mux = &alc883_capture_source,
7288		.unsol_event = alc883_tagra_unsol_event,
7289		.init_hook = alc883_tagra_automute,
7290	},
7291	[ALC883_ACER] = {
7292		.mixers = { alc883_base_mixer },
7293		/* On TravelMate laptops, GPIO 0 enables the internal speaker
7294		 * and the headphone jack.  Turn this on and rely on the
7295		 * standard mute methods whenever the user wants to turn
7296		 * these outputs off.
7297		 */
7298		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7299		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7300		.dac_nids = alc883_dac_nids,
7301		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7302		.adc_nids = alc883_adc_nids,
7303		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7304		.channel_mode = alc883_3ST_2ch_modes,
7305		.input_mux = &alc883_capture_source,
7306	},
7307	[ALC883_ACER_ASPIRE] = {
7308		.mixers = { alc883_acer_aspire_mixer },
7309		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7310		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7311		.dac_nids = alc883_dac_nids,
7312		.dig_out_nid = ALC883_DIGOUT_NID,
7313		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7314		.adc_nids = alc883_adc_nids,
7315		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7316		.channel_mode = alc883_3ST_2ch_modes,
7317		.input_mux = &alc883_capture_source,
7318		.unsol_event = alc883_acer_aspire_unsol_event,
7319		.init_hook = alc883_acer_aspire_automute,
7320	},
7321	[ALC883_MEDION] = {
7322		.mixers = { alc883_fivestack_mixer,
7323			    alc883_chmode_mixer },
7324		.init_verbs = { alc883_init_verbs,
7325				alc883_medion_eapd_verbs },
7326		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7327		.dac_nids = alc883_dac_nids,
7328		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7329		.adc_nids = alc883_adc_nids,
7330		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7331		.channel_mode = alc883_sixstack_modes,
7332		.input_mux = &alc883_capture_source,
7333	},
7334	[ALC883_MEDION_MD2] = {
7335		.mixers = { alc883_medion_md2_mixer},
7336		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7337		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7338		.dac_nids = alc883_dac_nids,
7339		.dig_out_nid = ALC883_DIGOUT_NID,
7340		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7341		.adc_nids = alc883_adc_nids,
7342		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7343		.channel_mode = alc883_3ST_2ch_modes,
7344		.input_mux = &alc883_capture_source,
7345		.unsol_event = alc883_medion_md2_unsol_event,
7346		.init_hook = alc883_medion_md2_automute,
7347	},
7348	[ALC883_LAPTOP_EAPD] = {
7349		.mixers = { alc883_base_mixer },
7350		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7351		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7352		.dac_nids = alc883_dac_nids,
7353		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7354		.adc_nids = alc883_adc_nids,
7355		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7356		.channel_mode = alc883_3ST_2ch_modes,
7357		.input_mux = &alc883_capture_source,
7358	},
7359	[ALC883_LENOVO_101E_2ch] = {
7360		.mixers = { alc883_lenovo_101e_2ch_mixer},
7361		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7362		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7363		.dac_nids = alc883_dac_nids,
7364		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7365		.adc_nids = alc883_adc_nids,
7366		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7367		.channel_mode = alc883_3ST_2ch_modes,
7368		.input_mux = &alc883_lenovo_101e_capture_source,
7369		.unsol_event = alc883_lenovo_101e_unsol_event,
7370		.init_hook = alc883_lenovo_101e_all_automute,
7371	},
7372	[ALC883_LENOVO_NB0763] = {
7373		.mixers = { alc883_lenovo_nb0763_mixer },
7374		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7375		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7376		.dac_nids = alc883_dac_nids,
7377		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7378		.adc_nids = alc883_adc_nids,
7379		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7380		.channel_mode = alc883_3ST_2ch_modes,
7381		.need_dac_fix = 1,
7382		.input_mux = &alc883_lenovo_nb0763_capture_source,
7383		.unsol_event = alc883_medion_md2_unsol_event,
7384		.init_hook = alc883_medion_md2_automute,
7385	},
7386	[ALC888_LENOVO_MS7195_DIG] = {
7387		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7388		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7389		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7390		.dac_nids = alc883_dac_nids,
7391		.dig_out_nid = ALC883_DIGOUT_NID,
7392		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7393		.adc_nids = alc883_adc_nids,
7394		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7395		.channel_mode = alc883_3ST_6ch_modes,
7396		.need_dac_fix = 1,
7397		.input_mux = &alc883_capture_source,
7398		.unsol_event = alc883_lenovo_ms7195_unsol_event,
7399		.init_hook = alc888_lenovo_ms7195_front_automute,
7400	},
7401	[ALC883_HAIER_W66] = {
7402		.mixers = { alc883_tagra_2ch_mixer},
7403		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7404		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7405		.dac_nids = alc883_dac_nids,
7406		.dig_out_nid = ALC883_DIGOUT_NID,
7407		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7408		.adc_nids = alc883_adc_nids,
7409		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7410		.channel_mode = alc883_3ST_2ch_modes,
7411		.input_mux = &alc883_capture_source,
7412		.unsol_event = alc883_haier_w66_unsol_event,
7413		.init_hook = alc883_haier_w66_automute,
7414	},
7415	[ALC888_6ST_HP] = {
7416		.mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7417		.init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7418		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7419		.dac_nids = alc883_dac_nids,
7420		.dig_out_nid = ALC883_DIGOUT_NID,
7421		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7422		.adc_nids = alc883_adc_nids,
7423		.dig_in_nid = ALC883_DIGIN_NID,
7424		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7425		.channel_mode = alc883_sixstack_modes,
7426		.input_mux = &alc883_capture_source,
7427	},
7428	[ALC888_3ST_HP] = {
7429		.mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7430		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7431		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7432		.dac_nids = alc883_dac_nids,
7433		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7434		.adc_nids = alc883_adc_nids,
7435		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7436		.channel_mode = alc888_3st_hp_modes,
7437		.need_dac_fix = 1,
7438		.input_mux = &alc883_capture_source,
7439	},
7440};
7441
7442
7443/*
7444 * BIOS auto configuration
7445 */
7446static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7447					      hda_nid_t nid, int pin_type,
7448					      int dac_idx)
7449{
7450	/* set as output */
7451	struct alc_spec *spec = codec->spec;
7452	int idx;
7453
7454	if (spec->multiout.dac_nids[dac_idx] == 0x25)
7455		idx = 4;
7456	else
7457		idx = spec->multiout.dac_nids[dac_idx] - 2;
7458
7459	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7460			    pin_type);
7461	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7462			    AMP_OUT_UNMUTE);
7463	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7464
7465}
7466
7467static void alc883_auto_init_multi_out(struct hda_codec *codec)
7468{
7469	struct alc_spec *spec = codec->spec;
7470	int i;
7471
7472	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7473	for (i = 0; i <= HDA_SIDE; i++) {
7474		hda_nid_t nid = spec->autocfg.line_out_pins[i];
7475		int pin_type = get_pin_type(spec->autocfg.line_out_type);
7476		if (nid)
7477			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7478							  i);
7479	}
7480}
7481
7482static void alc883_auto_init_hp_out(struct hda_codec *codec)
7483{
7484	struct alc_spec *spec = codec->spec;
7485	hda_nid_t pin;
7486
7487	pin = spec->autocfg.hp_pins[0];
7488	if (pin) /* connect to front */
7489		/* use dac 0 */
7490		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7491}
7492
7493#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
7494#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
7495
7496static void alc883_auto_init_analog_input(struct hda_codec *codec)
7497{
7498	struct alc_spec *spec = codec->spec;
7499	int i;
7500
7501	for (i = 0; i < AUTO_PIN_LAST; i++) {
7502		hda_nid_t nid = spec->autocfg.input_pins[i];
7503		if (alc883_is_input_pin(nid)) {
7504			snd_hda_codec_write(codec, nid, 0,
7505					    AC_VERB_SET_PIN_WIDGET_CONTROL,
7506					    (i <= AUTO_PIN_FRONT_MIC ?
7507					     PIN_VREF80 : PIN_IN));
7508			if (nid != ALC883_PIN_CD_NID)
7509				snd_hda_codec_write(codec, nid, 0,
7510						    AC_VERB_SET_AMP_GAIN_MUTE,
7511						    AMP_OUT_MUTE);
7512		}
7513	}
7514}
7515
7516/* almost identical with ALC880 parser... */
7517static int alc883_parse_auto_config(struct hda_codec *codec)
7518{
7519	struct alc_spec *spec = codec->spec;
7520	int err = alc880_parse_auto_config(codec);
7521
7522	if (err < 0)
7523		return err;
7524	else if (!err)
7525		return 0; /* no config found */
7526
7527	err = alc_auto_add_mic_boost(codec);
7528	if (err < 0)
7529		return err;
7530
7531	/* hack - override the init verbs */
7532	spec->init_verbs[0] = alc883_auto_init_verbs;
7533	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7534	spec->num_mixers++;
7535
7536	return 1; /* config found */
7537}
7538
7539/* additional initialization for auto-configuration model */
7540static void alc883_auto_init(struct hda_codec *codec)
7541{
7542	alc883_auto_init_multi_out(codec);
7543	alc883_auto_init_hp_out(codec);
7544	alc883_auto_init_analog_input(codec);
7545}
7546
7547static int patch_alc883(struct hda_codec *codec)
7548{
7549	struct alc_spec *spec;
7550	int err, board_config;
7551
7552	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7553	if (spec == NULL)
7554		return -ENOMEM;
7555
7556	codec->spec = spec;
7557
7558	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7559						  alc883_models,
7560						  alc883_cfg_tbl);
7561	if (board_config < 0) {
7562		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7563		       "trying auto-probe from BIOS...\n");
7564		board_config = ALC883_AUTO;
7565	}
7566
7567	if (board_config == ALC883_AUTO) {
7568		/* automatic parse from the BIOS config */
7569		err = alc883_parse_auto_config(codec);
7570		if (err < 0) {
7571			alc_free(codec);
7572			return err;
7573		} else if (!err) {
7574			printk(KERN_INFO
7575			       "hda_codec: Cannot set up configuration "
7576			       "from BIOS.  Using base mode...\n");
7577			board_config = ALC883_3ST_2ch_DIG;
7578		}
7579	}
7580
7581	if (board_config != ALC883_AUTO)
7582		setup_preset(spec, &alc883_presets[board_config]);
7583
7584	spec->stream_name_analog = "ALC883 Analog";
7585	spec->stream_analog_playback = &alc883_pcm_analog_playback;
7586	spec->stream_analog_capture = &alc883_pcm_analog_capture;
7587
7588	spec->stream_name_digital = "ALC883 Digital";
7589	spec->stream_digital_playback = &alc883_pcm_digital_playback;
7590	spec->stream_digital_capture = &alc883_pcm_digital_capture;
7591
7592	if (!spec->adc_nids && spec->input_mux) {
7593		spec->adc_nids = alc883_adc_nids;
7594		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7595	}
7596
7597	codec->patch_ops = alc_patch_ops;
7598	if (board_config == ALC883_AUTO)
7599		spec->init_hook = alc883_auto_init;
7600#ifdef CONFIG_SND_HDA_POWER_SAVE
7601	if (!spec->loopback.amplist)
7602		spec->loopback.amplist = alc883_loopbacks;
7603#endif
7604
7605	return 0;
7606}
7607
7608/*
7609 * ALC262 support
7610 */
7611
7612#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
7613#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
7614
7615#define alc262_dac_nids		alc260_dac_nids
7616#define alc262_adc_nids		alc882_adc_nids
7617#define alc262_adc_nids_alt	alc882_adc_nids_alt
7618
7619#define alc262_modes		alc260_modes
7620#define alc262_capture_source	alc882_capture_source
7621
7622static struct snd_kcontrol_new alc262_base_mixer[] = {
7623	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7624	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7625	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7626	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7627	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7628	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7629	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7630	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7631	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7632	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7633	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7634	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7635	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7636	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7637	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7638	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7639	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7640	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7641	{ } /* end */
7642};
7643
7644static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7645	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7646	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7647	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7648	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7649	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7650	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7651	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7652	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7653	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7654	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7655	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7656	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7657	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7658	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7659	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7660	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7661	{ } /* end */
7662};
7663
7664static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7665	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7666	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7667	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7668	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7669	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7670
7671	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7672	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7673	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7674	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7675	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7676	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7677	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7678	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7679	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7680	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7681	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7682	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7683	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7684	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7685	{ } /* end */
7686};
7687
7688static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7689	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7690	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7691	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7692	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7693	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7694	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7695	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7696	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7697	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7698	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7699	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7700	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7701	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7702	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7703	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7704	{ } /* end */
7705};
7706
7707static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7708	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7709	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7710	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7711	{ } /* end */
7712};
7713
7714static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7715	.ops = &snd_hda_bind_vol,
7716	.values = {
7717		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7718		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7719		0
7720	},
7721};
7722
7723static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7724	.ops = &snd_hda_bind_sw,
7725	.values = {
7726		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7727		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7728		0
7729	},
7730};
7731
7732/* mute/unmute internal speaker according to the hp jack and mute state */
7733static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7734{
7735	struct alc_spec *spec = codec->spec;
7736	unsigned int mute;
7737
7738	if (force || !spec->sense_updated) {
7739		unsigned int present;
7740		present = snd_hda_codec_read(codec, 0x15, 0,
7741					     AC_VERB_GET_PIN_SENSE, 0);
7742		spec->jack_present = (present & 0x80000000) != 0;
7743		spec->sense_updated = 1;
7744	}
7745	if (spec->jack_present)
7746		mute = (0x7080 | ((0)<<8));  /* mute internal speaker */
7747	else	/* unmute internal speaker if necessary */
7748		mute = (0x7000 | ((0)<<8));
7749       	snd_hda_codec_write(codec, 0x0c, 0,
7750			    AC_VERB_SET_AMP_GAIN_MUTE, mute );
7751}
7752
7753static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7754					unsigned int res)
7755{
7756	if ((res >> 26) != ALC880_HP_EVENT)
7757		return;
7758	alc262_hp_t5735_automute(codec, 1);
7759}
7760
7761static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7762{
7763	alc262_hp_t5735_automute(codec, 1);
7764}
7765
7766static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7767	HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7768	HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
7769	HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7770	HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7771	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7772	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7773	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7774	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7775	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7776	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7777	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7778	{ } /* end */
7779};
7780
7781static struct hda_verb alc262_hp_t5735_verbs[] = {
7782	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7783	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7784
7785	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7786	{ }
7787};
7788
7789/* bind hp and internal speaker mute (with plug check) */
7790static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7791				     struct snd_ctl_elem_value *ucontrol)
7792{
7793	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7794	long *valp = ucontrol->value.integer.value;
7795	int change;
7796
7797	/* change hp mute */
7798	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7799					  HDA_AMP_MUTE,
7800					  valp[0] ? 0 : HDA_AMP_MUTE);
7801	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7802					   HDA_AMP_MUTE,
7803					   valp[1] ? 0 : HDA_AMP_MUTE);
7804	if (change) {
7805		/* change speaker according to HP jack state */
7806		struct alc_spec *spec = codec->spec;
7807		unsigned int mute;
7808		if (spec->jack_present)
7809			mute = HDA_AMP_MUTE;
7810		else
7811			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7812						      HDA_OUTPUT, 0);
7813		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7814					 HDA_AMP_MUTE, mute);
7815	}
7816	return change;
7817}
7818
7819static struct snd_kcontrol_new alc262_sony_mixer[] = {
7820	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7821	{
7822		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7823		.name = "Master Playback Switch",
7824		.info = snd_hda_mixer_amp_switch_info,
7825		.get = snd_hda_mixer_amp_switch_get,
7826		.put = alc262_sony_master_sw_put,
7827		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7828	},
7829	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7830	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7831	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7832	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7833	{ } /* end */
7834};
7835
7836static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7837	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7838	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7839	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7840	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7841	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7842	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7843	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7844	{ } /* end */
7845};
7846
7847#define alc262_capture_mixer		alc882_capture_mixer
7848#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
7849
7850/*
7851 * generic initialization of ADC, input mixers and output mixers
7852 */
7853static struct hda_verb alc262_init_verbs[] = {
7854	/*
7855	 * Unmute ADC0-2 and set the default input to mic-in
7856	 */
7857	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7858	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7859	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7860	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7861	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7862	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7863
7864	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7865	 * mixer widget
7866	 * Note: PASD motherboards uses the Line In 2 as the input for
7867	 * front panel mic (mic 2)
7868	 */
7869	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7870	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7871	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7872	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7873	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7874	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7875
7876	/*
7877	 * Set up output mixers (0x0c - 0x0e)
7878	 */
7879	/* set vol=0 to output mixers */
7880	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7881	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7882	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7883	/* set up input amps for analog loopback */
7884	/* Amp Indices: DAC = 0, mixer = 1 */
7885	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7886	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7887	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7888	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7889	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7890	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7891
7892	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7893	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7894	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7895	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7896	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7897	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7898
7899	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7900	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7901	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7902	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7903	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7904
7905	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7906	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7907
7908	/* FIXME: use matrix-type input source selection */
7909	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7910	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7911	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7912	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7913	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7914	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7915	/* Input mixer2 */
7916	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7917	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7918	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7919	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7920	/* Input mixer3 */
7921	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7922	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7923	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7924	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7925
7926	{ }
7927};
7928
7929static struct hda_verb alc262_hippo_unsol_verbs[] = {
7930	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7931	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7932	{}
7933};
7934
7935static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7936	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7937	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7938	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7939
7940	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7941	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7942	{}
7943};
7944
7945static struct hda_verb alc262_sony_unsol_verbs[] = {
7946	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7947	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7948	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
7949
7950	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7951	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7952};
7953
7954/* mute/unmute internal speaker according to the hp jack and mute state */
7955static void alc262_hippo_automute(struct hda_codec *codec)
7956{
7957	struct alc_spec *spec = codec->spec;
7958	unsigned int mute;
7959	unsigned int present;
7960
7961	/* need to execute and sync at first */
7962	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7963	present = snd_hda_codec_read(codec, 0x15, 0,
7964				     AC_VERB_GET_PIN_SENSE, 0);
7965	spec->jack_present = (present & 0x80000000) != 0;
7966	if (spec->jack_present) {
7967		/* mute internal speaker */
7968		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7969					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7970	} else {
7971		/* unmute internal speaker if necessary */
7972		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7973		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7974					 HDA_AMP_MUTE, mute);
7975	}
7976}
7977
7978/* unsolicited event for HP jack sensing */
7979static void alc262_hippo_unsol_event(struct hda_codec *codec,
7980				       unsigned int res)
7981{
7982	if ((res >> 26) != ALC880_HP_EVENT)
7983		return;
7984	alc262_hippo_automute(codec);
7985}
7986
7987static void alc262_hippo1_automute(struct hda_codec *codec)
7988{
7989	unsigned int mute;
7990	unsigned int present;
7991
7992	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7993	present = snd_hda_codec_read(codec, 0x1b, 0,
7994				     AC_VERB_GET_PIN_SENSE, 0);
7995	present = (present & 0x80000000) != 0;
7996	if (present) {
7997		/* mute internal speaker */
7998		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7999					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8000	} else {
8001		/* unmute internal speaker if necessary */
8002		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8003		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8004					 HDA_AMP_MUTE, mute);
8005	}
8006}
8007
8008/* unsolicited event for HP jack sensing */
8009static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8010				       unsigned int res)
8011{
8012	if ((res >> 26) != ALC880_HP_EVENT)
8013		return;
8014	alc262_hippo1_automute(codec);
8015}
8016
8017/*
8018 * fujitsu model
8019 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
8020 */
8021
8022#define ALC_HP_EVENT	0x37
8023
8024static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8025	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8026	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8027	{}
8028};
8029
8030static struct hda_input_mux alc262_fujitsu_capture_source = {
8031	.num_items = 3,
8032	.items = {
8033		{ "Mic", 0x0 },
8034		{ "Int Mic", 0x1 },
8035		{ "CD", 0x4 },
8036	},
8037};
8038
8039static struct hda_input_mux alc262_HP_capture_source = {
8040	.num_items = 5,
8041	.items = {
8042		{ "Mic", 0x0 },
8043		{ "Front Mic", 0x1 },
8044		{ "Line", 0x2 },
8045		{ "CD", 0x4 },
8046		{ "AUX IN", 0x6 },
8047	},
8048};
8049
8050static struct hda_input_mux alc262_HP_D7000_capture_source = {
8051	.num_items = 4,
8052	.items = {
8053		{ "Mic", 0x0 },
8054		{ "Front Mic", 0x2 },
8055		{ "Line", 0x1 },
8056		{ "CD", 0x4 },
8057	},
8058};
8059
8060/* mute/unmute internal speaker according to the hp jack and mute state */
8061static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8062{
8063	struct alc_spec *spec = codec->spec;
8064	unsigned int mute;
8065
8066	if (force || !spec->sense_updated) {
8067		unsigned int present;
8068		/* need to execute and sync at first */
8069		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8070		present = snd_hda_codec_read(codec, 0x14, 0,
8071				    	 AC_VERB_GET_PIN_SENSE, 0);
8072		spec->jack_present = (present & 0x80000000) != 0;
8073		spec->sense_updated = 1;
8074	}
8075	if (spec->jack_present) {
8076		/* mute internal speaker */
8077		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8078					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8079	} else {
8080		/* unmute internal speaker if necessary */
8081		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8082		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8083					 HDA_AMP_MUTE, mute);
8084	}
8085}
8086
8087/* unsolicited event for HP jack sensing */
8088static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8089				       unsigned int res)
8090{
8091	if ((res >> 26) != ALC_HP_EVENT)
8092		return;
8093	alc262_fujitsu_automute(codec, 1);
8094}
8095
8096/* bind volumes of both NID 0x0c and 0x0d */
8097static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8098	.ops = &snd_hda_bind_vol,
8099	.values = {
8100		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8101		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8102		0
8103	},
8104};
8105
8106/* bind hp and internal speaker mute (with plug check) */
8107static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8108					 struct snd_ctl_elem_value *ucontrol)
8109{
8110	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8111	long *valp = ucontrol->value.integer.value;
8112	int change;
8113
8114	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8115					  HDA_AMP_MUTE,
8116					  valp[0] ? 0 : HDA_AMP_MUTE);
8117	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8118					   HDA_AMP_MUTE,
8119					   valp[1] ? 0 : HDA_AMP_MUTE);
8120	if (change)
8121		alc262_fujitsu_automute(codec, 0);
8122	return change;
8123}
8124
8125static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8126	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8127	{
8128		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8129		.name = "Master Playback Switch",
8130		.info = snd_hda_mixer_amp_switch_info,
8131		.get = snd_hda_mixer_amp_switch_get,
8132		.put = alc262_fujitsu_master_sw_put,
8133		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8134	},
8135	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8136	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8137	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8138	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8139	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8140	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8141	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8142	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8143	{ } /* end */
8144};
8145
8146/* additional init verbs for Benq laptops */
8147static struct hda_verb alc262_EAPD_verbs[] = {
8148	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8149	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
8150	{}
8151};
8152
8153static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8154	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8155	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8156
8157	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8158	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
8159	{}
8160};
8161
8162/* Samsung Q1 Ultra Vista model setup */
8163static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8164	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8165	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8166	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8167	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8168	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8169	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8170	{ } /* end */
8171};
8172
8173static struct hda_verb alc262_ultra_verbs[] = {
8174	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8175	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8176	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8177	/* Mic is on Node 0x19 */
8178	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8179	{0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8180	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8181	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8182	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8183	{0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8184	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8185	{}
8186};
8187
8188static struct hda_input_mux alc262_ultra_capture_source = {
8189	.num_items = 1,
8190	.items = {
8191		{ "Mic", 0x1 },
8192	},
8193};
8194
8195/* mute/unmute internal speaker according to the hp jack and mute state */
8196static void alc262_ultra_automute(struct hda_codec *codec)
8197{
8198	struct alc_spec *spec = codec->spec;
8199	unsigned int mute;
8200	unsigned int present;
8201
8202	/* need to execute and sync at first */
8203	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8204	present = snd_hda_codec_read(codec, 0x15, 0,
8205				     AC_VERB_GET_PIN_SENSE, 0);
8206	spec->jack_present = (present & 0x80000000) != 0;
8207	if (spec->jack_present) {
8208		/* mute internal speaker */
8209		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8210					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8211	} else {
8212		/* unmute internal speaker if necessary */
8213		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8214		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8215					 HDA_AMP_MUTE, mute);
8216	}
8217}
8218
8219/* unsolicited event for HP jack sensing */
8220static void alc262_ultra_unsol_event(struct hda_codec *codec,
8221				       unsigned int res)
8222{
8223	if ((res >> 26) != ALC880_HP_EVENT)
8224		return;
8225	alc262_ultra_automute(codec);
8226}
8227
8228/* add playback controls from the parsed DAC table */
8229static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8230					     const struct auto_pin_cfg *cfg)
8231{
8232	hda_nid_t nid;
8233	int err;
8234
8235	spec->multiout.num_dacs = 1;	/* only use one dac */
8236	spec->multiout.dac_nids = spec->private_dac_nids;
8237	spec->multiout.dac_nids[0] = 2;
8238
8239	nid = cfg->line_out_pins[0];
8240	if (nid) {
8241		err = add_control(spec, ALC_CTL_WIDGET_VOL,
8242				  "Front Playback Volume",
8243				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8244		if (err < 0)
8245			return err;
8246		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8247				  "Front Playback Switch",
8248				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8249		if (err < 0)
8250			return err;
8251	}
8252
8253	nid = cfg->speaker_pins[0];
8254	if (nid) {
8255		if (nid == 0x16) {
8256			err = add_control(spec, ALC_CTL_WIDGET_VOL,
8257					  "Speaker Playback Volume",
8258					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8259							      HDA_OUTPUT));
8260			if (err < 0)
8261				return err;
8262			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8263					  "Speaker Playback Switch",
8264					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8265							      HDA_OUTPUT));
8266			if (err < 0)
8267				return err;
8268		} else {
8269			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8270					  "Speaker Playback Switch",
8271					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8272							      HDA_OUTPUT));
8273			if (err < 0)
8274				return err;
8275		}
8276	}
8277	nid = cfg->hp_pins[0];
8278	if (nid) {
8279		/* spec->multiout.hp_nid = 2; */
8280		if (nid == 0x16) {
8281			err = add_control(spec, ALC_CTL_WIDGET_VOL,
8282					  "Headphone Playback Volume",
8283					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8284							      HDA_OUTPUT));
8285			if (err < 0)
8286				return err;
8287			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8288					  "Headphone Playback Switch",
8289					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8290							      HDA_OUTPUT));
8291			if (err < 0)
8292				return err;
8293		} else {
8294			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8295					  "Headphone Playback Switch",
8296					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8297							      HDA_OUTPUT));
8298			if (err < 0)
8299				return err;
8300		}
8301	}
8302	return 0;
8303}
8304
8305/* identical with ALC880 */
8306#define alc262_auto_create_analog_input_ctls \
8307	alc880_auto_create_analog_input_ctls
8308
8309/*
8310 * generic initialization of ADC, input mixers and output mixers
8311 */
8312static struct hda_verb alc262_volume_init_verbs[] = {
8313	/*
8314	 * Unmute ADC0-2 and set the default input to mic-in
8315	 */
8316	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8317	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8318	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8319	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8320	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8321	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8322
8323	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8324	 * mixer widget
8325	 * Note: PASD motherboards uses the Line In 2 as the input for
8326	 * front panel mic (mic 2)
8327	 */
8328	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8329	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8330	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8331	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8332	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8333	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8334
8335	/*
8336	 * Set up output mixers (0x0c - 0x0f)
8337	 */
8338	/* set vol=0 to output mixers */
8339	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8340	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8341	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8342
8343	/* set up input amps for analog loopback */
8344	/* Amp Indices: DAC = 0, mixer = 1 */
8345	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8346	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8347	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8348	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8349	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8350	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8351
8352	/* FIXME: use matrix-type input source selection */
8353	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8354	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8355	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8356	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8357	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8358	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8359	/* Input mixer2 */
8360	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8361	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8362	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8363	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8364	/* Input mixer3 */
8365	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8366	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8367	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8368	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8369
8370	{ }
8371};
8372
8373static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8374	/*
8375	 * Unmute ADC0-2 and set the default input to mic-in
8376	 */
8377	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8378	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8379	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8380	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8381	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8382	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8383
8384	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8385	 * mixer widget
8386	 * Note: PASD motherboards uses the Line In 2 as the input for
8387	 * front panel mic (mic 2)
8388	 */
8389	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8390	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8391	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8392	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8393	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8394	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8395	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8396        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8397
8398	/*
8399	 * Set up output mixers (0x0c - 0x0e)
8400	 */
8401	/* set vol=0 to output mixers */
8402	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8403	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8404	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8405
8406	/* set up input amps for analog loopback */
8407	/* Amp Indices: DAC = 0, mixer = 1 */
8408	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8409	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8410	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8411	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8412	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8413	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8414
8415	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8416	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8417	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8418
8419	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8420	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8421
8422	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8423	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8424
8425	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8426	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8427        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8428	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8429	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8430
8431	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8432	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8433        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8434	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8435	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8436	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8437
8438
8439	/* FIXME: use matrix-type input source selection */
8440	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8441	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8442	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8443	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8444	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8445	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8446	/* Input mixer2 */
8447	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8448	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8449	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8450	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8451	/* Input mixer3 */
8452	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8453	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8454	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8455	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8456
8457	{ }
8458};
8459
8460static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8461	/*
8462	 * Unmute ADC0-2 and set the default input to mic-in
8463	 */
8464	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8465	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8467	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8468	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8469	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470
8471	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8472	 * mixer widget
8473	 * Note: PASD motherboards uses the Line In 2 as the input for front
8474	 * panel mic (mic 2)
8475	 */
8476	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8477	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8478	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8479	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8480	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8481	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8482	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8483	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8484	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8485	/*
8486	 * Set up output mixers (0x0c - 0x0e)
8487	 */
8488	/* set vol=0 to output mixers */
8489	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8490	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8491	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8492
8493	/* set up input amps for analog loopback */
8494	/* Amp Indices: DAC = 0, mixer = 1 */
8495	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8496	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8497	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8498	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8499	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8500	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8501
8502
8503	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
8504	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
8505	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
8506	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
8507	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
8508	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
8509	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
8510
8511	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8512	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8513
8514	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8515	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8516
8517	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8518	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8519	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8520	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8521	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8522	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8523
8524	/* FIXME: use matrix-type input source selection */
8525	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8526	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8527	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8528	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8529	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8530	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8531	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8532        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8533	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8534	/* Input mixer2 */
8535	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8536	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8537	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8538	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8539	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8540        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8541	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8542	/* Input mixer3 */
8543	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8544	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8545	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8546	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8547	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8548        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8549	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8550
8551	{ }
8552};
8553
8554#ifdef CONFIG_SND_HDA_POWER_SAVE
8555#define alc262_loopbacks	alc880_loopbacks
8556#endif
8557
8558/* pcm configuration: identiacal with ALC880 */
8559#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
8560#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
8561#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
8562#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
8563
8564/*
8565 * BIOS auto configuration
8566 */
8567static int alc262_parse_auto_config(struct hda_codec *codec)
8568{
8569	struct alc_spec *spec = codec->spec;
8570	int err;
8571	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8572
8573	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8574					   alc262_ignore);
8575	if (err < 0)
8576		return err;
8577	if (!spec->autocfg.line_outs)
8578		return 0; /* can't find valid BIOS pin config */
8579	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8580	if (err < 0)
8581		return err;
8582	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8583	if (err < 0)
8584		return err;
8585
8586	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8587
8588	if (spec->autocfg.dig_out_pin)
8589		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8590	if (spec->autocfg.dig_in_pin)
8591		spec->dig_in_nid = ALC262_DIGIN_NID;
8592
8593	if (spec->kctl_alloc)
8594		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8595
8596	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8597	spec->num_mux_defs = 1;
8598	spec->input_mux = &spec->private_imux;
8599
8600	err = alc_auto_add_mic_boost(codec);
8601	if (err < 0)
8602		return err;
8603
8604	return 1;
8605}
8606
8607#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
8608#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
8609#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
8610
8611
8612/* init callback for auto-configuration model -- overriding the default init */
8613static void alc262_auto_init(struct hda_codec *codec)
8614{
8615	alc262_auto_init_multi_out(codec);
8616	alc262_auto_init_hp_out(codec);
8617	alc262_auto_init_analog_input(codec);
8618}
8619
8620/*
8621 * configuration and preset
8622 */
8623static const char *alc262_models[ALC262_MODEL_LAST] = {
8624	[ALC262_BASIC]		= "basic",
8625	[ALC262_HIPPO]		= "hippo",
8626	[ALC262_HIPPO_1]	= "hippo_1",
8627	[ALC262_FUJITSU]	= "fujitsu",
8628	[ALC262_HP_BPC]		= "hp-bpc",
8629	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8630	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
8631	[ALC262_BENQ_ED8]	= "benq",
8632	[ALC262_BENQ_T31]	= "benq-t31",
8633	[ALC262_SONY_ASSAMD]	= "sony-assamd",
8634	[ALC262_ULTRA]		= "ultra",
8635	[ALC262_AUTO]		= "auto",
8636};
8637
8638static struct snd_pci_quirk alc262_cfg_tbl[] = {
8639	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8640	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8641	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8642	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8643	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8644	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
8645	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8646	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8647	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
8648	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8649	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8650	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
8651	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8652	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8653	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8654	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8655	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8656	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8657	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8658	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8659	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8660		      ALC262_HP_TC_T5735),
8661	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8662	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8663	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8664	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8665	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8666	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8667	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8668	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8669	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8670	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
8671	{}
8672};
8673
8674static struct alc_config_preset alc262_presets[] = {
8675	[ALC262_BASIC] = {
8676		.mixers = { alc262_base_mixer },
8677		.init_verbs = { alc262_init_verbs },
8678		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8679		.dac_nids = alc262_dac_nids,
8680		.hp_nid = 0x03,
8681		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8682		.channel_mode = alc262_modes,
8683		.input_mux = &alc262_capture_source,
8684	},
8685	[ALC262_HIPPO] = {
8686		.mixers = { alc262_base_mixer },
8687		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8688		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8689		.dac_nids = alc262_dac_nids,
8690		.hp_nid = 0x03,
8691		.dig_out_nid = ALC262_DIGOUT_NID,
8692		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8693		.channel_mode = alc262_modes,
8694		.input_mux = &alc262_capture_source,
8695		.unsol_event = alc262_hippo_unsol_event,
8696		.init_hook = alc262_hippo_automute,
8697	},
8698	[ALC262_HIPPO_1] = {
8699		.mixers = { alc262_hippo1_mixer },
8700		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8701		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8702		.dac_nids = alc262_dac_nids,
8703		.hp_nid = 0x02,
8704		.dig_out_nid = ALC262_DIGOUT_NID,
8705		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8706		.channel_mode = alc262_modes,
8707		.input_mux = &alc262_capture_source,
8708		.unsol_event = alc262_hippo1_unsol_event,
8709		.init_hook = alc262_hippo1_automute,
8710	},
8711	[ALC262_FUJITSU] = {
8712		.mixers = { alc262_fujitsu_mixer },
8713		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8714				alc262_fujitsu_unsol_verbs },
8715		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8716		.dac_nids = alc262_dac_nids,
8717		.hp_nid = 0x03,
8718		.dig_out_nid = ALC262_DIGOUT_NID,
8719		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8720		.channel_mode = alc262_modes,
8721		.input_mux = &alc262_fujitsu_capture_source,
8722		.unsol_event = alc262_fujitsu_unsol_event,
8723	},
8724	[ALC262_HP_BPC] = {
8725		.mixers = { alc262_HP_BPC_mixer },
8726		.init_verbs = { alc262_HP_BPC_init_verbs },
8727		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8728		.dac_nids = alc262_dac_nids,
8729		.hp_nid = 0x03,
8730		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8731		.channel_mode = alc262_modes,
8732		.input_mux = &alc262_HP_capture_source,
8733	},
8734	[ALC262_HP_BPC_D7000_WF] = {
8735		.mixers = { alc262_HP_BPC_WildWest_mixer },
8736		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8737		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8738		.dac_nids = alc262_dac_nids,
8739		.hp_nid = 0x03,
8740		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8741		.channel_mode = alc262_modes,
8742		.input_mux = &alc262_HP_D7000_capture_source,
8743	},
8744	[ALC262_HP_BPC_D7000_WL] = {
8745		.mixers = { alc262_HP_BPC_WildWest_mixer,
8746			    alc262_HP_BPC_WildWest_option_mixer },
8747		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8748		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8749		.dac_nids = alc262_dac_nids,
8750		.hp_nid = 0x03,
8751		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8752		.channel_mode = alc262_modes,
8753		.input_mux = &alc262_HP_D7000_capture_source,
8754	},
8755	[ALC262_HP_TC_T5735] = {
8756		.mixers = { alc262_hp_t5735_mixer },
8757		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
8758		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8759		.dac_nids = alc262_dac_nids,
8760		.hp_nid = 0x03,
8761		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8762		.channel_mode = alc262_modes,
8763		.input_mux = &alc262_capture_source,
8764		.unsol_event = alc262_hp_t5735_unsol_event,
8765		.init_hook = alc262_hp_t5735_init_hook,
8766        },
8767	[ALC262_BENQ_ED8] = {
8768		.mixers = { alc262_base_mixer },
8769		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8770		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8771		.dac_nids = alc262_dac_nids,
8772		.hp_nid = 0x03,
8773		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8774		.channel_mode = alc262_modes,
8775		.input_mux = &alc262_capture_source,
8776	},
8777	[ALC262_SONY_ASSAMD] = {
8778		.mixers = { alc262_sony_mixer },
8779		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8780		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8781		.dac_nids = alc262_dac_nids,
8782		.hp_nid = 0x02,
8783		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8784		.channel_mode = alc262_modes,
8785		.input_mux = &alc262_capture_source,
8786		.unsol_event = alc262_hippo_unsol_event,
8787		.init_hook = alc262_hippo_automute,
8788	},
8789	[ALC262_BENQ_T31] = {
8790		.mixers = { alc262_benq_t31_mixer },
8791		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8792		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8793		.dac_nids = alc262_dac_nids,
8794		.hp_nid = 0x03,
8795		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8796		.channel_mode = alc262_modes,
8797		.input_mux = &alc262_capture_source,
8798		.unsol_event = alc262_hippo_unsol_event,
8799		.init_hook = alc262_hippo_automute,
8800	},
8801	[ALC262_ULTRA] = {
8802		.mixers = { alc262_ultra_mixer },
8803		.init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8804		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8805		.dac_nids = alc262_dac_nids,
8806		.hp_nid = 0x03,
8807		.dig_out_nid = ALC262_DIGOUT_NID,
8808		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8809		.channel_mode = alc262_modes,
8810		.input_mux = &alc262_ultra_capture_source,
8811		.unsol_event = alc262_ultra_unsol_event,
8812		.init_hook = alc262_ultra_automute,
8813	},
8814};
8815
8816static int patch_alc262(struct hda_codec *codec)
8817{
8818	struct alc_spec *spec;
8819	int board_config;
8820	int err;
8821
8822	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8823	if (spec == NULL)
8824		return -ENOMEM;
8825
8826	codec->spec = spec;
8827#if 0
8828	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8829	 * under-run
8830	 */
8831	{
8832	int tmp;
8833	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8834	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8835	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8836	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8837	}
8838#endif
8839
8840	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8841						  alc262_models,
8842						  alc262_cfg_tbl);
8843
8844	if (board_config < 0) {
8845		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8846		       "trying auto-probe from BIOS...\n");
8847		board_config = ALC262_AUTO;
8848	}
8849
8850	if (board_config == ALC262_AUTO) {
8851		/* automatic parse from the BIOS config */
8852		err = alc262_parse_auto_config(codec);
8853		if (err < 0) {
8854			alc_free(codec);
8855			return err;
8856		} else if (!err) {
8857			printk(KERN_INFO
8858			       "hda_codec: Cannot set up configuration "
8859			       "from BIOS.  Using base mode...\n");
8860			board_config = ALC262_BASIC;
8861		}
8862	}
8863
8864	if (board_config != ALC262_AUTO)
8865		setup_preset(spec, &alc262_presets[board_config]);
8866
8867	spec->stream_name_analog = "ALC262 Analog";
8868	spec->stream_analog_playback = &alc262_pcm_analog_playback;
8869	spec->stream_analog_capture = &alc262_pcm_analog_capture;
8870
8871	spec->stream_name_digital = "ALC262 Digital";
8872	spec->stream_digital_playback = &alc262_pcm_digital_playback;
8873	spec->stream_digital_capture = &alc262_pcm_digital_capture;
8874
8875	if (!spec->adc_nids && spec->input_mux) {
8876		/* check whether NID 0x07 is valid */
8877		unsigned int wcap = get_wcaps(codec, 0x07);
8878
8879		/* get type */
8880		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8881		if (wcap != AC_WID_AUD_IN) {
8882			spec->adc_nids = alc262_adc_nids_alt;
8883			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8884			spec->mixers[spec->num_mixers] =
8885				alc262_capture_alt_mixer;
8886			spec->num_mixers++;
8887		} else {
8888			spec->adc_nids = alc262_adc_nids;
8889			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8890			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8891			spec->num_mixers++;
8892		}
8893	}
8894
8895	codec->patch_ops = alc_patch_ops;
8896	if (board_config == ALC262_AUTO)
8897		spec->init_hook = alc262_auto_init;
8898#ifdef CONFIG_SND_HDA_POWER_SAVE
8899	if (!spec->loopback.amplist)
8900		spec->loopback.amplist = alc262_loopbacks;
8901#endif
8902
8903	return 0;
8904}
8905
8906/*
8907 *  ALC268 channel source setting (2 channel)
8908 */
8909#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
8910#define alc268_modes		alc260_modes
8911
8912static hda_nid_t alc268_dac_nids[2] = {
8913	/* front, hp */
8914	0x02, 0x03
8915};
8916
8917static hda_nid_t alc268_adc_nids[2] = {
8918	/* ADC0-1 */
8919	0x08, 0x07
8920};
8921
8922static hda_nid_t alc268_adc_nids_alt[1] = {
8923	/* ADC0 */
8924	0x08
8925};
8926
8927static struct snd_kcontrol_new alc268_base_mixer[] = {
8928	/* output mixer control */
8929	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8930	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8931	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8932	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8933	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8934	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8935	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
8936	{ }
8937};
8938
8939static struct hda_verb alc268_eapd_verbs[] = {
8940	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8941	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8942	{ }
8943};
8944
8945/* Toshiba specific */
8946#define alc268_toshiba_automute	alc262_hippo_automute
8947
8948static struct hda_verb alc268_toshiba_verbs[] = {
8949	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8950	{ } /* end */
8951};
8952
8953/* Acer specific */
8954/* bind volumes of both NID 0x02 and 0x03 */
8955static struct hda_bind_ctls alc268_acer_bind_master_vol = {
8956	.ops = &snd_hda_bind_vol,
8957	.values = {
8958		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
8959		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
8960		0
8961	},
8962};
8963
8964/* mute/unmute internal speaker according to the hp jack and mute state */
8965static void alc268_acer_automute(struct hda_codec *codec, int force)
8966{
8967	struct alc_spec *spec = codec->spec;
8968	unsigned int mute;
8969
8970	if (force || !spec->sense_updated) {
8971		unsigned int present;
8972		present = snd_hda_codec_read(codec, 0x14, 0,
8973				    	 AC_VERB_GET_PIN_SENSE, 0);
8974		spec->jack_present = (present & 0x80000000) != 0;
8975		spec->sense_updated = 1;
8976	}
8977	if (spec->jack_present)
8978		mute = HDA_AMP_MUTE; /* mute internal speaker */
8979	else /* unmute internal speaker if necessary */
8980		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8981	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8982				 HDA_AMP_MUTE, mute);
8983}
8984
8985
8986/* bind hp and internal speaker mute (with plug check) */
8987static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
8988				     struct snd_ctl_elem_value *ucontrol)
8989{
8990	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8991	long *valp = ucontrol->value.integer.value;
8992	int change;
8993
8994	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8995					  HDA_AMP_MUTE,
8996					  valp[0] ? 0 : HDA_AMP_MUTE);
8997	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8998					   HDA_AMP_MUTE,
8999					   valp[1] ? 0 : HDA_AMP_MUTE);
9000	if (change)
9001		alc268_acer_automute(codec, 0);
9002	return change;
9003}
9004
9005static struct snd_kcontrol_new alc268_acer_mixer[] = {
9006	/* output mixer control */
9007	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9008	{
9009		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9010		.name = "Master Playback Switch",
9011		.info = snd_hda_mixer_amp_switch_info,
9012		.get = snd_hda_mixer_amp_switch_get,
9013		.put = alc268_acer_master_sw_put,
9014		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9015	},
9016	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9017	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9018	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9019	{ }
9020};
9021
9022static struct hda_verb alc268_acer_verbs[] = {
9023	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9024	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9025
9026	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9027	{ }
9028};
9029
9030/* unsolicited event for HP jack sensing */
9031static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9032				       unsigned int res)
9033{
9034	if ((res >> 26) != ALC880_HP_EVENT)
9035		return;
9036	alc268_toshiba_automute(codec);
9037}
9038
9039static void alc268_acer_unsol_event(struct hda_codec *codec,
9040				       unsigned int res)
9041{
9042	if ((res >> 26) != ALC880_HP_EVENT)
9043		return;
9044	alc268_acer_automute(codec, 1);
9045}
9046
9047static void alc268_acer_init_hook(struct hda_codec *codec)
9048{
9049	alc268_acer_automute(codec, 1);
9050}
9051
9052/*
9053 * generic initialization of ADC, input mixers and output mixers
9054 */
9055static struct hda_verb alc268_base_init_verbs[] = {
9056	/* Unmute DAC0-1 and set vol = 0 */
9057	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9058	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9059	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9060	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9061	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9063
9064	/*
9065	 * Set up output mixers (0x0c - 0x0e)
9066	 */
9067	/* set vol=0 to output mixers */
9068	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9070	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9071        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9072
9073	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9074	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9075
9076	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9077	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9078	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9079	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9080	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9081	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9082	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9083	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9084
9085	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9086	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9087	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9088	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9089	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9090	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9091	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9092	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9093
9094	/* FIXME: use matrix-type input source selection */
9095	/* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
9096	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9097	/* Input mixer2 */
9098	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9099	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9100	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9101	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9102
9103	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9104	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9105	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9106	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9107	{ }
9108};
9109
9110/*
9111 * generic initialization of ADC, input mixers and output mixers
9112 */
9113static struct hda_verb alc268_volume_init_verbs[] = {
9114	/* set output DAC */
9115	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9116	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9117	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9118	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9119
9120	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9121	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9122	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9123	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9124	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9125
9126	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9127	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9128	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9129	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9130	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9131
9132	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9133	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9134	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9135	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9136
9137	/* set PCBEEP vol = 0 */
9138	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9139
9140	{ }
9141};
9142
9143#define alc268_mux_enum_info alc_mux_enum_info
9144#define alc268_mux_enum_get alc_mux_enum_get
9145
9146static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9147			       struct snd_ctl_elem_value *ucontrol)
9148{
9149	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9150	struct alc_spec *spec = codec->spec;
9151	const struct hda_input_mux *imux = spec->input_mux;
9152	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9153	static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9154	hda_nid_t nid = capture_mixers[adc_idx];
9155	unsigned int *cur_val = &spec->cur_mux[adc_idx];
9156	unsigned int i, idx;
9157
9158	idx = ucontrol->value.enumerated.item[0];
9159	if (idx >= imux->num_items)
9160		idx = imux->num_items - 1;
9161	if (*cur_val == idx)
9162		return 0;
9163	for (i = 0; i < imux->num_items; i++) {
9164		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
9165		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
9166					 imux->items[i].index,
9167					 HDA_AMP_MUTE, v);
9168                snd_hda_codec_write_cache(codec, nid, 0,
9169					  AC_VERB_SET_CONNECT_SEL,
9170					  idx );
9171	}
9172	*cur_val = idx;
9173	return 1;
9174}
9175
9176static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9177	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9178	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9179	{
9180		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9181		/* The multiple "Capture Source" controls confuse alsamixer
9182		 * So call somewhat different..
9183		 * FIXME: the controls appear in the "playback" view!
9184		 */
9185		/* .name = "Capture Source", */
9186		.name = "Input Source",
9187		.count = 1,
9188		.info = alc268_mux_enum_info,
9189		.get = alc268_mux_enum_get,
9190		.put = alc268_mux_enum_put,
9191	},
9192	{ } /* end */
9193};
9194
9195static struct snd_kcontrol_new alc268_capture_mixer[] = {
9196	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9197	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9198	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9199	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9200	{
9201		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9202		/* The multiple "Capture Source" controls confuse alsamixer
9203		 * So call somewhat different..
9204		 * FIXME: the controls appear in the "playback" view!
9205		 */
9206		/* .name = "Capture Source", */
9207		.name = "Input Source",
9208		.count = 2,
9209		.info = alc268_mux_enum_info,
9210		.get = alc268_mux_enum_get,
9211		.put = alc268_mux_enum_put,
9212	},
9213	{ } /* end */
9214};
9215
9216static struct hda_input_mux alc268_capture_source = {
9217	.num_items = 4,
9218	.items = {
9219		{ "Mic", 0x0 },
9220		{ "Front Mic", 0x1 },
9221		{ "Line", 0x2 },
9222		{ "CD", 0x3 },
9223	},
9224};
9225
9226/* create input playback/capture controls for the given pin */
9227static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9228				    const char *ctlname, int idx)
9229{
9230	char name[32];
9231	int err;
9232
9233	sprintf(name, "%s Playback Volume", ctlname);
9234	if (nid == 0x14) {
9235		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9236				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9237						      HDA_OUTPUT));
9238		if (err < 0)
9239			return err;
9240	} else if (nid == 0x15) {
9241		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9242				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9243						      HDA_OUTPUT));
9244		if (err < 0)
9245			return err;
9246	} else
9247		return -1;
9248	sprintf(name, "%s Playback Switch", ctlname);
9249	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9250			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9251	if (err < 0)
9252		return err;
9253	return 0;
9254}
9255
9256/* add playback controls from the parsed DAC table */
9257static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9258					     const struct auto_pin_cfg *cfg)
9259{
9260	hda_nid_t nid;
9261	int err;
9262
9263	spec->multiout.num_dacs = 2;	/* only use one dac */
9264	spec->multiout.dac_nids = spec->private_dac_nids;
9265	spec->multiout.dac_nids[0] = 2;
9266	spec->multiout.dac_nids[1] = 3;
9267
9268	nid = cfg->line_out_pins[0];
9269	if (nid)
9270		alc268_new_analog_output(spec, nid, "Front", 0);
9271
9272	nid = cfg->speaker_pins[0];
9273	if (nid == 0x1d) {
9274		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9275				  "Speaker Playback Volume",
9276				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9277		if (err < 0)
9278			return err;
9279	}
9280	nid = cfg->hp_pins[0];
9281	if (nid)
9282		alc268_new_analog_output(spec, nid, "Headphone", 0);
9283
9284	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9285	if (nid == 0x16) {
9286		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9287				  "Mono Playback Switch",
9288				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9289		if (err < 0)
9290			return err;
9291	}
9292	return 0;
9293}
9294
9295/* create playback/capture controls for input pins */
9296static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9297						const struct auto_pin_cfg *cfg)
9298{
9299	struct hda_input_mux *imux = &spec->private_imux;
9300	int i, idx1;
9301
9302	for (i = 0; i < AUTO_PIN_LAST; i++) {
9303		switch(cfg->input_pins[i]) {
9304		case 0x18:
9305			idx1 = 0;	/* Mic 1 */
9306			break;
9307		case 0x19:
9308			idx1 = 1;	/* Mic 2 */
9309			break;
9310		case 0x1a:
9311			idx1 = 2;	/* Line In */
9312			break;
9313		case 0x1c:
9314			idx1 = 3;	/* CD */
9315			break;
9316		default:
9317			continue;
9318		}
9319		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9320		imux->items[imux->num_items].index = idx1;
9321		imux->num_items++;
9322	}
9323	return 0;
9324}
9325
9326static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9327{
9328	struct alc_spec *spec = codec->spec;
9329	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9330	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9331	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9332	unsigned int	dac_vol1, dac_vol2;
9333
9334	if (speaker_nid) {
9335		snd_hda_codec_write(codec, speaker_nid, 0,
9336				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9337		snd_hda_codec_write(codec, 0x0f, 0,
9338				    AC_VERB_SET_AMP_GAIN_MUTE,
9339				    AMP_IN_UNMUTE(1));
9340		snd_hda_codec_write(codec, 0x10, 0,
9341				    AC_VERB_SET_AMP_GAIN_MUTE,
9342				    AMP_IN_UNMUTE(1));
9343	} else {
9344		snd_hda_codec_write(codec, 0x0f, 0,
9345				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9346		snd_hda_codec_write(codec, 0x10, 0,
9347				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9348	}
9349
9350	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
9351	if (line_nid == 0x14)
9352		dac_vol2 = AMP_OUT_ZERO;
9353	else if (line_nid == 0x15)
9354		dac_vol1 = AMP_OUT_ZERO;
9355	if (hp_nid == 0x14)
9356		dac_vol2 = AMP_OUT_ZERO;
9357	else if (hp_nid == 0x15)
9358		dac_vol1 = AMP_OUT_ZERO;
9359	if (line_nid != 0x16 || hp_nid != 0x16 ||
9360	    spec->autocfg.line_out_pins[1] != 0x16 ||
9361	    spec->autocfg.line_out_pins[2] != 0x16)
9362		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9363
9364	snd_hda_codec_write(codec, 0x02, 0,
9365			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9366	snd_hda_codec_write(codec, 0x03, 0,
9367			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9368}
9369
9370/* pcm configuration: identiacal with ALC880 */
9371#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
9372#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
9373#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
9374
9375/*
9376 * BIOS auto configuration
9377 */
9378static int alc268_parse_auto_config(struct hda_codec *codec)
9379{
9380	struct alc_spec *spec = codec->spec;
9381	int err;
9382	static hda_nid_t alc268_ignore[] = { 0 };
9383
9384	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9385					   alc268_ignore);
9386	if (err < 0)
9387		return err;
9388	if (!spec->autocfg.line_outs)
9389		return 0; /* can't find valid BIOS pin config */
9390
9391	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9392	if (err < 0)
9393		return err;
9394	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9395	if (err < 0)
9396		return err;
9397
9398	spec->multiout.max_channels = 2;
9399
9400	/* digital only support output */
9401	if (spec->autocfg.dig_out_pin)
9402		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9403
9404	if (spec->kctl_alloc)
9405		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9406
9407	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9408	spec->num_mux_defs = 1;
9409	spec->input_mux = &spec->private_imux;
9410
9411	err = alc_auto_add_mic_boost(codec);
9412	if (err < 0)
9413		return err;
9414
9415	return 1;
9416}
9417
9418#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
9419#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
9420#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
9421
9422/* init callback for auto-configuration model -- overriding the default init */
9423static void alc268_auto_init(struct hda_codec *codec)
9424{
9425	alc268_auto_init_multi_out(codec);
9426	alc268_auto_init_hp_out(codec);
9427	alc268_auto_init_mono_speaker_out(codec);
9428	alc268_auto_init_analog_input(codec);
9429}
9430
9431/*
9432 * configuration and preset
9433 */
9434static const char *alc268_models[ALC268_MODEL_LAST] = {
9435	[ALC268_3ST]		= "3stack",
9436	[ALC268_TOSHIBA]	= "toshiba",
9437	[ALC268_ACER]		= "acer",
9438	[ALC268_AUTO]		= "auto",
9439};
9440
9441static struct snd_pci_quirk alc268_cfg_tbl[] = {
9442	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9443	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9444	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9445	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9446	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9447	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9448	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9449	{}
9450};
9451
9452static struct alc_config_preset alc268_presets[] = {
9453	[ALC268_3ST] = {
9454		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9455		.init_verbs = { alc268_base_init_verbs },
9456		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
9457		.dac_nids = alc268_dac_nids,
9458                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9459                .adc_nids = alc268_adc_nids_alt,
9460		.hp_nid = 0x03,
9461		.dig_out_nid = ALC268_DIGOUT_NID,
9462		.num_channel_mode = ARRAY_SIZE(alc268_modes),
9463		.channel_mode = alc268_modes,
9464		.input_mux = &alc268_capture_source,
9465	},
9466	[ALC268_TOSHIBA] = {
9467		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9468		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9469				alc268_toshiba_verbs },
9470		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
9471		.dac_nids = alc268_dac_nids,
9472		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9473		.adc_nids = alc268_adc_nids_alt,
9474		.hp_nid = 0x03,
9475		.num_channel_mode = ARRAY_SIZE(alc268_modes),
9476		.channel_mode = alc268_modes,
9477		.input_mux = &alc268_capture_source,
9478		.unsol_event = alc268_toshiba_unsol_event,
9479		.init_hook = alc268_toshiba_automute,
9480	},
9481	[ALC268_ACER] = {
9482		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9483		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9484				alc268_acer_verbs },
9485		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
9486		.dac_nids = alc268_dac_nids,
9487		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9488		.adc_nids = alc268_adc_nids_alt,
9489		.hp_nid = 0x02,
9490		.num_channel_mode = ARRAY_SIZE(alc268_modes),
9491		.channel_mode = alc268_modes,
9492		.input_mux = &alc268_capture_source,
9493		.unsol_event = alc268_acer_unsol_event,
9494		.init_hook = alc268_acer_init_hook,
9495	},
9496};
9497
9498static int patch_alc268(struct hda_codec *codec)
9499{
9500	struct alc_spec *spec;
9501	int board_config;
9502	int err;
9503
9504	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9505	if (spec == NULL)
9506		return -ENOMEM;
9507
9508	codec->spec = spec;
9509
9510	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9511						  alc268_models,
9512						  alc268_cfg_tbl);
9513
9514	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9515		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9516		       "trying auto-probe from BIOS...\n");
9517		board_config = ALC268_AUTO;
9518	}
9519
9520	if (board_config == ALC268_AUTO) {
9521		/* automatic parse from the BIOS config */
9522		err = alc268_parse_auto_config(codec);
9523		if (err < 0) {
9524			alc_free(codec);
9525			return err;
9526		} else if (!err) {
9527			printk(KERN_INFO
9528			       "hda_codec: Cannot set up configuration "
9529			       "from BIOS.  Using base mode...\n");
9530			board_config = ALC268_3ST;
9531		}
9532	}
9533
9534	if (board_config != ALC268_AUTO)
9535		setup_preset(spec, &alc268_presets[board_config]);
9536
9537	spec->stream_name_analog = "ALC268 Analog";
9538	spec->stream_analog_playback = &alc268_pcm_analog_playback;
9539	spec->stream_analog_capture = &alc268_pcm_analog_capture;
9540
9541	spec->stream_name_digital = "ALC268 Digital";
9542	spec->stream_digital_playback = &alc268_pcm_digital_playback;
9543
9544	if (board_config == ALC268_AUTO) {
9545		if (!spec->adc_nids && spec->input_mux) {
9546			/* check whether NID 0x07 is valid */
9547			unsigned int wcap = get_wcaps(codec, 0x07);
9548
9549			/* get type */
9550			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9551			if (wcap != AC_WID_AUD_IN) {
9552				spec->adc_nids = alc268_adc_nids_alt;
9553				spec->num_adc_nids =
9554					ARRAY_SIZE(alc268_adc_nids_alt);
9555				spec->mixers[spec->num_mixers] =
9556					alc268_capture_alt_mixer;
9557				spec->num_mixers++;
9558			} else {
9559				spec->adc_nids = alc268_adc_nids;
9560				spec->num_adc_nids =
9561					ARRAY_SIZE(alc268_adc_nids);
9562				spec->mixers[spec->num_mixers] =
9563					alc268_capture_mixer;
9564				spec->num_mixers++;
9565			}
9566		}
9567	}
9568	codec->patch_ops = alc_patch_ops;
9569	if (board_config == ALC268_AUTO)
9570		spec->init_hook = alc268_auto_init;
9571
9572	return 0;
9573}
9574
9575/*
9576 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
9577 */
9578
9579/*
9580 * set the path ways for 2 channel output
9581 * need to set the codec line out and mic 1 pin widgets to inputs
9582 */
9583static struct hda_verb alc861_threestack_ch2_init[] = {
9584	/* set pin widget 1Ah (line in) for input */
9585	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9586	/* set pin widget 18h (mic1/2) for input, for mic also enable
9587	 * the vref
9588	 */
9589	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9590
9591	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9592#if 0
9593	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9594	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9595#endif
9596	{ } /* end */
9597};
9598/*
9599 * 6ch mode
9600 * need to set the codec line out and mic 1 pin widgets to outputs
9601 */
9602static struct hda_verb alc861_threestack_ch6_init[] = {
9603	/* set pin widget 1Ah (line in) for output (Back Surround)*/
9604	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9605	/* set pin widget 18h (mic1) for output (CLFE)*/
9606	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9607
9608	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9609	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9610
9611	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9612#if 0
9613	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9614	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9615#endif
9616	{ } /* end */
9617};
9618
9619static struct hda_channel_mode alc861_threestack_modes[2] = {
9620	{ 2, alc861_threestack_ch2_init },
9621	{ 6, alc861_threestack_ch6_init },
9622};
9623/* Set mic1 as input and unmute the mixer */
9624static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
9625	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9626	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9627	{ } /* end */
9628};
9629/* Set mic1 as output and mute mixer */
9630static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
9631	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9632	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9633	{ } /* end */
9634};
9635
9636static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
9637	{ 2, alc861_uniwill_m31_ch2_init },
9638	{ 4, alc861_uniwill_m31_ch4_init },
9639};
9640
9641/* Set mic1 and line-in as input and unmute the mixer */
9642static struct hda_verb alc861_asus_ch2_init[] = {
9643	/* set pin widget 1Ah (line in) for input */
9644	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9645	/* set pin widget 18h (mic1/2) for input, for mic also enable
9646	 * the vref
9647	 */
9648	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9649
9650	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9651#if 0
9652	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9653	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9654#endif
9655	{ } /* end */
9656};
9657/* Set mic1 nad line-in as output and mute mixer */
9658static struct hda_verb alc861_asus_ch6_init[] = {
9659	/* set pin widget 1Ah (line in) for output (Back Surround)*/
9660	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9661	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9662	/* set pin widget 18h (mic1) for output (CLFE)*/
9663	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9664	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9665	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9666	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9667
9668	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9669#if 0
9670	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9671	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9672#endif
9673	{ } /* end */
9674};
9675
9676static struct hda_channel_mode alc861_asus_modes[2] = {
9677	{ 2, alc861_asus_ch2_init },
9678	{ 6, alc861_asus_ch6_init },
9679};
9680
9681/* patch-ALC861 */
9682
9683static struct snd_kcontrol_new alc861_base_mixer[] = {
9684        /* output mixer control */
9685	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9686	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9687	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9688	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9689	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9690
9691        /*Input mixer control */
9692	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9693	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9694	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9695	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9696	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9697	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9698	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9699	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9700	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9701	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9702
9703        /* Capture mixer control */
9704	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9705	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9706	{
9707		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9708		.name = "Capture Source",
9709		.count = 1,
9710		.info = alc_mux_enum_info,
9711		.get = alc_mux_enum_get,
9712		.put = alc_mux_enum_put,
9713	},
9714	{ } /* end */
9715};
9716
9717static struct snd_kcontrol_new alc861_3ST_mixer[] = {
9718        /* output mixer control */
9719	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9720	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9721	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9722	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9723	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9724
9725	/* Input mixer control */
9726	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9727	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9728	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9729	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9730	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9731	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9732	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9733	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9734	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9735	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9736
9737	/* Capture mixer control */
9738	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9739	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9740	{
9741		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9742		.name = "Capture Source",
9743		.count = 1,
9744		.info = alc_mux_enum_info,
9745		.get = alc_mux_enum_get,
9746		.put = alc_mux_enum_put,
9747	},
9748	{
9749		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9750		.name = "Channel Mode",
9751		.info = alc_ch_mode_info,
9752		.get = alc_ch_mode_get,
9753		.put = alc_ch_mode_put,
9754                .private_value = ARRAY_SIZE(alc861_threestack_modes),
9755	},
9756	{ } /* end */
9757};
9758
9759static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
9760        /* output mixer control */
9761	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9762	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9763	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9764
9765        /*Capture mixer control */
9766	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9767	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9768	{
9769		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9770		.name = "Capture Source",
9771		.count = 1,
9772		.info = alc_mux_enum_info,
9773		.get = alc_mux_enum_get,
9774		.put = alc_mux_enum_put,
9775	},
9776
9777	{ } /* end */
9778};
9779
9780static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
9781        /* output mixer control */
9782	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9783	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9784	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9785	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9786	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9787
9788	/* Input mixer control */
9789	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9790	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9791	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9792	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9793	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9794	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9795	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9796	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9797	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9798	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9799
9800	/* Capture mixer control */
9801	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9802	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9803	{
9804		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9805		.name = "Capture Source",
9806		.count = 1,
9807		.info = alc_mux_enum_info,
9808		.get = alc_mux_enum_get,
9809		.put = alc_mux_enum_put,
9810	},
9811	{
9812		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9813		.name = "Channel Mode",
9814		.info = alc_ch_mode_info,
9815		.get = alc_ch_mode_get,
9816		.put = alc_ch_mode_put,
9817                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
9818	},
9819	{ } /* end */
9820};
9821
9822static struct snd_kcontrol_new alc861_asus_mixer[] = {
9823        /* output mixer control */
9824	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9825	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9826	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9827	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9828	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9829
9830	/* Input mixer control */
9831	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9832	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9833	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9834	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9835	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9836	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9837	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9838	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9839	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9840	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
9841
9842	/* Capture mixer control */
9843	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9844	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9845	{
9846		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9847		.name = "Capture Source",
9848		.count = 1,
9849		.info = alc_mux_enum_info,
9850		.get = alc_mux_enum_get,
9851		.put = alc_mux_enum_put,
9852	},
9853	{
9854		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9855		.name = "Channel Mode",
9856		.info = alc_ch_mode_info,
9857		.get = alc_ch_mode_get,
9858		.put = alc_ch_mode_put,
9859                .private_value = ARRAY_SIZE(alc861_asus_modes),
9860	},
9861	{ }
9862};
9863
9864/* additional mixer */
9865static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9866	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9867	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9868	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9869	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9870	{ }
9871};
9872
9873/*
9874 * generic initialization of ADC, input mixers and output mixers
9875 */
9876static struct hda_verb alc861_base_init_verbs[] = {
9877	/*
9878	 * Unmute ADC0 and set the default input to mic-in
9879	 */
9880	/* port-A for surround (rear panel) */
9881	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9882	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9883	/* port-B for mic-in (rear panel) with vref */
9884	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9885	/* port-C for line-in (rear panel) */
9886	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9887	/* port-D for Front */
9888	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9889	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9890	/* port-E for HP out (front panel) */
9891	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9892	/* route front PCM to HP */
9893	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9894	/* port-F for mic-in (front panel) with vref */
9895	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9896	/* port-G for CLFE (rear panel) */
9897	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9898	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9899	/* port-H for side (rear panel) */
9900	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9901	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9902	/* CD-in */
9903	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9904	/* route front mic to ADC1*/
9905	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9906	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9907
9908	/* Unmute DAC0~3 & spdif out*/
9909	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9910	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9911	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9912	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9913	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9914
9915	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9916	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9917        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9918	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9919        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9920
9921	/* Unmute Stereo Mixer 15 */
9922	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9923	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9924	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9925	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9926
9927	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9928	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9929	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9930	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9931	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9932	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9933	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9934	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9935	/* hp used DAC 3 (Front) */
9936	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9937        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9938
9939	{ }
9940};
9941
9942static struct hda_verb alc861_threestack_init_verbs[] = {
9943	/*
9944	 * Unmute ADC0 and set the default input to mic-in
9945	 */
9946	/* port-A for surround (rear panel) */
9947	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9948	/* port-B for mic-in (rear panel) with vref */
9949	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9950	/* port-C for line-in (rear panel) */
9951	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9952	/* port-D for Front */
9953	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9954	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9955	/* port-E for HP out (front panel) */
9956	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9957	/* route front PCM to HP */
9958	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9959	/* port-F for mic-in (front panel) with vref */
9960	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9961	/* port-G for CLFE (rear panel) */
9962	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9963	/* port-H for side (rear panel) */
9964	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9965	/* CD-in */
9966	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9967	/* route front mic to ADC1*/
9968	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9969	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9970	/* Unmute DAC0~3 & spdif out*/
9971	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9972	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9973	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9974	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9975	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9976
9977	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9978	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9979        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9980	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9981        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9982
9983	/* Unmute Stereo Mixer 15 */
9984	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9985	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9986	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9987	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9988
9989	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9990	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9991	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9992	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9993	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9994	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9995	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9996	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9997	/* hp used DAC 3 (Front) */
9998	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9999        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10000	{ }
10001};
10002
10003static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10004	/*
10005	 * Unmute ADC0 and set the default input to mic-in
10006	 */
10007	/* port-A for surround (rear panel) */
10008	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10009	/* port-B for mic-in (rear panel) with vref */
10010	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10011	/* port-C for line-in (rear panel) */
10012	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10013	/* port-D for Front */
10014	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10015	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10016	/* port-E for HP out (front panel) */
10017	/* this has to be set to VREF80 */
10018	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10019	/* route front PCM to HP */
10020	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10021	/* port-F for mic-in (front panel) with vref */
10022	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10023	/* port-G for CLFE (rear panel) */
10024	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10025	/* port-H for side (rear panel) */
10026	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10027	/* CD-in */
10028	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10029	/* route front mic to ADC1*/
10030	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10031	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10032	/* Unmute DAC0~3 & spdif out*/
10033	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10034	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10035	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10036	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10037	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10038
10039	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10040	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10041        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10042	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10043        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10044
10045	/* Unmute Stereo Mixer 15 */
10046	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10047	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10048	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10049	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10050
10051	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10052	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10053	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10054	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10055	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10056	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10057	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10058	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10059	/* hp used DAC 3 (Front) */
10060	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10061        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10062	{ }
10063};
10064
10065static struct hda_verb alc861_asus_init_verbs[] = {
10066	/*
10067	 * Unmute ADC0 and set the default input to mic-in
10068	 */
10069	/* port-A for surround (rear panel)
10070	 * according to codec#0 this is the HP jack
10071	 */
10072	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10073	/* route front PCM to HP */
10074	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10075	/* port-B for mic-in (rear panel) with vref */
10076	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10077	/* port-C for line-in (rear panel) */
10078	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10079	/* port-D for Front */
10080	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10081	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10082	/* port-E for HP out (front panel) */
10083	/* this has to be set to VREF80 */
10084	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10085	/* route front PCM to HP */
10086	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10087	/* port-F for mic-in (front panel) with vref */
10088	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10089	/* port-G for CLFE (rear panel) */
10090	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10091	/* port-H for side (rear panel) */
10092	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10093	/* CD-in */
10094	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10095	/* route front mic to ADC1*/
10096	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10097	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10098	/* Unmute DAC0~3 & spdif out*/
10099	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10100	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10101	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10102	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10103	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10104	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10105	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10106        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10107	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10108        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10109
10110	/* Unmute Stereo Mixer 15 */
10111	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10112	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10113	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10114	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10115
10116	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10117	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10118	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10119	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10120	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10121	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10122	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10123	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10124	/* hp used DAC 3 (Front) */
10125	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10126	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10127	{ }
10128};
10129
10130/* additional init verbs for ASUS laptops */
10131static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10132	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10133	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10134	{ }
10135};
10136
10137/*
10138 * generic initialization of ADC, input mixers and output mixers
10139 */
10140static struct hda_verb alc861_auto_init_verbs[] = {
10141	/*
10142	 * Unmute ADC0 and set the default input to mic-in
10143	 */
10144	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
10145	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10146
10147	/* Unmute DAC0~3 & spdif out*/
10148	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10149	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10150	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10151	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10152	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10153
10154	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10155	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10156	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10157	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10158	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10159
10160	/* Unmute Stereo Mixer 15 */
10161	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10162	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10163	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10164	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10165
10166	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10167	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10168	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10169	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10170	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10171	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10172	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10173	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10174
10175	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10176	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10177	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10178	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10179	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10180	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10181	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10182	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10183
10184	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
10185
10186	{ }
10187};
10188
10189static struct hda_verb alc861_toshiba_init_verbs[] = {
10190	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10191
10192	{ }
10193};
10194
10195/* toggle speaker-output according to the hp-jack state */
10196static void alc861_toshiba_automute(struct hda_codec *codec)
10197{
10198	unsigned int present;
10199
10200	present = snd_hda_codec_read(codec, 0x0f, 0,
10201				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10202	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10203				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10204	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10205				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10206}
10207
10208static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10209				       unsigned int res)
10210{
10211	if ((res >> 26) == ALC880_HP_EVENT)
10212		alc861_toshiba_automute(codec);
10213}
10214
10215/* pcm configuration: identiacal with ALC880 */
10216#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
10217#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
10218#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
10219#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
10220
10221
10222#define ALC861_DIGOUT_NID	0x07
10223
10224static struct hda_channel_mode alc861_8ch_modes[1] = {
10225	{ 8, NULL }
10226};
10227
10228static hda_nid_t alc861_dac_nids[4] = {
10229	/* front, surround, clfe, side */
10230	0x03, 0x06, 0x05, 0x04
10231};
10232
10233static hda_nid_t alc660_dac_nids[3] = {
10234	/* front, clfe, surround */
10235	0x03, 0x05, 0x06
10236};
10237
10238static hda_nid_t alc861_adc_nids[1] = {
10239	/* ADC0-2 */
10240	0x08,
10241};
10242
10243static struct hda_input_mux alc861_capture_source = {
10244	.num_items = 5,
10245	.items = {
10246		{ "Mic", 0x0 },
10247		{ "Front Mic", 0x3 },
10248		{ "Line", 0x1 },
10249		{ "CD", 0x4 },
10250		{ "Mixer", 0x5 },
10251	},
10252};
10253
10254/* fill in the dac_nids table from the parsed pin configuration */
10255static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10256				     const struct auto_pin_cfg *cfg)
10257{
10258	int i;
10259	hda_nid_t nid;
10260
10261	spec->multiout.dac_nids = spec->private_dac_nids;
10262	for (i = 0; i < cfg->line_outs; i++) {
10263		nid = cfg->line_out_pins[i];
10264		if (nid) {
10265			if (i >= ARRAY_SIZE(alc861_dac_nids))
10266				continue;
10267			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10268		}
10269	}
10270	spec->multiout.num_dacs = cfg->line_outs;
10271	return 0;
10272}
10273
10274/* add playback controls from the parsed DAC table */
10275static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10276					     const struct auto_pin_cfg *cfg)
10277{
10278	char name[32];
10279	static const char *chname[4] = {
10280		"Front", "Surround", NULL /*CLFE*/, "Side"
10281	};
10282	hda_nid_t nid;
10283	int i, idx, err;
10284
10285	for (i = 0; i < cfg->line_outs; i++) {
10286		nid = spec->multiout.dac_nids[i];
10287		if (!nid)
10288			continue;
10289		if (nid == 0x05) {
10290			/* Center/LFE */
10291			err = add_control(spec, ALC_CTL_BIND_MUTE,
10292					  "Center Playback Switch",
10293					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10294							      HDA_OUTPUT));
10295			if (err < 0)
10296				return err;
10297			err = add_control(spec, ALC_CTL_BIND_MUTE,
10298					  "LFE Playback Switch",
10299					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10300							      HDA_OUTPUT));
10301			if (err < 0)
10302				return err;
10303		} else {
10304			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10305			     idx++)
10306				if (nid == alc861_dac_nids[idx])
10307					break;
10308			sprintf(name, "%s Playback Switch", chname[idx]);
10309			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10310					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10311							      HDA_OUTPUT));
10312			if (err < 0)
10313				return err;
10314		}
10315	}
10316	return 0;
10317}
10318
10319static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10320{
10321	int err;
10322	hda_nid_t nid;
10323
10324	if (!pin)
10325		return 0;
10326
10327	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10328		nid = 0x03;
10329		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10330				  "Headphone Playback Switch",
10331				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10332		if (err < 0)
10333			return err;
10334		spec->multiout.hp_nid = nid;
10335	}
10336	return 0;
10337}
10338
10339/* create playback/capture controls for input pins */
10340static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10341						const struct auto_pin_cfg *cfg)
10342{
10343	struct hda_input_mux *imux = &spec->private_imux;
10344	int i, err, idx, idx1;
10345
10346	for (i = 0; i < AUTO_PIN_LAST; i++) {
10347		switch (cfg->input_pins[i]) {
10348		case 0x0c:
10349			idx1 = 1;
10350			idx = 2;	/* Line In */
10351			break;
10352		case 0x0f:
10353			idx1 = 2;
10354			idx = 2;	/* Line In */
10355			break;
10356		case 0x0d:
10357			idx1 = 0;
10358			idx = 1;	/* Mic In */
10359			break;
10360		case 0x10:
10361			idx1 = 3;
10362			idx = 1;	/* Mic In */
10363			break;
10364		case 0x11:
10365			idx1 = 4;
10366			idx = 0;	/* CD */
10367			break;
10368		default:
10369			continue;
10370		}
10371
10372		err = new_analog_input(spec, cfg->input_pins[i],
10373				       auto_pin_cfg_labels[i], idx, 0x15);
10374		if (err < 0)
10375			return err;
10376
10377		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10378		imux->items[imux->num_items].index = idx1;
10379		imux->num_items++;
10380	}
10381	return 0;
10382}
10383
10384static struct snd_kcontrol_new alc861_capture_mixer[] = {
10385	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10386	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10387
10388	{
10389		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10390		/* The multiple "Capture Source" controls confuse alsamixer
10391		 * So call somewhat different..
10392		 *FIXME: the controls appear in the "playback" view!
10393		 */
10394		/* .name = "Capture Source", */
10395		.name = "Input Source",
10396		.count = 1,
10397		.info = alc_mux_enum_info,
10398		.get = alc_mux_enum_get,
10399		.put = alc_mux_enum_put,
10400	},
10401	{ } /* end */
10402};
10403
10404static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10405					      hda_nid_t nid,
10406					      int pin_type, int dac_idx)
10407{
10408	/* set as output */
10409
10410	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10411			    pin_type);
10412	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10413			    AMP_OUT_UNMUTE);
10414
10415}
10416
10417static void alc861_auto_init_multi_out(struct hda_codec *codec)
10418{
10419	struct alc_spec *spec = codec->spec;
10420	int i;
10421
10422	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
10423	for (i = 0; i < spec->autocfg.line_outs; i++) {
10424		hda_nid_t nid = spec->autocfg.line_out_pins[i];
10425		int pin_type = get_pin_type(spec->autocfg.line_out_type);
10426		if (nid)
10427			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
10428							  spec->multiout.dac_nids[i]);
10429	}
10430}
10431
10432static void alc861_auto_init_hp_out(struct hda_codec *codec)
10433{
10434	struct alc_spec *spec = codec->spec;
10435	hda_nid_t pin;
10436
10437	pin = spec->autocfg.hp_pins[0];
10438	if (pin) /* connect to front */
10439		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
10440						  spec->multiout.dac_nids[0]);
10441}
10442
10443static void alc861_auto_init_analog_input(struct hda_codec *codec)
10444{
10445	struct alc_spec *spec = codec->spec;
10446	int i;
10447
10448	for (i = 0; i < AUTO_PIN_LAST; i++) {
10449		hda_nid_t nid = spec->autocfg.input_pins[i];
10450		if (nid >= 0x0c && nid <= 0x11) {
10451			snd_hda_codec_write(codec, nid, 0,
10452					    AC_VERB_SET_PIN_WIDGET_CONTROL,
10453					    i <= AUTO_PIN_FRONT_MIC ?
10454					    PIN_VREF80 : PIN_IN);
10455		}
10456	}
10457}
10458
10459/* parse the BIOS configuration and set up the alc_spec */
10460/* return 1 if successful, 0 if the proper config is not found,
10461 * or a negative error code
10462 */
10463static int alc861_parse_auto_config(struct hda_codec *codec)
10464{
10465	struct alc_spec *spec = codec->spec;
10466	int err;
10467	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
10468
10469	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10470					   alc861_ignore);
10471	if (err < 0)
10472		return err;
10473	if (!spec->autocfg.line_outs)
10474		return 0; /* can't find valid BIOS pin config */
10475
10476	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
10477	if (err < 0)
10478		return err;
10479	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
10480	if (err < 0)
10481		return err;
10482	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
10483	if (err < 0)
10484		return err;
10485	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
10486	if (err < 0)
10487		return err;
10488
10489	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10490
10491	if (spec->autocfg.dig_out_pin)
10492		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
10493
10494	if (spec->kctl_alloc)
10495		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10496
10497	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
10498
10499	spec->num_mux_defs = 1;
10500	spec->input_mux = &spec->private_imux;
10501
10502	spec->adc_nids = alc861_adc_nids;
10503	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
10504	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
10505	spec->num_mixers++;
10506
10507	return 1;
10508}
10509
10510/* additional initialization for auto-configuration model */
10511static void alc861_auto_init(struct hda_codec *codec)
10512{
10513	alc861_auto_init_multi_out(codec);
10514	alc861_auto_init_hp_out(codec);
10515	alc861_auto_init_analog_input(codec);
10516}
10517
10518#ifdef CONFIG_SND_HDA_POWER_SAVE
10519static struct hda_amp_list alc861_loopbacks[] = {
10520	{ 0x15, HDA_INPUT, 0 },
10521	{ 0x15, HDA_INPUT, 1 },
10522	{ 0x15, HDA_INPUT, 2 },
10523	{ 0x15, HDA_INPUT, 3 },
10524	{ } /* end */
10525};
10526#endif
10527
10528
10529/*
10530 * configuration and preset
10531 */
10532static const char *alc861_models[ALC861_MODEL_LAST] = {
10533	[ALC861_3ST]		= "3stack",
10534	[ALC660_3ST]		= "3stack-660",
10535	[ALC861_3ST_DIG]	= "3stack-dig",
10536	[ALC861_6ST_DIG]	= "6stack-dig",
10537	[ALC861_UNIWILL_M31]	= "uniwill-m31",
10538	[ALC861_TOSHIBA]	= "toshiba",
10539	[ALC861_ASUS]		= "asus",
10540	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
10541	[ALC861_AUTO]		= "auto",
10542};
10543
10544static struct snd_pci_quirk alc861_cfg_tbl[] = {
10545	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
10546	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10547	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10548	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
10549	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
10550	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
10551	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
10552	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
10553	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
10554	 *        Any other models that need this preset?
10555	 */
10556	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
10557	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
10558	SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
10559	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
10560	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
10561	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
10562	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
10563	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
10564	{}
10565};
10566
10567static struct alc_config_preset alc861_presets[] = {
10568	[ALC861_3ST] = {
10569		.mixers = { alc861_3ST_mixer },
10570		.init_verbs = { alc861_threestack_init_verbs },
10571		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10572		.dac_nids = alc861_dac_nids,
10573		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10574		.channel_mode = alc861_threestack_modes,
10575		.need_dac_fix = 1,
10576		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10577		.adc_nids = alc861_adc_nids,
10578		.input_mux = &alc861_capture_source,
10579	},
10580	[ALC861_3ST_DIG] = {
10581		.mixers = { alc861_base_mixer },
10582		.init_verbs = { alc861_threestack_init_verbs },
10583		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10584		.dac_nids = alc861_dac_nids,
10585		.dig_out_nid = ALC861_DIGOUT_NID,
10586		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10587		.channel_mode = alc861_threestack_modes,
10588		.need_dac_fix = 1,
10589		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10590		.adc_nids = alc861_adc_nids,
10591		.input_mux = &alc861_capture_source,
10592	},
10593	[ALC861_6ST_DIG] = {
10594		.mixers = { alc861_base_mixer },
10595		.init_verbs = { alc861_base_init_verbs },
10596		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10597		.dac_nids = alc861_dac_nids,
10598		.dig_out_nid = ALC861_DIGOUT_NID,
10599		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
10600		.channel_mode = alc861_8ch_modes,
10601		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10602		.adc_nids = alc861_adc_nids,
10603		.input_mux = &alc861_capture_source,
10604	},
10605	[ALC660_3ST] = {
10606		.mixers = { alc861_3ST_mixer },
10607		.init_verbs = { alc861_threestack_init_verbs },
10608		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
10609		.dac_nids = alc660_dac_nids,
10610		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10611		.channel_mode = alc861_threestack_modes,
10612		.need_dac_fix = 1,
10613		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10614		.adc_nids = alc861_adc_nids,
10615		.input_mux = &alc861_capture_source,
10616	},
10617	[ALC861_UNIWILL_M31] = {
10618		.mixers = { alc861_uniwill_m31_mixer },
10619		.init_verbs = { alc861_uniwill_m31_init_verbs },
10620		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10621		.dac_nids = alc861_dac_nids,
10622		.dig_out_nid = ALC861_DIGOUT_NID,
10623		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
10624		.channel_mode = alc861_uniwill_m31_modes,
10625		.need_dac_fix = 1,
10626		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10627		.adc_nids = alc861_adc_nids,
10628		.input_mux = &alc861_capture_source,
10629	},
10630	[ALC861_TOSHIBA] = {
10631		.mixers = { alc861_toshiba_mixer },
10632		.init_verbs = { alc861_base_init_verbs,
10633				alc861_toshiba_init_verbs },
10634		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10635		.dac_nids = alc861_dac_nids,
10636		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10637		.channel_mode = alc883_3ST_2ch_modes,
10638		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10639		.adc_nids = alc861_adc_nids,
10640		.input_mux = &alc861_capture_source,
10641		.unsol_event = alc861_toshiba_unsol_event,
10642		.init_hook = alc861_toshiba_automute,
10643	},
10644	[ALC861_ASUS] = {
10645		.mixers = { alc861_asus_mixer },
10646		.init_verbs = { alc861_asus_init_verbs },
10647		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10648		.dac_nids = alc861_dac_nids,
10649		.dig_out_nid = ALC861_DIGOUT_NID,
10650		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
10651		.channel_mode = alc861_asus_modes,
10652		.need_dac_fix = 1,
10653		.hp_nid = 0x06,
10654		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10655		.adc_nids = alc861_adc_nids,
10656		.input_mux = &alc861_capture_source,
10657	},
10658	[ALC861_ASUS_LAPTOP] = {
10659		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
10660		.init_verbs = { alc861_asus_init_verbs,
10661				alc861_asus_laptop_init_verbs },
10662		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10663		.dac_nids = alc861_dac_nids,
10664		.dig_out_nid = ALC861_DIGOUT_NID,
10665		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10666		.channel_mode = alc883_3ST_2ch_modes,
10667		.need_dac_fix = 1,
10668		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10669		.adc_nids = alc861_adc_nids,
10670		.input_mux = &alc861_capture_source,
10671	},
10672};
10673
10674
10675static int patch_alc861(struct hda_codec *codec)
10676{
10677	struct alc_spec *spec;
10678	int board_config;
10679	int err;
10680
10681	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10682	if (spec == NULL)
10683		return -ENOMEM;
10684
10685	codec->spec = spec;
10686
10687        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
10688						  alc861_models,
10689						  alc861_cfg_tbl);
10690
10691	if (board_config < 0) {
10692		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
10693		       "trying auto-probe from BIOS...\n");
10694		board_config = ALC861_AUTO;
10695	}
10696
10697	if (board_config == ALC861_AUTO) {
10698		/* automatic parse from the BIOS config */
10699		err = alc861_parse_auto_config(codec);
10700		if (err < 0) {
10701			alc_free(codec);
10702			return err;
10703		} else if (!err) {
10704			printk(KERN_INFO
10705			       "hda_codec: Cannot set up configuration "
10706			       "from BIOS.  Using base mode...\n");
10707		   board_config = ALC861_3ST_DIG;
10708		}
10709	}
10710
10711	if (board_config != ALC861_AUTO)
10712		setup_preset(spec, &alc861_presets[board_config]);
10713
10714	spec->stream_name_analog = "ALC861 Analog";
10715	spec->stream_analog_playback = &alc861_pcm_analog_playback;
10716	spec->stream_analog_capture = &alc861_pcm_analog_capture;
10717
10718	spec->stream_name_digital = "ALC861 Digital";
10719	spec->stream_digital_playback = &alc861_pcm_digital_playback;
10720	spec->stream_digital_capture = &alc861_pcm_digital_capture;
10721
10722	codec->patch_ops = alc_patch_ops;
10723	if (board_config == ALC861_AUTO)
10724		spec->init_hook = alc861_auto_init;
10725#ifdef CONFIG_SND_HDA_POWER_SAVE
10726	if (!spec->loopback.amplist)
10727		spec->loopback.amplist = alc861_loopbacks;
10728#endif
10729
10730	return 0;
10731}
10732
10733/*
10734 * ALC861-VD support
10735 *
10736 * Based on ALC882
10737 *
10738 * In addition, an independent DAC
10739 */
10740#define ALC861VD_DIGOUT_NID	0x06
10741
10742static hda_nid_t alc861vd_dac_nids[4] = {
10743	/* front, surr, clfe, side surr */
10744	0x02, 0x03, 0x04, 0x05
10745};
10746
10747/* dac_nids for ALC660vd are in a different order - according to
10748 * Realtek's driver.
10749 * This should probably tesult in a different mixer for 6stack models
10750 * of ALC660vd codecs, but for now there is only 3stack mixer
10751 * - and it is the same as in 861vd.
10752 * adc_nids in ALC660vd are (is) the same as in 861vd
10753 */
10754static hda_nid_t alc660vd_dac_nids[3] = {
10755	/* front, rear, clfe, rear_surr */
10756	0x02, 0x04, 0x03
10757};
10758
10759static hda_nid_t alc861vd_adc_nids[1] = {
10760	/* ADC0 */
10761	0x09,
10762};
10763
10764/* input MUX */
10765/* FIXME: should be a matrix-type input source selection */
10766static struct hda_input_mux alc861vd_capture_source = {
10767	.num_items = 4,
10768	.items = {
10769		{ "Mic", 0x0 },
10770		{ "Front Mic", 0x1 },
10771		{ "Line", 0x2 },
10772		{ "CD", 0x4 },
10773	},
10774};
10775
10776static struct hda_input_mux alc861vd_dallas_capture_source = {
10777	.num_items = 3,
10778	.items = {
10779		{ "Front Mic", 0x0 },
10780		{ "ATAPI Mic", 0x1 },
10781		{ "Line In", 0x5 },
10782	},
10783};
10784
10785static struct hda_input_mux alc861vd_hp_capture_source = {
10786	.num_items = 2,
10787	.items = {
10788		{ "Front Mic", 0x0 },
10789		{ "ATAPI Mic", 0x1 },
10790	},
10791};
10792
10793#define alc861vd_mux_enum_info alc_mux_enum_info
10794#define alc861vd_mux_enum_get alc_mux_enum_get
10795
10796static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
10797				struct snd_ctl_elem_value *ucontrol)
10798{
10799	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10800	struct alc_spec *spec = codec->spec;
10801	const struct hda_input_mux *imux = spec->input_mux;
10802	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10803	static hda_nid_t capture_mixers[1] = { 0x22 };
10804	hda_nid_t nid = capture_mixers[adc_idx];
10805	unsigned int *cur_val = &spec->cur_mux[adc_idx];
10806	unsigned int i, idx;
10807
10808	idx = ucontrol->value.enumerated.item[0];
10809	if (idx >= imux->num_items)
10810		idx = imux->num_items - 1;
10811	if (*cur_val == idx)
10812		return 0;
10813	for (i = 0; i < imux->num_items; i++) {
10814		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10815		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10816					 imux->items[i].index,
10817					 HDA_AMP_MUTE, v);
10818	}
10819	*cur_val = idx;
10820	return 1;
10821}
10822
10823/*
10824 * 2ch mode
10825 */
10826static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
10827	{ 2, NULL }
10828};
10829
10830/*
10831 * 6ch mode
10832 */
10833static struct hda_verb alc861vd_6stack_ch6_init[] = {
10834	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10835	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10836	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10837	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10838	{ } /* end */
10839};
10840
10841/*
10842 * 8ch mode
10843 */
10844static struct hda_verb alc861vd_6stack_ch8_init[] = {
10845	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10846	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10847	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10848	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10849	{ } /* end */
10850};
10851
10852static struct hda_channel_mode alc861vd_6stack_modes[2] = {
10853	{ 6, alc861vd_6stack_ch6_init },
10854	{ 8, alc861vd_6stack_ch8_init },
10855};
10856
10857static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
10858	{
10859		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10860		.name = "Channel Mode",
10861		.info = alc_ch_mode_info,
10862		.get = alc_ch_mode_get,
10863		.put = alc_ch_mode_put,
10864	},
10865	{ } /* end */
10866};
10867
10868static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
10869	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10870	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10871
10872	{
10873		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10874		/* The multiple "Capture Source" controls confuse alsamixer
10875		 * So call somewhat different..
10876		 *FIXME: the controls appear in the "playback" view!
10877		 */
10878		/* .name = "Capture Source", */
10879		.name = "Input Source",
10880		.count = 1,
10881		.info = alc861vd_mux_enum_info,
10882		.get = alc861vd_mux_enum_get,
10883		.put = alc861vd_mux_enum_put,
10884	},
10885	{ } /* end */
10886};
10887
10888/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10889 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10890 */
10891static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10892	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10893	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10894
10895	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10896	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10897
10898	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10899				HDA_OUTPUT),
10900	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10901				HDA_OUTPUT),
10902	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10903	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10904
10905	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10906	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10907
10908	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10909
10910	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10911	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10912	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10913
10914	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10915	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10916	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10917
10918	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10919	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10920
10921	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10922	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10923
10924	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10925	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10926
10927	{ } /* end */
10928};
10929
10930static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10931	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10932	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10933
10934	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10935
10936	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10937	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10938	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10939
10940	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10941	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10942	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10943
10944	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10945	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10946
10947	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10948	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10949
10950	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10951	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10952
10953	{ } /* end */
10954};
10955
10956static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10957	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10958	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10959	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10960
10961	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10962
10963	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10964	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10965	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10966
10967	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10968	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10969	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10970
10971	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10972	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10973
10974	{ } /* end */
10975};
10976
10977/* Pin assignment: Front=0x14, HP = 0x15,
10978 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10979 */
10980static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10981	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10982	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10983	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10984	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10985	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10986	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10987	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10988	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10989	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10990	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10991	{ } /* end */
10992};
10993
10994/* Pin assignment: Speaker=0x14, Line-out = 0x15,
10995 *                 Front Mic=0x18, ATAPI Mic = 0x19,
10996 */
10997static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
10998	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10999	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11000	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11001	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11002	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11003	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11004	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11005	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11006
11007	{ } /* end */
11008};
11009
11010/*
11011 * generic initialization of ADC, input mixers and output mixers
11012 */
11013static struct hda_verb alc861vd_volume_init_verbs[] = {
11014	/*
11015	 * Unmute ADC0 and set the default input to mic-in
11016	 */
11017	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11018	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11019
11020	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11021	 * the analog-loopback mixer widget
11022	 */
11023	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11024	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11025	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11026	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11027	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11028	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11029
11030	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
11031	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11032	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11033	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11034	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11035
11036	/*
11037	 * Set up output mixers (0x02 - 0x05)
11038	 */
11039	/* set vol=0 to output mixers */
11040	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11041	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11042	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11043	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11044
11045	/* set up input amps for analog loopback */
11046	/* Amp Indices: DAC = 0, mixer = 1 */
11047	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11048	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11049	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11050	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11051	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11052	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11053	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11054	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11055
11056	{ }
11057};
11058
11059/*
11060 * 3-stack pin configuration:
11061 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11062 */
11063static struct hda_verb alc861vd_3stack_init_verbs[] = {
11064	/*
11065	 * Set pin mode and muting
11066	 */
11067	/* set front pin widgets 0x14 for output */
11068	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11069	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11070	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11071
11072	/* Mic (rear) pin: input vref at 80% */
11073	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11074	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11075	/* Front Mic pin: input vref at 80% */
11076	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11077	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11078	/* Line In pin: input */
11079	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11080	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11081	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11082	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11083	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11084	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11085	/* CD pin widget for input */
11086	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11087
11088	{ }
11089};
11090
11091/*
11092 * 6-stack pin configuration:
11093 */
11094static struct hda_verb alc861vd_6stack_init_verbs[] = {
11095	/*
11096	 * Set pin mode and muting
11097	 */
11098	/* set front pin widgets 0x14 for output */
11099	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11100	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11101	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11102
11103	/* Rear Pin: output 1 (0x0d) */
11104	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11105	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11106	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11107	/* CLFE Pin: output 2 (0x0e) */
11108	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11109	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11110	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11111	/* Side Pin: output 3 (0x0f) */
11112	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11113	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11114	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11115
11116	/* Mic (rear) pin: input vref at 80% */
11117	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11118	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11119	/* Front Mic pin: input vref at 80% */
11120	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11121	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11122	/* Line In pin: input */
11123	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11124	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11125	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11126	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11127	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11128	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11129	/* CD pin widget for input */
11130	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11131
11132	{ }
11133};
11134
11135static struct hda_verb alc861vd_eapd_verbs[] = {
11136	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11137	{ }
11138};
11139
11140static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11141	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11142	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11143	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11144	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11145	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11146	{}
11147};
11148
11149/* toggle speaker-output according to the hp-jack state */
11150static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11151{
11152	unsigned int present;
11153	unsigned char bits;
11154
11155	present = snd_hda_codec_read(codec, 0x1b, 0,
11156				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11157	bits = present ? HDA_AMP_MUTE : 0;
11158	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11159				 HDA_AMP_MUTE, bits);
11160}
11161
11162static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11163{
11164	unsigned int present;
11165	unsigned char bits;
11166
11167	present = snd_hda_codec_read(codec, 0x18, 0,
11168				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11169	bits = present ? HDA_AMP_MUTE : 0;
11170	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11171				 HDA_AMP_MUTE, bits);
11172}
11173
11174static void alc861vd_lenovo_automute(struct hda_codec *codec)
11175{
11176	alc861vd_lenovo_hp_automute(codec);
11177	alc861vd_lenovo_mic_automute(codec);
11178}
11179
11180static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11181					unsigned int res)
11182{
11183	switch (res >> 26) {
11184	case ALC880_HP_EVENT:
11185		alc861vd_lenovo_hp_automute(codec);
11186		break;
11187	case ALC880_MIC_EVENT:
11188		alc861vd_lenovo_mic_automute(codec);
11189		break;
11190	}
11191}
11192
11193static struct hda_verb alc861vd_dallas_verbs[] = {
11194	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11195	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11196	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11197	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11198
11199	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11200	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11201	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11202	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11203	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11204	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11205	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11206	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11207
11208	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11209	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11210	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11211	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11212	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11213	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11214	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11215	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11216
11217	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11218	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11219	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11220	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11221	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11222	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11223	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11224	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11225
11226	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11227	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11228	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11229	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11230
11231	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11232	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11233	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11234
11235	{ } /* end */
11236};
11237
11238/* toggle speaker-output according to the hp-jack state */
11239static void alc861vd_dallas_automute(struct hda_codec *codec)
11240{
11241	unsigned int present;
11242
11243	present = snd_hda_codec_read(codec, 0x15, 0,
11244				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11245	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11246				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11247}
11248
11249static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11250{
11251	if ((res >> 26) == ALC880_HP_EVENT)
11252		alc861vd_dallas_automute(codec);
11253}
11254
11255#ifdef CONFIG_SND_HDA_POWER_SAVE
11256#define alc861vd_loopbacks	alc880_loopbacks
11257#endif
11258
11259/* pcm configuration: identiacal with ALC880 */
11260#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
11261#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
11262#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
11263#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
11264
11265/*
11266 * configuration and preset
11267 */
11268static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11269	[ALC660VD_3ST]		= "3stack-660",
11270	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
11271	[ALC861VD_3ST]		= "3stack",
11272	[ALC861VD_3ST_DIG]	= "3stack-digout",
11273	[ALC861VD_6ST_DIG]	= "6stack-digout",
11274	[ALC861VD_LENOVO]	= "lenovo",
11275	[ALC861VD_DALLAS]	= "dallas",
11276	[ALC861VD_HP]		= "hp",
11277	[ALC861VD_AUTO]		= "auto",
11278};
11279
11280static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11281	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11282	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11283	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11284	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11285	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11286
11287	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11288	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11289	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
11290	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11291	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11292	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11293	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
11294	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
11295	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11296	{}
11297};
11298
11299static struct alc_config_preset alc861vd_presets[] = {
11300	[ALC660VD_3ST] = {
11301		.mixers = { alc861vd_3st_mixer },
11302		.init_verbs = { alc861vd_volume_init_verbs,
11303				 alc861vd_3stack_init_verbs },
11304		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11305		.dac_nids = alc660vd_dac_nids,
11306		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11307		.adc_nids = alc861vd_adc_nids,
11308		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11309		.channel_mode = alc861vd_3stack_2ch_modes,
11310		.input_mux = &alc861vd_capture_source,
11311	},
11312	[ALC660VD_3ST_DIG] = {
11313		.mixers = { alc861vd_3st_mixer },
11314		.init_verbs = { alc861vd_volume_init_verbs,
11315				 alc861vd_3stack_init_verbs },
11316		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11317		.dac_nids = alc660vd_dac_nids,
11318		.dig_out_nid = ALC861VD_DIGOUT_NID,
11319		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11320		.adc_nids = alc861vd_adc_nids,
11321		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11322		.channel_mode = alc861vd_3stack_2ch_modes,
11323		.input_mux = &alc861vd_capture_source,
11324	},
11325	[ALC861VD_3ST] = {
11326		.mixers = { alc861vd_3st_mixer },
11327		.init_verbs = { alc861vd_volume_init_verbs,
11328				 alc861vd_3stack_init_verbs },
11329		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11330		.dac_nids = alc861vd_dac_nids,
11331		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11332		.channel_mode = alc861vd_3stack_2ch_modes,
11333		.input_mux = &alc861vd_capture_source,
11334	},
11335	[ALC861VD_3ST_DIG] = {
11336		.mixers = { alc861vd_3st_mixer },
11337		.init_verbs = { alc861vd_volume_init_verbs,
11338		 		 alc861vd_3stack_init_verbs },
11339		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11340		.dac_nids = alc861vd_dac_nids,
11341		.dig_out_nid = ALC861VD_DIGOUT_NID,
11342		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11343		.channel_mode = alc861vd_3stack_2ch_modes,
11344		.input_mux = &alc861vd_capture_source,
11345	},
11346	[ALC861VD_6ST_DIG] = {
11347		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11348		.init_verbs = { alc861vd_volume_init_verbs,
11349				alc861vd_6stack_init_verbs },
11350		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11351		.dac_nids = alc861vd_dac_nids,
11352		.dig_out_nid = ALC861VD_DIGOUT_NID,
11353		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11354		.channel_mode = alc861vd_6stack_modes,
11355		.input_mux = &alc861vd_capture_source,
11356	},
11357	[ALC861VD_LENOVO] = {
11358		.mixers = { alc861vd_lenovo_mixer },
11359		.init_verbs = { alc861vd_volume_init_verbs,
11360				alc861vd_3stack_init_verbs,
11361				alc861vd_eapd_verbs,
11362				alc861vd_lenovo_unsol_verbs },
11363		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11364		.dac_nids = alc660vd_dac_nids,
11365		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11366		.adc_nids = alc861vd_adc_nids,
11367		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11368		.channel_mode = alc861vd_3stack_2ch_modes,
11369		.input_mux = &alc861vd_capture_source,
11370		.unsol_event = alc861vd_lenovo_unsol_event,
11371		.init_hook = alc861vd_lenovo_automute,
11372	},
11373	[ALC861VD_DALLAS] = {
11374		.mixers = { alc861vd_dallas_mixer },
11375		.init_verbs = { alc861vd_dallas_verbs },
11376		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11377		.dac_nids = alc861vd_dac_nids,
11378		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11379		.adc_nids = alc861vd_adc_nids,
11380		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11381		.channel_mode = alc861vd_3stack_2ch_modes,
11382		.input_mux = &alc861vd_dallas_capture_source,
11383		.unsol_event = alc861vd_dallas_unsol_event,
11384		.init_hook = alc861vd_dallas_automute,
11385	},
11386	[ALC861VD_HP] = {
11387		.mixers = { alc861vd_hp_mixer },
11388		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11389		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11390		.dac_nids = alc861vd_dac_nids,
11391		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11392		.dig_out_nid = ALC861VD_DIGOUT_NID,
11393		.adc_nids = alc861vd_adc_nids,
11394		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11395		.channel_mode = alc861vd_3stack_2ch_modes,
11396		.input_mux = &alc861vd_hp_capture_source,
11397		.unsol_event = alc861vd_dallas_unsol_event,
11398		.init_hook = alc861vd_dallas_automute,
11399	},
11400};
11401
11402/*
11403 * BIOS auto configuration
11404 */
11405static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11406				hda_nid_t nid, int pin_type, int dac_idx)
11407{
11408	/* set as output */
11409	snd_hda_codec_write(codec, nid, 0,
11410				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11411	snd_hda_codec_write(codec, nid, 0,
11412				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11413}
11414
11415static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11416{
11417	struct alc_spec *spec = codec->spec;
11418	int i;
11419
11420	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
11421	for (i = 0; i <= HDA_SIDE; i++) {
11422		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11423		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11424		if (nid)
11425			alc861vd_auto_set_output_and_unmute(codec, nid,
11426							    pin_type, i);
11427	}
11428}
11429
11430
11431static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
11432{
11433	struct alc_spec *spec = codec->spec;
11434	hda_nid_t pin;
11435
11436	pin = spec->autocfg.hp_pins[0];
11437	if (pin) /* connect to front and  use dac 0 */
11438		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11439}
11440
11441#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
11442#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
11443
11444static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
11445{
11446	struct alc_spec *spec = codec->spec;
11447	int i;
11448
11449	for (i = 0; i < AUTO_PIN_LAST; i++) {
11450		hda_nid_t nid = spec->autocfg.input_pins[i];
11451		if (alc861vd_is_input_pin(nid)) {
11452			snd_hda_codec_write(codec, nid, 0,
11453					AC_VERB_SET_PIN_WIDGET_CONTROL,
11454					i <= AUTO_PIN_FRONT_MIC ?
11455							PIN_VREF80 : PIN_IN);
11456			if (nid != ALC861VD_PIN_CD_NID)
11457				snd_hda_codec_write(codec, nid, 0,
11458						AC_VERB_SET_AMP_GAIN_MUTE,
11459						AMP_OUT_MUTE);
11460		}
11461	}
11462}
11463
11464#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
11465#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
11466
11467/* add playback controls from the parsed DAC table */
11468/* Based on ALC880 version. But ALC861VD has separate,
11469 * different NIDs for mute/unmute switch and volume control */
11470static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
11471					     const struct auto_pin_cfg *cfg)
11472{
11473	char name[32];
11474	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
11475	hda_nid_t nid_v, nid_s;
11476	int i, err;
11477
11478	for (i = 0; i < cfg->line_outs; i++) {
11479		if (!spec->multiout.dac_nids[i])
11480			continue;
11481		nid_v = alc861vd_idx_to_mixer_vol(
11482				alc880_dac_to_idx(
11483					spec->multiout.dac_nids[i]));
11484		nid_s = alc861vd_idx_to_mixer_switch(
11485				alc880_dac_to_idx(
11486					spec->multiout.dac_nids[i]));
11487
11488		if (i == 2) {
11489			/* Center/LFE */
11490			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11491					  "Center Playback Volume",
11492					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
11493							      HDA_OUTPUT));
11494			if (err < 0)
11495				return err;
11496			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11497					  "LFE Playback Volume",
11498					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
11499							      HDA_OUTPUT));
11500			if (err < 0)
11501				return err;
11502			err = add_control(spec, ALC_CTL_BIND_MUTE,
11503					  "Center Playback Switch",
11504					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
11505							      HDA_INPUT));
11506			if (err < 0)
11507				return err;
11508			err = add_control(spec, ALC_CTL_BIND_MUTE,
11509					  "LFE Playback Switch",
11510					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
11511							      HDA_INPUT));
11512			if (err < 0)
11513				return err;
11514		} else {
11515			sprintf(name, "%s Playback Volume", chname[i]);
11516			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11517					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
11518							      HDA_OUTPUT));
11519			if (err < 0)
11520				return err;
11521			sprintf(name, "%s Playback Switch", chname[i]);
11522			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11523					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
11524							      HDA_INPUT));
11525			if (err < 0)
11526				return err;
11527		}
11528	}
11529	return 0;
11530}
11531
11532/* add playback controls for speaker and HP outputs */
11533/* Based on ALC880 version. But ALC861VD has separate,
11534 * different NIDs for mute/unmute switch and volume control */
11535static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
11536					hda_nid_t pin, const char *pfx)
11537{
11538	hda_nid_t nid_v, nid_s;
11539	int err;
11540	char name[32];
11541
11542	if (!pin)
11543		return 0;
11544
11545	if (alc880_is_fixed_pin(pin)) {
11546		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11547		/* specify the DAC as the extra output */
11548		if (!spec->multiout.hp_nid)
11549			spec->multiout.hp_nid = nid_v;
11550		else
11551			spec->multiout.extra_out_nid[0] = nid_v;
11552		/* control HP volume/switch on the output mixer amp */
11553		nid_v = alc861vd_idx_to_mixer_vol(
11554				alc880_fixed_pin_idx(pin));
11555		nid_s = alc861vd_idx_to_mixer_switch(
11556				alc880_fixed_pin_idx(pin));
11557
11558		sprintf(name, "%s Playback Volume", pfx);
11559		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11560				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
11561		if (err < 0)
11562			return err;
11563		sprintf(name, "%s Playback Switch", pfx);
11564		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11565				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
11566		if (err < 0)
11567			return err;
11568	} else if (alc880_is_multi_pin(pin)) {
11569		/* set manual connection */
11570		/* we have only a switch on HP-out PIN */
11571		sprintf(name, "%s Playback Switch", pfx);
11572		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11573				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11574		if (err < 0)
11575			return err;
11576	}
11577	return 0;
11578}
11579
11580/* parse the BIOS configuration and set up the alc_spec
11581 * return 1 if successful, 0 if the proper config is not found,
11582 * or a negative error code
11583 * Based on ALC880 version - had to change it to override
11584 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
11585static int alc861vd_parse_auto_config(struct hda_codec *codec)
11586{
11587	struct alc_spec *spec = codec->spec;
11588	int err;
11589	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
11590
11591	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11592					   alc861vd_ignore);
11593	if (err < 0)
11594		return err;
11595	if (!spec->autocfg.line_outs)
11596		return 0; /* can't find valid BIOS pin config */
11597
11598	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11599	if (err < 0)
11600		return err;
11601	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
11602	if (err < 0)
11603		return err;
11604	err = alc861vd_auto_create_extra_out(spec,
11605					     spec->autocfg.speaker_pins[0],
11606					     "Speaker");
11607	if (err < 0)
11608		return err;
11609	err = alc861vd_auto_create_extra_out(spec,
11610					     spec->autocfg.hp_pins[0],
11611					     "Headphone");
11612	if (err < 0)
11613		return err;
11614	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
11615	if (err < 0)
11616		return err;
11617
11618	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11619
11620	if (spec->autocfg.dig_out_pin)
11621		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
11622
11623	if (spec->kctl_alloc)
11624		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11625
11626	spec->init_verbs[spec->num_init_verbs++]
11627		= alc861vd_volume_init_verbs;
11628
11629	spec->num_mux_defs = 1;
11630	spec->input_mux = &spec->private_imux;
11631
11632	err = alc_auto_add_mic_boost(codec);
11633	if (err < 0)
11634		return err;
11635
11636	return 1;
11637}
11638
11639/* additional initialization for auto-configuration model */
11640static void alc861vd_auto_init(struct hda_codec *codec)
11641{
11642	alc861vd_auto_init_multi_out(codec);
11643	alc861vd_auto_init_hp_out(codec);
11644	alc861vd_auto_init_analog_input(codec);
11645}
11646
11647static int patch_alc861vd(struct hda_codec *codec)
11648{
11649	struct alc_spec *spec;
11650	int err, board_config;
11651
11652	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11653	if (spec == NULL)
11654		return -ENOMEM;
11655
11656	codec->spec = spec;
11657
11658	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
11659						  alc861vd_models,
11660						  alc861vd_cfg_tbl);
11661
11662	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
11663		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
11664			"ALC861VD, trying auto-probe from BIOS...\n");
11665		board_config = ALC861VD_AUTO;
11666	}
11667
11668	if (board_config == ALC861VD_AUTO) {
11669		/* automatic parse from the BIOS config */
11670		err = alc861vd_parse_auto_config(codec);
11671		if (err < 0) {
11672			alc_free(codec);
11673			return err;
11674		} else if (!err) {
11675			printk(KERN_INFO
11676			       "hda_codec: Cannot set up configuration "
11677			       "from BIOS.  Using base mode...\n");
11678			board_config = ALC861VD_3ST;
11679		}
11680	}
11681
11682	if (board_config != ALC861VD_AUTO)
11683		setup_preset(spec, &alc861vd_presets[board_config]);
11684
11685	spec->stream_name_analog = "ALC861VD Analog";
11686	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
11687	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
11688
11689	spec->stream_name_digital = "ALC861VD Digital";
11690	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
11691	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
11692
11693	spec->adc_nids = alc861vd_adc_nids;
11694	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
11695
11696	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
11697	spec->num_mixers++;
11698
11699	codec->patch_ops = alc_patch_ops;
11700
11701	if (board_config == ALC861VD_AUTO)
11702		spec->init_hook = alc861vd_auto_init;
11703#ifdef CONFIG_SND_HDA_POWER_SAVE
11704	if (!spec->loopback.amplist)
11705		spec->loopback.amplist = alc861vd_loopbacks;
11706#endif
11707
11708	return 0;
11709}
11710
11711/*
11712 * ALC662 support
11713 *
11714 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
11715 * configuration.  Each pin widget can choose any input DACs and a mixer.
11716 * Each ADC is connected from a mixer of all inputs.  This makes possible
11717 * 6-channel independent captures.
11718 *
11719 * In addition, an independent DAC for the multi-playback (not used in this
11720 * driver yet).
11721 */
11722#define ALC662_DIGOUT_NID	0x06
11723#define ALC662_DIGIN_NID	0x0a
11724
11725static hda_nid_t alc662_dac_nids[4] = {
11726	/* front, rear, clfe, rear_surr */
11727	0x02, 0x03, 0x04
11728};
11729
11730static hda_nid_t alc662_adc_nids[1] = {
11731	/* ADC1-2 */
11732	0x09,
11733};
11734/* input MUX */
11735/* FIXME: should be a matrix-type input source selection */
11736
11737static struct hda_input_mux alc662_capture_source = {
11738	.num_items = 4,
11739	.items = {
11740		{ "Mic", 0x0 },
11741		{ "Front Mic", 0x1 },
11742		{ "Line", 0x2 },
11743		{ "CD", 0x4 },
11744	},
11745};
11746
11747static struct hda_input_mux alc662_lenovo_101e_capture_source = {
11748	.num_items = 2,
11749	.items = {
11750		{ "Mic", 0x1 },
11751		{ "Line", 0x2 },
11752	},
11753};
11754
11755static struct hda_input_mux alc662_eeepc_capture_source = {
11756	.num_items = 2,
11757	.items = {
11758		{ "i-Mic", 0x1 },
11759		{ "e-Mic", 0x0 },
11760	},
11761};
11762
11763#define alc662_mux_enum_info alc_mux_enum_info
11764#define alc662_mux_enum_get alc_mux_enum_get
11765
11766static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
11767			       struct snd_ctl_elem_value *ucontrol)
11768{
11769	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11770	struct alc_spec *spec = codec->spec;
11771	const struct hda_input_mux *imux = spec->input_mux;
11772	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11773	static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
11774	hda_nid_t nid = capture_mixers[adc_idx];
11775	unsigned int *cur_val = &spec->cur_mux[adc_idx];
11776	unsigned int i, idx;
11777
11778	idx = ucontrol->value.enumerated.item[0];
11779	if (idx >= imux->num_items)
11780		idx = imux->num_items - 1;
11781	if (*cur_val == idx)
11782		return 0;
11783	for (i = 0; i < imux->num_items; i++) {
11784		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11785		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11786					 imux->items[i].index,
11787					 HDA_AMP_MUTE, v);
11788	}
11789	*cur_val = idx;
11790	return 1;
11791}
11792/*
11793 * 2ch mode
11794 */
11795static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
11796	{ 2, NULL }
11797};
11798
11799/*
11800 * 2ch mode
11801 */
11802static struct hda_verb alc662_3ST_ch2_init[] = {
11803	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
11804	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11805	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
11806	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11807	{ } /* end */
11808};
11809
11810/*
11811 * 6ch mode
11812 */
11813static struct hda_verb alc662_3ST_ch6_init[] = {
11814	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11815	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11816	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
11817	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11818	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11819	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
11820	{ } /* end */
11821};
11822
11823static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
11824	{ 2, alc662_3ST_ch2_init },
11825	{ 6, alc662_3ST_ch6_init },
11826};
11827
11828/*
11829 * 2ch mode
11830 */
11831static struct hda_verb alc662_sixstack_ch6_init[] = {
11832	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11833	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11834	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11835	{ } /* end */
11836};
11837
11838/*
11839 * 6ch mode
11840 */
11841static struct hda_verb alc662_sixstack_ch8_init[] = {
11842	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11843	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11844	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11845	{ } /* end */
11846};
11847
11848static struct hda_channel_mode alc662_5stack_modes[2] = {
11849	{ 2, alc662_sixstack_ch6_init },
11850	{ 6, alc662_sixstack_ch8_init },
11851};
11852
11853/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11854 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11855 */
11856
11857static struct snd_kcontrol_new alc662_base_mixer[] = {
11858	/* output mixer control */
11859	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11860	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
11861	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11862	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11863	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11864	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11865	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11866	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11867	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11868
11869	/*Input mixer control */
11870	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
11871	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
11872	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
11873	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
11874	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
11875	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
11876	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
11877	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
11878
11879	/* Capture mixer control */
11880	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11881	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11882	{
11883		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11884		.name = "Capture Source",
11885		.count = 1,
11886		.info = alc_mux_enum_info,
11887		.get = alc_mux_enum_get,
11888		.put = alc_mux_enum_put,
11889	},
11890	{ } /* end */
11891};
11892
11893static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
11894	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11895	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11896	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11897	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11898	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11899	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11900	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11901	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11902	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11903	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11904	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11905	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11906	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11907	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11908	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11909	{
11910		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11911		/* .name = "Capture Source", */
11912		.name = "Input Source",
11913		.count = 1,
11914		.info = alc662_mux_enum_info,
11915		.get = alc662_mux_enum_get,
11916		.put = alc662_mux_enum_put,
11917	},
11918	{ } /* end */
11919};
11920
11921static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11922	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11923	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11924	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11925	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11926	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11927	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11928	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11929	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11930	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11932	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11933	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11934	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11935	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11936	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11937	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11938	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11939	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11940	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11941	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11942	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11943	{
11944		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11945		/* .name = "Capture Source", */
11946		.name = "Input Source",
11947		.count = 1,
11948		.info = alc662_mux_enum_info,
11949		.get = alc662_mux_enum_get,
11950		.put = alc662_mux_enum_put,
11951	},
11952	{ } /* end */
11953};
11954
11955static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11956	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11957	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11958	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11959	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11960	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11961	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11962	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11963	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11964	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11965	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11966	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11967	{
11968		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11969		/* .name = "Capture Source", */
11970		.name = "Input Source",
11971		.count = 1,
11972		.info = alc662_mux_enum_info,
11973		.get = alc662_mux_enum_get,
11974		.put = alc662_mux_enum_put,
11975	},
11976	{ } /* end */
11977};
11978
11979static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
11980	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11981
11982	HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11983	HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11984
11985	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
11986	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11987	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11988
11989	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
11990	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11991	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11992	{ } /* end */
11993};
11994
11995static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11996	{
11997		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11998		.name = "Channel Mode",
11999		.info = alc_ch_mode_info,
12000		.get = alc_ch_mode_get,
12001		.put = alc_ch_mode_put,
12002	},
12003	{ } /* end */
12004};
12005
12006static struct hda_verb alc662_init_verbs[] = {
12007	/* ADC: mute amp left and right */
12008	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12009	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12010	/* Front mixer: unmute input/output amp left and right (volume = 0) */
12011
12012	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12013	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12014	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12015	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12016	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12017
12018	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12019	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12020	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12021	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12022	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12023	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12024
12025	/* Front Pin: output 0 (0x0c) */
12026	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12027	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12028
12029	/* Rear Pin: output 1 (0x0d) */
12030	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12031	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12032
12033	/* CLFE Pin: output 2 (0x0e) */
12034	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12035	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12036
12037	/* Mic (rear) pin: input vref at 80% */
12038	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12039	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12040	/* Front Mic pin: input vref at 80% */
12041	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12042	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12043	/* Line In pin: input */
12044	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12045	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12046	/* Line-2 In: Headphone output (output 0 - 0x0c) */
12047	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12048	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12049	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12050	/* CD pin widget for input */
12051	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12052
12053	/* FIXME: use matrix-type input source selection */
12054	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12055	/* Input mixer */
12056	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12057	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12058	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12059	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12060
12061	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12062	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12063	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12064	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12065	{ }
12066};
12067
12068static struct hda_verb alc662_sue_init_verbs[] = {
12069	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12070	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
12071	{}
12072};
12073
12074static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12075	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12076	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12077	{}
12078};
12079
12080/*
12081 * generic initialization of ADC, input mixers and output mixers
12082 */
12083static struct hda_verb alc662_auto_init_verbs[] = {
12084	/*
12085	 * Unmute ADC and set the default input to mic-in
12086	 */
12087	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12088	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12089
12090	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12091	 * mixer widget
12092	 * Note: PASD motherboards uses the Line In 2 as the input for front
12093	 * panel mic (mic 2)
12094	 */
12095	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12096	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12097	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12098	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12099	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12100	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12101
12102	/*
12103	 * Set up output mixers (0x0c - 0x0f)
12104	 */
12105	/* set vol=0 to output mixers */
12106	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12107	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12108	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12109
12110	/* set up input amps for analog loopback */
12111	/* Amp Indices: DAC = 0, mixer = 1 */
12112	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12113	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12114	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12115	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12116	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12117	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12118
12119
12120	/* FIXME: use matrix-type input source selection */
12121	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12122	/* Input mixer */
12123	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12124	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12125	{ }
12126};
12127
12128/* capture mixer elements */
12129static struct snd_kcontrol_new alc662_capture_mixer[] = {
12130	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12131	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12132	{
12133		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12134		/* The multiple "Capture Source" controls confuse alsamixer
12135		 * So call somewhat different..
12136		 * FIXME: the controls appear in the "playback" view!
12137		 */
12138		/* .name = "Capture Source", */
12139		.name = "Input Source",
12140		.count = 1,
12141		.info = alc882_mux_enum_info,
12142		.get = alc882_mux_enum_get,
12143		.put = alc882_mux_enum_put,
12144	},
12145	{ } /* end */
12146};
12147
12148static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12149{
12150	unsigned int present;
12151	unsigned char bits;
12152
12153	present = snd_hda_codec_read(codec, 0x14, 0,
12154				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12155	bits = present ? HDA_AMP_MUTE : 0;
12156	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12157				 HDA_AMP_MUTE, bits);
12158}
12159
12160static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12161{
12162	unsigned int present;
12163	unsigned char bits;
12164
12165 	present = snd_hda_codec_read(codec, 0x1b, 0,
12166				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12167	bits = present ? HDA_AMP_MUTE : 0;
12168	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12169				 HDA_AMP_MUTE, bits);
12170	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12171				 HDA_AMP_MUTE, bits);
12172}
12173
12174static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12175					   unsigned int res)
12176{
12177	if ((res >> 26) == ALC880_HP_EVENT)
12178		alc662_lenovo_101e_all_automute(codec);
12179	if ((res >> 26) == ALC880_FRONT_EVENT)
12180		alc662_lenovo_101e_ispeaker_automute(codec);
12181}
12182
12183static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12184{
12185	unsigned int present;
12186
12187	present = snd_hda_codec_read(codec, 0x18, 0,
12188				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12189	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12190			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12191	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12192			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12193	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12194			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12195	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12196			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12197}
12198
12199/* unsolicited event for HP jack sensing */
12200static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12201				     unsigned int res)
12202{
12203	if ((res >> 26) == ALC880_HP_EVENT)
12204		alc262_hippo1_automute( codec );
12205
12206	if ((res >> 26) == ALC880_MIC_EVENT)
12207		alc662_eeepc_mic_automute(codec);
12208}
12209
12210static void alc662_eeepc_inithook(struct hda_codec *codec)
12211{
12212	alc262_hippo1_automute( codec );
12213	alc662_eeepc_mic_automute(codec);
12214}
12215
12216#ifdef CONFIG_SND_HDA_POWER_SAVE
12217#define alc662_loopbacks	alc880_loopbacks
12218#endif
12219
12220
12221/* pcm configuration: identiacal with ALC880 */
12222#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
12223#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
12224#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
12225#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
12226
12227/*
12228 * configuration and preset
12229 */
12230static const char *alc662_models[ALC662_MODEL_LAST] = {
12231	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
12232	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
12233	[ALC662_3ST_6ch]	= "3stack-6ch",
12234	[ALC662_5ST_DIG]	= "6stack-dig",
12235	[ALC662_LENOVO_101E]	= "lenovo-101e",
12236	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12237	[ALC662_AUTO]		= "auto",
12238};
12239
12240static struct snd_pci_quirk alc662_cfg_tbl[] = {
12241	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12242	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12243	{}
12244};
12245
12246static struct alc_config_preset alc662_presets[] = {
12247	[ALC662_3ST_2ch_DIG] = {
12248		.mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12249		.init_verbs = { alc662_init_verbs },
12250		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12251		.dac_nids = alc662_dac_nids,
12252		.dig_out_nid = ALC662_DIGOUT_NID,
12253		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12254		.adc_nids = alc662_adc_nids,
12255		.dig_in_nid = ALC662_DIGIN_NID,
12256		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12257		.channel_mode = alc662_3ST_2ch_modes,
12258		.input_mux = &alc662_capture_source,
12259	},
12260	[ALC662_3ST_6ch_DIG] = {
12261		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12262			    alc662_capture_mixer },
12263		.init_verbs = { alc662_init_verbs },
12264		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12265		.dac_nids = alc662_dac_nids,
12266		.dig_out_nid = ALC662_DIGOUT_NID,
12267		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12268		.adc_nids = alc662_adc_nids,
12269		.dig_in_nid = ALC662_DIGIN_NID,
12270		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12271		.channel_mode = alc662_3ST_6ch_modes,
12272		.need_dac_fix = 1,
12273		.input_mux = &alc662_capture_source,
12274	},
12275	[ALC662_3ST_6ch] = {
12276		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12277			    alc662_capture_mixer },
12278		.init_verbs = { alc662_init_verbs },
12279		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12280		.dac_nids = alc662_dac_nids,
12281		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12282		.adc_nids = alc662_adc_nids,
12283		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12284		.channel_mode = alc662_3ST_6ch_modes,
12285		.need_dac_fix = 1,
12286		.input_mux = &alc662_capture_source,
12287	},
12288	[ALC662_5ST_DIG] = {
12289		.mixers = { alc662_base_mixer, alc662_chmode_mixer,
12290			    alc662_capture_mixer },
12291		.init_verbs = { alc662_init_verbs },
12292		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12293		.dac_nids = alc662_dac_nids,
12294		.dig_out_nid = ALC662_DIGOUT_NID,
12295		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12296		.adc_nids = alc662_adc_nids,
12297		.dig_in_nid = ALC662_DIGIN_NID,
12298		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12299		.channel_mode = alc662_5stack_modes,
12300		.input_mux = &alc662_capture_source,
12301	},
12302	[ALC662_LENOVO_101E] = {
12303		.mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
12304		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12305		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12306		.dac_nids = alc662_dac_nids,
12307		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12308		.adc_nids = alc662_adc_nids,
12309		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12310		.channel_mode = alc662_3ST_2ch_modes,
12311		.input_mux = &alc662_lenovo_101e_capture_source,
12312		.unsol_event = alc662_lenovo_101e_unsol_event,
12313		.init_hook = alc662_lenovo_101e_all_automute,
12314	},
12315	[ALC662_ASUS_EEEPC_P701] = {
12316		.mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12317		.init_verbs = { alc662_init_verbs,
12318				alc662_eeepc_sue_init_verbs },
12319		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12320		.dac_nids = alc662_dac_nids,
12321		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12322		.adc_nids = alc662_adc_nids,
12323		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12324		.channel_mode = alc662_3ST_2ch_modes,
12325		.input_mux = &alc662_eeepc_capture_source,
12326		.unsol_event = alc662_eeepc_unsol_event,
12327		.init_hook = alc662_eeepc_inithook,
12328	},
12329
12330};
12331
12332
12333/*
12334 * BIOS auto configuration
12335 */
12336
12337/* add playback controls from the parsed DAC table */
12338static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12339					     const struct auto_pin_cfg *cfg)
12340{
12341	char name[32];
12342	static const char *chname[4] = {
12343		"Front", "Surround", NULL /*CLFE*/, "Side"
12344	};
12345	hda_nid_t nid;
12346	int i, err;
12347
12348	for (i = 0; i < cfg->line_outs; i++) {
12349		if (!spec->multiout.dac_nids[i])
12350			continue;
12351		nid = alc880_idx_to_dac(i);
12352		if (i == 2) {
12353			/* Center/LFE */
12354			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12355					  "Center Playback Volume",
12356					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12357							      HDA_OUTPUT));
12358			if (err < 0)
12359				return err;
12360			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12361					  "LFE Playback Volume",
12362					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12363							      HDA_OUTPUT));
12364			if (err < 0)
12365				return err;
12366			err = add_control(spec, ALC_CTL_BIND_MUTE,
12367					  "Center Playback Switch",
12368					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12369							      HDA_INPUT));
12370			if (err < 0)
12371				return err;
12372			err = add_control(spec, ALC_CTL_BIND_MUTE,
12373					  "LFE Playback Switch",
12374					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12375							      HDA_INPUT));
12376			if (err < 0)
12377				return err;
12378		} else {
12379			sprintf(name, "%s Playback Volume", chname[i]);
12380			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12381					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12382							      HDA_OUTPUT));
12383			if (err < 0)
12384				return err;
12385			sprintf(name, "%s Playback Switch", chname[i]);
12386			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12387					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12388							      HDA_INPUT));
12389			if (err < 0)
12390				return err;
12391		}
12392	}
12393	return 0;
12394}
12395
12396/* add playback controls for speaker and HP outputs */
12397static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12398					const char *pfx)
12399{
12400	hda_nid_t nid;
12401	int err;
12402	char name[32];
12403
12404	if (!pin)
12405		return 0;
12406
12407	if (alc880_is_fixed_pin(pin)) {
12408		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12409                /* printk("DAC nid=%x\n",nid); */
12410		/* specify the DAC as the extra output */
12411		if (!spec->multiout.hp_nid)
12412			spec->multiout.hp_nid = nid;
12413		else
12414			spec->multiout.extra_out_nid[0] = nid;
12415		/* control HP volume/switch on the output mixer amp */
12416		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12417		sprintf(name, "%s Playback Volume", pfx);
12418		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12419				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12420		if (err < 0)
12421			return err;
12422		sprintf(name, "%s Playback Switch", pfx);
12423		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12424				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12425		if (err < 0)
12426			return err;
12427	} else if (alc880_is_multi_pin(pin)) {
12428		/* set manual connection */
12429		/* we have only a switch on HP-out PIN */
12430		sprintf(name, "%s Playback Switch", pfx);
12431		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12432				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12433		if (err < 0)
12434			return err;
12435	}
12436	return 0;
12437}
12438
12439/* create playback/capture controls for input pins */
12440static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12441						const struct auto_pin_cfg *cfg)
12442{
12443	struct hda_input_mux *imux = &spec->private_imux;
12444	int i, err, idx;
12445
12446	for (i = 0; i < AUTO_PIN_LAST; i++) {
12447		if (alc880_is_input_pin(cfg->input_pins[i])) {
12448			idx = alc880_input_pin_idx(cfg->input_pins[i]);
12449			err = new_analog_input(spec, cfg->input_pins[i],
12450					       auto_pin_cfg_labels[i],
12451					       idx, 0x0b);
12452			if (err < 0)
12453				return err;
12454			imux->items[imux->num_items].label =
12455				auto_pin_cfg_labels[i];
12456			imux->items[imux->num_items].index =
12457				alc880_input_pin_idx(cfg->input_pins[i]);
12458			imux->num_items++;
12459		}
12460	}
12461	return 0;
12462}
12463
12464static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12465					      hda_nid_t nid, int pin_type,
12466					      int dac_idx)
12467{
12468	/* set as output */
12469	snd_hda_codec_write(codec, nid, 0,
12470			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12471	snd_hda_codec_write(codec, nid, 0,
12472			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12473	/* need the manual connection? */
12474	if (alc880_is_multi_pin(nid)) {
12475		struct alc_spec *spec = codec->spec;
12476		int idx = alc880_multi_pin_idx(nid);
12477		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
12478				    AC_VERB_SET_CONNECT_SEL,
12479				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
12480	}
12481}
12482
12483static void alc662_auto_init_multi_out(struct hda_codec *codec)
12484{
12485	struct alc_spec *spec = codec->spec;
12486	int i;
12487
12488	for (i = 0; i <= HDA_SIDE; i++) {
12489		hda_nid_t nid = spec->autocfg.line_out_pins[i];
12490		int pin_type = get_pin_type(spec->autocfg.line_out_type);
12491		if (nid)
12492			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
12493							  i);
12494	}
12495}
12496
12497static void alc662_auto_init_hp_out(struct hda_codec *codec)
12498{
12499	struct alc_spec *spec = codec->spec;
12500	hda_nid_t pin;
12501
12502	pin = spec->autocfg.hp_pins[0];
12503	if (pin) /* connect to front */
12504		/* use dac 0 */
12505		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12506}
12507
12508#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
12509#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
12510
12511static void alc662_auto_init_analog_input(struct hda_codec *codec)
12512{
12513	struct alc_spec *spec = codec->spec;
12514	int i;
12515
12516	for (i = 0; i < AUTO_PIN_LAST; i++) {
12517		hda_nid_t nid = spec->autocfg.input_pins[i];
12518		if (alc662_is_input_pin(nid)) {
12519			snd_hda_codec_write(codec, nid, 0,
12520					    AC_VERB_SET_PIN_WIDGET_CONTROL,
12521					    (i <= AUTO_PIN_FRONT_MIC ?
12522					     PIN_VREF80 : PIN_IN));
12523			if (nid != ALC662_PIN_CD_NID)
12524				snd_hda_codec_write(codec, nid, 0,
12525						    AC_VERB_SET_AMP_GAIN_MUTE,
12526						    AMP_OUT_MUTE);
12527		}
12528	}
12529}
12530
12531static int alc662_parse_auto_config(struct hda_codec *codec)
12532{
12533	struct alc_spec *spec = codec->spec;
12534	int err;
12535	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
12536
12537	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12538					   alc662_ignore);
12539	if (err < 0)
12540		return err;
12541	if (!spec->autocfg.line_outs)
12542		return 0; /* can't find valid BIOS pin config */
12543
12544	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12545	if (err < 0)
12546		return err;
12547	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
12548	if (err < 0)
12549		return err;
12550	err = alc662_auto_create_extra_out(spec,
12551					   spec->autocfg.speaker_pins[0],
12552					   "Speaker");
12553	if (err < 0)
12554		return err;
12555	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
12556					   "Headphone");
12557	if (err < 0)
12558		return err;
12559	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
12560	if (err < 0)
12561		return err;
12562
12563	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12564
12565	if (spec->autocfg.dig_out_pin)
12566		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
12567
12568	if (spec->kctl_alloc)
12569		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12570
12571	spec->num_mux_defs = 1;
12572	spec->input_mux = &spec->private_imux;
12573
12574	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
12575	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
12576	spec->num_mixers++;
12577	return 1;
12578}
12579
12580/* additional initialization for auto-configuration model */
12581static void alc662_auto_init(struct hda_codec *codec)
12582{
12583	alc662_auto_init_multi_out(codec);
12584	alc662_auto_init_hp_out(codec);
12585	alc662_auto_init_analog_input(codec);
12586}
12587
12588static int patch_alc662(struct hda_codec *codec)
12589{
12590	struct alc_spec *spec;
12591	int err, board_config;
12592
12593	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12594	if (!spec)
12595		return -ENOMEM;
12596
12597	codec->spec = spec;
12598
12599	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
12600						  alc662_models,
12601			  	                  alc662_cfg_tbl);
12602	if (board_config < 0) {
12603		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
12604		       "trying auto-probe from BIOS...\n");
12605		board_config = ALC662_AUTO;
12606	}
12607
12608	if (board_config == ALC662_AUTO) {
12609		/* automatic parse from the BIOS config */
12610		err = alc662_parse_auto_config(codec);
12611		if (err < 0) {
12612			alc_free(codec);
12613			return err;
12614		} else if (!err) {
12615			printk(KERN_INFO
12616			       "hda_codec: Cannot set up configuration "
12617			       "from BIOS.  Using base mode...\n");
12618			board_config = ALC662_3ST_2ch_DIG;
12619		}
12620	}
12621
12622	if (board_config != ALC662_AUTO)
12623		setup_preset(spec, &alc662_presets[board_config]);
12624
12625	spec->stream_name_analog = "ALC662 Analog";
12626	spec->stream_analog_playback = &alc662_pcm_analog_playback;
12627	spec->stream_analog_capture = &alc662_pcm_analog_capture;
12628
12629	spec->stream_name_digital = "ALC662 Digital";
12630	spec->stream_digital_playback = &alc662_pcm_digital_playback;
12631	spec->stream_digital_capture = &alc662_pcm_digital_capture;
12632
12633	if (!spec->adc_nids && spec->input_mux) {
12634		spec->adc_nids = alc662_adc_nids;
12635		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
12636	}
12637
12638	codec->patch_ops = alc_patch_ops;
12639	if (board_config == ALC662_AUTO)
12640		spec->init_hook = alc662_auto_init;
12641#ifdef CONFIG_SND_HDA_POWER_SAVE
12642	if (!spec->loopback.amplist)
12643		spec->loopback.amplist = alc662_loopbacks;
12644#endif
12645
12646	return 0;
12647}
12648
12649/*
12650 * patch entries
12651 */
12652struct hda_codec_preset snd_hda_preset_realtek[] = {
12653	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
12654	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
12655	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
12656	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
12657	  .patch = patch_alc861 },
12658	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
12659	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
12660	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
12661	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
12662	  .patch = patch_alc883 },
12663	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
12664	  .patch = patch_alc662 },
12665	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
12666	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
12667	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
12668	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
12669	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
12670	{} /* terminator */
12671};
12672