patch_realtek.c revision e87f97a3e842a816f30f087d5bfac68ef2afaef2
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 *                    PeiSen Hou <pshou@realtek.com.tw>
8 *                    Takashi Iwai <tiwai@suse.de>
9 *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10 *
11 *  This driver is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This driver is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24 */
25
26#include <sound/driver.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pci.h>
31#include <sound/core.h>
32#include "hda_codec.h"
33#include "hda_local.h"
34
35#define ALC880_FRONT_EVENT		0x01
36#define ALC880_DCVOL_EVENT		0x02
37#define ALC880_HP_EVENT			0x04
38#define ALC880_MIC_EVENT		0x08
39
40/* ALC880 board config type */
41enum {
42	ALC880_3ST,
43	ALC880_3ST_DIG,
44	ALC880_5ST,
45	ALC880_5ST_DIG,
46	ALC880_W810,
47	ALC880_Z71V,
48	ALC880_6ST,
49	ALC880_6ST_DIG,
50	ALC880_F1734,
51	ALC880_ASUS,
52	ALC880_ASUS_DIG,
53	ALC880_ASUS_W1V,
54	ALC880_ASUS_DIG2,
55	ALC880_FUJITSU,
56	ALC880_UNIWILL_DIG,
57	ALC880_UNIWILL,
58	ALC880_UNIWILL_P53,
59	ALC880_CLEVO,
60	ALC880_TCL_S700,
61	ALC880_LG,
62	ALC880_LG_LW,
63#ifdef CONFIG_SND_DEBUG
64	ALC880_TEST,
65#endif
66	ALC880_AUTO,
67	ALC880_MODEL_LAST /* last tag */
68};
69
70/* ALC260 models */
71enum {
72	ALC260_BASIC,
73	ALC260_HP,
74	ALC260_HP_3013,
75	ALC260_FUJITSU_S702X,
76	ALC260_ACER,
77	ALC260_WILL,
78	ALC260_REPLACER_672V,
79#ifdef CONFIG_SND_DEBUG
80	ALC260_TEST,
81#endif
82	ALC260_AUTO,
83	ALC260_MODEL_LAST /* last tag */
84};
85
86/* ALC262 models */
87enum {
88	ALC262_BASIC,
89	ALC262_HIPPO,
90	ALC262_HIPPO_1,
91	ALC262_FUJITSU,
92	ALC262_HP_BPC,
93	ALC262_HP_BPC_D7000_WL,
94	ALC262_HP_BPC_D7000_WF,
95	ALC262_BENQ_ED8,
96	ALC262_SONY_ASSAMD,
97	ALC262_BENQ_T31,
98	ALC262_AUTO,
99	ALC262_MODEL_LAST /* last tag */
100};
101
102/* ALC268 models */
103enum {
104	ALC268_3ST,
105	ALC268_AUTO,
106	ALC268_MODEL_LAST /* last tag */
107};
108
109/* ALC861 models */
110enum {
111	ALC861_3ST,
112	ALC660_3ST,
113	ALC861_3ST_DIG,
114	ALC861_6ST_DIG,
115	ALC861_UNIWILL_M31,
116	ALC861_TOSHIBA,
117	ALC861_ASUS,
118	ALC861_ASUS_LAPTOP,
119	ALC861_AUTO,
120	ALC861_MODEL_LAST,
121};
122
123/* ALC861-VD models */
124enum {
125	ALC660VD_3ST,
126	ALC660VD_3ST_DIG,
127	ALC861VD_3ST,
128	ALC861VD_3ST_DIG,
129	ALC861VD_6ST_DIG,
130	ALC861VD_LENOVO,
131	ALC861VD_DALLAS,
132	ALC861VD_AUTO,
133	ALC861VD_MODEL_LAST,
134};
135
136/* ALC662 models */
137enum {
138	ALC662_3ST_2ch_DIG,
139	ALC662_3ST_6ch_DIG,
140	ALC662_3ST_6ch,
141	ALC662_5ST_DIG,
142	ALC662_LENOVO_101E,
143	ALC662_AUTO,
144	ALC662_MODEL_LAST,
145};
146
147/* ALC882 models */
148enum {
149	ALC882_3ST_DIG,
150	ALC882_6ST_DIG,
151	ALC882_ARIMA,
152	ALC882_W2JC,
153	ALC882_TARGA,
154	ALC882_ASUS_A7J,
155	ALC885_MACPRO,
156	ALC882_AUTO,
157	ALC882_MODEL_LAST,
158};
159
160/* ALC883 models */
161enum {
162	ALC883_3ST_2ch_DIG,
163	ALC883_3ST_6ch_DIG,
164	ALC883_3ST_6ch,
165	ALC883_6ST_DIG,
166	ALC883_TARGA_DIG,
167	ALC883_TARGA_2ch_DIG,
168	ALC883_ACER,
169	ALC883_MEDION,
170	ALC883_MEDION_MD2,
171	ALC883_LAPTOP_EAPD,
172	ALC883_LENOVO_101E_2ch,
173	ALC883_LENOVO_NB0763,
174	ALC888_LENOVO_MS7195_DIG,
175	ALC888_HP_NETTLE,
176	ALC888_HP_LUCKNOW,
177	ALC883_AUTO,
178	ALC883_MODEL_LAST,
179};
180
181/* for GPIO Poll */
182#define GPIO_MASK	0x03
183
184struct alc_spec {
185	/* codec parameterization */
186	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
187	unsigned int num_mixers;
188
189	const struct hda_verb *init_verbs[5];	/* initialization verbs
190						 * don't forget NULL
191						 * termination!
192						 */
193	unsigned int num_init_verbs;
194
195	char *stream_name_analog;	/* analog PCM stream */
196	struct hda_pcm_stream *stream_analog_playback;
197	struct hda_pcm_stream *stream_analog_capture;
198
199	char *stream_name_digital;	/* digital PCM stream */
200	struct hda_pcm_stream *stream_digital_playback;
201	struct hda_pcm_stream *stream_digital_capture;
202
203	/* playback */
204	struct hda_multi_out multiout;	/* playback set-up
205					 * max_channels, dacs must be set
206					 * dig_out_nid and hp_nid are optional
207					 */
208
209	/* capture */
210	unsigned int num_adc_nids;
211	hda_nid_t *adc_nids;
212	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
213
214	/* capture source */
215	unsigned int num_mux_defs;
216	const struct hda_input_mux *input_mux;
217	unsigned int cur_mux[3];
218
219	/* channel model */
220	const struct hda_channel_mode *channel_mode;
221	int num_channel_mode;
222	int need_dac_fix;
223
224	/* PCM information */
225	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
226
227	/* dynamic controls, init_verbs and input_mux */
228	struct auto_pin_cfg autocfg;
229	unsigned int num_kctl_alloc, num_kctl_used;
230	struct snd_kcontrol_new *kctl_alloc;
231	struct hda_input_mux private_imux;
232	hda_nid_t private_dac_nids[5];
233
234	/* hooks */
235	void (*init_hook)(struct hda_codec *codec);
236	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
237
238	/* for pin sensing */
239	unsigned int sense_updated: 1;
240	unsigned int jack_present: 1;
241};
242
243/*
244 * configuration template - to be copied to the spec instance
245 */
246struct alc_config_preset {
247	struct snd_kcontrol_new *mixers[5]; /* should be identical size
248					     * with spec
249					     */
250	const struct hda_verb *init_verbs[5];
251	unsigned int num_dacs;
252	hda_nid_t *dac_nids;
253	hda_nid_t dig_out_nid;		/* optional */
254	hda_nid_t hp_nid;		/* optional */
255	unsigned int num_adc_nids;
256	hda_nid_t *adc_nids;
257	hda_nid_t dig_in_nid;
258	unsigned int num_channel_mode;
259	const struct hda_channel_mode *channel_mode;
260	int need_dac_fix;
261	unsigned int num_mux_defs;
262	const struct hda_input_mux *input_mux;
263	void (*unsol_event)(struct hda_codec *, unsigned int);
264	void (*init_hook)(struct hda_codec *);
265};
266
267
268/*
269 * input MUX handling
270 */
271static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
272			     struct snd_ctl_elem_info *uinfo)
273{
274	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
275	struct alc_spec *spec = codec->spec;
276	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
277	if (mux_idx >= spec->num_mux_defs)
278		mux_idx = 0;
279	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
280}
281
282static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
283			    struct snd_ctl_elem_value *ucontrol)
284{
285	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
286	struct alc_spec *spec = codec->spec;
287	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
288
289	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
290	return 0;
291}
292
293static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
294			    struct snd_ctl_elem_value *ucontrol)
295{
296	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297	struct alc_spec *spec = codec->spec;
298	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
299	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
300	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
301				     spec->adc_nids[adc_idx],
302				     &spec->cur_mux[adc_idx]);
303}
304
305
306/*
307 * channel mode setting
308 */
309static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
310			    struct snd_ctl_elem_info *uinfo)
311{
312	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
313	struct alc_spec *spec = codec->spec;
314	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
315				    spec->num_channel_mode);
316}
317
318static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
319			   struct snd_ctl_elem_value *ucontrol)
320{
321	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
322	struct alc_spec *spec = codec->spec;
323	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
324				   spec->num_channel_mode,
325				   spec->multiout.max_channels);
326}
327
328static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
329			   struct snd_ctl_elem_value *ucontrol)
330{
331	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
332	struct alc_spec *spec = codec->spec;
333	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
334				      spec->num_channel_mode,
335				      &spec->multiout.max_channels);
336	if (err >= 0 && spec->need_dac_fix)
337		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
338	return err;
339}
340
341/*
342 * Control the mode of pin widget settings via the mixer.  "pc" is used
343 * instead of "%" to avoid consequences of accidently treating the % as
344 * being part of a format specifier.  Maximum allowed length of a value is
345 * 63 characters plus NULL terminator.
346 *
347 * Note: some retasking pin complexes seem to ignore requests for input
348 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
349 * are requested.  Therefore order this list so that this behaviour will not
350 * cause problems when mixer clients move through the enum sequentially.
351 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
352 * March 2006.
353 */
354static char *alc_pin_mode_names[] = {
355	"Mic 50pc bias", "Mic 80pc bias",
356	"Line in", "Line out", "Headphone out",
357};
358static unsigned char alc_pin_mode_values[] = {
359	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
360};
361/* The control can present all 5 options, or it can limit the options based
362 * in the pin being assumed to be exclusively an input or an output pin.  In
363 * addition, "input" pins may or may not process the mic bias option
364 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
365 * accept requests for bias as of chip versions up to March 2006) and/or
366 * wiring in the computer.
367 */
368#define ALC_PIN_DIR_IN              0x00
369#define ALC_PIN_DIR_OUT             0x01
370#define ALC_PIN_DIR_INOUT           0x02
371#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
372#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
373
374/* Info about the pin modes supported by the different pin direction modes.
375 * For each direction the minimum and maximum values are given.
376 */
377static signed char alc_pin_mode_dir_info[5][2] = {
378	{ 0, 2 },    /* ALC_PIN_DIR_IN */
379	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
380	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
381	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
382	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
383};
384#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
385#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
386#define alc_pin_mode_n_items(_dir) \
387	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
388
389static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
390			     struct snd_ctl_elem_info *uinfo)
391{
392	unsigned int item_num = uinfo->value.enumerated.item;
393	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
394
395	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
396	uinfo->count = 1;
397	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
398
399	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
400		item_num = alc_pin_mode_min(dir);
401	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
402	return 0;
403}
404
405static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
406			    struct snd_ctl_elem_value *ucontrol)
407{
408	unsigned int i;
409	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
410	hda_nid_t nid = kcontrol->private_value & 0xffff;
411	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
412	long *valp = ucontrol->value.integer.value;
413	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
414						 AC_VERB_GET_PIN_WIDGET_CONTROL,
415						 0x00);
416
417	/* Find enumerated value for current pinctl setting */
418	i = alc_pin_mode_min(dir);
419	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
420		i++;
421	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
422	return 0;
423}
424
425static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
426			    struct snd_ctl_elem_value *ucontrol)
427{
428	signed int change;
429	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
430	hda_nid_t nid = kcontrol->private_value & 0xffff;
431	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
432	long val = *ucontrol->value.integer.value;
433	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
434						 AC_VERB_GET_PIN_WIDGET_CONTROL,
435						 0x00);
436
437	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
438		val = alc_pin_mode_min(dir);
439
440	change = pinctl != alc_pin_mode_values[val];
441	if (change) {
442		/* Set pin mode to that requested */
443		snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
444				    alc_pin_mode_values[val]);
445
446		/* Also enable the retasking pin's input/output as required
447		 * for the requested pin mode.  Enum values of 2 or less are
448		 * input modes.
449		 *
450		 * Dynamically switching the input/output buffers probably
451		 * reduces noise slightly (particularly on input) so we'll
452		 * do it.  However, having both input and output buffers
453		 * enabled simultaneously doesn't seem to be problematic if
454		 * this turns out to be necessary in the future.
455		 */
456		if (val <= 2) {
457			snd_hda_codec_write(codec, nid, 0,
458					    AC_VERB_SET_AMP_GAIN_MUTE,
459					    AMP_OUT_MUTE);
460			snd_hda_codec_write(codec, nid, 0,
461					    AC_VERB_SET_AMP_GAIN_MUTE,
462					    AMP_IN_UNMUTE(0));
463		} else {
464			snd_hda_codec_write(codec, nid, 0,
465					    AC_VERB_SET_AMP_GAIN_MUTE,
466					    AMP_IN_MUTE(0));
467			snd_hda_codec_write(codec, nid, 0,
468					    AC_VERB_SET_AMP_GAIN_MUTE,
469					    AMP_OUT_UNMUTE);
470		}
471	}
472	return change;
473}
474
475#define ALC_PIN_MODE(xname, nid, dir) \
476	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
477	  .info = alc_pin_mode_info, \
478	  .get = alc_pin_mode_get, \
479	  .put = alc_pin_mode_put, \
480	  .private_value = nid | (dir<<16) }
481
482/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
483 * together using a mask with more than one bit set.  This control is
484 * currently used only by the ALC260 test model.  At this stage they are not
485 * needed for any "production" models.
486 */
487#ifdef CONFIG_SND_DEBUG
488static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
489			      struct snd_ctl_elem_info *uinfo)
490{
491	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
492	uinfo->count = 1;
493	uinfo->value.integer.min = 0;
494	uinfo->value.integer.max = 1;
495	return 0;
496}
497
498static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
499			     struct snd_ctl_elem_value *ucontrol)
500{
501	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502	hda_nid_t nid = kcontrol->private_value & 0xffff;
503	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
504	long *valp = ucontrol->value.integer.value;
505	unsigned int val = snd_hda_codec_read(codec, nid, 0,
506					      AC_VERB_GET_GPIO_DATA, 0x00);
507
508	*valp = (val & mask) != 0;
509	return 0;
510}
511static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
512			     struct snd_ctl_elem_value *ucontrol)
513{
514	signed int change;
515	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
516	hda_nid_t nid = kcontrol->private_value & 0xffff;
517	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
518	long val = *ucontrol->value.integer.value;
519	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
520						    AC_VERB_GET_GPIO_DATA,
521						    0x00);
522
523	/* Set/unset the masked GPIO bit(s) as needed */
524	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
525	if (val == 0)
526		gpio_data &= ~mask;
527	else
528		gpio_data |= mask;
529	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
530
531	return change;
532}
533#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
534	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
535	  .info = alc_gpio_data_info, \
536	  .get = alc_gpio_data_get, \
537	  .put = alc_gpio_data_put, \
538	  .private_value = nid | (mask<<16) }
539#endif   /* CONFIG_SND_DEBUG */
540
541/* A switch control to allow the enabling of the digital IO pins on the
542 * ALC260.  This is incredibly simplistic; the intention of this control is
543 * to provide something in the test model allowing digital outputs to be
544 * identified if present.  If models are found which can utilise these
545 * outputs a more complete mixer control can be devised for those models if
546 * necessary.
547 */
548#ifdef CONFIG_SND_DEBUG
549static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
550			       struct snd_ctl_elem_info *uinfo)
551{
552	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
553	uinfo->count = 1;
554	uinfo->value.integer.min = 0;
555	uinfo->value.integer.max = 1;
556	return 0;
557}
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(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}
641
642/* Enable GPIO mask and set output */
643static struct hda_verb alc_gpio1_init_verbs[] = {
644	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
645	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
646	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
647	{ }
648};
649
650static struct hda_verb alc_gpio2_init_verbs[] = {
651	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
652	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
653	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
654	{ }
655};
656
657static struct hda_verb alc_gpio3_init_verbs[] = {
658	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
659	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
660	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
661	{ }
662};
663
664/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
665 *	31 ~ 16 :	Manufacture ID
666 *	15 ~ 8	:	SKU ID
667 *	7  ~ 0	:	Assembly ID
668 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
669 */
670static void alc_subsystem_id(struct hda_codec *codec,
671			     unsigned int porta, unsigned int porte,
672			     unsigned int portd)
673{
674	unsigned int ass, tmp;
675
676	ass = codec->subsystem_id;
677	if (!(ass & 1))
678		return;
679
680	/* Override */
681	tmp = (ass & 0x38) >> 3;	/* external Amp control */
682	switch (tmp) {
683	case 1:
684		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
685		break;
686	case 3:
687		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
688		break;
689	case 7:
690		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
691		break;
692	case 5:
693		switch (codec->vendor_id) {
694		case 0x10ec0862:
695		case 0x10ec0660:
696		case 0x10ec0662:
697		case 0x10ec0267:
698		case 0x10ec0268:
699			snd_hda_codec_write(codec, 0x14, 0,
700					    AC_VERB_SET_EAPD_BTLENABLE, 2);
701			snd_hda_codec_write(codec, 0x15, 0,
702					    AC_VERB_SET_EAPD_BTLENABLE, 2);
703			return;
704		}
705	case 6:
706		if (ass & 4) {	/* bit 2 : 0 = Desktop, 1 = Laptop */
707			hda_nid_t port = 0;
708			tmp = (ass & 0x1800) >> 11;
709			switch (tmp) {
710			case 0: port = porta; break;
711			case 1: port = porte; break;
712			case 2: port = portd; break;
713			}
714			if (port)
715				snd_hda_codec_write(codec, port, 0,
716						    AC_VERB_SET_EAPD_BTLENABLE,
717						    2);
718		}
719		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
720		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
721				    (tmp == 5 ? 0x3040 : 0x3050));
722		break;
723	}
724}
725
726/*
727 * Fix-up pin default configurations
728 */
729
730struct alc_pincfg {
731	hda_nid_t nid;
732	u32 val;
733};
734
735static void alc_fix_pincfg(struct hda_codec *codec,
736			   const struct snd_pci_quirk *quirk,
737			   const struct alc_pincfg **pinfix)
738{
739	const struct alc_pincfg *cfg;
740
741	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
742	if (!quirk)
743		return;
744
745	cfg = pinfix[quirk->value];
746	for (; cfg->nid; cfg++) {
747		int i;
748		u32 val = cfg->val;
749		for (i = 0; i < 4; i++) {
750			snd_hda_codec_write(codec, cfg->nid, 0,
751				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
752				    val & 0xff);
753			val >>= 8;
754		}
755	}
756}
757
758/*
759 * ALC880 3-stack model
760 *
761 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
762 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
763 *                 F-Mic = 0x1b, HP = 0x19
764 */
765
766static hda_nid_t alc880_dac_nids[4] = {
767	/* front, rear, clfe, rear_surr */
768	0x02, 0x05, 0x04, 0x03
769};
770
771static hda_nid_t alc880_adc_nids[3] = {
772	/* ADC0-2 */
773	0x07, 0x08, 0x09,
774};
775
776/* The datasheet says the node 0x07 is connected from inputs,
777 * but it shows zero connection in the real implementation on some devices.
778 * Note: this is a 915GAV bug, fixed on 915GLV
779 */
780static hda_nid_t alc880_adc_nids_alt[2] = {
781	/* ADC1-2 */
782	0x08, 0x09,
783};
784
785#define ALC880_DIGOUT_NID	0x06
786#define ALC880_DIGIN_NID	0x0a
787
788static struct hda_input_mux alc880_capture_source = {
789	.num_items = 4,
790	.items = {
791		{ "Mic", 0x0 },
792		{ "Front Mic", 0x3 },
793		{ "Line", 0x2 },
794		{ "CD", 0x4 },
795	},
796};
797
798/* channel source setting (2/6 channel selection for 3-stack) */
799/* 2ch mode */
800static struct hda_verb alc880_threestack_ch2_init[] = {
801	/* set line-in to input, mute it */
802	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
803	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
804	/* set mic-in to input vref 80%, mute it */
805	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
806	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
807	{ } /* end */
808};
809
810/* 6ch mode */
811static struct hda_verb alc880_threestack_ch6_init[] = {
812	/* set line-in to output, unmute it */
813	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
814	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
815	/* set mic-in to output, unmute it */
816	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
817	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
818	{ } /* end */
819};
820
821static struct hda_channel_mode alc880_threestack_modes[2] = {
822	{ 2, alc880_threestack_ch2_init },
823	{ 6, alc880_threestack_ch6_init },
824};
825
826static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
827	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
828	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
829	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
830	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
831	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
832	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
833	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
834	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
835	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
836	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
837	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
838	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
839	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
840	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
841	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
842	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
843	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
844	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
845	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
846	{
847		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
848		.name = "Channel Mode",
849		.info = alc_ch_mode_info,
850		.get = alc_ch_mode_get,
851		.put = alc_ch_mode_put,
852	},
853	{ } /* end */
854};
855
856/* capture mixer elements */
857static struct snd_kcontrol_new alc880_capture_mixer[] = {
858	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
859	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
860	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
861	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
862	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
863	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
864	{
865		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
866		/* The multiple "Capture Source" controls confuse alsamixer
867		 * So call somewhat different..
868		 * FIXME: the controls appear in the "playback" view!
869		 */
870		/* .name = "Capture Source", */
871		.name = "Input Source",
872		.count = 3,
873		.info = alc_mux_enum_info,
874		.get = alc_mux_enum_get,
875		.put = alc_mux_enum_put,
876	},
877	{ } /* end */
878};
879
880/* capture mixer elements (in case NID 0x07 not available) */
881static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
882	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
883	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
884	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
885	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
886	{
887		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
888		/* The multiple "Capture Source" controls confuse alsamixer
889		 * So call somewhat different..
890		 * FIXME: the controls appear in the "playback" view!
891		 */
892		/* .name = "Capture Source", */
893		.name = "Input Source",
894		.count = 2,
895		.info = alc_mux_enum_info,
896		.get = alc_mux_enum_get,
897		.put = alc_mux_enum_put,
898	},
899	{ } /* end */
900};
901
902
903
904/*
905 * ALC880 5-stack model
906 *
907 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
908 *      Side = 0x02 (0xd)
909 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
910 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
911 */
912
913/* additional mixers to alc880_three_stack_mixer */
914static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
915	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
916	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
917	{ } /* end */
918};
919
920/* channel source setting (6/8 channel selection for 5-stack) */
921/* 6ch mode */
922static struct hda_verb alc880_fivestack_ch6_init[] = {
923	/* set line-in to input, mute it */
924	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
925	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
926	{ } /* end */
927};
928
929/* 8ch mode */
930static struct hda_verb alc880_fivestack_ch8_init[] = {
931	/* set line-in to output, unmute it */
932	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
933	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
934	{ } /* end */
935};
936
937static struct hda_channel_mode alc880_fivestack_modes[2] = {
938	{ 6, alc880_fivestack_ch6_init },
939	{ 8, alc880_fivestack_ch8_init },
940};
941
942
943/*
944 * ALC880 6-stack model
945 *
946 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
947 *      Side = 0x05 (0x0f)
948 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
949 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
950 */
951
952static hda_nid_t alc880_6st_dac_nids[4] = {
953	/* front, rear, clfe, rear_surr */
954	0x02, 0x03, 0x04, 0x05
955};
956
957static struct hda_input_mux alc880_6stack_capture_source = {
958	.num_items = 4,
959	.items = {
960		{ "Mic", 0x0 },
961		{ "Front Mic", 0x1 },
962		{ "Line", 0x2 },
963		{ "CD", 0x4 },
964	},
965};
966
967/* fixed 8-channels */
968static struct hda_channel_mode alc880_sixstack_modes[1] = {
969	{ 8, NULL },
970};
971
972static struct snd_kcontrol_new alc880_six_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", 0x0d, 0x0, HDA_OUTPUT),
976	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 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("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
982	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
983	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
984	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
985	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
986	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
987	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
988	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
989	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
990	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
991	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
992	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
993	{
994		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
995		.name = "Channel Mode",
996		.info = alc_ch_mode_info,
997		.get = alc_ch_mode_get,
998		.put = alc_ch_mode_put,
999	},
1000	{ } /* end */
1001};
1002
1003
1004/*
1005 * ALC880 W810 model
1006 *
1007 * W810 has rear IO for:
1008 * Front (DAC 02)
1009 * Surround (DAC 03)
1010 * Center/LFE (DAC 04)
1011 * Digital out (06)
1012 *
1013 * The system also has a pair of internal speakers, and a headphone jack.
1014 * These are both connected to Line2 on the codec, hence to DAC 02.
1015 *
1016 * There is a variable resistor to control the speaker or headphone
1017 * volume. This is a hardware-only device without a software API.
1018 *
1019 * Plugging headphones in will disable the internal speakers. This is
1020 * implemented in hardware, not via the driver using jack sense. In
1021 * a similar fashion, plugging into the rear socket marked "front" will
1022 * disable both the speakers and headphones.
1023 *
1024 * For input, there's a microphone jack, and an "audio in" jack.
1025 * These may not do anything useful with this driver yet, because I
1026 * haven't setup any initialization verbs for these yet...
1027 */
1028
1029static hda_nid_t alc880_w810_dac_nids[3] = {
1030	/* front, rear/surround, clfe */
1031	0x02, 0x03, 0x04
1032};
1033
1034/* fixed 6 channels */
1035static struct hda_channel_mode alc880_w810_modes[1] = {
1036	{ 6, NULL }
1037};
1038
1039/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1040static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1041	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1042	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1043	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1044	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1045	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1046	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1047	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1048	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1049	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1050	{ } /* end */
1051};
1052
1053
1054/*
1055 * Z710V model
1056 *
1057 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1058 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1059 *                 Line = 0x1a
1060 */
1061
1062static hda_nid_t alc880_z71v_dac_nids[1] = {
1063	0x02
1064};
1065#define ALC880_Z71V_HP_DAC	0x03
1066
1067/* fixed 2 channels */
1068static struct hda_channel_mode alc880_2_jack_modes[1] = {
1069	{ 2, NULL }
1070};
1071
1072static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1073	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1074	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1075	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1076	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1077	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1078	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1079	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1080	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1081	{ } /* end */
1082};
1083
1084
1085/* FIXME! */
1086/*
1087 * ALC880 F1734 model
1088 *
1089 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1090 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1091 */
1092
1093static hda_nid_t alc880_f1734_dac_nids[1] = {
1094	0x03
1095};
1096#define ALC880_F1734_HP_DAC	0x02
1097
1098static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1099	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1100	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1101	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1102	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1103	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1104	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1105	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1106	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1107	{ } /* end */
1108};
1109
1110
1111/* FIXME! */
1112/*
1113 * ALC880 ASUS model
1114 *
1115 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1116 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1117 *  Mic = 0x18, Line = 0x1a
1118 */
1119
1120#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1121#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1122
1123static struct snd_kcontrol_new alc880_asus_mixer[] = {
1124	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1125	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1126	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1127	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1128	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1129	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1130	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1131	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1132	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1133	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1134	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1135	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1136	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1137	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1138	{
1139		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1140		.name = "Channel Mode",
1141		.info = alc_ch_mode_info,
1142		.get = alc_ch_mode_get,
1143		.put = alc_ch_mode_put,
1144	},
1145	{ } /* end */
1146};
1147
1148/* FIXME! */
1149/*
1150 * ALC880 ASUS W1V model
1151 *
1152 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1153 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1154 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1155 */
1156
1157/* additional mixers to alc880_asus_mixer */
1158static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1159	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1160	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1161	{ } /* end */
1162};
1163
1164/* additional mixers to alc880_asus_mixer */
1165static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1166	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1167	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1168	{ } /* end */
1169};
1170
1171/* TCL S700 */
1172static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1173	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1174	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1175	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1176	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1177	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1178	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1179	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1180	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1181	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1182	{
1183		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1184		/* The multiple "Capture Source" controls confuse alsamixer
1185		 * So call somewhat different..
1186		 * FIXME: the controls appear in the "playback" view!
1187		 */
1188		/* .name = "Capture Source", */
1189		.name = "Input Source",
1190		.count = 1,
1191		.info = alc_mux_enum_info,
1192		.get = alc_mux_enum_get,
1193		.put = alc_mux_enum_put,
1194	},
1195	{ } /* end */
1196};
1197
1198/* Uniwill */
1199static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1200	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1201	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1202	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1203	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1204	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1205	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1206	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1207	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1208	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1209	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1210	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1211	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1212	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1213	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1214	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1215	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1216	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1217	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1218	{
1219		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1220		.name = "Channel Mode",
1221		.info = alc_ch_mode_info,
1222		.get = alc_ch_mode_get,
1223		.put = alc_ch_mode_put,
1224	},
1225	{ } /* end */
1226};
1227
1228static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1229	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1230	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1231	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1232	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1233	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1234	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1235	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1236	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1237	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1238	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1239	{ } /* end */
1240};
1241
1242static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1243	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1244	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1245	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1246	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1247	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1248	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1249	{ } /* end */
1250};
1251
1252/*
1253 * build control elements
1254 */
1255static int alc_build_controls(struct hda_codec *codec)
1256{
1257	struct alc_spec *spec = codec->spec;
1258	int err;
1259	int i;
1260
1261	for (i = 0; i < spec->num_mixers; i++) {
1262		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1263		if (err < 0)
1264			return err;
1265	}
1266
1267	if (spec->multiout.dig_out_nid) {
1268		err = snd_hda_create_spdif_out_ctls(codec,
1269						    spec->multiout.dig_out_nid);
1270		if (err < 0)
1271			return err;
1272	}
1273	if (spec->dig_in_nid) {
1274		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1275		if (err < 0)
1276			return err;
1277	}
1278	return 0;
1279}
1280
1281
1282/*
1283 * initialize the codec volumes, etc
1284 */
1285
1286/*
1287 * generic initialization of ADC, input mixers and output mixers
1288 */
1289static struct hda_verb alc880_volume_init_verbs[] = {
1290	/*
1291	 * Unmute ADC0-2 and set the default input to mic-in
1292	 */
1293	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1294	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1295	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1296	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1297	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1298	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1299
1300	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1301	 * mixer widget
1302	 * Note: PASD motherboards uses the Line In 2 as the input for front
1303	 * panel mic (mic 2)
1304	 */
1305	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1306	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1307	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1308	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1309	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1310	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1311
1312	/*
1313	 * Set up output mixers (0x0c - 0x0f)
1314	 */
1315	/* set vol=0 to output mixers */
1316	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1317	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1318	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1319	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1320	/* set up input amps for analog loopback */
1321	/* Amp Indices: DAC = 0, mixer = 1 */
1322	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1324	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1327	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1328	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1329	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1330
1331	{ }
1332};
1333
1334/*
1335 * 3-stack pin configuration:
1336 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1337 */
1338static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1339	/*
1340	 * preset connection lists of input pins
1341	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1342	 */
1343	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1344	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1345	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1346
1347	/*
1348	 * Set pin mode and muting
1349	 */
1350	/* set front pin widgets 0x14 for output */
1351	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1352	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1353	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1354	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1355	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1356	/* Mic2 (as headphone out) for HP output */
1357	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1358	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1359	/* Line In pin widget for input */
1360	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1361	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1362	/* Line2 (as front mic) pin widget for input and vref at 80% */
1363	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1364	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1365	/* CD pin widget for input */
1366	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1367
1368	{ }
1369};
1370
1371/*
1372 * 5-stack pin configuration:
1373 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1374 * line-in/side = 0x1a, f-mic = 0x1b
1375 */
1376static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1377	/*
1378	 * preset connection lists of input pins
1379	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1380	 */
1381	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1382	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1383
1384	/*
1385	 * Set pin mode and muting
1386	 */
1387	/* set pin widgets 0x14-0x17 for output */
1388	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1389	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1390	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1391	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1392	/* unmute pins for output (no gain on this amp) */
1393	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1394	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1395	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1396	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1397
1398	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1399	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1400	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1401	/* Mic2 (as headphone out) for HP output */
1402	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1403	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1404	/* Line In pin widget for input */
1405	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1406	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1407	/* Line2 (as front mic) pin widget for input and vref at 80% */
1408	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1409	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1410	/* CD pin widget for input */
1411	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1412
1413	{ }
1414};
1415
1416/*
1417 * W810 pin configuration:
1418 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1419 */
1420static struct hda_verb alc880_pin_w810_init_verbs[] = {
1421	/* hphone/speaker input selector: front DAC */
1422	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1423
1424	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1425	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1426	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1427	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1428	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1429	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1430
1431	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1432	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1433
1434	{ }
1435};
1436
1437/*
1438 * Z71V pin configuration:
1439 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1440 */
1441static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1442	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1443	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1445	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1446
1447	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1448	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1449	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1450	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1451
1452	{ }
1453};
1454
1455/*
1456 * 6-stack pin configuration:
1457 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1458 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1459 */
1460static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1461	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1462
1463	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1464	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1468	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1470	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1471
1472	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1473	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1474	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1475	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1476	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1477	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1478	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1479	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1480	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1481
1482	{ }
1483};
1484
1485/*
1486 * Uniwill pin configuration:
1487 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1488 * line = 0x1a
1489 */
1490static struct hda_verb alc880_uniwill_init_verbs[] = {
1491	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1492
1493	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1494	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1496	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1498	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1500	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1501	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1502	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1503	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1504	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1505	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1506	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1507
1508	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1509	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1510	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1511	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1512	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1513	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1514	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1515	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1516	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1517
1518	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1519	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1520
1521	{ }
1522};
1523
1524/*
1525* Uniwill P53
1526* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1527 */
1528static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1529	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1530
1531	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1532	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1533	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1534	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1535	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1536	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1537	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1538	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1539	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1540	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1541	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1542	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1543
1544	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1545	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1546	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1547	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1548	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1549	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1550
1551	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1552	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1553
1554	{ }
1555};
1556
1557static struct hda_verb alc880_beep_init_verbs[] = {
1558	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1559	{ }
1560};
1561
1562/* toggle speaker-output according to the hp-jack state */
1563static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1564{
1565 	unsigned int present;
1566	unsigned char bits;
1567
1568 	present = snd_hda_codec_read(codec, 0x14, 0,
1569				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1570	bits = present ? 0x80 : 0;
1571	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1572				 0x80, bits);
1573	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1574				 0x80, bits);
1575	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1576				 0x80, bits);
1577	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1578				 0x80, bits);
1579}
1580
1581/* auto-toggle front mic */
1582static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1583{
1584 	unsigned int present;
1585	unsigned char bits;
1586
1587	present = snd_hda_codec_read(codec, 0x18, 0,
1588				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1589	bits = present ? 0x80 : 0;
1590	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
1591				 0x80, bits);
1592	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
1593				 0x80, bits);
1594}
1595
1596static void alc880_uniwill_automute(struct hda_codec *codec)
1597{
1598	alc880_uniwill_hp_automute(codec);
1599	alc880_uniwill_mic_automute(codec);
1600}
1601
1602static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1603				       unsigned int res)
1604{
1605	/* Looks like the unsol event is incompatible with the standard
1606	 * definition.  4bit tag is placed at 28 bit!
1607	 */
1608	switch (res >> 28) {
1609	case ALC880_HP_EVENT:
1610		alc880_uniwill_hp_automute(codec);
1611		break;
1612	case ALC880_MIC_EVENT:
1613		alc880_uniwill_mic_automute(codec);
1614		break;
1615	}
1616}
1617
1618static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1619{
1620 	unsigned int present;
1621	unsigned char bits;
1622
1623 	present = snd_hda_codec_read(codec, 0x14, 0,
1624				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1625	bits = present ? 0x80 : 0;
1626	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1627				 0x80, bits);
1628	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1629				 0x80, bits);
1630}
1631
1632static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1633{
1634	unsigned int present;
1635
1636	present = snd_hda_codec_read(codec, 0x21, 0,
1637				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1638
1639	snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1640				 0x7f, present);
1641	snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1642				 0x7f,  present);
1643
1644	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1645				 0x7f,  present);
1646	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1647				 0x7f, present);
1648
1649}
1650static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1651					   unsigned int res)
1652{
1653	/* Looks like the unsol event is incompatible with the standard
1654	 * definition.  4bit tag is placed at 28 bit!
1655	 */
1656	if ((res >> 28) == ALC880_HP_EVENT)
1657		alc880_uniwill_p53_hp_automute(codec);
1658	if ((res >> 28) == ALC880_DCVOL_EVENT)
1659		alc880_uniwill_p53_dcvol_automute(codec);
1660}
1661
1662/* FIXME! */
1663/*
1664 * F1734 pin configuration:
1665 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1666 */
1667static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1668	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1669	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1670	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1671	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1672
1673	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1674	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1675	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1676	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1677
1678	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1679	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1680	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1681	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1682	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1683	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1684	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1685	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1686	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1687
1688	{ }
1689};
1690
1691/* FIXME! */
1692/*
1693 * ASUS pin configuration:
1694 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1695 */
1696static struct hda_verb alc880_pin_asus_init_verbs[] = {
1697	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1698	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1699	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1700	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1701
1702	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1703	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1705	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1707	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1708	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1709	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710
1711	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1712	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1713	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1714	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1715	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1716	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1717	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1718	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1719	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1720
1721	{ }
1722};
1723
1724/* Enable GPIO mask and set output */
1725#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1726#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1727
1728/* Clevo m520g init */
1729static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1730	/* headphone output */
1731	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1732	/* line-out */
1733	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1734	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1735	/* Line-in */
1736	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1737	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1738	/* CD */
1739	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1740	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1741	/* Mic1 (rear panel) */
1742	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1743	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744	/* Mic2 (front panel) */
1745	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1746	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1747	/* headphone */
1748	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1749	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1750        /* change to EAPD mode */
1751	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1752	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1753
1754	{ }
1755};
1756
1757static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1758	/* change to EAPD mode */
1759	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1760	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1761
1762	/* Headphone output */
1763	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1764	/* Front output*/
1765	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1766	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1767
1768	/* Line In pin widget for input */
1769	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1770	/* CD pin widget for input */
1771	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1772	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1773	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1774
1775	/* change to EAPD mode */
1776	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1777	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1778
1779	{ }
1780};
1781
1782/*
1783 * LG m1 express dual
1784 *
1785 * Pin assignment:
1786 *   Rear Line-In/Out (blue): 0x14
1787 *   Build-in Mic-In: 0x15
1788 *   Speaker-out: 0x17
1789 *   HP-Out (green): 0x1b
1790 *   Mic-In/Out (red): 0x19
1791 *   SPDIF-Out: 0x1e
1792 */
1793
1794/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1795static hda_nid_t alc880_lg_dac_nids[3] = {
1796	0x05, 0x02, 0x03
1797};
1798
1799/* seems analog CD is not working */
1800static struct hda_input_mux alc880_lg_capture_source = {
1801	.num_items = 3,
1802	.items = {
1803		{ "Mic", 0x1 },
1804		{ "Line", 0x5 },
1805		{ "Internal Mic", 0x6 },
1806	},
1807};
1808
1809/* 2,4,6 channel modes */
1810static struct hda_verb alc880_lg_ch2_init[] = {
1811	/* set line-in and mic-in to input */
1812	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1813	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1814	{ }
1815};
1816
1817static struct hda_verb alc880_lg_ch4_init[] = {
1818	/* set line-in to out and mic-in to input */
1819	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1820	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1821	{ }
1822};
1823
1824static struct hda_verb alc880_lg_ch6_init[] = {
1825	/* set line-in and mic-in to output */
1826	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1827	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1828	{ }
1829};
1830
1831static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1832	{ 2, alc880_lg_ch2_init },
1833	{ 4, alc880_lg_ch4_init },
1834	{ 6, alc880_lg_ch6_init },
1835};
1836
1837static struct snd_kcontrol_new alc880_lg_mixer[] = {
1838	/* FIXME: it's not really "master" but front channels */
1839	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1840	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1841	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1842	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1843	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1844	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1845	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1846	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1847	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1848	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1849	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1850	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1851	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1852	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1853	{
1854		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1855		.name = "Channel Mode",
1856		.info = alc_ch_mode_info,
1857		.get = alc_ch_mode_get,
1858		.put = alc_ch_mode_put,
1859	},
1860	{ } /* end */
1861};
1862
1863static struct hda_verb alc880_lg_init_verbs[] = {
1864	/* set capture source to mic-in */
1865	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1866	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1867	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1868	/* mute all amp mixer inputs */
1869	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1870	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1871	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1872	/* line-in to input */
1873	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1874	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1875	/* built-in mic */
1876	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1877	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1878	/* speaker-out */
1879	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1880	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1881	/* mic-in to input */
1882	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1883	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1884	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1885	/* HP-out */
1886	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1887	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1888	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1889	/* jack sense */
1890	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1891	{ }
1892};
1893
1894/* toggle speaker-output according to the hp-jack state */
1895static void alc880_lg_automute(struct hda_codec *codec)
1896{
1897	unsigned int present;
1898	unsigned char bits;
1899
1900	present = snd_hda_codec_read(codec, 0x1b, 0,
1901				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1902	bits = present ? 0x80 : 0;
1903	snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1904				 0x80, bits);
1905	snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1906				 0x80, bits);
1907}
1908
1909static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1910{
1911	/* Looks like the unsol event is incompatible with the standard
1912	 * definition.  4bit tag is placed at 28 bit!
1913	 */
1914	if ((res >> 28) == 0x01)
1915		alc880_lg_automute(codec);
1916}
1917
1918/*
1919 * LG LW20
1920 *
1921 * Pin assignment:
1922 *   Speaker-out: 0x14
1923 *   Mic-In: 0x18
1924 *   Built-in Mic-In: 0x19
1925 *   Line-In: 0x1b
1926 *   HP-Out: 0x1a
1927 *   SPDIF-Out: 0x1e
1928 */
1929
1930static struct hda_input_mux alc880_lg_lw_capture_source = {
1931	.num_items = 3,
1932	.items = {
1933		{ "Mic", 0x0 },
1934		{ "Internal Mic", 0x1 },
1935		{ "Line In", 0x2 },
1936	},
1937};
1938
1939#define alc880_lg_lw_modes alc880_threestack_modes
1940
1941static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1942	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1943	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1944	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1945	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1946	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1947	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1948	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1949	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1950	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1951	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1952	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1953	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1954	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1955	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1956	{
1957		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1958		.name = "Channel Mode",
1959		.info = alc_ch_mode_info,
1960		.get = alc_ch_mode_get,
1961		.put = alc_ch_mode_put,
1962	},
1963	{ } /* end */
1964};
1965
1966static struct hda_verb alc880_lg_lw_init_verbs[] = {
1967	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1968	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1969	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1970
1971	/* set capture source to mic-in */
1972	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1973	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1974	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1975	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1976	/* speaker-out */
1977	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1978	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1979	/* HP-out */
1980	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1981	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1982	/* mic-in to input */
1983	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1984	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1985	/* built-in mic */
1986	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1987	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1988	/* jack sense */
1989	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1990	{ }
1991};
1992
1993/* toggle speaker-output according to the hp-jack state */
1994static void alc880_lg_lw_automute(struct hda_codec *codec)
1995{
1996	unsigned int present;
1997	unsigned char bits;
1998
1999	present = snd_hda_codec_read(codec, 0x1b, 0,
2000				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2001	bits = present ? 0x80 : 0;
2002	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
2003				 0x80, bits);
2004	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
2005				 0x80, bits);
2006}
2007
2008static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2009{
2010	/* Looks like the unsol event is incompatible with the standard
2011	 * definition.  4bit tag is placed at 28 bit!
2012	 */
2013	if ((res >> 28) == 0x01)
2014		alc880_lg_lw_automute(codec);
2015}
2016
2017/*
2018 * Common callbacks
2019 */
2020
2021static int alc_init(struct hda_codec *codec)
2022{
2023	struct alc_spec *spec = codec->spec;
2024	unsigned int i;
2025
2026	for (i = 0; i < spec->num_init_verbs; i++)
2027		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2028
2029	if (spec->init_hook)
2030		spec->init_hook(codec);
2031
2032	return 0;
2033}
2034
2035static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2036{
2037	struct alc_spec *spec = codec->spec;
2038
2039	if (spec->unsol_event)
2040		spec->unsol_event(codec, res);
2041}
2042
2043#ifdef CONFIG_PM
2044/*
2045 * resume
2046 */
2047static int alc_resume(struct hda_codec *codec)
2048{
2049	struct alc_spec *spec = codec->spec;
2050	int i;
2051
2052	alc_init(codec);
2053	for (i = 0; i < spec->num_mixers; i++)
2054		snd_hda_resume_ctls(codec, spec->mixers[i]);
2055	if (spec->multiout.dig_out_nid)
2056		snd_hda_resume_spdif_out(codec);
2057	if (spec->dig_in_nid)
2058		snd_hda_resume_spdif_in(codec);
2059
2060	return 0;
2061}
2062#endif
2063
2064/*
2065 * Analog playback callbacks
2066 */
2067static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2068				    struct hda_codec *codec,
2069				    struct snd_pcm_substream *substream)
2070{
2071	struct alc_spec *spec = codec->spec;
2072	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2073}
2074
2075static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2076				       struct hda_codec *codec,
2077				       unsigned int stream_tag,
2078				       unsigned int format,
2079				       struct snd_pcm_substream *substream)
2080{
2081	struct alc_spec *spec = codec->spec;
2082	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2083						stream_tag, format, substream);
2084}
2085
2086static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2087				       struct hda_codec *codec,
2088				       struct snd_pcm_substream *substream)
2089{
2090	struct alc_spec *spec = codec->spec;
2091	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2092}
2093
2094/*
2095 * Digital out
2096 */
2097static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2098					struct hda_codec *codec,
2099					struct snd_pcm_substream *substream)
2100{
2101	struct alc_spec *spec = codec->spec;
2102	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2103}
2104
2105static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2106					   struct hda_codec *codec,
2107					   unsigned int stream_tag,
2108					   unsigned int format,
2109					   struct snd_pcm_substream *substream)
2110{
2111	struct alc_spec *spec = codec->spec;
2112	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2113					     stream_tag, format, substream);
2114}
2115
2116static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2117					 struct hda_codec *codec,
2118					 struct snd_pcm_substream *substream)
2119{
2120	struct alc_spec *spec = codec->spec;
2121	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2122}
2123
2124/*
2125 * Analog capture
2126 */
2127static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2128				      struct hda_codec *codec,
2129				      unsigned int stream_tag,
2130				      unsigned int format,
2131				      struct snd_pcm_substream *substream)
2132{
2133	struct alc_spec *spec = codec->spec;
2134
2135	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2136				   stream_tag, 0, format);
2137	return 0;
2138}
2139
2140static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2141				      struct hda_codec *codec,
2142				      struct snd_pcm_substream *substream)
2143{
2144	struct alc_spec *spec = codec->spec;
2145
2146	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2147				   0, 0, 0);
2148	return 0;
2149}
2150
2151
2152/*
2153 */
2154static struct hda_pcm_stream alc880_pcm_analog_playback = {
2155	.substreams = 1,
2156	.channels_min = 2,
2157	.channels_max = 8,
2158	/* NID is set in alc_build_pcms */
2159	.ops = {
2160		.open = alc880_playback_pcm_open,
2161		.prepare = alc880_playback_pcm_prepare,
2162		.cleanup = alc880_playback_pcm_cleanup
2163	},
2164};
2165
2166static struct hda_pcm_stream alc880_pcm_analog_capture = {
2167	.substreams = 2,
2168	.channels_min = 2,
2169	.channels_max = 2,
2170	/* NID is set in alc_build_pcms */
2171	.ops = {
2172		.prepare = alc880_capture_pcm_prepare,
2173		.cleanup = alc880_capture_pcm_cleanup
2174	},
2175};
2176
2177static struct hda_pcm_stream alc880_pcm_digital_playback = {
2178	.substreams = 1,
2179	.channels_min = 2,
2180	.channels_max = 2,
2181	/* NID is set in alc_build_pcms */
2182	.ops = {
2183		.open = alc880_dig_playback_pcm_open,
2184		.close = alc880_dig_playback_pcm_close,
2185		.prepare = alc880_dig_playback_pcm_prepare
2186	},
2187};
2188
2189static struct hda_pcm_stream alc880_pcm_digital_capture = {
2190	.substreams = 1,
2191	.channels_min = 2,
2192	.channels_max = 2,
2193	/* NID is set in alc_build_pcms */
2194};
2195
2196/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2197static struct hda_pcm_stream alc_pcm_null_playback = {
2198	.substreams = 0,
2199	.channels_min = 0,
2200	.channels_max = 0,
2201};
2202
2203static int alc_build_pcms(struct hda_codec *codec)
2204{
2205	struct alc_spec *spec = codec->spec;
2206	struct hda_pcm *info = spec->pcm_rec;
2207	int i;
2208
2209	codec->num_pcms = 1;
2210	codec->pcm_info = info;
2211
2212	info->name = spec->stream_name_analog;
2213	if (spec->stream_analog_playback) {
2214		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2215		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2216		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2217	}
2218	if (spec->stream_analog_capture) {
2219		snd_assert(spec->adc_nids, return -EINVAL);
2220		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2221		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2222	}
2223
2224	if (spec->channel_mode) {
2225		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2226		for (i = 0; i < spec->num_channel_mode; i++) {
2227			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2228				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2229			}
2230		}
2231	}
2232
2233	/* SPDIF for stream index #1 */
2234	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2235		codec->num_pcms = 2;
2236		info = spec->pcm_rec + 1;
2237		info->name = spec->stream_name_digital;
2238		if (spec->multiout.dig_out_nid &&
2239		    spec->stream_digital_playback) {
2240			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2241			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2242		}
2243		if (spec->dig_in_nid &&
2244		    spec->stream_digital_capture) {
2245			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2246			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2247		}
2248	}
2249
2250	/* If the use of more than one ADC is requested for the current
2251	 * model, configure a second analog capture-only PCM.
2252	 */
2253	/* Additional Analaog capture for index #2 */
2254	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2255	    spec->adc_nids) {
2256		codec->num_pcms = 3;
2257		info = spec->pcm_rec + 2;
2258		info->name = spec->stream_name_analog;
2259		/* No playback stream for second PCM */
2260		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2261		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2262		if (spec->stream_analog_capture) {
2263			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2264			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2265		}
2266	}
2267
2268	return 0;
2269}
2270
2271static void alc_free(struct hda_codec *codec)
2272{
2273	struct alc_spec *spec = codec->spec;
2274	unsigned int i;
2275
2276	if (!spec)
2277		return;
2278
2279	if (spec->kctl_alloc) {
2280		for (i = 0; i < spec->num_kctl_used; i++)
2281			kfree(spec->kctl_alloc[i].name);
2282		kfree(spec->kctl_alloc);
2283	}
2284	kfree(spec);
2285}
2286
2287/*
2288 */
2289static struct hda_codec_ops alc_patch_ops = {
2290	.build_controls = alc_build_controls,
2291	.build_pcms = alc_build_pcms,
2292	.init = alc_init,
2293	.free = alc_free,
2294	.unsol_event = alc_unsol_event,
2295#ifdef CONFIG_PM
2296	.resume = alc_resume,
2297#endif
2298};
2299
2300
2301/*
2302 * Test configuration for debugging
2303 *
2304 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2305 * enum controls.
2306 */
2307#ifdef CONFIG_SND_DEBUG
2308static hda_nid_t alc880_test_dac_nids[4] = {
2309	0x02, 0x03, 0x04, 0x05
2310};
2311
2312static struct hda_input_mux alc880_test_capture_source = {
2313	.num_items = 7,
2314	.items = {
2315		{ "In-1", 0x0 },
2316		{ "In-2", 0x1 },
2317		{ "In-3", 0x2 },
2318		{ "In-4", 0x3 },
2319		{ "CD", 0x4 },
2320		{ "Front", 0x5 },
2321		{ "Surround", 0x6 },
2322	},
2323};
2324
2325static struct hda_channel_mode alc880_test_modes[4] = {
2326	{ 2, NULL },
2327	{ 4, NULL },
2328	{ 6, NULL },
2329	{ 8, NULL },
2330};
2331
2332static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2333				 struct snd_ctl_elem_info *uinfo)
2334{
2335	static char *texts[] = {
2336		"N/A", "Line Out", "HP Out",
2337		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2338	};
2339	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2340	uinfo->count = 1;
2341	uinfo->value.enumerated.items = 8;
2342	if (uinfo->value.enumerated.item >= 8)
2343		uinfo->value.enumerated.item = 7;
2344	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2345	return 0;
2346}
2347
2348static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2349				struct snd_ctl_elem_value *ucontrol)
2350{
2351	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2352	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2353	unsigned int pin_ctl, item = 0;
2354
2355	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2356				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2357	if (pin_ctl & AC_PINCTL_OUT_EN) {
2358		if (pin_ctl & AC_PINCTL_HP_EN)
2359			item = 2;
2360		else
2361			item = 1;
2362	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2363		switch (pin_ctl & AC_PINCTL_VREFEN) {
2364		case AC_PINCTL_VREF_HIZ: item = 3; break;
2365		case AC_PINCTL_VREF_50:  item = 4; break;
2366		case AC_PINCTL_VREF_GRD: item = 5; break;
2367		case AC_PINCTL_VREF_80:  item = 6; break;
2368		case AC_PINCTL_VREF_100: item = 7; break;
2369		}
2370	}
2371	ucontrol->value.enumerated.item[0] = item;
2372	return 0;
2373}
2374
2375static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2376				struct snd_ctl_elem_value *ucontrol)
2377{
2378	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2379	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2380	static unsigned int ctls[] = {
2381		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2382		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2383		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2384		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2385		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2386		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2387	};
2388	unsigned int old_ctl, new_ctl;
2389
2390	old_ctl = snd_hda_codec_read(codec, nid, 0,
2391				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2392	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2393	if (old_ctl != new_ctl) {
2394		snd_hda_codec_write(codec, nid, 0,
2395				    AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2396		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2397				    (ucontrol->value.enumerated.item[0] >= 3 ?
2398				     0xb080 : 0xb000));
2399		return 1;
2400	}
2401	return 0;
2402}
2403
2404static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2405				 struct snd_ctl_elem_info *uinfo)
2406{
2407	static char *texts[] = {
2408		"Front", "Surround", "CLFE", "Side"
2409	};
2410	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2411	uinfo->count = 1;
2412	uinfo->value.enumerated.items = 4;
2413	if (uinfo->value.enumerated.item >= 4)
2414		uinfo->value.enumerated.item = 3;
2415	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2416	return 0;
2417}
2418
2419static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2420				struct snd_ctl_elem_value *ucontrol)
2421{
2422	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2423	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2424	unsigned int sel;
2425
2426	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2427	ucontrol->value.enumerated.item[0] = sel & 3;
2428	return 0;
2429}
2430
2431static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2432				struct snd_ctl_elem_value *ucontrol)
2433{
2434	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2435	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2436	unsigned int sel;
2437
2438	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2439	if (ucontrol->value.enumerated.item[0] != sel) {
2440		sel = ucontrol->value.enumerated.item[0] & 3;
2441		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2442		return 1;
2443	}
2444	return 0;
2445}
2446
2447#define PIN_CTL_TEST(xname,nid) {			\
2448		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2449			.name = xname,		       \
2450			.info = alc_test_pin_ctl_info, \
2451			.get = alc_test_pin_ctl_get,   \
2452			.put = alc_test_pin_ctl_put,   \
2453			.private_value = nid	       \
2454			}
2455
2456#define PIN_SRC_TEST(xname,nid) {			\
2457		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2458			.name = xname,		       \
2459			.info = alc_test_pin_src_info, \
2460			.get = alc_test_pin_src_get,   \
2461			.put = alc_test_pin_src_put,   \
2462			.private_value = nid	       \
2463			}
2464
2465static struct snd_kcontrol_new alc880_test_mixer[] = {
2466	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2467	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2468	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2469	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2470	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2471	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2472	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2473	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2474	PIN_CTL_TEST("Front Pin Mode", 0x14),
2475	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2476	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2477	PIN_CTL_TEST("Side Pin Mode", 0x17),
2478	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2479	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2480	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2481	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2482	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2483	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2484	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2485	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2486	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2487	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2488	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2489	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2490	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2491	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2492	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2493	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2494	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2495	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2496	{
2497		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2498		.name = "Channel Mode",
2499		.info = alc_ch_mode_info,
2500		.get = alc_ch_mode_get,
2501		.put = alc_ch_mode_put,
2502	},
2503	{ } /* end */
2504};
2505
2506static struct hda_verb alc880_test_init_verbs[] = {
2507	/* Unmute inputs of 0x0c - 0x0f */
2508	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2509	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2510	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2511	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2512	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2513	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2514	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2515	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2516	/* Vol output for 0x0c-0x0f */
2517	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2518	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2519	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2520	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2521	/* Set output pins 0x14-0x17 */
2522	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2523	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2524	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2525	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2526	/* Unmute output pins 0x14-0x17 */
2527	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2528	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2529	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2530	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2531	/* Set input pins 0x18-0x1c */
2532	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2533	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2534	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2535	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2536	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2537	/* Mute input pins 0x18-0x1b */
2538	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2539	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2540	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2541	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2542	/* ADC set up */
2543	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2544	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2545	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2546	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2547	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2548	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2549	/* Analog input/passthru */
2550	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2551	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2552	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2553	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2554	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2555	{ }
2556};
2557#endif
2558
2559/*
2560 */
2561
2562static const char *alc880_models[ALC880_MODEL_LAST] = {
2563	[ALC880_3ST]		= "3stack",
2564	[ALC880_TCL_S700]	= "tcl",
2565	[ALC880_3ST_DIG]	= "3stack-digout",
2566	[ALC880_CLEVO]		= "clevo",
2567	[ALC880_5ST]		= "5stack",
2568	[ALC880_5ST_DIG]	= "5stack-digout",
2569	[ALC880_W810]		= "w810",
2570	[ALC880_Z71V]		= "z71v",
2571	[ALC880_6ST]		= "6stack",
2572	[ALC880_6ST_DIG]	= "6stack-digout",
2573	[ALC880_ASUS]		= "asus",
2574	[ALC880_ASUS_W1V]	= "asus-w1v",
2575	[ALC880_ASUS_DIG]	= "asus-dig",
2576	[ALC880_ASUS_DIG2]	= "asus-dig2",
2577	[ALC880_UNIWILL_DIG]	= "uniwill",
2578	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2579	[ALC880_FUJITSU]	= "fujitsu",
2580	[ALC880_F1734]		= "F1734",
2581	[ALC880_LG]		= "lg",
2582	[ALC880_LG_LW]		= "lg-lw",
2583#ifdef CONFIG_SND_DEBUG
2584	[ALC880_TEST]		= "test",
2585#endif
2586	[ALC880_AUTO]		= "auto",
2587};
2588
2589static struct snd_pci_quirk alc880_cfg_tbl[] = {
2590	/* Broken BIOS configuration */
2591	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2592	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2593
2594	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2595	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2596	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2597	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2598	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2599	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2600	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2601	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2602	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2603
2604	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2605	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2606
2607	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2608	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2609	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2610	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2611	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2612	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2613	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2614	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2615	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2616	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2617	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2618	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2619	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2620	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2621	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2622
2623	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2624	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2625	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2626	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2627	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2628	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2629	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2630	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2631	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2632	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2633	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2634	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2635	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2636	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2637	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2638	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2639	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2640	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2641
2642	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2643	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2644	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2645	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2646
2647	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2648	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2649	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2650	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2651
2652	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2653	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2654	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2655	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2656
2657	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2658	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2659	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2660	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2661	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2662	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2663	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2664	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2665	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2666	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2667	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2668
2669	{}
2670};
2671
2672/*
2673 * ALC880 codec presets
2674 */
2675static struct alc_config_preset alc880_presets[] = {
2676	[ALC880_3ST] = {
2677		.mixers = { alc880_three_stack_mixer },
2678		.init_verbs = { alc880_volume_init_verbs,
2679				alc880_pin_3stack_init_verbs },
2680		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2681		.dac_nids = alc880_dac_nids,
2682		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2683		.channel_mode = alc880_threestack_modes,
2684		.need_dac_fix = 1,
2685		.input_mux = &alc880_capture_source,
2686	},
2687	[ALC880_3ST_DIG] = {
2688		.mixers = { alc880_three_stack_mixer },
2689		.init_verbs = { alc880_volume_init_verbs,
2690				alc880_pin_3stack_init_verbs },
2691		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2692		.dac_nids = alc880_dac_nids,
2693		.dig_out_nid = ALC880_DIGOUT_NID,
2694		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2695		.channel_mode = alc880_threestack_modes,
2696		.need_dac_fix = 1,
2697		.input_mux = &alc880_capture_source,
2698	},
2699	[ALC880_TCL_S700] = {
2700		.mixers = { alc880_tcl_s700_mixer },
2701		.init_verbs = { alc880_volume_init_verbs,
2702				alc880_pin_tcl_S700_init_verbs,
2703				alc880_gpio2_init_verbs },
2704		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2705		.dac_nids = alc880_dac_nids,
2706		.hp_nid = 0x03,
2707		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2708		.channel_mode = alc880_2_jack_modes,
2709		.input_mux = &alc880_capture_source,
2710	},
2711	[ALC880_5ST] = {
2712		.mixers = { alc880_three_stack_mixer,
2713			    alc880_five_stack_mixer},
2714		.init_verbs = { alc880_volume_init_verbs,
2715				alc880_pin_5stack_init_verbs },
2716		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2717		.dac_nids = alc880_dac_nids,
2718		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2719		.channel_mode = alc880_fivestack_modes,
2720		.input_mux = &alc880_capture_source,
2721	},
2722	[ALC880_5ST_DIG] = {
2723		.mixers = { alc880_three_stack_mixer,
2724			    alc880_five_stack_mixer },
2725		.init_verbs = { alc880_volume_init_verbs,
2726				alc880_pin_5stack_init_verbs },
2727		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2728		.dac_nids = alc880_dac_nids,
2729		.dig_out_nid = ALC880_DIGOUT_NID,
2730		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2731		.channel_mode = alc880_fivestack_modes,
2732		.input_mux = &alc880_capture_source,
2733	},
2734	[ALC880_6ST] = {
2735		.mixers = { alc880_six_stack_mixer },
2736		.init_verbs = { alc880_volume_init_verbs,
2737				alc880_pin_6stack_init_verbs },
2738		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2739		.dac_nids = alc880_6st_dac_nids,
2740		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2741		.channel_mode = alc880_sixstack_modes,
2742		.input_mux = &alc880_6stack_capture_source,
2743	},
2744	[ALC880_6ST_DIG] = {
2745		.mixers = { alc880_six_stack_mixer },
2746		.init_verbs = { alc880_volume_init_verbs,
2747				alc880_pin_6stack_init_verbs },
2748		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2749		.dac_nids = alc880_6st_dac_nids,
2750		.dig_out_nid = ALC880_DIGOUT_NID,
2751		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2752		.channel_mode = alc880_sixstack_modes,
2753		.input_mux = &alc880_6stack_capture_source,
2754	},
2755	[ALC880_W810] = {
2756		.mixers = { alc880_w810_base_mixer },
2757		.init_verbs = { alc880_volume_init_verbs,
2758				alc880_pin_w810_init_verbs,
2759				alc880_gpio2_init_verbs },
2760		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2761		.dac_nids = alc880_w810_dac_nids,
2762		.dig_out_nid = ALC880_DIGOUT_NID,
2763		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2764		.channel_mode = alc880_w810_modes,
2765		.input_mux = &alc880_capture_source,
2766	},
2767	[ALC880_Z71V] = {
2768		.mixers = { alc880_z71v_mixer },
2769		.init_verbs = { alc880_volume_init_verbs,
2770				alc880_pin_z71v_init_verbs },
2771		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2772		.dac_nids = alc880_z71v_dac_nids,
2773		.dig_out_nid = ALC880_DIGOUT_NID,
2774		.hp_nid = 0x03,
2775		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2776		.channel_mode = alc880_2_jack_modes,
2777		.input_mux = &alc880_capture_source,
2778	},
2779	[ALC880_F1734] = {
2780		.mixers = { alc880_f1734_mixer },
2781		.init_verbs = { alc880_volume_init_verbs,
2782				alc880_pin_f1734_init_verbs },
2783		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2784		.dac_nids = alc880_f1734_dac_nids,
2785		.hp_nid = 0x02,
2786		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2787		.channel_mode = alc880_2_jack_modes,
2788		.input_mux = &alc880_capture_source,
2789	},
2790	[ALC880_ASUS] = {
2791		.mixers = { alc880_asus_mixer },
2792		.init_verbs = { alc880_volume_init_verbs,
2793				alc880_pin_asus_init_verbs,
2794				alc880_gpio1_init_verbs },
2795		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2796		.dac_nids = alc880_asus_dac_nids,
2797		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2798		.channel_mode = alc880_asus_modes,
2799		.need_dac_fix = 1,
2800		.input_mux = &alc880_capture_source,
2801	},
2802	[ALC880_ASUS_DIG] = {
2803		.mixers = { alc880_asus_mixer },
2804		.init_verbs = { alc880_volume_init_verbs,
2805				alc880_pin_asus_init_verbs,
2806				alc880_gpio1_init_verbs },
2807		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2808		.dac_nids = alc880_asus_dac_nids,
2809		.dig_out_nid = ALC880_DIGOUT_NID,
2810		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2811		.channel_mode = alc880_asus_modes,
2812		.need_dac_fix = 1,
2813		.input_mux = &alc880_capture_source,
2814	},
2815	[ALC880_ASUS_DIG2] = {
2816		.mixers = { alc880_asus_mixer },
2817		.init_verbs = { alc880_volume_init_verbs,
2818				alc880_pin_asus_init_verbs,
2819				alc880_gpio2_init_verbs }, /* use GPIO2 */
2820		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2821		.dac_nids = alc880_asus_dac_nids,
2822		.dig_out_nid = ALC880_DIGOUT_NID,
2823		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2824		.channel_mode = alc880_asus_modes,
2825		.need_dac_fix = 1,
2826		.input_mux = &alc880_capture_source,
2827	},
2828	[ALC880_ASUS_W1V] = {
2829		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2830		.init_verbs = { alc880_volume_init_verbs,
2831				alc880_pin_asus_init_verbs,
2832				alc880_gpio1_init_verbs },
2833		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2834		.dac_nids = alc880_asus_dac_nids,
2835		.dig_out_nid = ALC880_DIGOUT_NID,
2836		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2837		.channel_mode = alc880_asus_modes,
2838		.need_dac_fix = 1,
2839		.input_mux = &alc880_capture_source,
2840	},
2841	[ALC880_UNIWILL_DIG] = {
2842		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2843		.init_verbs = { alc880_volume_init_verbs,
2844				alc880_pin_asus_init_verbs },
2845		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2846		.dac_nids = alc880_asus_dac_nids,
2847		.dig_out_nid = ALC880_DIGOUT_NID,
2848		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2849		.channel_mode = alc880_asus_modes,
2850		.need_dac_fix = 1,
2851		.input_mux = &alc880_capture_source,
2852	},
2853	[ALC880_UNIWILL] = {
2854		.mixers = { alc880_uniwill_mixer },
2855		.init_verbs = { alc880_volume_init_verbs,
2856				alc880_uniwill_init_verbs },
2857		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2858		.dac_nids = alc880_asus_dac_nids,
2859		.dig_out_nid = ALC880_DIGOUT_NID,
2860		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2861		.channel_mode = alc880_threestack_modes,
2862		.need_dac_fix = 1,
2863		.input_mux = &alc880_capture_source,
2864		.unsol_event = alc880_uniwill_unsol_event,
2865		.init_hook = alc880_uniwill_automute,
2866	},
2867	[ALC880_UNIWILL_P53] = {
2868		.mixers = { alc880_uniwill_p53_mixer },
2869		.init_verbs = { alc880_volume_init_verbs,
2870				alc880_uniwill_p53_init_verbs },
2871		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2872		.dac_nids = alc880_asus_dac_nids,
2873		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2874		.channel_mode = alc880_threestack_modes,
2875		.input_mux = &alc880_capture_source,
2876		.unsol_event = alc880_uniwill_p53_unsol_event,
2877		.init_hook = alc880_uniwill_p53_hp_automute,
2878	},
2879	[ALC880_FUJITSU] = {
2880		.mixers = { alc880_fujitsu_mixer,
2881			    alc880_pcbeep_mixer, },
2882		.init_verbs = { alc880_volume_init_verbs,
2883				alc880_uniwill_p53_init_verbs,
2884	       			alc880_beep_init_verbs },
2885		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2886		.dac_nids = alc880_dac_nids,
2887		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2888		.channel_mode = alc880_2_jack_modes,
2889		.input_mux = &alc880_capture_source,
2890		.unsol_event = alc880_uniwill_p53_unsol_event,
2891		.init_hook = alc880_uniwill_p53_hp_automute,
2892	},
2893	[ALC880_CLEVO] = {
2894		.mixers = { alc880_three_stack_mixer },
2895		.init_verbs = { alc880_volume_init_verbs,
2896				alc880_pin_clevo_init_verbs },
2897		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2898		.dac_nids = alc880_dac_nids,
2899		.hp_nid = 0x03,
2900		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2901		.channel_mode = alc880_threestack_modes,
2902		.need_dac_fix = 1,
2903		.input_mux = &alc880_capture_source,
2904	},
2905	[ALC880_LG] = {
2906		.mixers = { alc880_lg_mixer },
2907		.init_verbs = { alc880_volume_init_verbs,
2908				alc880_lg_init_verbs },
2909		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2910		.dac_nids = alc880_lg_dac_nids,
2911		.dig_out_nid = ALC880_DIGOUT_NID,
2912		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2913		.channel_mode = alc880_lg_ch_modes,
2914		.need_dac_fix = 1,
2915		.input_mux = &alc880_lg_capture_source,
2916		.unsol_event = alc880_lg_unsol_event,
2917		.init_hook = alc880_lg_automute,
2918	},
2919	[ALC880_LG_LW] = {
2920		.mixers = { alc880_lg_lw_mixer },
2921		.init_verbs = { alc880_volume_init_verbs,
2922				alc880_lg_lw_init_verbs },
2923		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2924		.dac_nids = alc880_dac_nids,
2925		.dig_out_nid = ALC880_DIGOUT_NID,
2926		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2927		.channel_mode = alc880_lg_lw_modes,
2928		.input_mux = &alc880_lg_lw_capture_source,
2929		.unsol_event = alc880_lg_lw_unsol_event,
2930		.init_hook = alc880_lg_lw_automute,
2931	},
2932#ifdef CONFIG_SND_DEBUG
2933	[ALC880_TEST] = {
2934		.mixers = { alc880_test_mixer },
2935		.init_verbs = { alc880_test_init_verbs },
2936		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2937		.dac_nids = alc880_test_dac_nids,
2938		.dig_out_nid = ALC880_DIGOUT_NID,
2939		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2940		.channel_mode = alc880_test_modes,
2941		.input_mux = &alc880_test_capture_source,
2942	},
2943#endif
2944};
2945
2946/*
2947 * Automatic parse of I/O pins from the BIOS configuration
2948 */
2949
2950#define NUM_CONTROL_ALLOC	32
2951#define NUM_VERB_ALLOC		32
2952
2953enum {
2954	ALC_CTL_WIDGET_VOL,
2955	ALC_CTL_WIDGET_MUTE,
2956	ALC_CTL_BIND_MUTE,
2957};
2958static struct snd_kcontrol_new alc880_control_templates[] = {
2959	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2960	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2961	HDA_BIND_MUTE(NULL, 0, 0, 0),
2962};
2963
2964/* add dynamic controls */
2965static int add_control(struct alc_spec *spec, int type, const char *name,
2966		       unsigned long val)
2967{
2968	struct snd_kcontrol_new *knew;
2969
2970	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2971		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2972
2973		/* array + terminator */
2974		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2975		if (!knew)
2976			return -ENOMEM;
2977		if (spec->kctl_alloc) {
2978			memcpy(knew, spec->kctl_alloc,
2979			       sizeof(*knew) * spec->num_kctl_alloc);
2980			kfree(spec->kctl_alloc);
2981		}
2982		spec->kctl_alloc = knew;
2983		spec->num_kctl_alloc = num;
2984	}
2985
2986	knew = &spec->kctl_alloc[spec->num_kctl_used];
2987	*knew = alc880_control_templates[type];
2988	knew->name = kstrdup(name, GFP_KERNEL);
2989	if (!knew->name)
2990		return -ENOMEM;
2991	knew->private_value = val;
2992	spec->num_kctl_used++;
2993	return 0;
2994}
2995
2996#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2997#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2998#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2999#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3000#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3001#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3002#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3003#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3004#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3005#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3006#define ALC880_PIN_CD_NID		0x1c
3007
3008/* fill in the dac_nids table from the parsed pin configuration */
3009static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3010				     const struct auto_pin_cfg *cfg)
3011{
3012	hda_nid_t nid;
3013	int assigned[4];
3014	int i, j;
3015
3016	memset(assigned, 0, sizeof(assigned));
3017	spec->multiout.dac_nids = spec->private_dac_nids;
3018
3019	/* check the pins hardwired to audio widget */
3020	for (i = 0; i < cfg->line_outs; i++) {
3021		nid = cfg->line_out_pins[i];
3022		if (alc880_is_fixed_pin(nid)) {
3023			int idx = alc880_fixed_pin_idx(nid);
3024			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3025			assigned[idx] = 1;
3026		}
3027	}
3028	/* left pins can be connect to any audio widget */
3029	for (i = 0; i < cfg->line_outs; i++) {
3030		nid = cfg->line_out_pins[i];
3031		if (alc880_is_fixed_pin(nid))
3032			continue;
3033		/* search for an empty channel */
3034		for (j = 0; j < cfg->line_outs; j++) {
3035			if (!assigned[j]) {
3036				spec->multiout.dac_nids[i] =
3037					alc880_idx_to_dac(j);
3038				assigned[j] = 1;
3039				break;
3040			}
3041		}
3042	}
3043	spec->multiout.num_dacs = cfg->line_outs;
3044	return 0;
3045}
3046
3047/* add playback controls from the parsed DAC table */
3048static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3049					     const struct auto_pin_cfg *cfg)
3050{
3051	char name[32];
3052	static const char *chname[4] = {
3053		"Front", "Surround", NULL /*CLFE*/, "Side"
3054	};
3055	hda_nid_t nid;
3056	int i, err;
3057
3058	for (i = 0; i < cfg->line_outs; i++) {
3059		if (!spec->multiout.dac_nids[i])
3060			continue;
3061		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3062		if (i == 2) {
3063			/* Center/LFE */
3064			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3065					  "Center Playback Volume",
3066					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3067							      HDA_OUTPUT));
3068			if (err < 0)
3069				return err;
3070			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3071					  "LFE Playback Volume",
3072					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3073							      HDA_OUTPUT));
3074			if (err < 0)
3075				return err;
3076			err = add_control(spec, ALC_CTL_BIND_MUTE,
3077					  "Center Playback Switch",
3078					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3079							      HDA_INPUT));
3080			if (err < 0)
3081				return err;
3082			err = add_control(spec, ALC_CTL_BIND_MUTE,
3083					  "LFE Playback Switch",
3084					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3085							      HDA_INPUT));
3086			if (err < 0)
3087				return err;
3088		} else {
3089			sprintf(name, "%s Playback Volume", chname[i]);
3090			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3091					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3092							      HDA_OUTPUT));
3093			if (err < 0)
3094				return err;
3095			sprintf(name, "%s Playback Switch", chname[i]);
3096			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3097					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3098							      HDA_INPUT));
3099			if (err < 0)
3100				return err;
3101		}
3102	}
3103	return 0;
3104}
3105
3106/* add playback controls for speaker and HP outputs */
3107static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3108					const char *pfx)
3109{
3110	hda_nid_t nid;
3111	int err;
3112	char name[32];
3113
3114	if (!pin)
3115		return 0;
3116
3117	if (alc880_is_fixed_pin(pin)) {
3118		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3119		/* specify the DAC as the extra output */
3120		if (!spec->multiout.hp_nid)
3121			spec->multiout.hp_nid = nid;
3122		else
3123			spec->multiout.extra_out_nid[0] = nid;
3124		/* control HP volume/switch on the output mixer amp */
3125		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3126		sprintf(name, "%s Playback Volume", pfx);
3127		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3128				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3129		if (err < 0)
3130			return err;
3131		sprintf(name, "%s Playback Switch", pfx);
3132		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3133				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3134		if (err < 0)
3135			return err;
3136	} else if (alc880_is_multi_pin(pin)) {
3137		/* set manual connection */
3138		/* we have only a switch on HP-out PIN */
3139		sprintf(name, "%s Playback Switch", pfx);
3140		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3141				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3142		if (err < 0)
3143			return err;
3144	}
3145	return 0;
3146}
3147
3148/* create input playback/capture controls for the given pin */
3149static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3150			    const char *ctlname,
3151			    int idx, hda_nid_t mix_nid)
3152{
3153	char name[32];
3154	int err;
3155
3156	sprintf(name, "%s Playback Volume", ctlname);
3157	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3158			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3159	if (err < 0)
3160		return err;
3161	sprintf(name, "%s Playback Switch", ctlname);
3162	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3163			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3164	if (err < 0)
3165		return err;
3166	return 0;
3167}
3168
3169/* create playback/capture controls for input pins */
3170static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3171						const struct auto_pin_cfg *cfg)
3172{
3173	struct hda_input_mux *imux = &spec->private_imux;
3174	int i, err, idx;
3175
3176	for (i = 0; i < AUTO_PIN_LAST; i++) {
3177		if (alc880_is_input_pin(cfg->input_pins[i])) {
3178			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3179			err = new_analog_input(spec, cfg->input_pins[i],
3180					       auto_pin_cfg_labels[i],
3181					       idx, 0x0b);
3182			if (err < 0)
3183				return err;
3184			imux->items[imux->num_items].label =
3185				auto_pin_cfg_labels[i];
3186			imux->items[imux->num_items].index =
3187				alc880_input_pin_idx(cfg->input_pins[i]);
3188			imux->num_items++;
3189		}
3190	}
3191	return 0;
3192}
3193
3194static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3195					      hda_nid_t nid, int pin_type,
3196					      int dac_idx)
3197{
3198	/* set as output */
3199	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3200			    pin_type);
3201	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3202			    AMP_OUT_UNMUTE);
3203	/* need the manual connection? */
3204	if (alc880_is_multi_pin(nid)) {
3205		struct alc_spec *spec = codec->spec;
3206		int idx = alc880_multi_pin_idx(nid);
3207		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3208				    AC_VERB_SET_CONNECT_SEL,
3209				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3210	}
3211}
3212
3213static int get_pin_type(int line_out_type)
3214{
3215	if (line_out_type == AUTO_PIN_HP_OUT)
3216		return PIN_HP;
3217	else
3218		return PIN_OUT;
3219}
3220
3221static void alc880_auto_init_multi_out(struct hda_codec *codec)
3222{
3223	struct alc_spec *spec = codec->spec;
3224	int i;
3225
3226	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3227	for (i = 0; i < spec->autocfg.line_outs; i++) {
3228		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3229		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3230		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3231	}
3232}
3233
3234static void alc880_auto_init_extra_out(struct hda_codec *codec)
3235{
3236	struct alc_spec *spec = codec->spec;
3237	hda_nid_t pin;
3238
3239	pin = spec->autocfg.speaker_pins[0];
3240	if (pin) /* connect to front */
3241		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3242	pin = spec->autocfg.hp_pins[0];
3243	if (pin) /* connect to front */
3244		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3245}
3246
3247static void alc880_auto_init_analog_input(struct hda_codec *codec)
3248{
3249	struct alc_spec *spec = codec->spec;
3250	int i;
3251
3252	for (i = 0; i < AUTO_PIN_LAST; i++) {
3253		hda_nid_t nid = spec->autocfg.input_pins[i];
3254		if (alc880_is_input_pin(nid)) {
3255			snd_hda_codec_write(codec, nid, 0,
3256					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3257					    i <= AUTO_PIN_FRONT_MIC ?
3258					    PIN_VREF80 : PIN_IN);
3259			if (nid != ALC880_PIN_CD_NID)
3260				snd_hda_codec_write(codec, nid, 0,
3261						    AC_VERB_SET_AMP_GAIN_MUTE,
3262						    AMP_OUT_MUTE);
3263		}
3264	}
3265}
3266
3267/* parse the BIOS configuration and set up the alc_spec */
3268/* return 1 if successful, 0 if the proper config is not found,
3269 * or a negative error code
3270 */
3271static int alc880_parse_auto_config(struct hda_codec *codec)
3272{
3273	struct alc_spec *spec = codec->spec;
3274	int err;
3275	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3276
3277	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3278					   alc880_ignore);
3279	if (err < 0)
3280		return err;
3281	if (!spec->autocfg.line_outs)
3282		return 0; /* can't find valid BIOS pin config */
3283
3284	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3285	if (err < 0)
3286		return err;
3287	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3288	if (err < 0)
3289		return err;
3290	err = alc880_auto_create_extra_out(spec,
3291					   spec->autocfg.speaker_pins[0],
3292					   "Speaker");
3293	if (err < 0)
3294		return err;
3295	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3296					   "Headphone");
3297	if (err < 0)
3298		return err;
3299	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3300	if (err < 0)
3301		return err;
3302
3303	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3304
3305	if (spec->autocfg.dig_out_pin)
3306		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3307	if (spec->autocfg.dig_in_pin)
3308		spec->dig_in_nid = ALC880_DIGIN_NID;
3309
3310	if (spec->kctl_alloc)
3311		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3312
3313	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3314
3315	spec->num_mux_defs = 1;
3316	spec->input_mux = &spec->private_imux;
3317
3318	return 1;
3319}
3320
3321/* additional initialization for auto-configuration model */
3322static void alc880_auto_init(struct hda_codec *codec)
3323{
3324	alc880_auto_init_multi_out(codec);
3325	alc880_auto_init_extra_out(codec);
3326	alc880_auto_init_analog_input(codec);
3327}
3328
3329/*
3330 * OK, here we have finally the patch for ALC880
3331 */
3332
3333static int patch_alc880(struct hda_codec *codec)
3334{
3335	struct alc_spec *spec;
3336	int board_config;
3337	int err;
3338
3339	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3340	if (spec == NULL)
3341		return -ENOMEM;
3342
3343	codec->spec = spec;
3344
3345	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3346						  alc880_models,
3347						  alc880_cfg_tbl);
3348	if (board_config < 0) {
3349		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3350		       "trying auto-probe from BIOS...\n");
3351		board_config = ALC880_AUTO;
3352	}
3353
3354	if (board_config == ALC880_AUTO) {
3355		/* automatic parse from the BIOS config */
3356		err = alc880_parse_auto_config(codec);
3357		if (err < 0) {
3358			alc_free(codec);
3359			return err;
3360		} else if (!err) {
3361			printk(KERN_INFO
3362			       "hda_codec: Cannot set up configuration "
3363			       "from BIOS.  Using 3-stack mode...\n");
3364			board_config = ALC880_3ST;
3365		}
3366	}
3367
3368	if (board_config != ALC880_AUTO)
3369		setup_preset(spec, &alc880_presets[board_config]);
3370
3371	spec->stream_name_analog = "ALC880 Analog";
3372	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3373	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3374
3375	spec->stream_name_digital = "ALC880 Digital";
3376	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3377	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3378
3379	if (!spec->adc_nids && spec->input_mux) {
3380		/* check whether NID 0x07 is valid */
3381		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3382		/* get type */
3383		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3384		if (wcap != AC_WID_AUD_IN) {
3385			spec->adc_nids = alc880_adc_nids_alt;
3386			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3387			spec->mixers[spec->num_mixers] =
3388				alc880_capture_alt_mixer;
3389			spec->num_mixers++;
3390		} else {
3391			spec->adc_nids = alc880_adc_nids;
3392			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3393			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3394			spec->num_mixers++;
3395		}
3396	}
3397
3398	codec->patch_ops = alc_patch_ops;
3399	if (board_config == ALC880_AUTO)
3400		spec->init_hook = alc880_auto_init;
3401
3402	return 0;
3403}
3404
3405
3406/*
3407 * ALC260 support
3408 */
3409
3410static hda_nid_t alc260_dac_nids[1] = {
3411	/* front */
3412	0x02,
3413};
3414
3415static hda_nid_t alc260_adc_nids[1] = {
3416	/* ADC0 */
3417	0x04,
3418};
3419
3420static hda_nid_t alc260_adc_nids_alt[1] = {
3421	/* ADC1 */
3422	0x05,
3423};
3424
3425static hda_nid_t alc260_hp_adc_nids[2] = {
3426	/* ADC1, 0 */
3427	0x05, 0x04
3428};
3429
3430/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3431 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3432 */
3433static hda_nid_t alc260_dual_adc_nids[2] = {
3434	/* ADC0, ADC1 */
3435	0x04, 0x05
3436};
3437
3438#define ALC260_DIGOUT_NID	0x03
3439#define ALC260_DIGIN_NID	0x06
3440
3441static struct hda_input_mux alc260_capture_source = {
3442	.num_items = 4,
3443	.items = {
3444		{ "Mic", 0x0 },
3445		{ "Front Mic", 0x1 },
3446		{ "Line", 0x2 },
3447		{ "CD", 0x4 },
3448	},
3449};
3450
3451/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3452 * headphone jack and the internal CD lines since these are the only pins at
3453 * which audio can appear.  For flexibility, also allow the option of
3454 * recording the mixer output on the second ADC (ADC0 doesn't have a
3455 * connection to the mixer output).
3456 */
3457static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3458	{
3459		.num_items = 3,
3460		.items = {
3461			{ "Mic/Line", 0x0 },
3462			{ "CD", 0x4 },
3463			{ "Headphone", 0x2 },
3464		},
3465	},
3466	{
3467		.num_items = 4,
3468		.items = {
3469			{ "Mic/Line", 0x0 },
3470			{ "CD", 0x4 },
3471			{ "Headphone", 0x2 },
3472			{ "Mixer", 0x5 },
3473		},
3474	},
3475
3476};
3477
3478/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3479 * the Fujitsu S702x, but jacks are marked differently.
3480 */
3481static struct hda_input_mux alc260_acer_capture_sources[2] = {
3482	{
3483		.num_items = 4,
3484		.items = {
3485			{ "Mic", 0x0 },
3486			{ "Line", 0x2 },
3487			{ "CD", 0x4 },
3488			{ "Headphone", 0x5 },
3489		},
3490	},
3491	{
3492		.num_items = 5,
3493		.items = {
3494			{ "Mic", 0x0 },
3495			{ "Line", 0x2 },
3496			{ "CD", 0x4 },
3497			{ "Headphone", 0x6 },
3498			{ "Mixer", 0x5 },
3499		},
3500	},
3501};
3502/*
3503 * This is just place-holder, so there's something for alc_build_pcms to look
3504 * at when it calculates the maximum number of channels. ALC260 has no mixer
3505 * element which allows changing the channel mode, so the verb list is
3506 * never used.
3507 */
3508static struct hda_channel_mode alc260_modes[1] = {
3509	{ 2, NULL },
3510};
3511
3512
3513/* Mixer combinations
3514 *
3515 * basic: base_output + input + pc_beep + capture
3516 * HP: base_output + input + capture_alt
3517 * HP_3013: hp_3013 + input + capture
3518 * fujitsu: fujitsu + capture
3519 * acer: acer + capture
3520 */
3521
3522static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3523	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3524	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3525	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3526	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3527	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3528	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3529	{ } /* end */
3530};
3531
3532static struct snd_kcontrol_new alc260_input_mixer[] = {
3533	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3534	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3535	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3536	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3537	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3538	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3539	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3540	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3541	{ } /* end */
3542};
3543
3544static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3545	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3546	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3547	{ } /* end */
3548};
3549
3550static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3551	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3552	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3553	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3554	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3555	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3556	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3557	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3558	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3559	{ } /* end */
3560};
3561
3562/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3563 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3564 */
3565static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3566	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3567	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3568	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3569	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3570	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3571	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3572	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3573	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3574	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3575	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3576	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3577	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3578	{ } /* end */
3579};
3580
3581/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3582 * versions of the ALC260 don't act on requests to enable mic bias from NID
3583 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3584 * datasheet doesn't mention this restriction.  At this stage it's not clear
3585 * whether this behaviour is intentional or is a hardware bug in chip
3586 * revisions available in early 2006.  Therefore for now allow the
3587 * "Headphone Jack Mode" control to span all choices, but if it turns out
3588 * that the lack of mic bias for this NID is intentional we could change the
3589 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3590 *
3591 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3592 * don't appear to make the mic bias available from the "line" jack, even
3593 * though the NID used for this jack (0x14) can supply it.  The theory is
3594 * that perhaps Acer have included blocking capacitors between the ALC260
3595 * and the output jack.  If this turns out to be the case for all such
3596 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3597 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3598 *
3599 * The C20x Tablet series have a mono internal speaker which is controlled
3600 * via the chip's Mono sum widget and pin complex, so include the necessary
3601 * controls for such models.  On models without a "mono speaker" the control
3602 * won't do anything.
3603 */
3604static struct snd_kcontrol_new alc260_acer_mixer[] = {
3605	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3606	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3607	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3608	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3609			      HDA_OUTPUT),
3610	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3611			   HDA_INPUT),
3612	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3613	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3614	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3615	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3616	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3617	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3618	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3619	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3620	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3621	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3622	{ } /* end */
3623};
3624
3625/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3626 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3627 */
3628static struct snd_kcontrol_new alc260_will_mixer[] = {
3629	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3630	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3631	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3632	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3633	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3634	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3635	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3636	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3637	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3638	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3639	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3640	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3641	{ } /* end */
3642};
3643
3644/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3645 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3646 */
3647static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3648	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3649	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3650	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3651	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3652	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3653	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3654	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3655	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3656	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3657	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3658	{ } /* end */
3659};
3660
3661/* capture mixer elements */
3662static struct snd_kcontrol_new alc260_capture_mixer[] = {
3663	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3664	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3665	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3666	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3667	{
3668		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3669		/* The multiple "Capture Source" controls confuse alsamixer
3670		 * So call somewhat different..
3671		 * FIXME: the controls appear in the "playback" view!
3672		 */
3673		/* .name = "Capture Source", */
3674		.name = "Input Source",
3675		.count = 2,
3676		.info = alc_mux_enum_info,
3677		.get = alc_mux_enum_get,
3678		.put = alc_mux_enum_put,
3679	},
3680	{ } /* end */
3681};
3682
3683static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3684	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3685	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3686	{
3687		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3688		/* The multiple "Capture Source" controls confuse alsamixer
3689		 * So call somewhat different..
3690		 * FIXME: the controls appear in the "playback" view!
3691		 */
3692		/* .name = "Capture Source", */
3693		.name = "Input Source",
3694		.count = 1,
3695		.info = alc_mux_enum_info,
3696		.get = alc_mux_enum_get,
3697		.put = alc_mux_enum_put,
3698	},
3699	{ } /* end */
3700};
3701
3702/*
3703 * initialization verbs
3704 */
3705static struct hda_verb alc260_init_verbs[] = {
3706	/* Line In pin widget for input */
3707	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3708	/* CD pin widget for input */
3709	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3710	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3711	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3712	/* Mic2 (front panel) pin widget for input and vref at 80% */
3713	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3714	/* LINE-2 is used for line-out in rear */
3715	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3716	/* select line-out */
3717	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3718	/* LINE-OUT pin */
3719	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3720	/* enable HP */
3721	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3722	/* enable Mono */
3723	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3724	/* mute capture amp left and right */
3725	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3726	/* set connection select to line in (default select for this ADC) */
3727	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3728	/* mute capture amp left and right */
3729	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3730	/* set connection select to line in (default select for this ADC) */
3731	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3732	/* set vol=0 Line-Out mixer amp left and right */
3733	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3734	/* unmute pin widget amp left and right (no gain on this amp) */
3735	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3736	/* set vol=0 HP mixer amp left and right */
3737	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3738	/* unmute pin widget amp left and right (no gain on this amp) */
3739	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3740	/* set vol=0 Mono mixer amp left and right */
3741	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3742	/* unmute pin widget amp left and right (no gain on this amp) */
3743	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3744	/* unmute LINE-2 out pin */
3745	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3746	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3747	 * Line In 2 = 0x03
3748	 */
3749	/* mute CD */
3750	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3751	/* mute Line In */
3752	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3753	/* mute Mic */
3754	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3755	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3756	/* mute Front out path */
3757	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3758	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3759	/* mute Headphone out path */
3760	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3761	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3762	/* mute Mono out path */
3763	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3764	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3765	{ }
3766};
3767
3768#if 0 /* should be identical with alc260_init_verbs? */
3769static struct hda_verb alc260_hp_init_verbs[] = {
3770	/* Headphone and output */
3771	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3772	/* mono output */
3773	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3774	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3775	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3776	/* Mic2 (front panel) pin widget for input and vref at 80% */
3777	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3778	/* Line In pin widget for input */
3779	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3780	/* Line-2 pin widget for output */
3781	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3782	/* CD pin widget for input */
3783	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3784	/* unmute amp left and right */
3785	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3786	/* set connection select to line in (default select for this ADC) */
3787	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3788	/* unmute Line-Out mixer amp left and right (volume = 0) */
3789	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3790	/* mute pin widget amp left and right (no gain on this amp) */
3791	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3792	/* unmute HP mixer amp left and right (volume = 0) */
3793	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3794	/* mute pin widget amp left and right (no gain on this amp) */
3795	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3796	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3797	 * Line In 2 = 0x03
3798	 */
3799	/* unmute CD */
3800	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3801	/* unmute Line In */
3802	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3803	/* unmute Mic */
3804	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3805	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3806	/* Unmute Front out path */
3807	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3808	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3809	/* Unmute Headphone out path */
3810	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3811	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3812	/* Unmute Mono out path */
3813	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3814	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3815	{ }
3816};
3817#endif
3818
3819static struct hda_verb alc260_hp_3013_init_verbs[] = {
3820	/* Line out and output */
3821	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3822	/* mono output */
3823	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3824	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3825	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3826	/* Mic2 (front panel) pin widget for input and vref at 80% */
3827	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3828	/* Line In pin widget for input */
3829	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3830	/* Headphone pin widget for output */
3831	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3832	/* CD pin widget for input */
3833	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3834	/* unmute amp left and right */
3835	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3836	/* set connection select to line in (default select for this ADC) */
3837	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3838	/* unmute Line-Out mixer amp left and right (volume = 0) */
3839	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3840	/* mute pin widget amp left and right (no gain on this amp) */
3841	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3842	/* unmute HP mixer amp left and right (volume = 0) */
3843	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3844	/* mute pin widget amp left and right (no gain on this amp) */
3845	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3846	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3847	 * Line In 2 = 0x03
3848	 */
3849	/* unmute CD */
3850	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3851	/* unmute Line In */
3852	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3853	/* unmute Mic */
3854	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3855	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3856	/* Unmute Front out path */
3857	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3858	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3859	/* Unmute Headphone out path */
3860	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3861	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3862	/* Unmute Mono out path */
3863	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3864	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3865	{ }
3866};
3867
3868/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3869 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3870 * audio = 0x16, internal speaker = 0x10.
3871 */
3872static struct hda_verb alc260_fujitsu_init_verbs[] = {
3873	/* Disable all GPIOs */
3874	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3875	/* Internal speaker is connected to headphone pin */
3876	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3877	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3878	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3879	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3880	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3881	/* Ensure all other unused pins are disabled and muted. */
3882	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3883	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3884	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3885	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3886	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3887	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3888	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3889	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3890
3891	/* Disable digital (SPDIF) pins */
3892	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3893	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3894
3895	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3896	 * when acting as an output.
3897	 */
3898	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3899
3900	/* Start with output sum widgets muted and their output gains at min */
3901	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3902	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3903	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3904	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3905	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3906	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3907	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3908	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3909	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3910
3911	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3912	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3913	/* Unmute Line1 pin widget output buffer since it starts as an output.
3914	 * If the pin mode is changed by the user the pin mode control will
3915	 * take care of enabling the pin's input/output buffers as needed.
3916	 * Therefore there's no need to enable the input buffer at this
3917	 * stage.
3918	 */
3919	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3920	/* Unmute input buffer of pin widget used for Line-in (no equiv
3921	 * mixer ctrl)
3922	 */
3923	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3924
3925	/* Mute capture amp left and right */
3926	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3927	/* Set ADC connection select to match default mixer setting - line
3928	 * in (on mic1 pin)
3929	 */
3930	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3931
3932	/* Do the same for the second ADC: mute capture input amp and
3933	 * set ADC connection to line in (on mic1 pin)
3934	 */
3935	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3936	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3937
3938	/* Mute all inputs to mixer widget (even unconnected ones) */
3939	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3940	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3941	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3942	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3943	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3944	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3945	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3946	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3947
3948	{ }
3949};
3950
3951/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3952 * similar laptops (adapted from Fujitsu init verbs).
3953 */
3954static struct hda_verb alc260_acer_init_verbs[] = {
3955	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3956	 * the headphone jack.  Turn this on and rely on the standard mute
3957	 * methods whenever the user wants to turn these outputs off.
3958	 */
3959	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3960	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3961	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3962	/* Internal speaker/Headphone jack is connected to Line-out pin */
3963	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3964	/* Internal microphone/Mic jack is connected to Mic1 pin */
3965	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3966	/* Line In jack is connected to Line1 pin */
3967	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3968	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3969	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3970	/* Ensure all other unused pins are disabled and muted. */
3971	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3972	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3973	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3974	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3975	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3976	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3977	/* Disable digital (SPDIF) pins */
3978	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3979	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3980
3981	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3982	 * bus when acting as outputs.
3983	 */
3984	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3985	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3986
3987	/* Start with output sum widgets muted and their output gains at min */
3988	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3989	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3990	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3991	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3992	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3993	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3994	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3995	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3996	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3997
3998	/* Unmute Line-out pin widget amp left and right
3999	 * (no equiv mixer ctrl)
4000	 */
4001	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4002	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4003	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4004	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4005	 * inputs. If the pin mode is changed by the user the pin mode control
4006	 * will take care of enabling the pin's input/output buffers as needed.
4007	 * Therefore there's no need to enable the input buffer at this
4008	 * stage.
4009	 */
4010	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4011	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4012
4013	/* Mute capture amp left and right */
4014	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4015	/* Set ADC connection select to match default mixer setting - mic
4016	 * (on mic1 pin)
4017	 */
4018	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4019
4020	/* Do similar with the second ADC: mute capture input amp and
4021	 * set ADC connection to mic to match ALSA's default state.
4022	 */
4023	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4024	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4025
4026	/* Mute all inputs to mixer widget (even unconnected ones) */
4027	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4028	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4029	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4030	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4031	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4032	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4033	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4034	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4035
4036	{ }
4037};
4038
4039static struct hda_verb alc260_will_verbs[] = {
4040	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4041	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4042	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4043	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4044	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4045	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4046	{}
4047};
4048
4049static struct hda_verb alc260_replacer_672v_verbs[] = {
4050	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4051	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4052	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4053
4054	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4055	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4056	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4057
4058	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4059	{}
4060};
4061
4062/* toggle speaker-output according to the hp-jack state */
4063static void alc260_replacer_672v_automute(struct hda_codec *codec)
4064{
4065        unsigned int present;
4066
4067	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4068        present = snd_hda_codec_read(codec, 0x0f, 0,
4069                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4070	if (present) {
4071		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
4072		snd_hda_codec_write(codec, 0x0f, 0,
4073				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4074	} else {
4075		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4076		snd_hda_codec_write(codec, 0x0f, 0,
4077				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4078	}
4079}
4080
4081static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4082                                       unsigned int res)
4083{
4084        if ((res >> 26) == ALC880_HP_EVENT)
4085                alc260_replacer_672v_automute(codec);
4086}
4087
4088/* Test configuration for debugging, modelled after the ALC880 test
4089 * configuration.
4090 */
4091#ifdef CONFIG_SND_DEBUG
4092static hda_nid_t alc260_test_dac_nids[1] = {
4093	0x02,
4094};
4095static hda_nid_t alc260_test_adc_nids[2] = {
4096	0x04, 0x05,
4097};
4098/* For testing the ALC260, each input MUX needs its own definition since
4099 * the signal assignments are different.  This assumes that the first ADC
4100 * is NID 0x04.
4101 */
4102static struct hda_input_mux alc260_test_capture_sources[2] = {
4103	{
4104		.num_items = 7,
4105		.items = {
4106			{ "MIC1 pin", 0x0 },
4107			{ "MIC2 pin", 0x1 },
4108			{ "LINE1 pin", 0x2 },
4109			{ "LINE2 pin", 0x3 },
4110			{ "CD pin", 0x4 },
4111			{ "LINE-OUT pin", 0x5 },
4112			{ "HP-OUT pin", 0x6 },
4113		},
4114        },
4115	{
4116		.num_items = 8,
4117		.items = {
4118			{ "MIC1 pin", 0x0 },
4119			{ "MIC2 pin", 0x1 },
4120			{ "LINE1 pin", 0x2 },
4121			{ "LINE2 pin", 0x3 },
4122			{ "CD pin", 0x4 },
4123			{ "Mixer", 0x5 },
4124			{ "LINE-OUT pin", 0x6 },
4125			{ "HP-OUT pin", 0x7 },
4126		},
4127        },
4128};
4129static struct snd_kcontrol_new alc260_test_mixer[] = {
4130	/* Output driver widgets */
4131	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4132	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4133	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4134	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4135	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4136	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4137
4138	/* Modes for retasking pin widgets
4139	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4140         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4141         * mention this restriction.  At this stage it's not clear whether
4142         * this behaviour is intentional or is a hardware bug in chip
4143         * revisions available at least up until early 2006.  Therefore for
4144         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4145         * choices, but if it turns out that the lack of mic bias for these
4146         * NIDs is intentional we could change their modes from
4147         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4148	 */
4149	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4150	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4151	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4152	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4153	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4154	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4155
4156	/* Loopback mixer controls */
4157	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4158	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4159	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4160	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4161	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4162	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4163	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4164	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4165	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4166	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4167	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4168	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4169	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4170	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4171	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4172	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4173
4174	/* Controls for GPIO pins, assuming they are configured as outputs */
4175	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4176	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4177	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4178	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4179
4180	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4181	 * is ambigious as to which NID is which; testing on laptops which
4182	 * make this output available should provide clarification.
4183	 */
4184	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4185	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4186
4187	{ } /* end */
4188};
4189static struct hda_verb alc260_test_init_verbs[] = {
4190	/* Enable all GPIOs as outputs with an initial value of 0 */
4191	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4192	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4193	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4194
4195	/* Enable retasking pins as output, initially without power amp */
4196	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4197	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4200	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4201	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4202
4203	/* Disable digital (SPDIF) pins initially, but users can enable
4204	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4205	 * payload also sets the generation to 0, output to be in "consumer"
4206	 * PCM format, copyright asserted, no pre-emphasis and no validity
4207	 * control.
4208	 */
4209	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4210	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4211
4212	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4213	 * OUT1 sum bus when acting as an output.
4214	 */
4215	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4216	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4217	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4218	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4219
4220	/* Start with output sum widgets muted and their output gains at min */
4221	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4222	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4223	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4224	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4225	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4226	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4227	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4228	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4229	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4230
4231	/* Unmute retasking pin widget output buffers since the default
4232	 * state appears to be output.  As the pin mode is changed by the
4233	 * user the pin mode control will take care of enabling the pin's
4234	 * input/output buffers as needed.
4235	 */
4236	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4237	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4238	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4239	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4240	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4241	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4242	/* Also unmute the mono-out pin widget */
4243	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4244
4245	/* Mute capture amp left and right */
4246	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4247	/* Set ADC connection select to match default mixer setting (mic1
4248	 * pin)
4249	 */
4250	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4251
4252	/* Do the same for the second ADC: mute capture input amp and
4253	 * set ADC connection to mic1 pin
4254	 */
4255	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4256	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4257
4258	/* Mute all inputs to mixer widget (even unconnected ones) */
4259	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4260	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4261	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4262	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4263	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4264	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4265	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4266	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4267
4268	{ }
4269};
4270#endif
4271
4272static struct hda_pcm_stream alc260_pcm_analog_playback = {
4273	.substreams = 1,
4274	.channels_min = 2,
4275	.channels_max = 2,
4276};
4277
4278static struct hda_pcm_stream alc260_pcm_analog_capture = {
4279	.substreams = 1,
4280	.channels_min = 2,
4281	.channels_max = 2,
4282};
4283
4284#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4285#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4286
4287/*
4288 * for BIOS auto-configuration
4289 */
4290
4291static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4292					const char *pfx)
4293{
4294	hda_nid_t nid_vol;
4295	unsigned long vol_val, sw_val;
4296	char name[32];
4297	int err;
4298
4299	if (nid >= 0x0f && nid < 0x11) {
4300		nid_vol = nid - 0x7;
4301		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4302		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4303	} else if (nid == 0x11) {
4304		nid_vol = nid - 0x7;
4305		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4306		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4307	} else if (nid >= 0x12 && nid <= 0x15) {
4308		nid_vol = 0x08;
4309		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4310		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4311	} else
4312		return 0; /* N/A */
4313
4314	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4315	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4316	if (err < 0)
4317		return err;
4318	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4319	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4320	if (err < 0)
4321		return err;
4322	return 1;
4323}
4324
4325/* add playback controls from the parsed DAC table */
4326static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4327					     const struct auto_pin_cfg *cfg)
4328{
4329	hda_nid_t nid;
4330	int err;
4331
4332	spec->multiout.num_dacs = 1;
4333	spec->multiout.dac_nids = spec->private_dac_nids;
4334	spec->multiout.dac_nids[0] = 0x02;
4335
4336	nid = cfg->line_out_pins[0];
4337	if (nid) {
4338		err = alc260_add_playback_controls(spec, nid, "Front");
4339		if (err < 0)
4340			return err;
4341	}
4342
4343	nid = cfg->speaker_pins[0];
4344	if (nid) {
4345		err = alc260_add_playback_controls(spec, nid, "Speaker");
4346		if (err < 0)
4347			return err;
4348	}
4349
4350	nid = cfg->hp_pins[0];
4351	if (nid) {
4352		err = alc260_add_playback_controls(spec, nid, "Headphone");
4353		if (err < 0)
4354			return err;
4355	}
4356	return 0;
4357}
4358
4359/* create playback/capture controls for input pins */
4360static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4361						const struct auto_pin_cfg *cfg)
4362{
4363	struct hda_input_mux *imux = &spec->private_imux;
4364	int i, err, idx;
4365
4366	for (i = 0; i < AUTO_PIN_LAST; i++) {
4367		if (cfg->input_pins[i] >= 0x12) {
4368			idx = cfg->input_pins[i] - 0x12;
4369			err = new_analog_input(spec, cfg->input_pins[i],
4370					       auto_pin_cfg_labels[i], idx,
4371					       0x07);
4372			if (err < 0)
4373				return err;
4374			imux->items[imux->num_items].label =
4375				auto_pin_cfg_labels[i];
4376			imux->items[imux->num_items].index = idx;
4377			imux->num_items++;
4378		}
4379		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4380			idx = cfg->input_pins[i] - 0x09;
4381			err = new_analog_input(spec, cfg->input_pins[i],
4382					       auto_pin_cfg_labels[i], idx,
4383					       0x07);
4384			if (err < 0)
4385				return err;
4386			imux->items[imux->num_items].label =
4387				auto_pin_cfg_labels[i];
4388			imux->items[imux->num_items].index = idx;
4389			imux->num_items++;
4390		}
4391	}
4392	return 0;
4393}
4394
4395static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4396					      hda_nid_t nid, int pin_type,
4397					      int sel_idx)
4398{
4399	/* set as output */
4400	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4401			    pin_type);
4402	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4403			    AMP_OUT_UNMUTE);
4404	/* need the manual connection? */
4405	if (nid >= 0x12) {
4406		int idx = nid - 0x12;
4407		snd_hda_codec_write(codec, idx + 0x0b, 0,
4408				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4409	}
4410}
4411
4412static void alc260_auto_init_multi_out(struct hda_codec *codec)
4413{
4414	struct alc_spec *spec = codec->spec;
4415	hda_nid_t nid;
4416
4417	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4418	nid = spec->autocfg.line_out_pins[0];
4419	if (nid) {
4420		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4421		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4422	}
4423
4424	nid = spec->autocfg.speaker_pins[0];
4425	if (nid)
4426		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4427
4428	nid = spec->autocfg.hp_pins[0];
4429	if (nid)
4430		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4431}
4432
4433#define ALC260_PIN_CD_NID		0x16
4434static void alc260_auto_init_analog_input(struct hda_codec *codec)
4435{
4436	struct alc_spec *spec = codec->spec;
4437	int i;
4438
4439	for (i = 0; i < AUTO_PIN_LAST; i++) {
4440		hda_nid_t nid = spec->autocfg.input_pins[i];
4441		if (nid >= 0x12) {
4442			snd_hda_codec_write(codec, nid, 0,
4443					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4444					    i <= AUTO_PIN_FRONT_MIC ?
4445					    PIN_VREF80 : PIN_IN);
4446			if (nid != ALC260_PIN_CD_NID)
4447				snd_hda_codec_write(codec, nid, 0,
4448						    AC_VERB_SET_AMP_GAIN_MUTE,
4449						    AMP_OUT_MUTE);
4450		}
4451	}
4452}
4453
4454/*
4455 * generic initialization of ADC, input mixers and output mixers
4456 */
4457static struct hda_verb alc260_volume_init_verbs[] = {
4458	/*
4459	 * Unmute ADC0-1 and set the default input to mic-in
4460	 */
4461	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4462	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4463	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4464	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4465
4466	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4467	 * mixer widget
4468	 * Note: PASD motherboards uses the Line In 2 as the input for
4469	 * front panel mic (mic 2)
4470	 */
4471	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4472	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4473	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4474	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4475	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4476	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4477
4478	/*
4479	 * Set up output mixers (0x08 - 0x0a)
4480	 */
4481	/* set vol=0 to output mixers */
4482	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4483	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4484	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4485	/* set up input amps for analog loopback */
4486	/* Amp Indices: DAC = 0, mixer = 1 */
4487	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4488	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4489	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4490	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4491	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4492	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4493
4494	{ }
4495};
4496
4497static int alc260_parse_auto_config(struct hda_codec *codec)
4498{
4499	struct alc_spec *spec = codec->spec;
4500	unsigned int wcap;
4501	int err;
4502	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4503
4504	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4505					   alc260_ignore);
4506	if (err < 0)
4507		return err;
4508	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4509	if (err < 0)
4510		return err;
4511	if (!spec->kctl_alloc)
4512		return 0; /* can't find valid BIOS pin config */
4513	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4514	if (err < 0)
4515		return err;
4516
4517	spec->multiout.max_channels = 2;
4518
4519	if (spec->autocfg.dig_out_pin)
4520		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4521	if (spec->kctl_alloc)
4522		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4523
4524	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4525
4526	spec->num_mux_defs = 1;
4527	spec->input_mux = &spec->private_imux;
4528
4529	/* check whether NID 0x04 is valid */
4530	wcap = get_wcaps(codec, 0x04);
4531	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4532	if (wcap != AC_WID_AUD_IN) {
4533		spec->adc_nids = alc260_adc_nids_alt;
4534		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4535		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4536	} else {
4537		spec->adc_nids = alc260_adc_nids;
4538		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4539		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4540	}
4541	spec->num_mixers++;
4542
4543	return 1;
4544}
4545
4546/* additional initialization for auto-configuration model */
4547static void alc260_auto_init(struct hda_codec *codec)
4548{
4549	alc260_auto_init_multi_out(codec);
4550	alc260_auto_init_analog_input(codec);
4551}
4552
4553/*
4554 * ALC260 configurations
4555 */
4556static const char *alc260_models[ALC260_MODEL_LAST] = {
4557	[ALC260_BASIC]		= "basic",
4558	[ALC260_HP]		= "hp",
4559	[ALC260_HP_3013]	= "hp-3013",
4560	[ALC260_FUJITSU_S702X]	= "fujitsu",
4561	[ALC260_ACER]		= "acer",
4562	[ALC260_WILL]		= "will",
4563	[ALC260_REPLACER_672V]	= "replacer",
4564#ifdef CONFIG_SND_DEBUG
4565	[ALC260_TEST]		= "test",
4566#endif
4567	[ALC260_AUTO]		= "auto",
4568};
4569
4570static struct snd_pci_quirk alc260_cfg_tbl[] = {
4571	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4572	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4573	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4574	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4575	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4576	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4577	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4578	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4579	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4580	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4581	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4582	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4583	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4584	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4585	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4586	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4587	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4588	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4589	{}
4590};
4591
4592static struct alc_config_preset alc260_presets[] = {
4593	[ALC260_BASIC] = {
4594		.mixers = { alc260_base_output_mixer,
4595			    alc260_input_mixer,
4596			    alc260_pc_beep_mixer,
4597			    alc260_capture_mixer },
4598		.init_verbs = { alc260_init_verbs },
4599		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4600		.dac_nids = alc260_dac_nids,
4601		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4602		.adc_nids = alc260_adc_nids,
4603		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4604		.channel_mode = alc260_modes,
4605		.input_mux = &alc260_capture_source,
4606	},
4607	[ALC260_HP] = {
4608		.mixers = { alc260_base_output_mixer,
4609			    alc260_input_mixer,
4610			    alc260_capture_alt_mixer },
4611		.init_verbs = { alc260_init_verbs },
4612		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4613		.dac_nids = alc260_dac_nids,
4614		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4615		.adc_nids = alc260_hp_adc_nids,
4616		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4617		.channel_mode = alc260_modes,
4618		.input_mux = &alc260_capture_source,
4619	},
4620	[ALC260_HP_3013] = {
4621		.mixers = { alc260_hp_3013_mixer,
4622			    alc260_input_mixer,
4623			    alc260_capture_alt_mixer },
4624		.init_verbs = { alc260_hp_3013_init_verbs },
4625		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4626		.dac_nids = alc260_dac_nids,
4627		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4628		.adc_nids = alc260_hp_adc_nids,
4629		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4630		.channel_mode = alc260_modes,
4631		.input_mux = &alc260_capture_source,
4632	},
4633	[ALC260_FUJITSU_S702X] = {
4634		.mixers = { alc260_fujitsu_mixer,
4635			    alc260_capture_mixer },
4636		.init_verbs = { alc260_fujitsu_init_verbs },
4637		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4638		.dac_nids = alc260_dac_nids,
4639		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4640		.adc_nids = alc260_dual_adc_nids,
4641		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4642		.channel_mode = alc260_modes,
4643		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4644		.input_mux = alc260_fujitsu_capture_sources,
4645	},
4646	[ALC260_ACER] = {
4647		.mixers = { alc260_acer_mixer,
4648			    alc260_capture_mixer },
4649		.init_verbs = { alc260_acer_init_verbs },
4650		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4651		.dac_nids = alc260_dac_nids,
4652		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4653		.adc_nids = alc260_dual_adc_nids,
4654		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4655		.channel_mode = alc260_modes,
4656		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4657		.input_mux = alc260_acer_capture_sources,
4658	},
4659	[ALC260_WILL] = {
4660		.mixers = { alc260_will_mixer,
4661			    alc260_capture_mixer },
4662		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4663		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4664		.dac_nids = alc260_dac_nids,
4665		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4666		.adc_nids = alc260_adc_nids,
4667		.dig_out_nid = ALC260_DIGOUT_NID,
4668		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4669		.channel_mode = alc260_modes,
4670		.input_mux = &alc260_capture_source,
4671	},
4672	[ALC260_REPLACER_672V] = {
4673		.mixers = { alc260_replacer_672v_mixer,
4674			    alc260_capture_mixer },
4675		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4676		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4677		.dac_nids = alc260_dac_nids,
4678		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4679		.adc_nids = alc260_adc_nids,
4680		.dig_out_nid = ALC260_DIGOUT_NID,
4681		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4682		.channel_mode = alc260_modes,
4683		.input_mux = &alc260_capture_source,
4684		.unsol_event = alc260_replacer_672v_unsol_event,
4685		.init_hook = alc260_replacer_672v_automute,
4686	},
4687#ifdef CONFIG_SND_DEBUG
4688	[ALC260_TEST] = {
4689		.mixers = { alc260_test_mixer,
4690			    alc260_capture_mixer },
4691		.init_verbs = { alc260_test_init_verbs },
4692		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4693		.dac_nids = alc260_test_dac_nids,
4694		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4695		.adc_nids = alc260_test_adc_nids,
4696		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4697		.channel_mode = alc260_modes,
4698		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4699		.input_mux = alc260_test_capture_sources,
4700	},
4701#endif
4702};
4703
4704static int patch_alc260(struct hda_codec *codec)
4705{
4706	struct alc_spec *spec;
4707	int err, board_config;
4708
4709	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4710	if (spec == NULL)
4711		return -ENOMEM;
4712
4713	codec->spec = spec;
4714
4715	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4716						  alc260_models,
4717						  alc260_cfg_tbl);
4718	if (board_config < 0) {
4719		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4720			   "trying auto-probe from BIOS...\n");
4721		board_config = ALC260_AUTO;
4722	}
4723
4724	if (board_config == ALC260_AUTO) {
4725		/* automatic parse from the BIOS config */
4726		err = alc260_parse_auto_config(codec);
4727		if (err < 0) {
4728			alc_free(codec);
4729			return err;
4730		} else if (!err) {
4731			printk(KERN_INFO
4732			       "hda_codec: Cannot set up configuration "
4733			       "from BIOS.  Using base mode...\n");
4734			board_config = ALC260_BASIC;
4735		}
4736	}
4737
4738	if (board_config != ALC260_AUTO)
4739		setup_preset(spec, &alc260_presets[board_config]);
4740
4741	spec->stream_name_analog = "ALC260 Analog";
4742	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4743	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4744
4745	spec->stream_name_digital = "ALC260 Digital";
4746	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4747	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4748
4749	codec->patch_ops = alc_patch_ops;
4750	if (board_config == ALC260_AUTO)
4751		spec->init_hook = alc260_auto_init;
4752
4753	return 0;
4754}
4755
4756
4757/*
4758 * ALC882 support
4759 *
4760 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4761 * configuration.  Each pin widget can choose any input DACs and a mixer.
4762 * Each ADC is connected from a mixer of all inputs.  This makes possible
4763 * 6-channel independent captures.
4764 *
4765 * In addition, an independent DAC for the multi-playback (not used in this
4766 * driver yet).
4767 */
4768#define ALC882_DIGOUT_NID	0x06
4769#define ALC882_DIGIN_NID	0x0a
4770
4771static struct hda_channel_mode alc882_ch_modes[1] = {
4772	{ 8, NULL }
4773};
4774
4775static hda_nid_t alc882_dac_nids[4] = {
4776	/* front, rear, clfe, rear_surr */
4777	0x02, 0x03, 0x04, 0x05
4778};
4779
4780/* identical with ALC880 */
4781#define alc882_adc_nids		alc880_adc_nids
4782#define alc882_adc_nids_alt	alc880_adc_nids_alt
4783
4784/* input MUX */
4785/* FIXME: should be a matrix-type input source selection */
4786
4787static struct hda_input_mux alc882_capture_source = {
4788	.num_items = 4,
4789	.items = {
4790		{ "Mic", 0x0 },
4791		{ "Front Mic", 0x1 },
4792		{ "Line", 0x2 },
4793		{ "CD", 0x4 },
4794	},
4795};
4796#define alc882_mux_enum_info alc_mux_enum_info
4797#define alc882_mux_enum_get alc_mux_enum_get
4798
4799static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4800			       struct snd_ctl_elem_value *ucontrol)
4801{
4802	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4803	struct alc_spec *spec = codec->spec;
4804	const struct hda_input_mux *imux = spec->input_mux;
4805	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4806	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4807	hda_nid_t nid = capture_mixers[adc_idx];
4808	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4809	unsigned int i, idx;
4810
4811	idx = ucontrol->value.enumerated.item[0];
4812	if (idx >= imux->num_items)
4813		idx = imux->num_items - 1;
4814	if (*cur_val == idx && !codec->in_resume)
4815		return 0;
4816	for (i = 0; i < imux->num_items; i++) {
4817		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4818		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4819				    v | (imux->items[i].index << 8));
4820	}
4821	*cur_val = idx;
4822	return 1;
4823}
4824
4825/*
4826 * 2ch mode
4827 */
4828static struct hda_verb alc882_3ST_ch2_init[] = {
4829	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4830	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4831	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4832	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4833	{ } /* end */
4834};
4835
4836/*
4837 * 6ch mode
4838 */
4839static struct hda_verb alc882_3ST_ch6_init[] = {
4840	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4841	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4842	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4843	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4844	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4845	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4846	{ } /* end */
4847};
4848
4849static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4850	{ 2, alc882_3ST_ch2_init },
4851	{ 6, alc882_3ST_ch6_init },
4852};
4853
4854/*
4855 * 6ch mode
4856 */
4857static struct hda_verb alc882_sixstack_ch6_init[] = {
4858	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4859	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4860	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4861	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4862	{ } /* end */
4863};
4864
4865/*
4866 * 8ch mode
4867 */
4868static struct hda_verb alc882_sixstack_ch8_init[] = {
4869	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4870	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4871	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4872	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4873	{ } /* end */
4874};
4875
4876static struct hda_channel_mode alc882_sixstack_modes[2] = {
4877	{ 6, alc882_sixstack_ch6_init },
4878	{ 8, alc882_sixstack_ch8_init },
4879};
4880
4881/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4882 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4883 */
4884static struct snd_kcontrol_new alc882_base_mixer[] = {
4885	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4886	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4887	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4888	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4889	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4890	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4891	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4892	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4893	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4894	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4895	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4896	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4897	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4898	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4899	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4900	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4901	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4902	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4903	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4904	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4905	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4906	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4907	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4908	{ } /* end */
4909};
4910
4911static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4912	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4913	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4914	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4915	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4916	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4917	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4918	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4919	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4920	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4921	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4922	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4923	{ } /* end */
4924};
4925
4926static struct snd_kcontrol_new alc882_targa_mixer[] = {
4927	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4928	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4929	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4930	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4931	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4932	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4933	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4934	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4935	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4936	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4937	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4938	{ } /* end */
4939};
4940
4941/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4942 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4943 */
4944static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4945	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4946	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4947	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4948	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4949	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4950	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4951	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4952	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4953	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4954	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4955	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4956	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4957	{ } /* end */
4958};
4959
4960static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4961	{
4962		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4963		.name = "Channel Mode",
4964		.info = alc_ch_mode_info,
4965		.get = alc_ch_mode_get,
4966		.put = alc_ch_mode_put,
4967	},
4968	{ } /* end */
4969};
4970
4971static struct hda_verb alc882_init_verbs[] = {
4972	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4973	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4974	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4975	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4976	/* Rear mixer */
4977	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4978	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4979	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4980	/* CLFE mixer */
4981	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4982	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4983	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4984	/* Side mixer */
4985	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4986	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4987	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4988
4989	/* Front Pin: output 0 (0x0c) */
4990	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4991	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4992	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4993	/* Rear Pin: output 1 (0x0d) */
4994	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4995	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4996	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4997	/* CLFE Pin: output 2 (0x0e) */
4998	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4999	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5000	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5001	/* Side Pin: output 3 (0x0f) */
5002	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5003	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5004	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5005	/* Mic (rear) pin: input vref at 80% */
5006	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5007	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5008	/* Front Mic pin: input vref at 80% */
5009	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5010	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5011	/* Line In pin: input */
5012	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5013	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5014	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5015	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5016	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5017	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5018	/* CD pin widget for input */
5019	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5020
5021	/* FIXME: use matrix-type input source selection */
5022	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5023	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5024	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5025	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5026	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5027	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5028	/* Input mixer2 */
5029	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5030	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5031	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5032	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5033	/* Input mixer3 */
5034	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5035	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5036	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5037	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5038	/* ADC1: mute amp left and right */
5039	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5040	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5041	/* ADC2: mute amp left and right */
5042	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5043	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5044	/* ADC3: mute amp left and right */
5045	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5046	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5047
5048	{ }
5049};
5050
5051static struct hda_verb alc882_eapd_verbs[] = {
5052	/* change to EAPD mode */
5053	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5054	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5055	{ }
5056};
5057
5058/* Mac Pro test */
5059static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5060	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5061	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5062	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5063	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5064	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5065	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5066	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5067	{ } /* end */
5068};
5069
5070static struct hda_verb alc882_macpro_init_verbs[] = {
5071	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5072	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5073	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5074	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5075	/* Front Pin: output 0 (0x0c) */
5076	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5077	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5078	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5079	/* Front Mic pin: input vref at 80% */
5080	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5081	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5082	/* Speaker:  output */
5083	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5084	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5085	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5086	/* Headphone output (output 0 - 0x0c) */
5087	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5088	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5089	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5090
5091	/* FIXME: use matrix-type input source selection */
5092	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5093	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5094	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5095	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5096	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5097	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5098	/* Input mixer2 */
5099	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5100	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5101	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5102	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5103	/* Input mixer3 */
5104	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5105	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5106	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5107	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5108	/* ADC1: mute amp left and right */
5109	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5110	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5111	/* ADC2: mute amp left and right */
5112	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5113	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5114	/* ADC3: mute amp left and right */
5115	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5116	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5117
5118	{ }
5119};
5120
5121static struct hda_verb alc882_targa_verbs[] = {
5122	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5123	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5124
5125	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5126	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5127
5128	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5129	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5130	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5131
5132	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5133	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5134	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5135	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5136	{ } /* end */
5137};
5138
5139/* toggle speaker-output according to the hp-jack state */
5140static void alc882_targa_automute(struct hda_codec *codec)
5141{
5142 	unsigned int present;
5143
5144 	present = snd_hda_codec_read(codec, 0x14, 0,
5145				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5146	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5147				 0x80, present ? 0x80 : 0);
5148	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5149				 0x80, present ? 0x80 : 0);
5150	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5151}
5152
5153static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5154{
5155	/* Looks like the unsol event is incompatible with the standard
5156	 * definition.  4bit tag is placed at 26 bit!
5157	 */
5158	if (((res >> 26) == ALC880_HP_EVENT)) {
5159		alc882_targa_automute(codec);
5160	}
5161}
5162
5163static struct hda_verb alc882_asus_a7j_verbs[] = {
5164	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5165	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5166
5167	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5168	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5169	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5170
5171	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5172	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5173	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5174
5175	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5176	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5177	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5178	{ } /* end */
5179};
5180
5181static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5182{
5183	unsigned int gpiostate, gpiomask, gpiodir;
5184
5185	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5186				       AC_VERB_GET_GPIO_DATA, 0);
5187
5188	if (!muted)
5189		gpiostate |= (1 << pin);
5190	else
5191		gpiostate &= ~(1 << pin);
5192
5193	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5194				      AC_VERB_GET_GPIO_MASK, 0);
5195	gpiomask |= (1 << pin);
5196
5197	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5198				     AC_VERB_GET_GPIO_DIRECTION, 0);
5199	gpiodir |= (1 << pin);
5200
5201
5202	snd_hda_codec_write(codec, codec->afg, 0,
5203			    AC_VERB_SET_GPIO_MASK, gpiomask);
5204	snd_hda_codec_write(codec, codec->afg, 0,
5205			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5206
5207	msleep(1);
5208
5209	snd_hda_codec_write(codec, codec->afg, 0,
5210			    AC_VERB_SET_GPIO_DATA, gpiostate);
5211}
5212
5213/*
5214 * generic initialization of ADC, input mixers and output mixers
5215 */
5216static struct hda_verb alc882_auto_init_verbs[] = {
5217	/*
5218	 * Unmute ADC0-2 and set the default input to mic-in
5219	 */
5220	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5221	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5222	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5223	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5224	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5225	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5226
5227	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5228	 * mixer widget
5229	 * Note: PASD motherboards uses the Line In 2 as the input for
5230	 * front panel mic (mic 2)
5231	 */
5232	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5233	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5234	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5235	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5236	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5237	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5238
5239	/*
5240	 * Set up output mixers (0x0c - 0x0f)
5241	 */
5242	/* set vol=0 to output mixers */
5243	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5244	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5245	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5246	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5247	/* set up input amps for analog loopback */
5248	/* Amp Indices: DAC = 0, mixer = 1 */
5249	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5250	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5251	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5252	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5253	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5254	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5255	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5256	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5257	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5258	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5259
5260	/* FIXME: use matrix-type input source selection */
5261	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5262	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5263	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5264	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5265	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5266	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5267	/* Input mixer2 */
5268	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5269	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5270	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5271	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5272	/* Input mixer3 */
5273	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5274	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5275	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5276	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5277
5278	{ }
5279};
5280
5281/* capture mixer elements */
5282static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5283	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5284	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5285	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5286	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5287	{
5288		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5289		/* The multiple "Capture Source" controls confuse alsamixer
5290		 * So call somewhat different..
5291		 * FIXME: the controls appear in the "playback" view!
5292		 */
5293		/* .name = "Capture Source", */
5294		.name = "Input Source",
5295		.count = 2,
5296		.info = alc882_mux_enum_info,
5297		.get = alc882_mux_enum_get,
5298		.put = alc882_mux_enum_put,
5299	},
5300	{ } /* end */
5301};
5302
5303static struct snd_kcontrol_new alc882_capture_mixer[] = {
5304	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5305	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5306	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5307	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5308	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5309	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5310	{
5311		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5312		/* The multiple "Capture Source" controls confuse alsamixer
5313		 * So call somewhat different..
5314		 * FIXME: the controls appear in the "playback" view!
5315		 */
5316		/* .name = "Capture Source", */
5317		.name = "Input Source",
5318		.count = 3,
5319		.info = alc882_mux_enum_info,
5320		.get = alc882_mux_enum_get,
5321		.put = alc882_mux_enum_put,
5322	},
5323	{ } /* end */
5324};
5325
5326/* pcm configuration: identiacal with ALC880 */
5327#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5328#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5329#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5330#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5331
5332/*
5333 * configuration and preset
5334 */
5335static const char *alc882_models[ALC882_MODEL_LAST] = {
5336	[ALC882_3ST_DIG]	= "3stack-dig",
5337	[ALC882_6ST_DIG]	= "6stack-dig",
5338	[ALC882_ARIMA]		= "arima",
5339	[ALC882_W2JC]		= "w2jc",
5340	[ALC885_MACPRO]		= "macpro",
5341	[ALC882_AUTO]		= "auto",
5342};
5343
5344static struct snd_pci_quirk alc882_cfg_tbl[] = {
5345	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5346	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5347	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5348	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5349	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5350	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5351	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5352	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5353	{}
5354};
5355
5356static struct alc_config_preset alc882_presets[] = {
5357	[ALC882_3ST_DIG] = {
5358		.mixers = { alc882_base_mixer },
5359		.init_verbs = { alc882_init_verbs },
5360		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5361		.dac_nids = alc882_dac_nids,
5362		.dig_out_nid = ALC882_DIGOUT_NID,
5363		.dig_in_nid = ALC882_DIGIN_NID,
5364		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5365		.channel_mode = alc882_ch_modes,
5366		.need_dac_fix = 1,
5367		.input_mux = &alc882_capture_source,
5368	},
5369	[ALC882_6ST_DIG] = {
5370		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5371		.init_verbs = { alc882_init_verbs },
5372		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5373		.dac_nids = alc882_dac_nids,
5374		.dig_out_nid = ALC882_DIGOUT_NID,
5375		.dig_in_nid = ALC882_DIGIN_NID,
5376		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5377		.channel_mode = alc882_sixstack_modes,
5378		.input_mux = &alc882_capture_source,
5379	},
5380	[ALC882_ARIMA] = {
5381		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5382		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5383		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5384		.dac_nids = alc882_dac_nids,
5385		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5386		.channel_mode = alc882_sixstack_modes,
5387		.input_mux = &alc882_capture_source,
5388	},
5389	[ALC882_W2JC] = {
5390		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5391		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5392				alc880_gpio1_init_verbs },
5393		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5394		.dac_nids = alc882_dac_nids,
5395		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5396		.channel_mode = alc880_threestack_modes,
5397		.need_dac_fix = 1,
5398		.input_mux = &alc882_capture_source,
5399		.dig_out_nid = ALC882_DIGOUT_NID,
5400	},
5401	[ALC885_MACPRO] = {
5402		.mixers = { alc882_macpro_mixer },
5403		.init_verbs = { alc882_macpro_init_verbs },
5404		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5405		.dac_nids = alc882_dac_nids,
5406		.dig_out_nid = ALC882_DIGOUT_NID,
5407		.dig_in_nid = ALC882_DIGIN_NID,
5408		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5409		.channel_mode = alc882_ch_modes,
5410		.input_mux = &alc882_capture_source,
5411	},
5412	[ALC882_TARGA] = {
5413		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5414			    alc882_capture_mixer },
5415		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5416		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5417		.dac_nids = alc882_dac_nids,
5418		.dig_out_nid = ALC882_DIGOUT_NID,
5419		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5420		.adc_nids = alc882_adc_nids,
5421		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5422		.channel_mode = alc882_3ST_6ch_modes,
5423		.need_dac_fix = 1,
5424		.input_mux = &alc882_capture_source,
5425		.unsol_event = alc882_targa_unsol_event,
5426		.init_hook = alc882_targa_automute,
5427	},
5428	[ALC882_ASUS_A7J] = {
5429		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5430			    alc882_capture_mixer },
5431		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5432		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5433		.dac_nids = alc882_dac_nids,
5434		.dig_out_nid = ALC882_DIGOUT_NID,
5435		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5436		.adc_nids = alc882_adc_nids,
5437		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5438		.channel_mode = alc882_3ST_6ch_modes,
5439		.need_dac_fix = 1,
5440		.input_mux = &alc882_capture_source,
5441	},
5442};
5443
5444
5445/*
5446 * Pin config fixes
5447 */
5448enum {
5449	PINFIX_ABIT_AW9D_MAX
5450};
5451
5452static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5453	{ 0x15, 0x01080104 }, /* side */
5454	{ 0x16, 0x01011012 }, /* rear */
5455	{ 0x17, 0x01016011 }, /* clfe */
5456	{ }
5457};
5458
5459static const struct alc_pincfg *alc882_pin_fixes[] = {
5460	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5461};
5462
5463static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5464	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5465	{}
5466};
5467
5468/*
5469 * BIOS auto configuration
5470 */
5471static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5472					      hda_nid_t nid, int pin_type,
5473					      int dac_idx)
5474{
5475	/* set as output */
5476	struct alc_spec *spec = codec->spec;
5477	int idx;
5478
5479	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5480		idx = 4;
5481	else
5482		idx = spec->multiout.dac_nids[dac_idx] - 2;
5483
5484	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5485			    pin_type);
5486	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5487			    AMP_OUT_UNMUTE);
5488	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5489
5490}
5491
5492static void alc882_auto_init_multi_out(struct hda_codec *codec)
5493{
5494	struct alc_spec *spec = codec->spec;
5495	int i;
5496
5497	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5498	for (i = 0; i <= HDA_SIDE; i++) {
5499		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5500		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5501		if (nid)
5502			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5503							  i);
5504	}
5505}
5506
5507static void alc882_auto_init_hp_out(struct hda_codec *codec)
5508{
5509	struct alc_spec *spec = codec->spec;
5510	hda_nid_t pin;
5511
5512	pin = spec->autocfg.hp_pins[0];
5513	if (pin) /* connect to front */
5514		/* use dac 0 */
5515		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5516}
5517
5518#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
5519#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
5520
5521static void alc882_auto_init_analog_input(struct hda_codec *codec)
5522{
5523	struct alc_spec *spec = codec->spec;
5524	int i;
5525
5526	for (i = 0; i < AUTO_PIN_LAST; i++) {
5527		hda_nid_t nid = spec->autocfg.input_pins[i];
5528		if (alc882_is_input_pin(nid)) {
5529			snd_hda_codec_write(codec, nid, 0,
5530					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5531					    i <= AUTO_PIN_FRONT_MIC ?
5532					    PIN_VREF80 : PIN_IN);
5533			if (nid != ALC882_PIN_CD_NID)
5534				snd_hda_codec_write(codec, nid, 0,
5535						    AC_VERB_SET_AMP_GAIN_MUTE,
5536						    AMP_OUT_MUTE);
5537		}
5538	}
5539}
5540
5541/* almost identical with ALC880 parser... */
5542static int alc882_parse_auto_config(struct hda_codec *codec)
5543{
5544	struct alc_spec *spec = codec->spec;
5545	int err = alc880_parse_auto_config(codec);
5546
5547	if (err < 0)
5548		return err;
5549	else if (err > 0)
5550		/* hack - override the init verbs */
5551		spec->init_verbs[0] = alc882_auto_init_verbs;
5552	return err;
5553}
5554
5555/* additional initialization for auto-configuration model */
5556static void alc882_auto_init(struct hda_codec *codec)
5557{
5558	alc882_auto_init_multi_out(codec);
5559	alc882_auto_init_hp_out(codec);
5560	alc882_auto_init_analog_input(codec);
5561}
5562
5563static int patch_alc882(struct hda_codec *codec)
5564{
5565	struct alc_spec *spec;
5566	int err, board_config;
5567
5568	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5569	if (spec == NULL)
5570		return -ENOMEM;
5571
5572	codec->spec = spec;
5573
5574	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5575						  alc882_models,
5576						  alc882_cfg_tbl);
5577
5578	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5579		/* Pick up systems that don't supply PCI SSID */
5580		switch (codec->subsystem_id) {
5581		case 0x106b0c00: /* Mac Pro */
5582			board_config = ALC885_MACPRO;
5583			break;
5584		default:
5585			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5586		       			 "trying auto-probe from BIOS...\n");
5587			board_config = ALC882_AUTO;
5588		}
5589	}
5590
5591	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5592
5593	if (board_config == ALC882_AUTO) {
5594		/* automatic parse from the BIOS config */
5595		err = alc882_parse_auto_config(codec);
5596		if (err < 0) {
5597			alc_free(codec);
5598			return err;
5599		} else if (!err) {
5600			printk(KERN_INFO
5601			       "hda_codec: Cannot set up configuration "
5602			       "from BIOS.  Using base mode...\n");
5603			board_config = ALC882_3ST_DIG;
5604		}
5605	}
5606
5607	if (board_config != ALC882_AUTO)
5608		setup_preset(spec, &alc882_presets[board_config]);
5609
5610	if (board_config == ALC885_MACPRO) {
5611		alc882_gpio_mute(codec, 0, 0);
5612		alc882_gpio_mute(codec, 1, 0);
5613	}
5614
5615	spec->stream_name_analog = "ALC882 Analog";
5616	spec->stream_analog_playback = &alc882_pcm_analog_playback;
5617	spec->stream_analog_capture = &alc882_pcm_analog_capture;
5618
5619	spec->stream_name_digital = "ALC882 Digital";
5620	spec->stream_digital_playback = &alc882_pcm_digital_playback;
5621	spec->stream_digital_capture = &alc882_pcm_digital_capture;
5622
5623	if (!spec->adc_nids && spec->input_mux) {
5624		/* check whether NID 0x07 is valid */
5625		unsigned int wcap = get_wcaps(codec, 0x07);
5626		/* get type */
5627		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5628		if (wcap != AC_WID_AUD_IN) {
5629			spec->adc_nids = alc882_adc_nids_alt;
5630			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5631			spec->mixers[spec->num_mixers] =
5632				alc882_capture_alt_mixer;
5633			spec->num_mixers++;
5634		} else {
5635			spec->adc_nids = alc882_adc_nids;
5636			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5637			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5638			spec->num_mixers++;
5639		}
5640	}
5641
5642	codec->patch_ops = alc_patch_ops;
5643	if (board_config == ALC882_AUTO)
5644		spec->init_hook = alc882_auto_init;
5645
5646	return 0;
5647}
5648
5649/*
5650 * ALC883 support
5651 *
5652 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5653 * configuration.  Each pin widget can choose any input DACs and a mixer.
5654 * Each ADC is connected from a mixer of all inputs.  This makes possible
5655 * 6-channel independent captures.
5656 *
5657 * In addition, an independent DAC for the multi-playback (not used in this
5658 * driver yet).
5659 */
5660#define ALC883_DIGOUT_NID	0x06
5661#define ALC883_DIGIN_NID	0x0a
5662
5663static hda_nid_t alc883_dac_nids[4] = {
5664	/* front, rear, clfe, rear_surr */
5665	0x02, 0x04, 0x03, 0x05
5666};
5667
5668static hda_nid_t alc883_adc_nids[2] = {
5669	/* ADC1-2 */
5670	0x08, 0x09,
5671};
5672
5673/* input MUX */
5674/* FIXME: should be a matrix-type input source selection */
5675
5676static struct hda_input_mux alc883_capture_source = {
5677	.num_items = 4,
5678	.items = {
5679		{ "Mic", 0x0 },
5680		{ "Front Mic", 0x1 },
5681		{ "Line", 0x2 },
5682		{ "CD", 0x4 },
5683	},
5684};
5685
5686static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5687	.num_items = 2,
5688	.items = {
5689		{ "Mic", 0x1 },
5690		{ "Line", 0x2 },
5691	},
5692};
5693
5694static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5695	.num_items = 4,
5696	.items = {
5697		{ "Mic", 0x0 },
5698		{ "iMic", 0x1 },
5699		{ "Line", 0x2 },
5700		{ "CD", 0x4 },
5701	},
5702};
5703
5704#define alc883_mux_enum_info alc_mux_enum_info
5705#define alc883_mux_enum_get alc_mux_enum_get
5706
5707static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5708			       struct snd_ctl_elem_value *ucontrol)
5709{
5710	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5711	struct alc_spec *spec = codec->spec;
5712	const struct hda_input_mux *imux = spec->input_mux;
5713	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5714	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5715	hda_nid_t nid = capture_mixers[adc_idx];
5716	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5717	unsigned int i, idx;
5718
5719	idx = ucontrol->value.enumerated.item[0];
5720	if (idx >= imux->num_items)
5721		idx = imux->num_items - 1;
5722	if (*cur_val == idx && !codec->in_resume)
5723		return 0;
5724	for (i = 0; i < imux->num_items; i++) {
5725		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
5726		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5727				    v | (imux->items[i].index << 8));
5728	}
5729	*cur_val = idx;
5730	return 1;
5731}
5732
5733/*
5734 * 2ch mode
5735 */
5736static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5737	{ 2, NULL }
5738};
5739
5740/*
5741 * 2ch mode
5742 */
5743static struct hda_verb alc883_3ST_ch2_init[] = {
5744	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5745	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5746	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5747	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5748	{ } /* end */
5749};
5750
5751/*
5752 * 6ch mode
5753 */
5754static struct hda_verb alc883_3ST_ch6_init[] = {
5755	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5756	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5757	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5758	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5759	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5760	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5761	{ } /* end */
5762};
5763
5764static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5765	{ 2, alc883_3ST_ch2_init },
5766	{ 6, alc883_3ST_ch6_init },
5767};
5768
5769/*
5770 * 6ch mode
5771 */
5772static struct hda_verb alc883_sixstack_ch6_init[] = {
5773	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5774	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5775	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5776	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5777	{ } /* end */
5778};
5779
5780/*
5781 * 8ch mode
5782 */
5783static struct hda_verb alc883_sixstack_ch8_init[] = {
5784	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5785	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5786	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5787	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5788	{ } /* end */
5789};
5790
5791static struct hda_channel_mode alc883_sixstack_modes[2] = {
5792	{ 6, alc883_sixstack_ch6_init },
5793	{ 8, alc883_sixstack_ch8_init },
5794};
5795
5796static struct hda_verb alc883_medion_eapd_verbs[] = {
5797        /* eanable EAPD on medion laptop */
5798	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5799	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5800	{ }
5801};
5802
5803/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5804 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5805 */
5806
5807static struct snd_kcontrol_new alc883_base_mixer[] = {
5808	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5809	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5810	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5811	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5812	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5813	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5814	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5815	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5816	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5817	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5818	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5819	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5820	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5821	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5822	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5823	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5824	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5825	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5826	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5827	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5828	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5829	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5830	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5831	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5832	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5833	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5834	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5835	{
5836		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5837		/* .name = "Capture Source", */
5838		.name = "Input Source",
5839		.count = 2,
5840		.info = alc883_mux_enum_info,
5841		.get = alc883_mux_enum_get,
5842		.put = alc883_mux_enum_put,
5843	},
5844	{ } /* end */
5845};
5846
5847static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5848	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5849	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5850	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5851	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5852	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5853	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5854	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5855	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5856	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5857	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5858	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5859	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5860	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5861	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5862	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5863	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5864	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5865	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5866	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5867	{
5868		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5869		/* .name = "Capture Source", */
5870		.name = "Input Source",
5871		.count = 2,
5872		.info = alc883_mux_enum_info,
5873		.get = alc883_mux_enum_get,
5874		.put = alc883_mux_enum_put,
5875	},
5876	{ } /* end */
5877};
5878
5879static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5880	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5881	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5882	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5883	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5884	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5885	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5886	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5887	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5888	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5889	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5890	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5891	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5892	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5893	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5894	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5895	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5896	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5897	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5898	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5899	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5900	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5901	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5902	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5903	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5904	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5905	{
5906		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5907		/* .name = "Capture Source", */
5908		.name = "Input Source",
5909		.count = 2,
5910		.info = alc883_mux_enum_info,
5911		.get = alc883_mux_enum_get,
5912		.put = alc883_mux_enum_put,
5913	},
5914	{ } /* end */
5915};
5916
5917static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5918	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5919	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5920	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5921	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5922	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5923	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5924	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5925	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5926	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5927	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5928	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5929	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5930	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5931	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5932	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5933	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5934	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5935	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5936	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5937	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5938	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5939	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5940	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5941
5942	{
5943		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5944		/* .name = "Capture Source", */
5945		.name = "Input Source",
5946		.count = 1,
5947		.info = alc883_mux_enum_info,
5948		.get = alc883_mux_enum_get,
5949		.put = alc883_mux_enum_put,
5950	},
5951	{ } /* end */
5952};
5953
5954static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5955	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5956	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5957	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5958	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5959	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5960	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5961	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5962	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5963	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5964	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5965	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5966	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5967	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5968	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5969	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5970	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5971	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5972	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5973	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5974	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5975	{
5976		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5977		/* .name = "Capture Source", */
5978		.name = "Input Source",
5979		.count = 2,
5980		.info = alc883_mux_enum_info,
5981		.get = alc883_mux_enum_get,
5982		.put = alc883_mux_enum_put,
5983	},
5984	{ } /* end */
5985};
5986
5987static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5988	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5989	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5990	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5991	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5992	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5993	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5994	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5995	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5996	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5997	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5998	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5999	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6000	{
6001		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6002		/* .name = "Capture Source", */
6003		.name = "Input Source",
6004		.count = 2,
6005		.info = alc883_mux_enum_info,
6006		.get = alc883_mux_enum_get,
6007		.put = alc883_mux_enum_put,
6008	},
6009	{ } /* end */
6010};
6011
6012static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6013	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6014	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6015	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6016	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6017	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6018	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6019	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6020	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6021	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6022	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6023	{
6024		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6025		/* .name = "Capture Source", */
6026		.name = "Input Source",
6027		.count = 1,
6028		.info = alc883_mux_enum_info,
6029		.get = alc883_mux_enum_get,
6030		.put = alc883_mux_enum_put,
6031	},
6032	{ } /* end */
6033};
6034
6035static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6036	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6037	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6038	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6039	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6040	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6041	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6042	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6043	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6044	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6045	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6046	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6047	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6048	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6049	{
6050		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6051		/* .name = "Capture Source", */
6052		.name = "Input Source",
6053		.count = 2,
6054		.info = alc883_mux_enum_info,
6055		.get = alc883_mux_enum_get,
6056		.put = alc883_mux_enum_put,
6057	},
6058	{ } /* end */
6059};
6060
6061static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6062	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6063	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6064	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6065	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6066	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6067	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6068	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6069	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6070	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6071	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6072	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6073	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6074	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6075	{
6076		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6077		/* .name = "Capture Source", */
6078		.name = "Input Source",
6079		.count = 2,
6080		.info = alc883_mux_enum_info,
6081		.get = alc883_mux_enum_get,
6082		.put = alc883_mux_enum_put,
6083	},
6084	{ } /* end */
6085};
6086
6087static struct snd_kcontrol_new alc888_hp_nettle_mixer[] = {
6088	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6089	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6090	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6091	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6092	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6093	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6094	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6095	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6096	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6097	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6098	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6099	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6100	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6101	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6102	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6103	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6104	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6105	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6106	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6107	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6108	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6109	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6110	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6111	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6112	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6113	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6114	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6115	{
6116		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6117		/* .name = "Capture Source", */
6118		.name = "Input Source",
6119		.count = 2,
6120		.info = alc883_mux_enum_info,
6121		.get = alc883_mux_enum_get,
6122		.put = alc883_mux_enum_put,
6123	},
6124	{ } /* end */
6125};
6126
6127static struct snd_kcontrol_new alc888_hp_lucknow_mixer[] = {
6128	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6129	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6130	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6131	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6132	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6133	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6134	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6135	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6136	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6137	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6138	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6139	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6140	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6141	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6142	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6143	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6144	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6145	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6146	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6147	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6148	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6149	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6150	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6151	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6152	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6153	{
6154		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6155		/* .name = "Capture Source", */
6156		.name = "Input Source",
6157		.count = 2,
6158		.info = alc883_mux_enum_info,
6159		.get = alc883_mux_enum_get,
6160		.put = alc883_mux_enum_put,
6161	},
6162	{ } /* end */
6163};
6164
6165static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6166	{
6167		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6168		.name = "Channel Mode",
6169		.info = alc_ch_mode_info,
6170		.get = alc_ch_mode_get,
6171		.put = alc_ch_mode_put,
6172	},
6173	{ } /* end */
6174};
6175
6176static struct hda_verb alc883_init_verbs[] = {
6177	/* ADC1: mute amp left and right */
6178	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6179	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6180	/* ADC2: mute amp left and right */
6181	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6182	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6183	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6184	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6185	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6186	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6187	/* Rear mixer */
6188	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6189	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6190	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6191	/* CLFE mixer */
6192	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6193	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6194	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6195	/* Side mixer */
6196	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6197	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6198	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6199
6200	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6201	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6202	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6203	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6204	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6205
6206	/* Front Pin: output 0 (0x0c) */
6207	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6208	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6209	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6210	/* Rear Pin: output 1 (0x0d) */
6211	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6212	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6213	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6214	/* CLFE Pin: output 2 (0x0e) */
6215	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6216	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6217	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6218	/* Side Pin: output 3 (0x0f) */
6219	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6220	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6221	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6222	/* Mic (rear) pin: input vref at 80% */
6223	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6224	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6225	/* Front Mic pin: input vref at 80% */
6226	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6227	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6228	/* Line In pin: input */
6229	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6230	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6231	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6232	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6233	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6234	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6235	/* CD pin widget for input */
6236	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6237
6238	/* FIXME: use matrix-type input source selection */
6239	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6240	/* Input mixer2 */
6241	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6242	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6243	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6244	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6245	/* Input mixer3 */
6246	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6247	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6248	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6249	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6250	{ }
6251};
6252
6253static struct hda_verb alc883_tagra_verbs[] = {
6254	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6255	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6256
6257	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6258	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6259
6260	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6261	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6262	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6263
6264	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6265	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6266	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6267	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6268
6269	{ } /* end */
6270};
6271
6272static struct hda_verb alc883_lenovo_101e_verbs[] = {
6273	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6274	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6275        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6276	{ } /* end */
6277};
6278
6279static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6280        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6281	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6282        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6283        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6284	{ } /* end */
6285};
6286
6287static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6288	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6289	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6290	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6291	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6292	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6293	{ } /* end */
6294};
6295
6296static struct hda_verb alc888_hp_nettle_verbs[] = {
6297	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6298	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},	/* Rear : output 2 (0x0e) */
6299	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* CLFE : output 1 (0x0d) */
6300	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},	/* Side : output 3 (0x0f) */
6301	{ }
6302};
6303
6304static struct hda_verb alc888_hp_lucknow_verbs[] = {
6305	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6306	{0x18, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
6307	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
6308	{ }
6309};
6310
6311static struct hda_verb alc888_hp_lucknow_2ch_init[] = {
6312	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6313	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6314	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6315	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6316	{ }
6317};
6318
6319static struct hda_verb alc888_hp_lucknow_6ch_init[] = {
6320	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6321	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6322	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6323	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6324	{ }
6325};
6326
6327static struct hda_channel_mode alc888_hp_lucknow_modes[2] = {
6328	{ 2, alc888_hp_lucknow_2ch_init },
6329	{ 6, alc888_hp_lucknow_6ch_init },
6330};
6331
6332/* toggle front-jack and RCA according to the hp-jack state */
6333static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6334{
6335 	unsigned int present;
6336
6337 	present = snd_hda_codec_read(codec, 0x1b, 0,
6338				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6339	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6340				 0x80, present ? 0x80 : 0);
6341	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6342				 0x80, present ? 0x80 : 0);
6343	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6344				 0x80, present ? 0x80 : 0);
6345	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6346				 0x80, present ? 0x80 : 0);
6347
6348}
6349
6350/* toggle RCA according to the front-jack state */
6351static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6352{
6353 	unsigned int present;
6354
6355 	present = snd_hda_codec_read(codec, 0x14, 0,
6356				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6357	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6358				 0x80, present ? 0x80 : 0);
6359	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6360				 0x80, present ? 0x80 : 0);
6361
6362}
6363static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6364					     unsigned int res)
6365{
6366	if ((res >> 26) == ALC880_HP_EVENT)
6367		alc888_lenovo_ms7195_front_automute(codec);
6368	if ((res >> 26) == ALC880_FRONT_EVENT)
6369		alc888_lenovo_ms7195_rca_automute(codec);
6370}
6371
6372static struct hda_verb alc883_medion_md2_verbs[] = {
6373	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6374	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6375
6376	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6377
6378	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6379	{ } /* end */
6380};
6381
6382/* toggle speaker-output according to the hp-jack state */
6383static void alc883_medion_md2_automute(struct hda_codec *codec)
6384{
6385 	unsigned int present;
6386
6387 	present = snd_hda_codec_read(codec, 0x14, 0,
6388				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6389	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6390				 0x80, present ? 0x80 : 0);
6391	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6392				 0x80, present ? 0x80 : 0);
6393}
6394
6395static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6396					  unsigned int res)
6397{
6398	if ((res >> 26) == ALC880_HP_EVENT)
6399		alc883_medion_md2_automute(codec);
6400}
6401
6402/* toggle speaker-output according to the hp-jack state */
6403static void alc883_tagra_automute(struct hda_codec *codec)
6404{
6405 	unsigned int present;
6406	unsigned char bits;
6407
6408 	present = snd_hda_codec_read(codec, 0x14, 0,
6409				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6410	bits = present ? 0x80 : 0;
6411	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
6412				 0x80, bits);
6413	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6414				 0x80, bits);
6415	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6416			    present ? 1 : 3);
6417}
6418
6419static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6420{
6421	if ((res >> 26) == ALC880_HP_EVENT)
6422		alc883_tagra_automute(codec);
6423}
6424
6425static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6426{
6427 	unsigned int present;
6428	unsigned char bits;
6429
6430 	present = snd_hda_codec_read(codec, 0x14, 0,
6431				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6432	bits = present ? 0x80 : 0;
6433	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6434				 0x80, bits);
6435	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6436				 0x80, bits);
6437}
6438
6439static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6440{
6441 	unsigned int present;
6442	unsigned char bits;
6443
6444 	present = snd_hda_codec_read(codec, 0x1b, 0,
6445				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6446	bits = present ? 0x80 : 0;
6447	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6448				 0x80, bits);
6449	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6450				 0x80, bits);
6451	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6452				 0x80, bits);
6453	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6454				 0x80, bits);
6455}
6456
6457static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6458					   unsigned int res)
6459{
6460	if ((res >> 26) == ALC880_HP_EVENT)
6461		alc883_lenovo_101e_all_automute(codec);
6462	if ((res >> 26) == ALC880_FRONT_EVENT)
6463		alc883_lenovo_101e_ispeaker_automute(codec);
6464}
6465
6466/*
6467 * generic initialization of ADC, input mixers and output mixers
6468 */
6469static struct hda_verb alc883_auto_init_verbs[] = {
6470	/*
6471	 * Unmute ADC0-2 and set the default input to mic-in
6472	 */
6473	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6474	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6475	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6476	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6477
6478	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6479	 * mixer widget
6480	 * Note: PASD motherboards uses the Line In 2 as the input for
6481	 * front panel mic (mic 2)
6482	 */
6483	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6484	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6485	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6486	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6487	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6488	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6489
6490	/*
6491	 * Set up output mixers (0x0c - 0x0f)
6492	 */
6493	/* set vol=0 to output mixers */
6494	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6495	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6496	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6497	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6498	/* set up input amps for analog loopback */
6499	/* Amp Indices: DAC = 0, mixer = 1 */
6500	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6501	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6502	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6503	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6504	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6505	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6506	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6507	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6508	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6509	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6510
6511	/* FIXME: use matrix-type input source selection */
6512	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6513	/* Input mixer1 */
6514	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6515	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6516	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6517	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6518	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6519	/* Input mixer2 */
6520	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6521	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6522	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6523	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6524	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6525
6526	{ }
6527};
6528
6529/* capture mixer elements */
6530static struct snd_kcontrol_new alc883_capture_mixer[] = {
6531	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6532	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6533	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6534	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6535	{
6536		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6537		/* The multiple "Capture Source" controls confuse alsamixer
6538		 * So call somewhat different..
6539		 * FIXME: the controls appear in the "playback" view!
6540		 */
6541		/* .name = "Capture Source", */
6542		.name = "Input Source",
6543		.count = 2,
6544		.info = alc882_mux_enum_info,
6545		.get = alc882_mux_enum_get,
6546		.put = alc882_mux_enum_put,
6547	},
6548	{ } /* end */
6549};
6550
6551/* pcm configuration: identiacal with ALC880 */
6552#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
6553#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
6554#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
6555#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
6556
6557/*
6558 * configuration and preset
6559 */
6560static const char *alc883_models[ALC883_MODEL_LAST] = {
6561	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
6562	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
6563	[ALC883_3ST_6ch]	= "3stack-6ch",
6564	[ALC883_6ST_DIG]	= "6stack-dig",
6565	[ALC883_TARGA_DIG]	= "targa-dig",
6566	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
6567	[ALC883_ACER]		= "acer",
6568	[ALC883_MEDION]		= "medion",
6569	[ALC883_MEDION_MD2]	= "medion-md2",
6570	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
6571	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6572	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
6573	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6574	[ALC888_HP_NETTLE]	= "hp-nettle",
6575	[ALC888_HP_LUCKNOW]	= "hp-lucknow",
6576	[ALC883_AUTO]		= "auto",
6577};
6578
6579static struct snd_pci_quirk alc883_cfg_tbl[] = {
6580	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6581	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6582	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6583	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6584	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6585	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6586	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6587	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6588	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6589	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6590	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6591	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6592	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6593	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6594	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6595	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6596	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6597	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6598	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6599	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6600	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6601	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6602	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6603	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6604	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6605	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6606	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6607	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6608	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6609	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6610	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6611	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_HP_NETTLE),
6612	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_HP_LUCKNOW),
6613	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_HP_LUCKNOW),
6614	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6615	{}
6616};
6617
6618static struct alc_config_preset alc883_presets[] = {
6619	[ALC883_3ST_2ch_DIG] = {
6620		.mixers = { alc883_3ST_2ch_mixer },
6621		.init_verbs = { alc883_init_verbs },
6622		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6623		.dac_nids = alc883_dac_nids,
6624		.dig_out_nid = ALC883_DIGOUT_NID,
6625		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6626		.adc_nids = alc883_adc_nids,
6627		.dig_in_nid = ALC883_DIGIN_NID,
6628		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6629		.channel_mode = alc883_3ST_2ch_modes,
6630		.input_mux = &alc883_capture_source,
6631	},
6632	[ALC883_3ST_6ch_DIG] = {
6633		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6634		.init_verbs = { alc883_init_verbs },
6635		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6636		.dac_nids = alc883_dac_nids,
6637		.dig_out_nid = ALC883_DIGOUT_NID,
6638		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6639		.adc_nids = alc883_adc_nids,
6640		.dig_in_nid = ALC883_DIGIN_NID,
6641		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6642		.channel_mode = alc883_3ST_6ch_modes,
6643		.need_dac_fix = 1,
6644		.input_mux = &alc883_capture_source,
6645	},
6646	[ALC883_3ST_6ch] = {
6647		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6648		.init_verbs = { alc883_init_verbs },
6649		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6650		.dac_nids = alc883_dac_nids,
6651		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6652		.adc_nids = alc883_adc_nids,
6653		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6654		.channel_mode = alc883_3ST_6ch_modes,
6655		.need_dac_fix = 1,
6656		.input_mux = &alc883_capture_source,
6657	},
6658	[ALC883_6ST_DIG] = {
6659		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
6660		.init_verbs = { alc883_init_verbs },
6661		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6662		.dac_nids = alc883_dac_nids,
6663		.dig_out_nid = ALC883_DIGOUT_NID,
6664		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6665		.adc_nids = alc883_adc_nids,
6666		.dig_in_nid = ALC883_DIGIN_NID,
6667		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6668		.channel_mode = alc883_sixstack_modes,
6669		.input_mux = &alc883_capture_source,
6670	},
6671	[ALC883_TARGA_DIG] = {
6672		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6673		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6674		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6675		.dac_nids = alc883_dac_nids,
6676		.dig_out_nid = ALC883_DIGOUT_NID,
6677		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6678		.adc_nids = alc883_adc_nids,
6679		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6680		.channel_mode = alc883_3ST_6ch_modes,
6681		.need_dac_fix = 1,
6682		.input_mux = &alc883_capture_source,
6683		.unsol_event = alc883_tagra_unsol_event,
6684		.init_hook = alc883_tagra_automute,
6685	},
6686	[ALC883_TARGA_2ch_DIG] = {
6687		.mixers = { alc883_tagra_2ch_mixer},
6688		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6689		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6690		.dac_nids = alc883_dac_nids,
6691		.dig_out_nid = ALC883_DIGOUT_NID,
6692		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6693		.adc_nids = alc883_adc_nids,
6694		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6695		.channel_mode = alc883_3ST_2ch_modes,
6696		.input_mux = &alc883_capture_source,
6697		.unsol_event = alc883_tagra_unsol_event,
6698		.init_hook = alc883_tagra_automute,
6699	},
6700	[ALC883_ACER] = {
6701		.mixers = { alc883_base_mixer,
6702			    alc883_chmode_mixer },
6703		/* On TravelMate laptops, GPIO 0 enables the internal speaker
6704		 * and the headphone jack.  Turn this on and rely on the
6705		 * standard mute methods whenever the user wants to turn
6706		 * these outputs off.
6707		 */
6708		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6709		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6710		.dac_nids = alc883_dac_nids,
6711		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6712		.adc_nids = alc883_adc_nids,
6713		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6714		.channel_mode = alc883_3ST_2ch_modes,
6715		.input_mux = &alc883_capture_source,
6716	},
6717	[ALC883_MEDION] = {
6718		.mixers = { alc883_fivestack_mixer,
6719			    alc883_chmode_mixer },
6720		.init_verbs = { alc883_init_verbs,
6721				alc883_medion_eapd_verbs },
6722		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6723		.dac_nids = alc883_dac_nids,
6724		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6725		.adc_nids = alc883_adc_nids,
6726		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6727		.channel_mode = alc883_sixstack_modes,
6728		.input_mux = &alc883_capture_source,
6729	},
6730	[ALC883_MEDION_MD2] = {
6731		.mixers = { alc883_medion_md2_mixer},
6732		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6733		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6734		.dac_nids = alc883_dac_nids,
6735		.dig_out_nid = ALC883_DIGOUT_NID,
6736		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6737		.adc_nids = alc883_adc_nids,
6738		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6739		.channel_mode = alc883_3ST_2ch_modes,
6740		.input_mux = &alc883_capture_source,
6741		.unsol_event = alc883_medion_md2_unsol_event,
6742		.init_hook = alc883_medion_md2_automute,
6743	},
6744	[ALC883_LAPTOP_EAPD] = {
6745		.mixers = { alc883_base_mixer,
6746			    alc883_chmode_mixer },
6747		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6748		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6749		.dac_nids = alc883_dac_nids,
6750		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6751		.adc_nids = alc883_adc_nids,
6752		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6753		.channel_mode = alc883_3ST_2ch_modes,
6754		.input_mux = &alc883_capture_source,
6755	},
6756	[ALC883_LENOVO_101E_2ch] = {
6757		.mixers = { alc883_lenovo_101e_2ch_mixer},
6758		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6759		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6760		.dac_nids = alc883_dac_nids,
6761		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6762		.adc_nids = alc883_adc_nids,
6763		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6764		.channel_mode = alc883_3ST_2ch_modes,
6765		.input_mux = &alc883_lenovo_101e_capture_source,
6766		.unsol_event = alc883_lenovo_101e_unsol_event,
6767		.init_hook = alc883_lenovo_101e_all_automute,
6768	},
6769	[ALC883_LENOVO_NB0763] = {
6770		.mixers = { alc883_lenovo_nb0763_mixer },
6771		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6772		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6773		.dac_nids = alc883_dac_nids,
6774		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6775		.adc_nids = alc883_adc_nids,
6776		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6777		.channel_mode = alc883_3ST_2ch_modes,
6778		.need_dac_fix = 1,
6779		.input_mux = &alc883_lenovo_nb0763_capture_source,
6780		.unsol_event = alc883_medion_md2_unsol_event,
6781		.init_hook = alc883_medion_md2_automute,
6782	},
6783	[ALC888_LENOVO_MS7195_DIG] = {
6784		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6785		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6786		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6787		.dac_nids = alc883_dac_nids,
6788		.dig_out_nid = ALC883_DIGOUT_NID,
6789		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6790		.adc_nids = alc883_adc_nids,
6791		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6792		.channel_mode = alc883_3ST_6ch_modes,
6793		.need_dac_fix = 1,
6794		.input_mux = &alc883_capture_source,
6795		.unsol_event = alc883_lenovo_ms7195_unsol_event,
6796		.init_hook = alc888_lenovo_ms7195_front_automute,
6797	},
6798	[ALC888_HP_NETTLE] = {
6799		.mixers = { alc888_hp_nettle_mixer, alc883_chmode_mixer },
6800		.init_verbs = { alc883_init_verbs, alc888_hp_nettle_verbs },
6801		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6802		.dac_nids = alc883_dac_nids,
6803		.dig_out_nid = ALC883_DIGOUT_NID,
6804		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6805		.adc_nids = alc883_adc_nids,
6806		.dig_in_nid = ALC883_DIGIN_NID,
6807		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6808		.channel_mode = alc883_sixstack_modes,
6809		.input_mux = &alc883_capture_source,
6810	},
6811	[ALC888_HP_LUCKNOW] = {
6812		.mixers = { alc888_hp_lucknow_mixer, alc883_chmode_mixer },
6813		.init_verbs = { alc883_init_verbs, alc888_hp_lucknow_verbs },
6814		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6815		.dac_nids = alc883_dac_nids,
6816		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6817		.adc_nids = alc883_adc_nids,
6818		.num_channel_mode = ARRAY_SIZE(alc888_hp_lucknow_modes),
6819		.channel_mode = alc888_hp_lucknow_modes,
6820		.need_dac_fix = 1,
6821		.input_mux = &alc883_capture_source,
6822	},
6823};
6824
6825
6826/*
6827 * BIOS auto configuration
6828 */
6829static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6830					      hda_nid_t nid, int pin_type,
6831					      int dac_idx)
6832{
6833	/* set as output */
6834	struct alc_spec *spec = codec->spec;
6835	int idx;
6836
6837	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6838		idx = 4;
6839	else
6840		idx = spec->multiout.dac_nids[dac_idx] - 2;
6841
6842	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6843			    pin_type);
6844	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6845			    AMP_OUT_UNMUTE);
6846	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6847
6848}
6849
6850static void alc883_auto_init_multi_out(struct hda_codec *codec)
6851{
6852	struct alc_spec *spec = codec->spec;
6853	int i;
6854
6855	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6856	for (i = 0; i <= HDA_SIDE; i++) {
6857		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6858		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6859		if (nid)
6860			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6861							  i);
6862	}
6863}
6864
6865static void alc883_auto_init_hp_out(struct hda_codec *codec)
6866{
6867	struct alc_spec *spec = codec->spec;
6868	hda_nid_t pin;
6869
6870	pin = spec->autocfg.hp_pins[0];
6871	if (pin) /* connect to front */
6872		/* use dac 0 */
6873		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6874}
6875
6876#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
6877#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
6878
6879static void alc883_auto_init_analog_input(struct hda_codec *codec)
6880{
6881	struct alc_spec *spec = codec->spec;
6882	int i;
6883
6884	for (i = 0; i < AUTO_PIN_LAST; i++) {
6885		hda_nid_t nid = spec->autocfg.input_pins[i];
6886		if (alc883_is_input_pin(nid)) {
6887			snd_hda_codec_write(codec, nid, 0,
6888					    AC_VERB_SET_PIN_WIDGET_CONTROL,
6889					    (i <= AUTO_PIN_FRONT_MIC ?
6890					     PIN_VREF80 : PIN_IN));
6891			if (nid != ALC883_PIN_CD_NID)
6892				snd_hda_codec_write(codec, nid, 0,
6893						    AC_VERB_SET_AMP_GAIN_MUTE,
6894						    AMP_OUT_MUTE);
6895		}
6896	}
6897}
6898
6899/* almost identical with ALC880 parser... */
6900static int alc883_parse_auto_config(struct hda_codec *codec)
6901{
6902	struct alc_spec *spec = codec->spec;
6903	int err = alc880_parse_auto_config(codec);
6904
6905	if (err < 0)
6906		return err;
6907	else if (err > 0)
6908		/* hack - override the init verbs */
6909		spec->init_verbs[0] = alc883_auto_init_verbs;
6910	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6911	spec->num_mixers++;
6912	return err;
6913}
6914
6915/* additional initialization for auto-configuration model */
6916static void alc883_auto_init(struct hda_codec *codec)
6917{
6918	alc883_auto_init_multi_out(codec);
6919	alc883_auto_init_hp_out(codec);
6920	alc883_auto_init_analog_input(codec);
6921}
6922
6923static int patch_alc883(struct hda_codec *codec)
6924{
6925	struct alc_spec *spec;
6926	int err, board_config;
6927
6928	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6929	if (spec == NULL)
6930		return -ENOMEM;
6931
6932	codec->spec = spec;
6933
6934	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
6935						  alc883_models,
6936						  alc883_cfg_tbl);
6937	if (board_config < 0) {
6938		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
6939		       "trying auto-probe from BIOS...\n");
6940		board_config = ALC883_AUTO;
6941	}
6942
6943	if (board_config == ALC883_AUTO) {
6944		/* automatic parse from the BIOS config */
6945		err = alc883_parse_auto_config(codec);
6946		if (err < 0) {
6947			alc_free(codec);
6948			return err;
6949		} else if (!err) {
6950			printk(KERN_INFO
6951			       "hda_codec: Cannot set up configuration "
6952			       "from BIOS.  Using base mode...\n");
6953			board_config = ALC883_3ST_2ch_DIG;
6954		}
6955	}
6956
6957	if (board_config != ALC883_AUTO)
6958		setup_preset(spec, &alc883_presets[board_config]);
6959
6960	spec->stream_name_analog = "ALC883 Analog";
6961	spec->stream_analog_playback = &alc883_pcm_analog_playback;
6962	spec->stream_analog_capture = &alc883_pcm_analog_capture;
6963
6964	spec->stream_name_digital = "ALC883 Digital";
6965	spec->stream_digital_playback = &alc883_pcm_digital_playback;
6966	spec->stream_digital_capture = &alc883_pcm_digital_capture;
6967
6968	if (!spec->adc_nids && spec->input_mux) {
6969		spec->adc_nids = alc883_adc_nids;
6970		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
6971	}
6972
6973	codec->patch_ops = alc_patch_ops;
6974	if (board_config == ALC883_AUTO)
6975		spec->init_hook = alc883_auto_init;
6976
6977	return 0;
6978}
6979
6980/*
6981 * ALC262 support
6982 */
6983
6984#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
6985#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
6986
6987#define alc262_dac_nids		alc260_dac_nids
6988#define alc262_adc_nids		alc882_adc_nids
6989#define alc262_adc_nids_alt	alc882_adc_nids_alt
6990
6991#define alc262_modes		alc260_modes
6992#define alc262_capture_source	alc882_capture_source
6993
6994static struct snd_kcontrol_new alc262_base_mixer[] = {
6995	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6996	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6997	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6998	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6999	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7000	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7001	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7002	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7003	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7004	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7005	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7006	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7007	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7008	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7009	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7010	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7011	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7012	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7013	{ } /* end */
7014};
7015
7016static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7017	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7018	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7019	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7020	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7021	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7022	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7023	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7024	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7025	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7026	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7027	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7028	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7029	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7030	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7031	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7032	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7033	{ } /* end */
7034};
7035
7036static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7037	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7038	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7039	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7040	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7041	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7042
7043	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7044	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7045	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7046	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7047	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7048	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7049	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7050	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7051	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7052	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7053	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7054	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7055	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7056	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7057	{ } /* end */
7058};
7059
7060static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7061	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7062	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7063	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7064	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7065	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7066	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7067	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7068	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7069	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7070	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7071	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7072	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7073	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7074	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7075	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7076	{ } /* end */
7077};
7078
7079static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7080	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7081	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7082	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7083	{ } /* end */
7084};
7085
7086static struct snd_kcontrol_new alc262_sony_mixer[] = {
7087	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7088	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7089	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7090	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7091	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7092	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7093	{ } /* end */
7094};
7095
7096static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7097	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7098	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7099	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7100	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7101	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7102	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7103	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7104	{ } /* end */
7105};
7106
7107#define alc262_capture_mixer		alc882_capture_mixer
7108#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
7109
7110/*
7111 * generic initialization of ADC, input mixers and output mixers
7112 */
7113static struct hda_verb alc262_init_verbs[] = {
7114	/*
7115	 * Unmute ADC0-2 and set the default input to mic-in
7116	 */
7117	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7118	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7119	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7120	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7121	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7122	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7123
7124	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7125	 * mixer widget
7126	 * Note: PASD motherboards uses the Line In 2 as the input for
7127	 * front panel mic (mic 2)
7128	 */
7129	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7130	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7131	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7132	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7133	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7134	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7135
7136	/*
7137	 * Set up output mixers (0x0c - 0x0e)
7138	 */
7139	/* set vol=0 to output mixers */
7140	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7141	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7142	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7143	/* set up input amps for analog loopback */
7144	/* Amp Indices: DAC = 0, mixer = 1 */
7145	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7146	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7147	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7148	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7149	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7150	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7151
7152	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7153	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7154	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7155	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7156	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7157	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7158
7159	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7160	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7161	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7162	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7163	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7164
7165	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7166	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7167
7168	/* FIXME: use matrix-type input source selection */
7169	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7170	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7171	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7172	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7173	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7174	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7175	/* Input mixer2 */
7176	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7177	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7178	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7179	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7180	/* Input mixer3 */
7181	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7182	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7183	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7184	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7185
7186	{ }
7187};
7188
7189static struct hda_verb alc262_hippo_unsol_verbs[] = {
7190	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7191	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7192	{}
7193};
7194
7195static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7196	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7197	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7198	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7199
7200	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7201	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7202	{}
7203};
7204
7205static struct hda_verb alc262_sony_unsol_verbs[] = {
7206	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7207	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7208	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
7209
7210	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7211	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7212};
7213
7214/* mute/unmute internal speaker according to the hp jack and mute state */
7215static void alc262_hippo_automute(struct hda_codec *codec, int force)
7216{
7217	struct alc_spec *spec = codec->spec;
7218	unsigned int mute;
7219
7220	if (force || !spec->sense_updated) {
7221		unsigned int present;
7222		/* need to execute and sync at first */
7223		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7224		present = snd_hda_codec_read(codec, 0x15, 0,
7225				    	 AC_VERB_GET_PIN_SENSE, 0);
7226		spec->jack_present = (present & 0x80000000) != 0;
7227		spec->sense_updated = 1;
7228	}
7229	if (spec->jack_present) {
7230		/* mute internal speaker */
7231		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7232					 0x80, 0x80);
7233		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7234					 0x80, 0x80);
7235	} else {
7236		/* unmute internal speaker if necessary */
7237		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7238		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7239					 0x80, mute & 0x80);
7240		mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
7241		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7242					 0x80, mute & 0x80);
7243	}
7244}
7245
7246/* unsolicited event for HP jack sensing */
7247static void alc262_hippo_unsol_event(struct hda_codec *codec,
7248				       unsigned int res)
7249{
7250	if ((res >> 26) != ALC880_HP_EVENT)
7251		return;
7252	alc262_hippo_automute(codec, 1);
7253}
7254
7255static void alc262_hippo1_automute(struct hda_codec *codec, int force)
7256{
7257	struct alc_spec *spec = codec->spec;
7258	unsigned int mute;
7259
7260	if (force || !spec->sense_updated) {
7261		unsigned int present;
7262		/* need to execute and sync at first */
7263		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7264		present = snd_hda_codec_read(codec, 0x1b, 0,
7265				    	 AC_VERB_GET_PIN_SENSE, 0);
7266		spec->jack_present = (present & 0x80000000) != 0;
7267		spec->sense_updated = 1;
7268	}
7269	if (spec->jack_present) {
7270		/* mute internal speaker */
7271		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7272					 0x80, 0x80);
7273		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7274					 0x80, 0x80);
7275	} else {
7276		/* unmute internal speaker if necessary */
7277		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7278		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7279					 0x80, mute & 0x80);
7280		mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
7281		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7282					 0x80, mute & 0x80);
7283	}
7284}
7285
7286/* unsolicited event for HP jack sensing */
7287static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7288				       unsigned int res)
7289{
7290	if ((res >> 26) != ALC880_HP_EVENT)
7291		return;
7292	alc262_hippo1_automute(codec, 1);
7293}
7294
7295/*
7296 * fujitsu model
7297 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7298 */
7299
7300#define ALC_HP_EVENT	0x37
7301
7302static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7303	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7304	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7305	{}
7306};
7307
7308static struct hda_input_mux alc262_fujitsu_capture_source = {
7309	.num_items = 2,
7310	.items = {
7311		{ "Mic", 0x0 },
7312		{ "CD", 0x4 },
7313	},
7314};
7315
7316static struct hda_input_mux alc262_HP_capture_source = {
7317	.num_items = 5,
7318	.items = {
7319		{ "Mic", 0x0 },
7320		{ "Front Mic", 0x3 },
7321		{ "Line", 0x2 },
7322		{ "CD", 0x4 },
7323		{ "AUX IN", 0x6 },
7324	},
7325};
7326
7327/* mute/unmute internal speaker according to the hp jack and mute state */
7328static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7329{
7330	struct alc_spec *spec = codec->spec;
7331	unsigned int mute;
7332
7333	if (force || !spec->sense_updated) {
7334		unsigned int present;
7335		/* need to execute and sync at first */
7336		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7337		present = snd_hda_codec_read(codec, 0x14, 0,
7338				    	 AC_VERB_GET_PIN_SENSE, 0);
7339		spec->jack_present = (present & 0x80000000) != 0;
7340		spec->sense_updated = 1;
7341	}
7342	if (spec->jack_present) {
7343		/* mute internal speaker */
7344		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7345					 0x80, 0x80);
7346		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7347					 0x80, 0x80);
7348	} else {
7349		/* unmute internal speaker if necessary */
7350		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7351		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7352					 0x80, mute & 0x80);
7353		mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
7354		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7355					 0x80, mute & 0x80);
7356	}
7357}
7358
7359/* unsolicited event for HP jack sensing */
7360static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7361				       unsigned int res)
7362{
7363	if ((res >> 26) != ALC_HP_EVENT)
7364		return;
7365	alc262_fujitsu_automute(codec, 1);
7366}
7367
7368/* bind volumes of both NID 0x0c and 0x0d */
7369static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7370					 struct snd_ctl_elem_value *ucontrol)
7371{
7372	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7373	long *valp = ucontrol->value.integer.value;
7374	int change;
7375
7376	change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7377					  0x7f, valp[0] & 0x7f);
7378	change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7379					   0x7f, valp[1] & 0x7f);
7380	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7381				 0x7f, valp[0] & 0x7f);
7382	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7383				 0x7f, valp[1] & 0x7f);
7384	return change;
7385}
7386
7387/* bind hp and internal speaker mute (with plug check) */
7388static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7389					 struct snd_ctl_elem_value *ucontrol)
7390{
7391	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7392	long *valp = ucontrol->value.integer.value;
7393	int change;
7394
7395	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7396					  0x80, valp[0] ? 0 : 0x80);
7397	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7398					   0x80, valp[1] ? 0 : 0x80);
7399	if (change || codec->in_resume)
7400		alc262_fujitsu_automute(codec, codec->in_resume);
7401	return change;
7402}
7403
7404static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7405	{
7406		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7407		.name = "Master Playback Volume",
7408		.info = snd_hda_mixer_amp_volume_info,
7409		.get = snd_hda_mixer_amp_volume_get,
7410		.put = alc262_fujitsu_master_vol_put,
7411		.tlv = { .c = snd_hda_mixer_amp_tlv },
7412		.private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7413	},
7414	{
7415		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7416		.name = "Master Playback Switch",
7417		.info = snd_hda_mixer_amp_switch_info,
7418		.get = snd_hda_mixer_amp_switch_get,
7419		.put = alc262_fujitsu_master_sw_put,
7420		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7421	},
7422	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7423	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7424	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7425	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7426	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7427	{ } /* end */
7428};
7429
7430/* additional init verbs for Benq laptops */
7431static struct hda_verb alc262_EAPD_verbs[] = {
7432	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7433	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7434	{}
7435};
7436
7437static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7438	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7439	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7440
7441	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7442	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7443	{}
7444};
7445
7446/* add playback controls from the parsed DAC table */
7447static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7448					     const struct auto_pin_cfg *cfg)
7449{
7450	hda_nid_t nid;
7451	int err;
7452
7453	spec->multiout.num_dacs = 1;	/* only use one dac */
7454	spec->multiout.dac_nids = spec->private_dac_nids;
7455	spec->multiout.dac_nids[0] = 2;
7456
7457	nid = cfg->line_out_pins[0];
7458	if (nid) {
7459		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7460				  "Front Playback Volume",
7461				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7462		if (err < 0)
7463			return err;
7464		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7465				  "Front Playback Switch",
7466				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7467		if (err < 0)
7468			return err;
7469	}
7470
7471	nid = cfg->speaker_pins[0];
7472	if (nid) {
7473		if (nid == 0x16) {
7474			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7475					  "Speaker Playback Volume",
7476					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7477							      HDA_OUTPUT));
7478			if (err < 0)
7479				return err;
7480			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7481					  "Speaker Playback Switch",
7482					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7483							      HDA_OUTPUT));
7484			if (err < 0)
7485				return err;
7486		} else {
7487			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7488					  "Speaker Playback Switch",
7489					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7490							      HDA_OUTPUT));
7491			if (err < 0)
7492				return err;
7493		}
7494	}
7495	nid = cfg->hp_pins[0];
7496	if (nid) {
7497		/* spec->multiout.hp_nid = 2; */
7498		if (nid == 0x16) {
7499			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7500					  "Headphone Playback Volume",
7501					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7502							      HDA_OUTPUT));
7503			if (err < 0)
7504				return err;
7505			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7506					  "Headphone Playback Switch",
7507					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7508							      HDA_OUTPUT));
7509			if (err < 0)
7510				return err;
7511		} else {
7512			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7513					  "Headphone Playback Switch",
7514					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7515							      HDA_OUTPUT));
7516			if (err < 0)
7517				return err;
7518		}
7519	}
7520	return 0;
7521}
7522
7523/* identical with ALC880 */
7524#define alc262_auto_create_analog_input_ctls \
7525	alc880_auto_create_analog_input_ctls
7526
7527/*
7528 * generic initialization of ADC, input mixers and output mixers
7529 */
7530static struct hda_verb alc262_volume_init_verbs[] = {
7531	/*
7532	 * Unmute ADC0-2 and set the default input to mic-in
7533	 */
7534	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7535	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7536	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7537	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7538	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7539	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7540
7541	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7542	 * mixer widget
7543	 * Note: PASD motherboards uses the Line In 2 as the input for
7544	 * front panel mic (mic 2)
7545	 */
7546	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7547	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7548	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7549	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7550	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7551	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7552
7553	/*
7554	 * Set up output mixers (0x0c - 0x0f)
7555	 */
7556	/* set vol=0 to output mixers */
7557	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7558	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7559	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7560
7561	/* set up input amps for analog loopback */
7562	/* Amp Indices: DAC = 0, mixer = 1 */
7563	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7564	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7565	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7566	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7567	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7568	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7569
7570	/* FIXME: use matrix-type input source selection */
7571	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7572	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7573	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7574	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7575	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7576	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7577	/* Input mixer2 */
7578	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7579	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7580	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7581	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7582	/* Input mixer3 */
7583	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7584	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7585	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7586	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7587
7588	{ }
7589};
7590
7591static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7592	/*
7593	 * Unmute ADC0-2 and set the default input to mic-in
7594	 */
7595	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7596	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7597	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7598	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7599	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7600	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7601
7602	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7603	 * mixer widget
7604	 * Note: PASD motherboards uses the Line In 2 as the input for
7605	 * front panel mic (mic 2)
7606	 */
7607	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7608	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7609	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7610	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7611	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7612	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7613	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7614        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7615
7616	/*
7617	 * Set up output mixers (0x0c - 0x0e)
7618	 */
7619	/* set vol=0 to output mixers */
7620	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7621	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7622	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7623
7624	/* set up input amps for analog loopback */
7625	/* Amp Indices: DAC = 0, mixer = 1 */
7626	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7627	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7628	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7629	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7630	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7631	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7632
7633	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7634	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7635	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7636
7637	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7638	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7639
7640	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7641	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7642
7643	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7644	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7645        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7646	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7647	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7648
7649	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7650	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7651        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7652	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7653	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7654	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7655
7656
7657	/* FIXME: use matrix-type input source selection */
7658	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7659	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7660	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7661	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7662	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7663	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7664	/* Input mixer2 */
7665	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7666	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7667	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7668	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7669	/* Input mixer3 */
7670	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7671	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7672	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7673	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7674
7675	{ }
7676};
7677
7678static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7679	/*
7680	 * Unmute ADC0-2 and set the default input to mic-in
7681	 */
7682	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7683	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7684	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7685	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7686	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7687	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7688
7689	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7690	 * mixer widget
7691	 * Note: PASD motherboards uses the Line In 2 as the input for front
7692	 * panel mic (mic 2)
7693	 */
7694	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7695	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7696	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7697	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7698	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7699	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7700	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7701	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7702	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7703	/*
7704	 * Set up output mixers (0x0c - 0x0e)
7705	 */
7706	/* set vol=0 to output mixers */
7707	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7708	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7709	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7710
7711	/* set up input amps for analog loopback */
7712	/* Amp Indices: DAC = 0, mixer = 1 */
7713	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7714	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7715	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7716	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7717	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7718	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7719
7720
7721	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
7722	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
7723	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
7724	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
7725	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
7726	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
7727	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
7728
7729	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7730	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7731
7732	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7733	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7734
7735	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7736	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7737	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7738	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7739	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7740	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7741
7742	/* FIXME: use matrix-type input source selection */
7743	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7744	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7745	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7746	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7747	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7748	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7749	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7750        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7751	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7752	/* Input mixer2 */
7753	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7754	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7755	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7756	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7757	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7758        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7759	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7760	/* Input mixer3 */
7761	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7762	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7763	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7764	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7765	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7766        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7767	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7768
7769	{ }
7770};
7771
7772/* pcm configuration: identiacal with ALC880 */
7773#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
7774#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
7775#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
7776#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
7777
7778/*
7779 * BIOS auto configuration
7780 */
7781static int alc262_parse_auto_config(struct hda_codec *codec)
7782{
7783	struct alc_spec *spec = codec->spec;
7784	int err;
7785	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7786
7787	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7788					   alc262_ignore);
7789	if (err < 0)
7790		return err;
7791	if (!spec->autocfg.line_outs)
7792		return 0; /* can't find valid BIOS pin config */
7793	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7794	if (err < 0)
7795		return err;
7796	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7797	if (err < 0)
7798		return err;
7799
7800	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7801
7802	if (spec->autocfg.dig_out_pin)
7803		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7804	if (spec->autocfg.dig_in_pin)
7805		spec->dig_in_nid = ALC262_DIGIN_NID;
7806
7807	if (spec->kctl_alloc)
7808		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7809
7810	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7811	spec->num_mux_defs = 1;
7812	spec->input_mux = &spec->private_imux;
7813
7814	return 1;
7815}
7816
7817#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
7818#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
7819#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
7820
7821
7822/* init callback for auto-configuration model -- overriding the default init */
7823static void alc262_auto_init(struct hda_codec *codec)
7824{
7825	alc262_auto_init_multi_out(codec);
7826	alc262_auto_init_hp_out(codec);
7827	alc262_auto_init_analog_input(codec);
7828}
7829
7830/*
7831 * configuration and preset
7832 */
7833static const char *alc262_models[ALC262_MODEL_LAST] = {
7834	[ALC262_BASIC]		= "basic",
7835	[ALC262_HIPPO]		= "hippo",
7836	[ALC262_HIPPO_1]	= "hippo_1",
7837	[ALC262_FUJITSU]	= "fujitsu",
7838	[ALC262_HP_BPC]		= "hp-bpc",
7839	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7840	[ALC262_BENQ_ED8]	= "benq",
7841	[ALC262_BENQ_T31]	= "benq-t31",
7842	[ALC262_SONY_ASSAMD]	= "sony-assamd",
7843	[ALC262_AUTO]		= "auto",
7844};
7845
7846static struct snd_pci_quirk alc262_cfg_tbl[] = {
7847	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7848	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7849	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7850	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7851	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7852	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7853	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7854	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7855	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7856	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7857	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7858	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7859	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7860	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7861	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7862	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7863	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7864	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7865	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7866	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7867	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7868	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7869	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7870	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7871	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7872	{}
7873};
7874
7875static struct alc_config_preset alc262_presets[] = {
7876	[ALC262_BASIC] = {
7877		.mixers = { alc262_base_mixer },
7878		.init_verbs = { alc262_init_verbs },
7879		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7880		.dac_nids = alc262_dac_nids,
7881		.hp_nid = 0x03,
7882		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7883		.channel_mode = alc262_modes,
7884		.input_mux = &alc262_capture_source,
7885	},
7886	[ALC262_HIPPO] = {
7887		.mixers = { alc262_base_mixer },
7888		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7889		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7890		.dac_nids = alc262_dac_nids,
7891		.hp_nid = 0x03,
7892		.dig_out_nid = ALC262_DIGOUT_NID,
7893		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7894		.channel_mode = alc262_modes,
7895		.input_mux = &alc262_capture_source,
7896		.unsol_event = alc262_hippo_unsol_event,
7897	},
7898	[ALC262_HIPPO_1] = {
7899		.mixers = { alc262_hippo1_mixer },
7900		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7901		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7902		.dac_nids = alc262_dac_nids,
7903		.hp_nid = 0x02,
7904		.dig_out_nid = ALC262_DIGOUT_NID,
7905		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7906		.channel_mode = alc262_modes,
7907		.input_mux = &alc262_capture_source,
7908		.unsol_event = alc262_hippo1_unsol_event,
7909	},
7910	[ALC262_FUJITSU] = {
7911		.mixers = { alc262_fujitsu_mixer },
7912		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7913		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7914		.dac_nids = alc262_dac_nids,
7915		.hp_nid = 0x03,
7916		.dig_out_nid = ALC262_DIGOUT_NID,
7917		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7918		.channel_mode = alc262_modes,
7919		.input_mux = &alc262_fujitsu_capture_source,
7920		.unsol_event = alc262_fujitsu_unsol_event,
7921	},
7922	[ALC262_HP_BPC] = {
7923		.mixers = { alc262_HP_BPC_mixer },
7924		.init_verbs = { alc262_HP_BPC_init_verbs },
7925		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7926		.dac_nids = alc262_dac_nids,
7927		.hp_nid = 0x03,
7928		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7929		.channel_mode = alc262_modes,
7930		.input_mux = &alc262_HP_capture_source,
7931	},
7932	[ALC262_HP_BPC_D7000_WF] = {
7933		.mixers = { alc262_HP_BPC_WildWest_mixer },
7934		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7935		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7936		.dac_nids = alc262_dac_nids,
7937		.hp_nid = 0x03,
7938		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7939		.channel_mode = alc262_modes,
7940		.input_mux = &alc262_HP_capture_source,
7941	},
7942	[ALC262_HP_BPC_D7000_WL] = {
7943		.mixers = { alc262_HP_BPC_WildWest_mixer,
7944			    alc262_HP_BPC_WildWest_option_mixer },
7945		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7946		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7947		.dac_nids = alc262_dac_nids,
7948		.hp_nid = 0x03,
7949		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7950		.channel_mode = alc262_modes,
7951		.input_mux = &alc262_HP_capture_source,
7952	},
7953	[ALC262_BENQ_ED8] = {
7954		.mixers = { alc262_base_mixer },
7955		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
7956		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7957		.dac_nids = alc262_dac_nids,
7958		.hp_nid = 0x03,
7959		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7960		.channel_mode = alc262_modes,
7961		.input_mux = &alc262_capture_source,
7962	},
7963	[ALC262_SONY_ASSAMD] = {
7964		.mixers = { alc262_sony_mixer },
7965		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
7966		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7967		.dac_nids = alc262_dac_nids,
7968		.hp_nid = 0x02,
7969		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7970		.channel_mode = alc262_modes,
7971		.input_mux = &alc262_capture_source,
7972		.unsol_event = alc262_hippo_unsol_event,
7973	},
7974	[ALC262_BENQ_T31] = {
7975		.mixers = { alc262_benq_t31_mixer },
7976		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
7977		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7978		.dac_nids = alc262_dac_nids,
7979		.hp_nid = 0x03,
7980		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7981		.channel_mode = alc262_modes,
7982		.input_mux = &alc262_capture_source,
7983		.unsol_event = alc262_hippo_unsol_event,
7984	},
7985};
7986
7987static int patch_alc262(struct hda_codec *codec)
7988{
7989	struct alc_spec *spec;
7990	int board_config;
7991	int err;
7992
7993	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7994	if (spec == NULL)
7995		return -ENOMEM;
7996
7997	codec->spec = spec;
7998#if 0
7999	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8000	 * under-run
8001	 */
8002	{
8003	int tmp;
8004	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8005	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8006	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8007	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8008	}
8009#endif
8010
8011	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8012						  alc262_models,
8013						  alc262_cfg_tbl);
8014
8015	if (board_config < 0) {
8016		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8017		       "trying auto-probe from BIOS...\n");
8018		board_config = ALC262_AUTO;
8019	}
8020
8021	if (board_config == ALC262_AUTO) {
8022		/* automatic parse from the BIOS config */
8023		err = alc262_parse_auto_config(codec);
8024		if (err < 0) {
8025			alc_free(codec);
8026			return err;
8027		} else if (!err) {
8028			printk(KERN_INFO
8029			       "hda_codec: Cannot set up configuration "
8030			       "from BIOS.  Using base mode...\n");
8031			board_config = ALC262_BASIC;
8032		}
8033	}
8034
8035	if (board_config != ALC262_AUTO)
8036		setup_preset(spec, &alc262_presets[board_config]);
8037
8038	spec->stream_name_analog = "ALC262 Analog";
8039	spec->stream_analog_playback = &alc262_pcm_analog_playback;
8040	spec->stream_analog_capture = &alc262_pcm_analog_capture;
8041
8042	spec->stream_name_digital = "ALC262 Digital";
8043	spec->stream_digital_playback = &alc262_pcm_digital_playback;
8044	spec->stream_digital_capture = &alc262_pcm_digital_capture;
8045
8046	if (!spec->adc_nids && spec->input_mux) {
8047		/* check whether NID 0x07 is valid */
8048		unsigned int wcap = get_wcaps(codec, 0x07);
8049
8050		/* get type */
8051		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8052		if (wcap != AC_WID_AUD_IN) {
8053			spec->adc_nids = alc262_adc_nids_alt;
8054			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8055			spec->mixers[spec->num_mixers] =
8056				alc262_capture_alt_mixer;
8057			spec->num_mixers++;
8058		} else {
8059			spec->adc_nids = alc262_adc_nids;
8060			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8061			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8062			spec->num_mixers++;
8063		}
8064	}
8065
8066	codec->patch_ops = alc_patch_ops;
8067	if (board_config == ALC262_AUTO)
8068		spec->init_hook = alc262_auto_init;
8069
8070	return 0;
8071}
8072
8073/*
8074 *  ALC268 channel source setting (2 channel)
8075 */
8076#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
8077#define alc268_modes		alc260_modes
8078
8079static hda_nid_t alc268_dac_nids[2] = {
8080	/* front, hp */
8081	0x02, 0x03
8082};
8083
8084static hda_nid_t alc268_adc_nids[2] = {
8085	/* ADC0-1 */
8086	0x08, 0x07
8087};
8088
8089static hda_nid_t alc268_adc_nids_alt[1] = {
8090	/* ADC0 */
8091	0x08
8092};
8093
8094static struct snd_kcontrol_new alc268_base_mixer[] = {
8095	/* output mixer control */
8096	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8097	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8098	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8099	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8100	{ }
8101};
8102
8103/*
8104 * generic initialization of ADC, input mixers and output mixers
8105 */
8106static struct hda_verb alc268_base_init_verbs[] = {
8107	/* Unmute DAC0-1 and set vol = 0 */
8108	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8109	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8110	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8111	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8112	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8113	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8114
8115	/*
8116	 * Set up output mixers (0x0c - 0x0e)
8117	 */
8118	/* set vol=0 to output mixers */
8119	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8120	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8121	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8122        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8123
8124	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8125	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8126
8127	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8128	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8129	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8130	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8131	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8132	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8133	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8134	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8135
8136	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8137	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8138	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8139	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8140	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8141	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8142	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8143	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8144
8145	/* FIXME: use matrix-type input source selection */
8146	/* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8147	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8148	/* Input mixer2 */
8149	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8150	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8151	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8152	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8153
8154	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8155	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8156	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8157	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8158	{ }
8159};
8160
8161/*
8162 * generic initialization of ADC, input mixers and output mixers
8163 */
8164static struct hda_verb alc268_volume_init_verbs[] = {
8165	/* set output DAC */
8166	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8167	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8168	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8169	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8170
8171	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8172	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8173	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8174	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8175	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8176
8177	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8178	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8179	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8180	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8181	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8182
8183	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8184	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8185	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8186	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8187
8188	/* set PCBEEP vol = 0 */
8189	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8190
8191	{ }
8192};
8193
8194#define alc268_mux_enum_info alc_mux_enum_info
8195#define alc268_mux_enum_get alc_mux_enum_get
8196
8197static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8198			       struct snd_ctl_elem_value *ucontrol)
8199{
8200	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8201	struct alc_spec *spec = codec->spec;
8202	const struct hda_input_mux *imux = spec->input_mux;
8203	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8204	static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8205	hda_nid_t nid = capture_mixers[adc_idx];
8206	unsigned int *cur_val = &spec->cur_mux[adc_idx];
8207	unsigned int i, idx;
8208
8209	idx = ucontrol->value.enumerated.item[0];
8210	if (idx >= imux->num_items)
8211		idx = imux->num_items - 1;
8212	if (*cur_val == idx && !codec->in_resume)
8213		return 0;
8214	for (i = 0; i < imux->num_items; i++) {
8215		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8216		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8217				    v | (imux->items[i].index << 8));
8218                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
8219				    idx );
8220	}
8221	*cur_val = idx;
8222	return 1;
8223}
8224
8225static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8226	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8227	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8228	{
8229		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8230		/* The multiple "Capture Source" controls confuse alsamixer
8231		 * So call somewhat different..
8232		 * FIXME: the controls appear in the "playback" view!
8233		 */
8234		/* .name = "Capture Source", */
8235		.name = "Input Source",
8236		.count = 1,
8237		.info = alc268_mux_enum_info,
8238		.get = alc268_mux_enum_get,
8239		.put = alc268_mux_enum_put,
8240	},
8241	{ } /* end */
8242};
8243
8244static struct snd_kcontrol_new alc268_capture_mixer[] = {
8245	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8246	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8247	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8248	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8249	{
8250		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8251		/* The multiple "Capture Source" controls confuse alsamixer
8252		 * So call somewhat different..
8253		 * FIXME: the controls appear in the "playback" view!
8254		 */
8255		/* .name = "Capture Source", */
8256		.name = "Input Source",
8257		.count = 2,
8258		.info = alc268_mux_enum_info,
8259		.get = alc268_mux_enum_get,
8260		.put = alc268_mux_enum_put,
8261	},
8262	{ } /* end */
8263};
8264
8265static struct hda_input_mux alc268_capture_source = {
8266	.num_items = 4,
8267	.items = {
8268		{ "Mic", 0x0 },
8269		{ "Front Mic", 0x1 },
8270		{ "Line", 0x2 },
8271		{ "CD", 0x3 },
8272	},
8273};
8274
8275/* create input playback/capture controls for the given pin */
8276static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8277				    const char *ctlname, int idx)
8278{
8279	char name[32];
8280	int err;
8281
8282	sprintf(name, "%s Playback Volume", ctlname);
8283	if (nid == 0x14) {
8284		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8285				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8286						      HDA_OUTPUT));
8287		if (err < 0)
8288			return err;
8289	} else if (nid == 0x15) {
8290		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8291				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8292						      HDA_OUTPUT));
8293		if (err < 0)
8294			return err;
8295	} else
8296		return -1;
8297	sprintf(name, "%s Playback Switch", ctlname);
8298	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8299			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8300	if (err < 0)
8301		return err;
8302	return 0;
8303}
8304
8305/* add playback controls from the parsed DAC table */
8306static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8307					     const struct auto_pin_cfg *cfg)
8308{
8309	hda_nid_t nid;
8310	int err;
8311
8312	spec->multiout.num_dacs = 2;	/* only use one dac */
8313	spec->multiout.dac_nids = spec->private_dac_nids;
8314	spec->multiout.dac_nids[0] = 2;
8315	spec->multiout.dac_nids[1] = 3;
8316
8317	nid = cfg->line_out_pins[0];
8318	if (nid)
8319		alc268_new_analog_output(spec, nid, "Front", 0);
8320
8321	nid = cfg->speaker_pins[0];
8322	if (nid == 0x1d) {
8323		err = add_control(spec, ALC_CTL_WIDGET_VOL,
8324				  "Speaker Playback Volume",
8325				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8326		if (err < 0)
8327			return err;
8328	}
8329	nid = cfg->hp_pins[0];
8330	if (nid)
8331		alc268_new_analog_output(spec, nid, "Headphone", 0);
8332
8333	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8334	if (nid == 0x16) {
8335		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8336				  "Mono Playback Switch",
8337				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8338		if (err < 0)
8339			return err;
8340	}
8341	return 0;
8342}
8343
8344/* create playback/capture controls for input pins */
8345static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8346						const struct auto_pin_cfg *cfg)
8347{
8348	struct hda_input_mux *imux = &spec->private_imux;
8349	int i, idx1;
8350
8351	for (i = 0; i < AUTO_PIN_LAST; i++) {
8352		switch(cfg->input_pins[i]) {
8353		case 0x18:
8354			idx1 = 0;	/* Mic 1 */
8355			break;
8356		case 0x19:
8357			idx1 = 1;	/* Mic 2 */
8358			break;
8359		case 0x1a:
8360			idx1 = 2;	/* Line In */
8361			break;
8362		case 0x1c:
8363			idx1 = 3;	/* CD */
8364			break;
8365		default:
8366			continue;
8367		}
8368		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8369		imux->items[imux->num_items].index = idx1;
8370		imux->num_items++;
8371	}
8372	return 0;
8373}
8374
8375static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8376{
8377	struct alc_spec *spec = codec->spec;
8378	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8379	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8380	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8381	unsigned int	dac_vol1, dac_vol2;
8382
8383	if (speaker_nid) {
8384		snd_hda_codec_write(codec, speaker_nid, 0,
8385				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8386		snd_hda_codec_write(codec, 0x0f, 0,
8387				    AC_VERB_SET_AMP_GAIN_MUTE,
8388				    AMP_IN_UNMUTE(1));
8389		snd_hda_codec_write(codec, 0x10, 0,
8390				    AC_VERB_SET_AMP_GAIN_MUTE,
8391				    AMP_IN_UNMUTE(1));
8392	} else {
8393		snd_hda_codec_write(codec, 0x0f, 0,
8394				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8395		snd_hda_codec_write(codec, 0x10, 0,
8396				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8397	}
8398
8399	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
8400	if (line_nid == 0x14)
8401		dac_vol2 = AMP_OUT_ZERO;
8402	else if (line_nid == 0x15)
8403		dac_vol1 = AMP_OUT_ZERO;
8404	if (hp_nid == 0x14)
8405		dac_vol2 = AMP_OUT_ZERO;
8406	else if (hp_nid == 0x15)
8407		dac_vol1 = AMP_OUT_ZERO;
8408	if (line_nid != 0x16 || hp_nid != 0x16 ||
8409	    spec->autocfg.line_out_pins[1] != 0x16 ||
8410	    spec->autocfg.line_out_pins[2] != 0x16)
8411		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8412
8413	snd_hda_codec_write(codec, 0x02, 0,
8414			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8415	snd_hda_codec_write(codec, 0x03, 0,
8416			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8417}
8418
8419/* pcm configuration: identiacal with ALC880 */
8420#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
8421#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
8422#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
8423
8424/*
8425 * BIOS auto configuration
8426 */
8427static int alc268_parse_auto_config(struct hda_codec *codec)
8428{
8429	struct alc_spec *spec = codec->spec;
8430	int err;
8431	static hda_nid_t alc268_ignore[] = { 0 };
8432
8433	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8434					   alc268_ignore);
8435	if (err < 0)
8436		return err;
8437	if (!spec->autocfg.line_outs)
8438		return 0; /* can't find valid BIOS pin config */
8439
8440	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8441	if (err < 0)
8442		return err;
8443	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8444	if (err < 0)
8445		return err;
8446
8447	spec->multiout.max_channels = 2;
8448
8449	/* digital only support output */
8450	if (spec->autocfg.dig_out_pin)
8451		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8452
8453	if (spec->kctl_alloc)
8454		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8455
8456	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8457	spec->num_mux_defs = 1;
8458	spec->input_mux = &spec->private_imux;
8459
8460	return 1;
8461}
8462
8463#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
8464#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
8465#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
8466
8467/* init callback for auto-configuration model -- overriding the default init */
8468static void alc268_auto_init(struct hda_codec *codec)
8469{
8470	alc268_auto_init_multi_out(codec);
8471	alc268_auto_init_hp_out(codec);
8472	alc268_auto_init_mono_speaker_out(codec);
8473	alc268_auto_init_analog_input(codec);
8474}
8475
8476/*
8477 * configuration and preset
8478 */
8479static const char *alc268_models[ALC268_MODEL_LAST] = {
8480	[ALC268_3ST]		= "3stack",
8481	[ALC268_AUTO]		= "auto",
8482};
8483
8484static struct snd_pci_quirk alc268_cfg_tbl[] = {
8485	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8486	{}
8487};
8488
8489static struct alc_config_preset alc268_presets[] = {
8490	[ALC268_3ST] = {
8491		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8492		.init_verbs = { alc268_base_init_verbs },
8493		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8494		.dac_nids = alc268_dac_nids,
8495                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8496                .adc_nids = alc268_adc_nids_alt,
8497		.hp_nid = 0x03,
8498		.dig_out_nid = ALC268_DIGOUT_NID,
8499		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8500		.channel_mode = alc268_modes,
8501		.input_mux = &alc268_capture_source,
8502	},
8503};
8504
8505static int patch_alc268(struct hda_codec *codec)
8506{
8507	struct alc_spec *spec;
8508	int board_config;
8509	int err;
8510
8511	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8512	if (spec == NULL)
8513		return -ENOMEM;
8514
8515	codec->spec = spec;
8516
8517	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8518						  alc268_models,
8519						  alc268_cfg_tbl);
8520
8521	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8522		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8523		       "trying auto-probe from BIOS...\n");
8524		board_config = ALC268_AUTO;
8525	}
8526
8527	if (board_config == ALC268_AUTO) {
8528		/* automatic parse from the BIOS config */
8529		err = alc268_parse_auto_config(codec);
8530		if (err < 0) {
8531			alc_free(codec);
8532			return err;
8533		} else if (!err) {
8534			printk(KERN_INFO
8535			       "hda_codec: Cannot set up configuration "
8536			       "from BIOS.  Using base mode...\n");
8537			board_config = ALC268_3ST;
8538		}
8539	}
8540
8541	if (board_config != ALC268_AUTO)
8542		setup_preset(spec, &alc268_presets[board_config]);
8543
8544	spec->stream_name_analog = "ALC268 Analog";
8545	spec->stream_analog_playback = &alc268_pcm_analog_playback;
8546	spec->stream_analog_capture = &alc268_pcm_analog_capture;
8547
8548	spec->stream_name_digital = "ALC268 Digital";
8549	spec->stream_digital_playback = &alc268_pcm_digital_playback;
8550
8551	if (board_config == ALC268_AUTO) {
8552		if (!spec->adc_nids && spec->input_mux) {
8553			/* check whether NID 0x07 is valid */
8554			unsigned int wcap = get_wcaps(codec, 0x07);
8555
8556			/* get type */
8557			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8558			if (wcap != AC_WID_AUD_IN) {
8559				spec->adc_nids = alc268_adc_nids_alt;
8560				spec->num_adc_nids =
8561					ARRAY_SIZE(alc268_adc_nids_alt);
8562				spec->mixers[spec->num_mixers] =
8563					alc268_capture_alt_mixer;
8564				spec->num_mixers++;
8565			} else {
8566				spec->adc_nids = alc268_adc_nids;
8567				spec->num_adc_nids =
8568					ARRAY_SIZE(alc268_adc_nids);
8569				spec->mixers[spec->num_mixers] =
8570					alc268_capture_mixer;
8571				spec->num_mixers++;
8572			}
8573		}
8574	}
8575	codec->patch_ops = alc_patch_ops;
8576	if (board_config == ALC268_AUTO)
8577		spec->init_hook = alc268_auto_init;
8578
8579	return 0;
8580}
8581
8582/*
8583 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8584 */
8585
8586/*
8587 * set the path ways for 2 channel output
8588 * need to set the codec line out and mic 1 pin widgets to inputs
8589 */
8590static struct hda_verb alc861_threestack_ch2_init[] = {
8591	/* set pin widget 1Ah (line in) for input */
8592	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8593	/* set pin widget 18h (mic1/2) for input, for mic also enable
8594	 * the vref
8595	 */
8596	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8597
8598	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8599#if 0
8600	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8601	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8602#endif
8603	{ } /* end */
8604};
8605/*
8606 * 6ch mode
8607 * need to set the codec line out and mic 1 pin widgets to outputs
8608 */
8609static struct hda_verb alc861_threestack_ch6_init[] = {
8610	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8611	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8612	/* set pin widget 18h (mic1) for output (CLFE)*/
8613	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8614
8615	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8616	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8617
8618	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8619#if 0
8620	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8621	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8622#endif
8623	{ } /* end */
8624};
8625
8626static struct hda_channel_mode alc861_threestack_modes[2] = {
8627	{ 2, alc861_threestack_ch2_init },
8628	{ 6, alc861_threestack_ch6_init },
8629};
8630/* Set mic1 as input and unmute the mixer */
8631static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8632	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8633	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8634	{ } /* end */
8635};
8636/* Set mic1 as output and mute mixer */
8637static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8638	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8639	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8640	{ } /* end */
8641};
8642
8643static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8644	{ 2, alc861_uniwill_m31_ch2_init },
8645	{ 4, alc861_uniwill_m31_ch4_init },
8646};
8647
8648/* Set mic1 and line-in as input and unmute the mixer */
8649static struct hda_verb alc861_asus_ch2_init[] = {
8650	/* set pin widget 1Ah (line in) for input */
8651	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8652	/* set pin widget 18h (mic1/2) for input, for mic also enable
8653	 * the vref
8654	 */
8655	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8656
8657	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8658#if 0
8659	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8660	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8661#endif
8662	{ } /* end */
8663};
8664/* Set mic1 nad line-in as output and mute mixer */
8665static struct hda_verb alc861_asus_ch6_init[] = {
8666	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8667	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8668	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8669	/* set pin widget 18h (mic1) for output (CLFE)*/
8670	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8671	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8672	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8673	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8674
8675	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8676#if 0
8677	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8678	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8679#endif
8680	{ } /* end */
8681};
8682
8683static struct hda_channel_mode alc861_asus_modes[2] = {
8684	{ 2, alc861_asus_ch2_init },
8685	{ 6, alc861_asus_ch6_init },
8686};
8687
8688/* patch-ALC861 */
8689
8690static struct snd_kcontrol_new alc861_base_mixer[] = {
8691        /* output mixer control */
8692	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8693	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8694	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8695	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8696	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8697
8698        /*Input mixer control */
8699	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8700	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8701	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8702	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8703	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8704	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8705	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8706	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8707	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8708	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8709
8710        /* Capture mixer control */
8711	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8712	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8713	{
8714		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8715		.name = "Capture Source",
8716		.count = 1,
8717		.info = alc_mux_enum_info,
8718		.get = alc_mux_enum_get,
8719		.put = alc_mux_enum_put,
8720	},
8721	{ } /* end */
8722};
8723
8724static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8725        /* output mixer control */
8726	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8727	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8728	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8729	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8730	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8731
8732	/* Input mixer control */
8733	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8734	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8735	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8736	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8737	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8738	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8739	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8740	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8741	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8742	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8743
8744	/* Capture mixer control */
8745	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8746	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8747	{
8748		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8749		.name = "Capture Source",
8750		.count = 1,
8751		.info = alc_mux_enum_info,
8752		.get = alc_mux_enum_get,
8753		.put = alc_mux_enum_put,
8754	},
8755	{
8756		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8757		.name = "Channel Mode",
8758		.info = alc_ch_mode_info,
8759		.get = alc_ch_mode_get,
8760		.put = alc_ch_mode_put,
8761                .private_value = ARRAY_SIZE(alc861_threestack_modes),
8762	},
8763	{ } /* end */
8764};
8765
8766static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8767        /* output mixer control */
8768	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8769	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8770	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8771
8772        /*Capture mixer control */
8773	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8774	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8775	{
8776		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8777		.name = "Capture Source",
8778		.count = 1,
8779		.info = alc_mux_enum_info,
8780		.get = alc_mux_enum_get,
8781		.put = alc_mux_enum_put,
8782	},
8783
8784	{ } /* end */
8785};
8786
8787static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8788        /* output mixer control */
8789	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8790	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8791	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8792	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8793	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8794
8795	/* Input mixer control */
8796	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8797	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8798	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8799	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8800	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8801	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8802	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8803	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8804	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8805	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8806
8807	/* Capture mixer control */
8808	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8809	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8810	{
8811		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8812		.name = "Capture Source",
8813		.count = 1,
8814		.info = alc_mux_enum_info,
8815		.get = alc_mux_enum_get,
8816		.put = alc_mux_enum_put,
8817	},
8818	{
8819		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8820		.name = "Channel Mode",
8821		.info = alc_ch_mode_info,
8822		.get = alc_ch_mode_get,
8823		.put = alc_ch_mode_put,
8824                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8825	},
8826	{ } /* end */
8827};
8828
8829static struct snd_kcontrol_new alc861_asus_mixer[] = {
8830        /* output mixer control */
8831	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8832	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8833	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8834	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8835	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8836
8837	/* Input mixer control */
8838	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8839	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8840	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8841	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8842	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8843	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8844	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8845	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8846	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8847	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8848
8849	/* Capture mixer control */
8850	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8851	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8852	{
8853		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8854		.name = "Capture Source",
8855		.count = 1,
8856		.info = alc_mux_enum_info,
8857		.get = alc_mux_enum_get,
8858		.put = alc_mux_enum_put,
8859	},
8860	{
8861		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8862		.name = "Channel Mode",
8863		.info = alc_ch_mode_info,
8864		.get = alc_ch_mode_get,
8865		.put = alc_ch_mode_put,
8866                .private_value = ARRAY_SIZE(alc861_asus_modes),
8867	},
8868	{ }
8869};
8870
8871/* additional mixer */
8872static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
8873	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8874	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8875	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
8876	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
8877	{ }
8878};
8879
8880/*
8881 * generic initialization of ADC, input mixers and output mixers
8882 */
8883static struct hda_verb alc861_base_init_verbs[] = {
8884	/*
8885	 * Unmute ADC0 and set the default input to mic-in
8886	 */
8887	/* port-A for surround (rear panel) */
8888	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8889	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
8890	/* port-B for mic-in (rear panel) with vref */
8891	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8892	/* port-C for line-in (rear panel) */
8893	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8894	/* port-D for Front */
8895	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8896	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8897	/* port-E for HP out (front panel) */
8898	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8899	/* route front PCM to HP */
8900	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8901	/* port-F for mic-in (front panel) with vref */
8902	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8903	/* port-G for CLFE (rear panel) */
8904	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8905	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8906	/* port-H for side (rear panel) */
8907	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8908	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8909	/* CD-in */
8910	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8911	/* route front mic to ADC1*/
8912	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8913	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8914
8915	/* Unmute DAC0~3 & spdif out*/
8916	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8917	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8918	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8919	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8920	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8921
8922	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8923	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8924        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8925	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8926        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8927
8928	/* Unmute Stereo Mixer 15 */
8929	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8930	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8931	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8932	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8933
8934	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8935	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8936	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8937	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8938	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8939	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8940	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8941	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8942	/* hp used DAC 3 (Front) */
8943	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8944        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8945
8946	{ }
8947};
8948
8949static struct hda_verb alc861_threestack_init_verbs[] = {
8950	/*
8951	 * Unmute ADC0 and set the default input to mic-in
8952	 */
8953	/* port-A for surround (rear panel) */
8954	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8955	/* port-B for mic-in (rear panel) with vref */
8956	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8957	/* port-C for line-in (rear panel) */
8958	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8959	/* port-D for Front */
8960	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8961	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8962	/* port-E for HP out (front panel) */
8963	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8964	/* route front PCM to HP */
8965	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8966	/* port-F for mic-in (front panel) with vref */
8967	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8968	/* port-G for CLFE (rear panel) */
8969	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8970	/* port-H for side (rear panel) */
8971	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8972	/* CD-in */
8973	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8974	/* route front mic to ADC1*/
8975	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8976	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8977	/* Unmute DAC0~3 & spdif out*/
8978	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8979	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8980	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8981	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8982	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8983
8984	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8985	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8986        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8987	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8988        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8989
8990	/* Unmute Stereo Mixer 15 */
8991	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8992	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8993	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8994	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8995
8996	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8997	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8998	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8999	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9000	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9001	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9002	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9003	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9004	/* hp used DAC 3 (Front) */
9005	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9006        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9007	{ }
9008};
9009
9010static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9011	/*
9012	 * Unmute ADC0 and set the default input to mic-in
9013	 */
9014	/* port-A for surround (rear panel) */
9015	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9016	/* port-B for mic-in (rear panel) with vref */
9017	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9018	/* port-C for line-in (rear panel) */
9019	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9020	/* port-D for Front */
9021	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9022	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9023	/* port-E for HP out (front panel) */
9024	/* this has to be set to VREF80 */
9025	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9026	/* route front PCM to HP */
9027	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9028	/* port-F for mic-in (front panel) with vref */
9029	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9030	/* port-G for CLFE (rear panel) */
9031	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9032	/* port-H for side (rear panel) */
9033	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9034	/* CD-in */
9035	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9036	/* route front mic to ADC1*/
9037	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9038	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9039	/* Unmute DAC0~3 & spdif out*/
9040	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9041	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9042	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9043	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9044	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9045
9046	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9047	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9048        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9049	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9050        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9051
9052	/* Unmute Stereo Mixer 15 */
9053	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9054	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9055	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9056	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9057
9058	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9059	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9060	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9061	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9062	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9063	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9064	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066	/* hp used DAC 3 (Front) */
9067	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9068        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9069	{ }
9070};
9071
9072static struct hda_verb alc861_asus_init_verbs[] = {
9073	/*
9074	 * Unmute ADC0 and set the default input to mic-in
9075	 */
9076	/* port-A for surround (rear panel)
9077	 * according to codec#0 this is the HP jack
9078	 */
9079	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9080	/* route front PCM to HP */
9081	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9082	/* port-B for mic-in (rear panel) with vref */
9083	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9084	/* port-C for line-in (rear panel) */
9085	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9086	/* port-D for Front */
9087	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9088	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9089	/* port-E for HP out (front panel) */
9090	/* this has to be set to VREF80 */
9091	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9092	/* route front PCM to HP */
9093	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9094	/* port-F for mic-in (front panel) with vref */
9095	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9096	/* port-G for CLFE (rear panel) */
9097	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9098	/* port-H for side (rear panel) */
9099	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9100	/* CD-in */
9101	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9102	/* route front mic to ADC1*/
9103	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9104	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9105	/* Unmute DAC0~3 & spdif out*/
9106	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9107	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9108	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9109	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9110	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9111	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9112	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9113        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9114	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9115        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9116
9117	/* Unmute Stereo Mixer 15 */
9118	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9119	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9120	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9121	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9122
9123	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9124	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9125	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9126	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9127	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9128	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9129	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9130	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9131	/* hp used DAC 3 (Front) */
9132	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9133	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9134	{ }
9135};
9136
9137/* additional init verbs for ASUS laptops */
9138static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9139	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9140	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9141	{ }
9142};
9143
9144/*
9145 * generic initialization of ADC, input mixers and output mixers
9146 */
9147static struct hda_verb alc861_auto_init_verbs[] = {
9148	/*
9149	 * Unmute ADC0 and set the default input to mic-in
9150	 */
9151	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9152	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9153
9154	/* Unmute DAC0~3 & spdif out*/
9155	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9156	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9157	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9158	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9159	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9160
9161	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9162	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9163	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9164	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9165	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9166
9167	/* Unmute Stereo Mixer 15 */
9168	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9169	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9170	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9171	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9172
9173	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9174	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9175	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9176	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9177	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9178	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9179	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9180	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9181
9182	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9183	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9184	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9185	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9186	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9187	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9188	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9189	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9190
9191	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
9192
9193	{ }
9194};
9195
9196static struct hda_verb alc861_toshiba_init_verbs[] = {
9197	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9198
9199	{ }
9200};
9201
9202/* toggle speaker-output according to the hp-jack state */
9203static void alc861_toshiba_automute(struct hda_codec *codec)
9204{
9205	unsigned int present;
9206
9207	present = snd_hda_codec_read(codec, 0x0f, 0,
9208				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9209	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
9210				 0x80, present ? 0x80 : 0);
9211	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
9212				 0x80, present ? 0x80 : 0);
9213	snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
9214				 0x80, present ? 0 : 0x80);
9215	snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
9216				 0x80, present ? 0 : 0x80);
9217}
9218
9219static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9220				       unsigned int res)
9221{
9222	if ((res >> 26) == ALC880_HP_EVENT)
9223		alc861_toshiba_automute(codec);
9224}
9225
9226/* pcm configuration: identiacal with ALC880 */
9227#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
9228#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
9229#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
9230#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
9231
9232
9233#define ALC861_DIGOUT_NID	0x07
9234
9235static struct hda_channel_mode alc861_8ch_modes[1] = {
9236	{ 8, NULL }
9237};
9238
9239static hda_nid_t alc861_dac_nids[4] = {
9240	/* front, surround, clfe, side */
9241	0x03, 0x06, 0x05, 0x04
9242};
9243
9244static hda_nid_t alc660_dac_nids[3] = {
9245	/* front, clfe, surround */
9246	0x03, 0x05, 0x06
9247};
9248
9249static hda_nid_t alc861_adc_nids[1] = {
9250	/* ADC0-2 */
9251	0x08,
9252};
9253
9254static struct hda_input_mux alc861_capture_source = {
9255	.num_items = 5,
9256	.items = {
9257		{ "Mic", 0x0 },
9258		{ "Front Mic", 0x3 },
9259		{ "Line", 0x1 },
9260		{ "CD", 0x4 },
9261		{ "Mixer", 0x5 },
9262	},
9263};
9264
9265/* fill in the dac_nids table from the parsed pin configuration */
9266static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9267				     const struct auto_pin_cfg *cfg)
9268{
9269	int i;
9270	hda_nid_t nid;
9271
9272	spec->multiout.dac_nids = spec->private_dac_nids;
9273	for (i = 0; i < cfg->line_outs; i++) {
9274		nid = cfg->line_out_pins[i];
9275		if (nid) {
9276			if (i >= ARRAY_SIZE(alc861_dac_nids))
9277				continue;
9278			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9279		}
9280	}
9281	spec->multiout.num_dacs = cfg->line_outs;
9282	return 0;
9283}
9284
9285/* add playback controls from the parsed DAC table */
9286static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9287					     const struct auto_pin_cfg *cfg)
9288{
9289	char name[32];
9290	static const char *chname[4] = {
9291		"Front", "Surround", NULL /*CLFE*/, "Side"
9292	};
9293	hda_nid_t nid;
9294	int i, idx, err;
9295
9296	for (i = 0; i < cfg->line_outs; i++) {
9297		nid = spec->multiout.dac_nids[i];
9298		if (!nid)
9299			continue;
9300		if (nid == 0x05) {
9301			/* Center/LFE */
9302			err = add_control(spec, ALC_CTL_BIND_MUTE,
9303					  "Center Playback Switch",
9304					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9305							      HDA_OUTPUT));
9306			if (err < 0)
9307				return err;
9308			err = add_control(spec, ALC_CTL_BIND_MUTE,
9309					  "LFE Playback Switch",
9310					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9311							      HDA_OUTPUT));
9312			if (err < 0)
9313				return err;
9314		} else {
9315			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9316			     idx++)
9317				if (nid == alc861_dac_nids[idx])
9318					break;
9319			sprintf(name, "%s Playback Switch", chname[idx]);
9320			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9321					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9322							      HDA_OUTPUT));
9323			if (err < 0)
9324				return err;
9325		}
9326	}
9327	return 0;
9328}
9329
9330static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9331{
9332	int err;
9333	hda_nid_t nid;
9334
9335	if (!pin)
9336		return 0;
9337
9338	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9339		nid = 0x03;
9340		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9341				  "Headphone Playback Switch",
9342				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9343		if (err < 0)
9344			return err;
9345		spec->multiout.hp_nid = nid;
9346	}
9347	return 0;
9348}
9349
9350/* create playback/capture controls for input pins */
9351static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9352						const struct auto_pin_cfg *cfg)
9353{
9354	struct hda_input_mux *imux = &spec->private_imux;
9355	int i, err, idx, idx1;
9356
9357	for (i = 0; i < AUTO_PIN_LAST; i++) {
9358		switch (cfg->input_pins[i]) {
9359		case 0x0c:
9360			idx1 = 1;
9361			idx = 2;	/* Line In */
9362			break;
9363		case 0x0f:
9364			idx1 = 2;
9365			idx = 2;	/* Line In */
9366			break;
9367		case 0x0d:
9368			idx1 = 0;
9369			idx = 1;	/* Mic In */
9370			break;
9371		case 0x10:
9372			idx1 = 3;
9373			idx = 1;	/* Mic In */
9374			break;
9375		case 0x11:
9376			idx1 = 4;
9377			idx = 0;	/* CD */
9378			break;
9379		default:
9380			continue;
9381		}
9382
9383		err = new_analog_input(spec, cfg->input_pins[i],
9384				       auto_pin_cfg_labels[i], idx, 0x15);
9385		if (err < 0)
9386			return err;
9387
9388		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9389		imux->items[imux->num_items].index = idx1;
9390		imux->num_items++;
9391	}
9392	return 0;
9393}
9394
9395static struct snd_kcontrol_new alc861_capture_mixer[] = {
9396	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9397	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9398
9399	{
9400		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9401		/* The multiple "Capture Source" controls confuse alsamixer
9402		 * So call somewhat different..
9403		 *FIXME: the controls appear in the "playback" view!
9404		 */
9405		/* .name = "Capture Source", */
9406		.name = "Input Source",
9407		.count = 1,
9408		.info = alc_mux_enum_info,
9409		.get = alc_mux_enum_get,
9410		.put = alc_mux_enum_put,
9411	},
9412	{ } /* end */
9413};
9414
9415static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9416					      hda_nid_t nid,
9417					      int pin_type, int dac_idx)
9418{
9419	/* set as output */
9420
9421	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9422			    pin_type);
9423	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9424			    AMP_OUT_UNMUTE);
9425
9426}
9427
9428static void alc861_auto_init_multi_out(struct hda_codec *codec)
9429{
9430	struct alc_spec *spec = codec->spec;
9431	int i;
9432
9433	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9434	for (i = 0; i < spec->autocfg.line_outs; i++) {
9435		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9436		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9437		if (nid)
9438			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9439							  spec->multiout.dac_nids[i]);
9440	}
9441}
9442
9443static void alc861_auto_init_hp_out(struct hda_codec *codec)
9444{
9445	struct alc_spec *spec = codec->spec;
9446	hda_nid_t pin;
9447
9448	pin = spec->autocfg.hp_pins[0];
9449	if (pin) /* connect to front */
9450		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9451						  spec->multiout.dac_nids[0]);
9452}
9453
9454static void alc861_auto_init_analog_input(struct hda_codec *codec)
9455{
9456	struct alc_spec *spec = codec->spec;
9457	int i;
9458
9459	for (i = 0; i < AUTO_PIN_LAST; i++) {
9460		hda_nid_t nid = spec->autocfg.input_pins[i];
9461		if (nid >= 0x0c && nid <= 0x11) {
9462			snd_hda_codec_write(codec, nid, 0,
9463					    AC_VERB_SET_PIN_WIDGET_CONTROL,
9464					    i <= AUTO_PIN_FRONT_MIC ?
9465					    PIN_VREF80 : PIN_IN);
9466		}
9467	}
9468}
9469
9470/* parse the BIOS configuration and set up the alc_spec */
9471/* return 1 if successful, 0 if the proper config is not found,
9472 * or a negative error code
9473 */
9474static int alc861_parse_auto_config(struct hda_codec *codec)
9475{
9476	struct alc_spec *spec = codec->spec;
9477	int err;
9478	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9479
9480	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9481					   alc861_ignore);
9482	if (err < 0)
9483		return err;
9484	if (!spec->autocfg.line_outs)
9485		return 0; /* can't find valid BIOS pin config */
9486
9487	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9488	if (err < 0)
9489		return err;
9490	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9491	if (err < 0)
9492		return err;
9493	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9494	if (err < 0)
9495		return err;
9496	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9497	if (err < 0)
9498		return err;
9499
9500	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9501
9502	if (spec->autocfg.dig_out_pin)
9503		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9504
9505	if (spec->kctl_alloc)
9506		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9507
9508	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9509
9510	spec->num_mux_defs = 1;
9511	spec->input_mux = &spec->private_imux;
9512
9513	spec->adc_nids = alc861_adc_nids;
9514	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9515	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9516	spec->num_mixers++;
9517
9518	return 1;
9519}
9520
9521/* additional initialization for auto-configuration model */
9522static void alc861_auto_init(struct hda_codec *codec)
9523{
9524	alc861_auto_init_multi_out(codec);
9525	alc861_auto_init_hp_out(codec);
9526	alc861_auto_init_analog_input(codec);
9527}
9528
9529
9530/*
9531 * configuration and preset
9532 */
9533static const char *alc861_models[ALC861_MODEL_LAST] = {
9534	[ALC861_3ST]		= "3stack",
9535	[ALC660_3ST]		= "3stack-660",
9536	[ALC861_3ST_DIG]	= "3stack-dig",
9537	[ALC861_6ST_DIG]	= "6stack-dig",
9538	[ALC861_UNIWILL_M31]	= "uniwill-m31",
9539	[ALC861_TOSHIBA]	= "toshiba",
9540	[ALC861_ASUS]		= "asus",
9541	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
9542	[ALC861_AUTO]		= "auto",
9543};
9544
9545static struct snd_pci_quirk alc861_cfg_tbl[] = {
9546	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9547	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9548	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9549	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9550	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9551	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9552	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9553	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9554	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9555	 *        Any other models that need this preset?
9556	 */
9557	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9558	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9559	SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9560	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9561	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9562	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9563	{}
9564};
9565
9566static struct alc_config_preset alc861_presets[] = {
9567	[ALC861_3ST] = {
9568		.mixers = { alc861_3ST_mixer },
9569		.init_verbs = { alc861_threestack_init_verbs },
9570		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9571		.dac_nids = alc861_dac_nids,
9572		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9573		.channel_mode = alc861_threestack_modes,
9574		.need_dac_fix = 1,
9575		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9576		.adc_nids = alc861_adc_nids,
9577		.input_mux = &alc861_capture_source,
9578	},
9579	[ALC861_3ST_DIG] = {
9580		.mixers = { alc861_base_mixer },
9581		.init_verbs = { alc861_threestack_init_verbs },
9582		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9583		.dac_nids = alc861_dac_nids,
9584		.dig_out_nid = ALC861_DIGOUT_NID,
9585		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9586		.channel_mode = alc861_threestack_modes,
9587		.need_dac_fix = 1,
9588		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9589		.adc_nids = alc861_adc_nids,
9590		.input_mux = &alc861_capture_source,
9591	},
9592	[ALC861_6ST_DIG] = {
9593		.mixers = { alc861_base_mixer },
9594		.init_verbs = { alc861_base_init_verbs },
9595		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9596		.dac_nids = alc861_dac_nids,
9597		.dig_out_nid = ALC861_DIGOUT_NID,
9598		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9599		.channel_mode = alc861_8ch_modes,
9600		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9601		.adc_nids = alc861_adc_nids,
9602		.input_mux = &alc861_capture_source,
9603	},
9604	[ALC660_3ST] = {
9605		.mixers = { alc861_3ST_mixer },
9606		.init_verbs = { alc861_threestack_init_verbs },
9607		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
9608		.dac_nids = alc660_dac_nids,
9609		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9610		.channel_mode = alc861_threestack_modes,
9611		.need_dac_fix = 1,
9612		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9613		.adc_nids = alc861_adc_nids,
9614		.input_mux = &alc861_capture_source,
9615	},
9616	[ALC861_UNIWILL_M31] = {
9617		.mixers = { alc861_uniwill_m31_mixer },
9618		.init_verbs = { alc861_uniwill_m31_init_verbs },
9619		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9620		.dac_nids = alc861_dac_nids,
9621		.dig_out_nid = ALC861_DIGOUT_NID,
9622		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9623		.channel_mode = alc861_uniwill_m31_modes,
9624		.need_dac_fix = 1,
9625		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9626		.adc_nids = alc861_adc_nids,
9627		.input_mux = &alc861_capture_source,
9628	},
9629	[ALC861_TOSHIBA] = {
9630		.mixers = { alc861_toshiba_mixer },
9631		.init_verbs = { alc861_base_init_verbs,
9632				alc861_toshiba_init_verbs },
9633		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9634		.dac_nids = alc861_dac_nids,
9635		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9636		.channel_mode = alc883_3ST_2ch_modes,
9637		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9638		.adc_nids = alc861_adc_nids,
9639		.input_mux = &alc861_capture_source,
9640		.unsol_event = alc861_toshiba_unsol_event,
9641		.init_hook = alc861_toshiba_automute,
9642	},
9643	[ALC861_ASUS] = {
9644		.mixers = { alc861_asus_mixer },
9645		.init_verbs = { alc861_asus_init_verbs },
9646		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9647		.dac_nids = alc861_dac_nids,
9648		.dig_out_nid = ALC861_DIGOUT_NID,
9649		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9650		.channel_mode = alc861_asus_modes,
9651		.need_dac_fix = 1,
9652		.hp_nid = 0x06,
9653		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9654		.adc_nids = alc861_adc_nids,
9655		.input_mux = &alc861_capture_source,
9656	},
9657	[ALC861_ASUS_LAPTOP] = {
9658		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9659		.init_verbs = { alc861_asus_init_verbs,
9660				alc861_asus_laptop_init_verbs },
9661		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9662		.dac_nids = alc861_dac_nids,
9663		.dig_out_nid = ALC861_DIGOUT_NID,
9664		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9665		.channel_mode = alc883_3ST_2ch_modes,
9666		.need_dac_fix = 1,
9667		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9668		.adc_nids = alc861_adc_nids,
9669		.input_mux = &alc861_capture_source,
9670	},
9671};
9672
9673
9674static int patch_alc861(struct hda_codec *codec)
9675{
9676	struct alc_spec *spec;
9677	int board_config;
9678	int err;
9679
9680	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9681	if (spec == NULL)
9682		return -ENOMEM;
9683
9684	codec->spec = spec;
9685
9686        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9687						  alc861_models,
9688						  alc861_cfg_tbl);
9689
9690	if (board_config < 0) {
9691		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9692		       "trying auto-probe from BIOS...\n");
9693		board_config = ALC861_AUTO;
9694	}
9695
9696	if (board_config == ALC861_AUTO) {
9697		/* automatic parse from the BIOS config */
9698		err = alc861_parse_auto_config(codec);
9699		if (err < 0) {
9700			alc_free(codec);
9701			return err;
9702		} else if (!err) {
9703			printk(KERN_INFO
9704			       "hda_codec: Cannot set up configuration "
9705			       "from BIOS.  Using base mode...\n");
9706		   board_config = ALC861_3ST_DIG;
9707		}
9708	}
9709
9710	if (board_config != ALC861_AUTO)
9711		setup_preset(spec, &alc861_presets[board_config]);
9712
9713	spec->stream_name_analog = "ALC861 Analog";
9714	spec->stream_analog_playback = &alc861_pcm_analog_playback;
9715	spec->stream_analog_capture = &alc861_pcm_analog_capture;
9716
9717	spec->stream_name_digital = "ALC861 Digital";
9718	spec->stream_digital_playback = &alc861_pcm_digital_playback;
9719	spec->stream_digital_capture = &alc861_pcm_digital_capture;
9720
9721	codec->patch_ops = alc_patch_ops;
9722	if (board_config == ALC861_AUTO)
9723		spec->init_hook = alc861_auto_init;
9724
9725	return 0;
9726}
9727
9728/*
9729 * ALC861-VD support
9730 *
9731 * Based on ALC882
9732 *
9733 * In addition, an independent DAC
9734 */
9735#define ALC861VD_DIGOUT_NID	0x06
9736
9737static hda_nid_t alc861vd_dac_nids[4] = {
9738	/* front, surr, clfe, side surr */
9739	0x02, 0x03, 0x04, 0x05
9740};
9741
9742/* dac_nids for ALC660vd are in a different order - according to
9743 * Realtek's driver.
9744 * This should probably tesult in a different mixer for 6stack models
9745 * of ALC660vd codecs, but for now there is only 3stack mixer
9746 * - and it is the same as in 861vd.
9747 * adc_nids in ALC660vd are (is) the same as in 861vd
9748 */
9749static hda_nid_t alc660vd_dac_nids[3] = {
9750	/* front, rear, clfe, rear_surr */
9751	0x02, 0x04, 0x03
9752};
9753
9754static hda_nid_t alc861vd_adc_nids[1] = {
9755	/* ADC0 */
9756	0x09,
9757};
9758
9759/* input MUX */
9760/* FIXME: should be a matrix-type input source selection */
9761static struct hda_input_mux alc861vd_capture_source = {
9762	.num_items = 4,
9763	.items = {
9764		{ "Mic", 0x0 },
9765		{ "Front Mic", 0x1 },
9766		{ "Line", 0x2 },
9767		{ "CD", 0x4 },
9768	},
9769};
9770
9771static struct hda_input_mux alc861vd_dallas_capture_source = {
9772	.num_items = 3,
9773	.items = {
9774		{ "Front Mic", 0x0 },
9775		{ "ATAPI Mic", 0x1 },
9776		{ "Line In", 0x5 },
9777	},
9778};
9779
9780#define alc861vd_mux_enum_info alc_mux_enum_info
9781#define alc861vd_mux_enum_get alc_mux_enum_get
9782
9783static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9784				struct snd_ctl_elem_value *ucontrol)
9785{
9786	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9787	struct alc_spec *spec = codec->spec;
9788	const struct hda_input_mux *imux = spec->input_mux;
9789	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9790	static hda_nid_t capture_mixers[1] = { 0x22 };
9791	hda_nid_t nid = capture_mixers[adc_idx];
9792	unsigned int *cur_val = &spec->cur_mux[adc_idx];
9793	unsigned int i, idx;
9794
9795	idx = ucontrol->value.enumerated.item[0];
9796	if (idx >= imux->num_items)
9797		idx = imux->num_items - 1;
9798	if (*cur_val == idx && !codec->in_resume)
9799		return 0;
9800	for (i = 0; i < imux->num_items; i++) {
9801		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
9802		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9803				    v | (imux->items[i].index << 8));
9804	}
9805	*cur_val = idx;
9806	return 1;
9807}
9808
9809/*
9810 * 2ch mode
9811 */
9812static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9813	{ 2, NULL }
9814};
9815
9816/*
9817 * 6ch mode
9818 */
9819static struct hda_verb alc861vd_6stack_ch6_init[] = {
9820	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9821	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9822	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9823	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9824	{ } /* end */
9825};
9826
9827/*
9828 * 8ch mode
9829 */
9830static struct hda_verb alc861vd_6stack_ch8_init[] = {
9831	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9832	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9833	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9834	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9835	{ } /* end */
9836};
9837
9838static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9839	{ 6, alc861vd_6stack_ch6_init },
9840	{ 8, alc861vd_6stack_ch8_init },
9841};
9842
9843static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9844	{
9845		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9846		.name = "Channel Mode",
9847		.info = alc_ch_mode_info,
9848		.get = alc_ch_mode_get,
9849		.put = alc_ch_mode_put,
9850	},
9851	{ } /* end */
9852};
9853
9854static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9855	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9856	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9857
9858	{
9859		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9860		/* The multiple "Capture Source" controls confuse alsamixer
9861		 * So call somewhat different..
9862		 *FIXME: the controls appear in the "playback" view!
9863		 */
9864		/* .name = "Capture Source", */
9865		.name = "Input Source",
9866		.count = 1,
9867		.info = alc861vd_mux_enum_info,
9868		.get = alc861vd_mux_enum_get,
9869		.put = alc861vd_mux_enum_put,
9870	},
9871	{ } /* end */
9872};
9873
9874/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9875 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9876 */
9877static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
9878	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9879	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9880
9881	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9882	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9883
9884	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9885				HDA_OUTPUT),
9886	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9887				HDA_OUTPUT),
9888	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9889	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9890
9891	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
9892	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9893
9894	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9895
9896	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9897	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9898	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9899
9900	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9901	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9902	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9903
9904	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9905	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9906
9907	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9908	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9909
9910	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9911	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9912
9913	{ } /* end */
9914};
9915
9916static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
9917	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9918	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9919
9920	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9921
9922	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9923	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9924	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9925
9926	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9927	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9928	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9929
9930	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9931	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9932
9933	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9934	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9935
9936	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9937	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9938
9939	{ } /* end */
9940};
9941
9942static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
9943	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9944	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
9945	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9946
9947	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9948
9949	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9950	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9951	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9952
9953	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9954	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9955	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9956
9957	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9958	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9959
9960	{ } /* end */
9961};
9962
9963/* Pin assignment: Front=0x14, HP = 0x15,
9964 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
9965 */
9966static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
9967	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9968	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9969	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9970	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
9971	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9972	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9973	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9974	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9975	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
9976	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
9977	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9978	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9979	{
9980		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9981		/* .name = "Capture Source", */
9982		.name = "Input Source",
9983		.count = 1,
9984		.info = alc882_mux_enum_info,
9985		.get = alc882_mux_enum_get,
9986		.put = alc882_mux_enum_put,
9987	},
9988	{ } /* end */
9989};
9990
9991/*
9992 * generic initialization of ADC, input mixers and output mixers
9993 */
9994static struct hda_verb alc861vd_volume_init_verbs[] = {
9995	/*
9996	 * Unmute ADC0 and set the default input to mic-in
9997	 */
9998	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9999	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10000
10001	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10002	 * the analog-loopback mixer widget
10003	 */
10004	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10005	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10006	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10007	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10008	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10009	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10010
10011	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10012	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10013	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10014	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10015	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10016
10017	/*
10018	 * Set up output mixers (0x02 - 0x05)
10019	 */
10020	/* set vol=0 to output mixers */
10021	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10022	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10023	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10024	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10025
10026	/* set up input amps for analog loopback */
10027	/* Amp Indices: DAC = 0, mixer = 1 */
10028	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10029	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10030	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10031	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10032	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10033	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10034	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10035	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10036
10037	{ }
10038};
10039
10040/*
10041 * 3-stack pin configuration:
10042 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10043 */
10044static struct hda_verb alc861vd_3stack_init_verbs[] = {
10045	/*
10046	 * Set pin mode and muting
10047	 */
10048	/* set front pin widgets 0x14 for output */
10049	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10050	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10051	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10052
10053	/* Mic (rear) pin: input vref at 80% */
10054	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10055	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10056	/* Front Mic pin: input vref at 80% */
10057	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10058	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10059	/* Line In pin: input */
10060	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10061	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10062	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10063	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10064	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10065	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10066	/* CD pin widget for input */
10067	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10068
10069	{ }
10070};
10071
10072/*
10073 * 6-stack pin configuration:
10074 */
10075static struct hda_verb alc861vd_6stack_init_verbs[] = {
10076	/*
10077	 * Set pin mode and muting
10078	 */
10079	/* set front pin widgets 0x14 for output */
10080	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10081	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10082	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10083
10084	/* Rear Pin: output 1 (0x0d) */
10085	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10086	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10087	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10088	/* CLFE Pin: output 2 (0x0e) */
10089	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10090	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10091	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10092	/* Side Pin: output 3 (0x0f) */
10093	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10094	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10095	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10096
10097	/* Mic (rear) pin: input vref at 80% */
10098	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10099	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10100	/* Front Mic pin: input vref at 80% */
10101	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10102	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10103	/* Line In pin: input */
10104	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10105	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10106	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10107	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10108	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10109	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10110	/* CD pin widget for input */
10111	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10112
10113	{ }
10114};
10115
10116static struct hda_verb alc861vd_eapd_verbs[] = {
10117	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10118	{ }
10119};
10120
10121static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10122	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10123	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10124	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10125	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10126	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10127	{}
10128};
10129
10130/* toggle speaker-output according to the hp-jack state */
10131static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10132{
10133	unsigned int present;
10134	unsigned char bits;
10135
10136	present = snd_hda_codec_read(codec, 0x1b, 0,
10137				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10138	bits = present ? 0x80 : 0;
10139	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10140				 0x80, bits);
10141	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10142				 0x80, bits);
10143}
10144
10145static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10146{
10147	unsigned int present;
10148	unsigned char bits;
10149
10150	present = snd_hda_codec_read(codec, 0x18, 0,
10151				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10152	bits = present ? 0x80 : 0;
10153	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
10154				 0x80, bits);
10155	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
10156				 0x80, bits);
10157}
10158
10159static void alc861vd_lenovo_automute(struct hda_codec *codec)
10160{
10161	alc861vd_lenovo_hp_automute(codec);
10162	alc861vd_lenovo_mic_automute(codec);
10163}
10164
10165static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10166					unsigned int res)
10167{
10168	switch (res >> 26) {
10169	case ALC880_HP_EVENT:
10170		alc861vd_lenovo_hp_automute(codec);
10171		break;
10172	case ALC880_MIC_EVENT:
10173		alc861vd_lenovo_mic_automute(codec);
10174		break;
10175	}
10176}
10177
10178static struct hda_verb alc861vd_dallas_verbs[] = {
10179	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10180	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10181	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10182	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10183
10184	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10185	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10186	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10187	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10188	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10189	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10190	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10191	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10192
10193	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10194	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10195	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10196	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10197	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10198	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10199	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10200	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10201
10202	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10203	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10204	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10205	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10206	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10207	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10208	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10209	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10210
10211	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10212	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10213	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10214	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10215
10216	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10217	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10218	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10219
10220	{ } /* end */
10221};
10222
10223/* toggle speaker-output according to the hp-jack state */
10224static void alc861vd_dallas_automute(struct hda_codec *codec)
10225{
10226	unsigned int present;
10227
10228	present = snd_hda_codec_read(codec, 0x15, 0,
10229				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10230	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10231				 0x80, present ? 0x80 : 0);
10232	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10233				 0x80, present ? 0x80 : 0);
10234}
10235
10236static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10237{
10238	if ((res >> 26) == ALC880_HP_EVENT)
10239		alc861vd_dallas_automute(codec);
10240}
10241
10242/* pcm configuration: identiacal with ALC880 */
10243#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
10244#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
10245#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
10246#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
10247
10248/*
10249 * configuration and preset
10250 */
10251static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10252	[ALC660VD_3ST]		= "3stack-660",
10253	[ALC660VD_3ST_DIG]= "3stack-660-digout",
10254	[ALC861VD_3ST]		= "3stack",
10255	[ALC861VD_3ST_DIG]	= "3stack-digout",
10256	[ALC861VD_6ST_DIG]	= "6stack-digout",
10257	[ALC861VD_LENOVO]	= "lenovo",
10258	[ALC861VD_DALLAS]	= "dallas",
10259	[ALC861VD_AUTO]		= "auto",
10260};
10261
10262static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10263	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10264	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10265	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10266	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10267	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10268
10269	SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10270	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10271	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10272	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10273	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10274	{}
10275};
10276
10277static struct alc_config_preset alc861vd_presets[] = {
10278	[ALC660VD_3ST] = {
10279		.mixers = { alc861vd_3st_mixer },
10280		.init_verbs = { alc861vd_volume_init_verbs,
10281				 alc861vd_3stack_init_verbs },
10282		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10283		.dac_nids = alc660vd_dac_nids,
10284		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10285		.adc_nids = alc861vd_adc_nids,
10286		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10287		.channel_mode = alc861vd_3stack_2ch_modes,
10288		.input_mux = &alc861vd_capture_source,
10289	},
10290	[ALC660VD_3ST_DIG] = {
10291		.mixers = { alc861vd_3st_mixer },
10292		.init_verbs = { alc861vd_volume_init_verbs,
10293				 alc861vd_3stack_init_verbs },
10294		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10295		.dac_nids = alc660vd_dac_nids,
10296		.dig_out_nid = ALC861VD_DIGOUT_NID,
10297		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10298		.adc_nids = alc861vd_adc_nids,
10299		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10300		.channel_mode = alc861vd_3stack_2ch_modes,
10301		.input_mux = &alc861vd_capture_source,
10302	},
10303	[ALC861VD_3ST] = {
10304		.mixers = { alc861vd_3st_mixer },
10305		.init_verbs = { alc861vd_volume_init_verbs,
10306				 alc861vd_3stack_init_verbs },
10307		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10308		.dac_nids = alc861vd_dac_nids,
10309		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10310		.channel_mode = alc861vd_3stack_2ch_modes,
10311		.input_mux = &alc861vd_capture_source,
10312	},
10313	[ALC861VD_3ST_DIG] = {
10314		.mixers = { alc861vd_3st_mixer },
10315		.init_verbs = { alc861vd_volume_init_verbs,
10316		 		 alc861vd_3stack_init_verbs },
10317		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10318		.dac_nids = alc861vd_dac_nids,
10319		.dig_out_nid = ALC861VD_DIGOUT_NID,
10320		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10321		.channel_mode = alc861vd_3stack_2ch_modes,
10322		.input_mux = &alc861vd_capture_source,
10323	},
10324	[ALC861VD_6ST_DIG] = {
10325		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10326		.init_verbs = { alc861vd_volume_init_verbs,
10327				alc861vd_6stack_init_verbs },
10328		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10329		.dac_nids = alc861vd_dac_nids,
10330		.dig_out_nid = ALC861VD_DIGOUT_NID,
10331		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10332		.channel_mode = alc861vd_6stack_modes,
10333		.input_mux = &alc861vd_capture_source,
10334	},
10335	[ALC861VD_LENOVO] = {
10336		.mixers = { alc861vd_lenovo_mixer },
10337		.init_verbs = { alc861vd_volume_init_verbs,
10338				alc861vd_3stack_init_verbs,
10339				alc861vd_eapd_verbs,
10340				alc861vd_lenovo_unsol_verbs },
10341		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10342		.dac_nids = alc660vd_dac_nids,
10343		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10344		.adc_nids = alc861vd_adc_nids,
10345		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10346		.channel_mode = alc861vd_3stack_2ch_modes,
10347		.input_mux = &alc861vd_capture_source,
10348		.unsol_event = alc861vd_lenovo_unsol_event,
10349		.init_hook = alc861vd_lenovo_automute,
10350	},
10351	[ALC861VD_DALLAS] = {
10352		.mixers = { alc861vd_dallas_mixer },
10353		.init_verbs = { alc861vd_dallas_verbs },
10354		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10355		.dac_nids = alc861vd_dac_nids,
10356		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10357		.adc_nids = alc861vd_adc_nids,
10358		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10359		.channel_mode = alc861vd_3stack_2ch_modes,
10360		.input_mux = &alc861vd_dallas_capture_source,
10361		.unsol_event = alc861vd_dallas_unsol_event,
10362		.init_hook = alc861vd_dallas_automute,
10363	},
10364};
10365
10366/*
10367 * BIOS auto configuration
10368 */
10369static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10370				hda_nid_t nid, int pin_type, int dac_idx)
10371{
10372	/* set as output */
10373	snd_hda_codec_write(codec, nid, 0,
10374				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10375	snd_hda_codec_write(codec, nid, 0,
10376				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10377}
10378
10379static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10380{
10381	struct alc_spec *spec = codec->spec;
10382	int i;
10383
10384	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10385	for (i = 0; i <= HDA_SIDE; i++) {
10386		hda_nid_t nid = spec->autocfg.line_out_pins[i];
10387		int pin_type = get_pin_type(spec->autocfg.line_out_type);
10388		if (nid)
10389			alc861vd_auto_set_output_and_unmute(codec, nid,
10390							    pin_type, i);
10391	}
10392}
10393
10394
10395static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10396{
10397	struct alc_spec *spec = codec->spec;
10398	hda_nid_t pin;
10399
10400	pin = spec->autocfg.hp_pins[0];
10401	if (pin) /* connect to front and  use dac 0 */
10402		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10403}
10404
10405#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
10406#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
10407
10408static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10409{
10410	struct alc_spec *spec = codec->spec;
10411	int i;
10412
10413	for (i = 0; i < AUTO_PIN_LAST; i++) {
10414		hda_nid_t nid = spec->autocfg.input_pins[i];
10415		if (alc861vd_is_input_pin(nid)) {
10416			snd_hda_codec_write(codec, nid, 0,
10417					AC_VERB_SET_PIN_WIDGET_CONTROL,
10418					i <= AUTO_PIN_FRONT_MIC ?
10419							PIN_VREF80 : PIN_IN);
10420			if (nid != ALC861VD_PIN_CD_NID)
10421				snd_hda_codec_write(codec, nid, 0,
10422						AC_VERB_SET_AMP_GAIN_MUTE,
10423						AMP_OUT_MUTE);
10424		}
10425	}
10426}
10427
10428#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
10429#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
10430
10431/* add playback controls from the parsed DAC table */
10432/* Based on ALC880 version. But ALC861VD has separate,
10433 * different NIDs for mute/unmute switch and volume control */
10434static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10435					     const struct auto_pin_cfg *cfg)
10436{
10437	char name[32];
10438	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10439	hda_nid_t nid_v, nid_s;
10440	int i, err;
10441
10442	for (i = 0; i < cfg->line_outs; i++) {
10443		if (!spec->multiout.dac_nids[i])
10444			continue;
10445		nid_v = alc861vd_idx_to_mixer_vol(
10446				alc880_dac_to_idx(
10447					spec->multiout.dac_nids[i]));
10448		nid_s = alc861vd_idx_to_mixer_switch(
10449				alc880_dac_to_idx(
10450					spec->multiout.dac_nids[i]));
10451
10452		if (i == 2) {
10453			/* Center/LFE */
10454			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10455					  "Center Playback Volume",
10456					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10457							      HDA_OUTPUT));
10458			if (err < 0)
10459				return err;
10460			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10461					  "LFE Playback Volume",
10462					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10463							      HDA_OUTPUT));
10464			if (err < 0)
10465				return err;
10466			err = add_control(spec, ALC_CTL_BIND_MUTE,
10467					  "Center Playback Switch",
10468					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10469							      HDA_INPUT));
10470			if (err < 0)
10471				return err;
10472			err = add_control(spec, ALC_CTL_BIND_MUTE,
10473					  "LFE Playback Switch",
10474					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10475							      HDA_INPUT));
10476			if (err < 0)
10477				return err;
10478		} else {
10479			sprintf(name, "%s Playback Volume", chname[i]);
10480			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10481					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10482							      HDA_OUTPUT));
10483			if (err < 0)
10484				return err;
10485			sprintf(name, "%s Playback Switch", chname[i]);
10486			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10487					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10488							      HDA_INPUT));
10489			if (err < 0)
10490				return err;
10491		}
10492	}
10493	return 0;
10494}
10495
10496/* add playback controls for speaker and HP outputs */
10497/* Based on ALC880 version. But ALC861VD has separate,
10498 * different NIDs for mute/unmute switch and volume control */
10499static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10500					hda_nid_t pin, const char *pfx)
10501{
10502	hda_nid_t nid_v, nid_s;
10503	int err;
10504	char name[32];
10505
10506	if (!pin)
10507		return 0;
10508
10509	if (alc880_is_fixed_pin(pin)) {
10510		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10511		/* specify the DAC as the extra output */
10512		if (!spec->multiout.hp_nid)
10513			spec->multiout.hp_nid = nid_v;
10514		else
10515			spec->multiout.extra_out_nid[0] = nid_v;
10516		/* control HP volume/switch on the output mixer amp */
10517		nid_v = alc861vd_idx_to_mixer_vol(
10518				alc880_fixed_pin_idx(pin));
10519		nid_s = alc861vd_idx_to_mixer_switch(
10520				alc880_fixed_pin_idx(pin));
10521
10522		sprintf(name, "%s Playback Volume", pfx);
10523		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10524				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10525		if (err < 0)
10526			return err;
10527		sprintf(name, "%s Playback Switch", pfx);
10528		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10529				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10530		if (err < 0)
10531			return err;
10532	} else if (alc880_is_multi_pin(pin)) {
10533		/* set manual connection */
10534		/* we have only a switch on HP-out PIN */
10535		sprintf(name, "%s Playback Switch", pfx);
10536		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10537				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10538		if (err < 0)
10539			return err;
10540	}
10541	return 0;
10542}
10543
10544/* parse the BIOS configuration and set up the alc_spec
10545 * return 1 if successful, 0 if the proper config is not found,
10546 * or a negative error code
10547 * Based on ALC880 version - had to change it to override
10548 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10549static int alc861vd_parse_auto_config(struct hda_codec *codec)
10550{
10551	struct alc_spec *spec = codec->spec;
10552	int err;
10553	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10554
10555	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10556					   alc861vd_ignore);
10557	if (err < 0)
10558		return err;
10559	if (!spec->autocfg.line_outs)
10560		return 0; /* can't find valid BIOS pin config */
10561
10562	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10563	if (err < 0)
10564		return err;
10565	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10566	if (err < 0)
10567		return err;
10568	err = alc861vd_auto_create_extra_out(spec,
10569					     spec->autocfg.speaker_pins[0],
10570					     "Speaker");
10571	if (err < 0)
10572		return err;
10573	err = alc861vd_auto_create_extra_out(spec,
10574					     spec->autocfg.hp_pins[0],
10575					     "Headphone");
10576	if (err < 0)
10577		return err;
10578	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10579	if (err < 0)
10580		return err;
10581
10582	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10583
10584	if (spec->autocfg.dig_out_pin)
10585		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10586
10587	if (spec->kctl_alloc)
10588		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10589
10590	spec->init_verbs[spec->num_init_verbs++]
10591		= alc861vd_volume_init_verbs;
10592
10593	spec->num_mux_defs = 1;
10594	spec->input_mux = &spec->private_imux;
10595
10596	return 1;
10597}
10598
10599/* additional initialization for auto-configuration model */
10600static void alc861vd_auto_init(struct hda_codec *codec)
10601{
10602	alc861vd_auto_init_multi_out(codec);
10603	alc861vd_auto_init_hp_out(codec);
10604	alc861vd_auto_init_analog_input(codec);
10605}
10606
10607static int patch_alc861vd(struct hda_codec *codec)
10608{
10609	struct alc_spec *spec;
10610	int err, board_config;
10611
10612	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10613	if (spec == NULL)
10614		return -ENOMEM;
10615
10616	codec->spec = spec;
10617
10618	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10619						  alc861vd_models,
10620						  alc861vd_cfg_tbl);
10621
10622	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10623		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10624			"ALC861VD, trying auto-probe from BIOS...\n");
10625		board_config = ALC861VD_AUTO;
10626	}
10627
10628	if (board_config == ALC861VD_AUTO) {
10629		/* automatic parse from the BIOS config */
10630		err = alc861vd_parse_auto_config(codec);
10631		if (err < 0) {
10632			alc_free(codec);
10633			return err;
10634		} else if (!err) {
10635			printk(KERN_INFO
10636			       "hda_codec: Cannot set up configuration "
10637			       "from BIOS.  Using base mode...\n");
10638			board_config = ALC861VD_3ST;
10639		}
10640	}
10641
10642	if (board_config != ALC861VD_AUTO)
10643		setup_preset(spec, &alc861vd_presets[board_config]);
10644
10645	spec->stream_name_analog = "ALC861VD Analog";
10646	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10647	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10648
10649	spec->stream_name_digital = "ALC861VD Digital";
10650	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10651	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10652
10653	spec->adc_nids = alc861vd_adc_nids;
10654	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10655
10656	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10657	spec->num_mixers++;
10658
10659	codec->patch_ops = alc_patch_ops;
10660
10661	if (board_config == ALC861VD_AUTO)
10662		spec->init_hook = alc861vd_auto_init;
10663
10664	return 0;
10665}
10666
10667/*
10668 * ALC662 support
10669 *
10670 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10671 * configuration.  Each pin widget can choose any input DACs and a mixer.
10672 * Each ADC is connected from a mixer of all inputs.  This makes possible
10673 * 6-channel independent captures.
10674 *
10675 * In addition, an independent DAC for the multi-playback (not used in this
10676 * driver yet).
10677 */
10678#define ALC662_DIGOUT_NID	0x06
10679#define ALC662_DIGIN_NID	0x0a
10680
10681static hda_nid_t alc662_dac_nids[4] = {
10682	/* front, rear, clfe, rear_surr */
10683	0x02, 0x03, 0x04
10684};
10685
10686static hda_nid_t alc662_adc_nids[1] = {
10687	/* ADC1-2 */
10688	0x09,
10689};
10690/* input MUX */
10691/* FIXME: should be a matrix-type input source selection */
10692
10693static struct hda_input_mux alc662_capture_source = {
10694	.num_items = 4,
10695	.items = {
10696		{ "Mic", 0x0 },
10697		{ "Front Mic", 0x1 },
10698		{ "Line", 0x2 },
10699		{ "CD", 0x4 },
10700	},
10701};
10702
10703static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10704	.num_items = 2,
10705	.items = {
10706		{ "Mic", 0x1 },
10707		{ "Line", 0x2 },
10708	},
10709};
10710#define alc662_mux_enum_info alc_mux_enum_info
10711#define alc662_mux_enum_get alc_mux_enum_get
10712
10713static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10714			       struct snd_ctl_elem_value *ucontrol)
10715{
10716	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10717	struct alc_spec *spec = codec->spec;
10718	const struct hda_input_mux *imux = spec->input_mux;
10719	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10720	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10721	hda_nid_t nid = capture_mixers[adc_idx];
10722	unsigned int *cur_val = &spec->cur_mux[adc_idx];
10723	unsigned int i, idx;
10724
10725	idx = ucontrol->value.enumerated.item[0];
10726	if (idx >= imux->num_items)
10727		idx = imux->num_items - 1;
10728	if (*cur_val == idx && !codec->in_resume)
10729		return 0;
10730	for (i = 0; i < imux->num_items; i++) {
10731		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
10732		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10733				    v | (imux->items[i].index << 8));
10734	}
10735	*cur_val = idx;
10736	return 1;
10737}
10738/*
10739 * 2ch mode
10740 */
10741static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10742	{ 2, NULL }
10743};
10744
10745/*
10746 * 2ch mode
10747 */
10748static struct hda_verb alc662_3ST_ch2_init[] = {
10749	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10750	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10751	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10752	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10753	{ } /* end */
10754};
10755
10756/*
10757 * 6ch mode
10758 */
10759static struct hda_verb alc662_3ST_ch6_init[] = {
10760	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10761	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10762	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10763	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10764	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10765	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10766	{ } /* end */
10767};
10768
10769static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10770	{ 2, alc662_3ST_ch2_init },
10771	{ 6, alc662_3ST_ch6_init },
10772};
10773
10774/*
10775 * 2ch mode
10776 */
10777static struct hda_verb alc662_sixstack_ch6_init[] = {
10778	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10779	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10780	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10781	{ } /* end */
10782};
10783
10784/*
10785 * 6ch mode
10786 */
10787static struct hda_verb alc662_sixstack_ch8_init[] = {
10788	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10789	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10790	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10791	{ } /* end */
10792};
10793
10794static struct hda_channel_mode alc662_5stack_modes[2] = {
10795	{ 2, alc662_sixstack_ch6_init },
10796	{ 6, alc662_sixstack_ch8_init },
10797};
10798
10799/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10800 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10801 */
10802
10803static struct snd_kcontrol_new alc662_base_mixer[] = {
10804	/* output mixer control */
10805	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10806	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10807	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10808	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10809	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10810	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10811	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10812	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10813	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10814
10815	/*Input mixer control */
10816	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10817	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10818	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10819	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10820	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10821	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10822	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10823	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10824
10825	/* Capture mixer control */
10826	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10827	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10828	{
10829		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10830		.name = "Capture Source",
10831		.count = 1,
10832		.info = alc_mux_enum_info,
10833		.get = alc_mux_enum_get,
10834		.put = alc_mux_enum_put,
10835	},
10836	{ } /* end */
10837};
10838
10839static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10840	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10841	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10842	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10843	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10844	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10845	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10846	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10847	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10848	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10849	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10850	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10851	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10852	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10853	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10854	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10855	{
10856		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10857		/* .name = "Capture Source", */
10858		.name = "Input Source",
10859		.count = 1,
10860		.info = alc662_mux_enum_info,
10861		.get = alc662_mux_enum_get,
10862		.put = alc662_mux_enum_put,
10863	},
10864	{ } /* end */
10865};
10866
10867static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
10868	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10869	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10870	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10871	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
10872	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10873	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10874	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10875	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10876	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10877	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10878	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10879	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10880	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10881	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10882	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10883	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10884	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10885	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10886	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10887	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10888	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10889	{
10890		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10891		/* .name = "Capture Source", */
10892		.name = "Input Source",
10893		.count = 1,
10894		.info = alc662_mux_enum_info,
10895		.get = alc662_mux_enum_get,
10896		.put = alc662_mux_enum_put,
10897	},
10898	{ } /* end */
10899};
10900
10901static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
10902	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10903	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10904	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10905	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
10906	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10907	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10908	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10909	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10910	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10911	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10912	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10913	{
10914		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10915		/* .name = "Capture Source", */
10916		.name = "Input Source",
10917		.count = 1,
10918		.info = alc662_mux_enum_info,
10919		.get = alc662_mux_enum_get,
10920		.put = alc662_mux_enum_put,
10921	},
10922	{ } /* end */
10923};
10924
10925static struct snd_kcontrol_new alc662_chmode_mixer[] = {
10926	{
10927		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10928		.name = "Channel Mode",
10929		.info = alc_ch_mode_info,
10930		.get = alc_ch_mode_get,
10931		.put = alc_ch_mode_put,
10932	},
10933	{ } /* end */
10934};
10935
10936static struct hda_verb alc662_init_verbs[] = {
10937	/* ADC: mute amp left and right */
10938	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10939	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10940	/* Front mixer: unmute input/output amp left and right (volume = 0) */
10941
10942	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10943	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10944	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10945	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10946	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10947
10948	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10949	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10950	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10951	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10952	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10953	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10954
10955	/* Front Pin: output 0 (0x0c) */
10956	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10957	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10958
10959	/* Rear Pin: output 1 (0x0d) */
10960	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10961	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10962
10963	/* CLFE Pin: output 2 (0x0e) */
10964	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10965	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10966
10967	/* Mic (rear) pin: input vref at 80% */
10968	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10969	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10970	/* Front Mic pin: input vref at 80% */
10971	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10972	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10973	/* Line In pin: input */
10974	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10975	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10976	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10977	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10978	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10979	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10980	/* CD pin widget for input */
10981	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10982
10983	/* FIXME: use matrix-type input source selection */
10984	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10985	/* Input mixer */
10986	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10987	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10988	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10989	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10990	{ }
10991};
10992
10993static struct hda_verb alc662_sue_init_verbs[] = {
10994	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
10995	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
10996        {}
10997};
10998
10999/*
11000 * generic initialization of ADC, input mixers and output mixers
11001 */
11002static struct hda_verb alc662_auto_init_verbs[] = {
11003	/*
11004	 * Unmute ADC and set the default input to mic-in
11005	 */
11006	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11007	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11008
11009	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11010	 * mixer widget
11011	 * Note: PASD motherboards uses the Line In 2 as the input for front
11012	 * panel mic (mic 2)
11013	 */
11014	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11015	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11016	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11017	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11018	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11019	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11020
11021	/*
11022	 * Set up output mixers (0x0c - 0x0f)
11023	 */
11024	/* set vol=0 to output mixers */
11025	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11026	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11027	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11028
11029	/* set up input amps for analog loopback */
11030	/* Amp Indices: DAC = 0, mixer = 1 */
11031	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11032	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11033	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11034	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11035	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11036	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11037
11038
11039	/* FIXME: use matrix-type input source selection */
11040	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11041	/* Input mixer */
11042	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11043	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11044	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11045	/*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
11046	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11047
11048	{ }
11049};
11050
11051/* capture mixer elements */
11052static struct snd_kcontrol_new alc662_capture_mixer[] = {
11053	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11054	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11055	{
11056		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11057		/* The multiple "Capture Source" controls confuse alsamixer
11058		 * So call somewhat different..
11059		 * FIXME: the controls appear in the "playback" view!
11060		 */
11061		/* .name = "Capture Source", */
11062		.name = "Input Source",
11063		.count = 1,
11064		.info = alc882_mux_enum_info,
11065		.get = alc882_mux_enum_get,
11066		.put = alc882_mux_enum_put,
11067	},
11068	{ } /* end */
11069};
11070
11071static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11072{
11073	unsigned int present;
11074	unsigned char bits;
11075
11076	present = snd_hda_codec_read(codec, 0x14, 0,
11077				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11078	bits = present ? 0x80 : 0;
11079	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11080				 0x80, bits);
11081	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11082				 0x80, bits);
11083}
11084
11085static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11086{
11087	unsigned int present;
11088	unsigned char bits;
11089
11090 	present = snd_hda_codec_read(codec, 0x1b, 0,
11091				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11092	bits = present ? 0x80 : 0;
11093	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11094				 0x80, bits);
11095	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11096				 0x80, bits);
11097	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11098				 0x80, bits);
11099	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11100				 0x80, bits);
11101}
11102
11103static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11104					   unsigned int res)
11105{
11106	if ((res >> 26) == ALC880_HP_EVENT)
11107		alc662_lenovo_101e_all_automute(codec);
11108	if ((res >> 26) == ALC880_FRONT_EVENT)
11109		alc662_lenovo_101e_ispeaker_automute(codec);
11110}
11111
11112
11113/* pcm configuration: identiacal with ALC880 */
11114#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
11115#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
11116#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
11117#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
11118
11119/*
11120 * configuration and preset
11121 */
11122static const char *alc662_models[ALC662_MODEL_LAST] = {
11123	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
11124	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
11125	[ALC662_3ST_6ch]	= "3stack-6ch",
11126	[ALC662_5ST_DIG]	= "6stack-dig",
11127	[ALC662_LENOVO_101E]	= "lenovo-101e",
11128	[ALC662_AUTO]		= "auto",
11129};
11130
11131static struct snd_pci_quirk alc662_cfg_tbl[] = {
11132	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11133	{}
11134};
11135
11136static struct alc_config_preset alc662_presets[] = {
11137	[ALC662_3ST_2ch_DIG] = {
11138		.mixers = { alc662_3ST_2ch_mixer },
11139		.init_verbs = { alc662_init_verbs },
11140		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11141		.dac_nids = alc662_dac_nids,
11142		.dig_out_nid = ALC662_DIGOUT_NID,
11143		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11144		.adc_nids = alc662_adc_nids,
11145		.dig_in_nid = ALC662_DIGIN_NID,
11146		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11147		.channel_mode = alc662_3ST_2ch_modes,
11148		.input_mux = &alc662_capture_source,
11149	},
11150	[ALC662_3ST_6ch_DIG] = {
11151		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11152		.init_verbs = { alc662_init_verbs },
11153		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11154		.dac_nids = alc662_dac_nids,
11155		.dig_out_nid = ALC662_DIGOUT_NID,
11156		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11157		.adc_nids = alc662_adc_nids,
11158		.dig_in_nid = ALC662_DIGIN_NID,
11159		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11160		.channel_mode = alc662_3ST_6ch_modes,
11161		.need_dac_fix = 1,
11162		.input_mux = &alc662_capture_source,
11163	},
11164	[ALC662_3ST_6ch] = {
11165		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11166		.init_verbs = { alc662_init_verbs },
11167		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11168		.dac_nids = alc662_dac_nids,
11169		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11170		.adc_nids = alc662_adc_nids,
11171		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11172		.channel_mode = alc662_3ST_6ch_modes,
11173		.need_dac_fix = 1,
11174		.input_mux = &alc662_capture_source,
11175	},
11176	[ALC662_5ST_DIG] = {
11177		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
11178		.init_verbs = { alc662_init_verbs },
11179		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11180		.dac_nids = alc662_dac_nids,
11181		.dig_out_nid = ALC662_DIGOUT_NID,
11182		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11183		.adc_nids = alc662_adc_nids,
11184		.dig_in_nid = ALC662_DIGIN_NID,
11185		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11186		.channel_mode = alc662_5stack_modes,
11187		.input_mux = &alc662_capture_source,
11188	},
11189	[ALC662_LENOVO_101E] = {
11190		.mixers = { alc662_lenovo_101e_mixer },
11191		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11192		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11193		.dac_nids = alc662_dac_nids,
11194		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11195		.adc_nids = alc662_adc_nids,
11196		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11197		.channel_mode = alc662_3ST_2ch_modes,
11198		.input_mux = &alc662_lenovo_101e_capture_source,
11199		.unsol_event = alc662_lenovo_101e_unsol_event,
11200		.init_hook = alc662_lenovo_101e_all_automute,
11201	},
11202
11203};
11204
11205
11206/*
11207 * BIOS auto configuration
11208 */
11209
11210/* add playback controls from the parsed DAC table */
11211static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11212					     const struct auto_pin_cfg *cfg)
11213{
11214	char name[32];
11215	static const char *chname[4] = {
11216		"Front", "Surround", NULL /*CLFE*/, "Side"
11217	};
11218	hda_nid_t nid;
11219	int i, err;
11220
11221	for (i = 0; i < cfg->line_outs; i++) {
11222		if (!spec->multiout.dac_nids[i])
11223			continue;
11224		nid = alc880_idx_to_mixer(i);
11225		if (i == 2) {
11226			/* Center/LFE */
11227			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11228					  "Center Playback Volume",
11229					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11230							      HDA_OUTPUT));
11231			if (err < 0)
11232				return err;
11233			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11234					  "LFE Playback Volume",
11235					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11236							      HDA_OUTPUT));
11237			if (err < 0)
11238				return err;
11239			err = add_control(spec, ALC_CTL_BIND_MUTE,
11240					  "Center Playback Switch",
11241					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11242							      HDA_INPUT));
11243			if (err < 0)
11244				return err;
11245			err = add_control(spec, ALC_CTL_BIND_MUTE,
11246					  "LFE Playback Switch",
11247					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11248							      HDA_INPUT));
11249			if (err < 0)
11250				return err;
11251		} else {
11252			sprintf(name, "%s Playback Volume", chname[i]);
11253			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11254					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11255							      HDA_OUTPUT));
11256			if (err < 0)
11257				return err;
11258			sprintf(name, "%s Playback Switch", chname[i]);
11259			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11260					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11261							      HDA_INPUT));
11262			if (err < 0)
11263				return err;
11264		}
11265	}
11266	return 0;
11267}
11268
11269/* add playback controls for speaker and HP outputs */
11270static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11271					const char *pfx)
11272{
11273	hda_nid_t nid;
11274	int err;
11275	char name[32];
11276
11277	if (!pin)
11278		return 0;
11279
11280	if (alc880_is_fixed_pin(pin)) {
11281		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11282                /* printk("DAC nid=%x\n",nid); */
11283		/* specify the DAC as the extra output */
11284		if (!spec->multiout.hp_nid)
11285			spec->multiout.hp_nid = nid;
11286		else
11287			spec->multiout.extra_out_nid[0] = nid;
11288		/* control HP volume/switch on the output mixer amp */
11289		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11290		sprintf(name, "%s Playback Volume", pfx);
11291		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11292				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11293		if (err < 0)
11294			return err;
11295		sprintf(name, "%s Playback Switch", pfx);
11296		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11297				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11298		if (err < 0)
11299			return err;
11300	} else if (alc880_is_multi_pin(pin)) {
11301		/* set manual connection */
11302		/* we have only a switch on HP-out PIN */
11303		sprintf(name, "%s Playback Switch", pfx);
11304		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11305				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11306		if (err < 0)
11307			return err;
11308	}
11309	return 0;
11310}
11311
11312/* create playback/capture controls for input pins */
11313static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11314						const struct auto_pin_cfg *cfg)
11315{
11316	struct hda_input_mux *imux = &spec->private_imux;
11317	int i, err, idx;
11318
11319	for (i = 0; i < AUTO_PIN_LAST; i++) {
11320		if (alc880_is_input_pin(cfg->input_pins[i])) {
11321			idx = alc880_input_pin_idx(cfg->input_pins[i]);
11322			err = new_analog_input(spec, cfg->input_pins[i],
11323					       auto_pin_cfg_labels[i],
11324					       idx, 0x0b);
11325			if (err < 0)
11326				return err;
11327			imux->items[imux->num_items].label =
11328				auto_pin_cfg_labels[i];
11329			imux->items[imux->num_items].index =
11330				alc880_input_pin_idx(cfg->input_pins[i]);
11331			imux->num_items++;
11332		}
11333	}
11334	return 0;
11335}
11336
11337static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11338					      hda_nid_t nid, int pin_type,
11339					      int dac_idx)
11340{
11341	/* set as output */
11342	snd_hda_codec_write(codec, nid, 0,
11343			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11344	snd_hda_codec_write(codec, nid, 0,
11345			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11346	/* need the manual connection? */
11347	if (alc880_is_multi_pin(nid)) {
11348		struct alc_spec *spec = codec->spec;
11349		int idx = alc880_multi_pin_idx(nid);
11350		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11351				    AC_VERB_SET_CONNECT_SEL,
11352				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11353	}
11354}
11355
11356static void alc662_auto_init_multi_out(struct hda_codec *codec)
11357{
11358	struct alc_spec *spec = codec->spec;
11359	int i;
11360
11361	for (i = 0; i <= HDA_SIDE; i++) {
11362		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11363		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11364		if (nid)
11365			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11366							  i);
11367	}
11368}
11369
11370static void alc662_auto_init_hp_out(struct hda_codec *codec)
11371{
11372	struct alc_spec *spec = codec->spec;
11373	hda_nid_t pin;
11374
11375	pin = spec->autocfg.hp_pins[0];
11376	if (pin) /* connect to front */
11377		/* use dac 0 */
11378		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11379}
11380
11381#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
11382#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
11383
11384static void alc662_auto_init_analog_input(struct hda_codec *codec)
11385{
11386	struct alc_spec *spec = codec->spec;
11387	int i;
11388
11389	for (i = 0; i < AUTO_PIN_LAST; i++) {
11390		hda_nid_t nid = spec->autocfg.input_pins[i];
11391		if (alc662_is_input_pin(nid)) {
11392			snd_hda_codec_write(codec, nid, 0,
11393					    AC_VERB_SET_PIN_WIDGET_CONTROL,
11394					    (i <= AUTO_PIN_FRONT_MIC ?
11395					     PIN_VREF80 : PIN_IN));
11396			if (nid != ALC662_PIN_CD_NID)
11397				snd_hda_codec_write(codec, nid, 0,
11398						    AC_VERB_SET_AMP_GAIN_MUTE,
11399						    AMP_OUT_MUTE);
11400		}
11401	}
11402}
11403
11404static int alc662_parse_auto_config(struct hda_codec *codec)
11405{
11406	struct alc_spec *spec = codec->spec;
11407	int err;
11408	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11409
11410	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11411					   alc662_ignore);
11412	if (err < 0)
11413		return err;
11414	if (!spec->autocfg.line_outs)
11415		return 0; /* can't find valid BIOS pin config */
11416
11417	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11418	if (err < 0)
11419		return err;
11420	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11421	if (err < 0)
11422		return err;
11423	err = alc662_auto_create_extra_out(spec,
11424					   spec->autocfg.speaker_pins[0],
11425					   "Speaker");
11426	if (err < 0)
11427		return err;
11428	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11429					   "Headphone");
11430	if (err < 0)
11431		return err;
11432	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11433	if (err < 0)
11434		return err;
11435
11436	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11437
11438	if (spec->autocfg.dig_out_pin)
11439		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11440
11441	if (spec->kctl_alloc)
11442		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11443
11444	spec->num_mux_defs = 1;
11445	spec->input_mux = &spec->private_imux;
11446
11447	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11448	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11449	spec->num_mixers++;
11450	return 1;
11451}
11452
11453/* additional initialization for auto-configuration model */
11454static void alc662_auto_init(struct hda_codec *codec)
11455{
11456	alc662_auto_init_multi_out(codec);
11457	alc662_auto_init_hp_out(codec);
11458	alc662_auto_init_analog_input(codec);
11459}
11460
11461static int patch_alc662(struct hda_codec *codec)
11462{
11463	struct alc_spec *spec;
11464	int err, board_config;
11465
11466	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11467	if (!spec)
11468		return -ENOMEM;
11469
11470	codec->spec = spec;
11471
11472	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11473						  alc662_models,
11474			  	                  alc662_cfg_tbl);
11475	if (board_config < 0) {
11476		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11477		       "trying auto-probe from BIOS...\n");
11478		board_config = ALC662_AUTO;
11479	}
11480
11481	if (board_config == ALC662_AUTO) {
11482		/* automatic parse from the BIOS config */
11483		err = alc662_parse_auto_config(codec);
11484		if (err < 0) {
11485			alc_free(codec);
11486			return err;
11487		} else if (!err) {
11488			printk(KERN_INFO
11489			       "hda_codec: Cannot set up configuration "
11490			       "from BIOS.  Using base mode...\n");
11491			board_config = ALC662_3ST_2ch_DIG;
11492		}
11493	}
11494
11495	if (board_config != ALC662_AUTO)
11496		setup_preset(spec, &alc662_presets[board_config]);
11497
11498	spec->stream_name_analog = "ALC662 Analog";
11499	spec->stream_analog_playback = &alc662_pcm_analog_playback;
11500	spec->stream_analog_capture = &alc662_pcm_analog_capture;
11501
11502	spec->stream_name_digital = "ALC662 Digital";
11503	spec->stream_digital_playback = &alc662_pcm_digital_playback;
11504	spec->stream_digital_capture = &alc662_pcm_digital_capture;
11505
11506	if (!spec->adc_nids && spec->input_mux) {
11507		spec->adc_nids = alc662_adc_nids;
11508		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11509	}
11510
11511	codec->patch_ops = alc_patch_ops;
11512	if (board_config == ALC662_AUTO)
11513		spec->init_hook = alc662_auto_init;
11514
11515	return 0;
11516}
11517
11518/*
11519 * patch entries
11520 */
11521struct hda_codec_preset snd_hda_preset_realtek[] = {
11522	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11523	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11524	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11525	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11526	  .patch = patch_alc861 },
11527	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11528	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11529	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11530	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11531	  .patch = patch_alc883 },
11532	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11533	  .patch = patch_alc662 },
11534	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11535	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11536	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11537	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11538	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11539	{} /* terminator */
11540};
11541