patch_realtek.c revision 378bd6a5211f05d6d8eb3e78a92e2a197e456e4e
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 <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
33#include "hda_patch.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	ALC880_MEDION_RIM,
64#ifdef CONFIG_SND_DEBUG
65	ALC880_TEST,
66#endif
67	ALC880_AUTO,
68	ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73	ALC260_BASIC,
74	ALC260_HP,
75	ALC260_HP_3013,
76	ALC260_FUJITSU_S702X,
77	ALC260_ACER,
78	ALC260_WILL,
79	ALC260_REPLACER_672V,
80#ifdef CONFIG_SND_DEBUG
81	ALC260_TEST,
82#endif
83	ALC260_AUTO,
84	ALC260_MODEL_LAST /* last tag */
85};
86
87/* ALC262 models */
88enum {
89	ALC262_BASIC,
90	ALC262_HIPPO,
91	ALC262_HIPPO_1,
92	ALC262_FUJITSU,
93	ALC262_HP_BPC,
94	ALC262_HP_BPC_D7000_WL,
95	ALC262_HP_BPC_D7000_WF,
96	ALC262_HP_TC_T5735,
97	ALC262_HP_RP5700,
98	ALC262_BENQ_ED8,
99	ALC262_SONY_ASSAMD,
100	ALC262_BENQ_T31,
101	ALC262_ULTRA,
102	ALC262_LENOVO_3000,
103	ALC262_AUTO,
104	ALC262_MODEL_LAST /* last tag */
105};
106
107/* ALC268 models */
108enum {
109	ALC267_QUANTA_IL1,
110	ALC268_3ST,
111	ALC268_TOSHIBA,
112	ALC268_ACER,
113	ALC268_DELL,
114	ALC268_ZEPTO,
115#ifdef CONFIG_SND_DEBUG
116	ALC268_TEST,
117#endif
118	ALC268_AUTO,
119	ALC268_MODEL_LAST /* last tag */
120};
121
122/* ALC269 models */
123enum {
124	ALC269_BASIC,
125	ALC269_AUTO,
126	ALC269_MODEL_LAST /* last tag */
127};
128
129/* ALC861 models */
130enum {
131	ALC861_3ST,
132	ALC660_3ST,
133	ALC861_3ST_DIG,
134	ALC861_6ST_DIG,
135	ALC861_UNIWILL_M31,
136	ALC861_TOSHIBA,
137	ALC861_ASUS,
138	ALC861_ASUS_LAPTOP,
139	ALC861_AUTO,
140	ALC861_MODEL_LAST,
141};
142
143/* ALC861-VD models */
144enum {
145	ALC660VD_3ST,
146	ALC660VD_3ST_DIG,
147	ALC861VD_3ST,
148	ALC861VD_3ST_DIG,
149	ALC861VD_6ST_DIG,
150	ALC861VD_LENOVO,
151	ALC861VD_DALLAS,
152	ALC861VD_HP,
153	ALC861VD_AUTO,
154	ALC861VD_MODEL_LAST,
155};
156
157/* ALC662 models */
158enum {
159	ALC662_3ST_2ch_DIG,
160	ALC662_3ST_6ch_DIG,
161	ALC662_3ST_6ch,
162	ALC662_5ST_DIG,
163	ALC662_LENOVO_101E,
164	ALC662_ASUS_EEEPC_P701,
165	ALC662_ASUS_EEEPC_EP20,
166	ALC662_AUTO,
167	ALC662_MODEL_LAST,
168};
169
170/* ALC882 models */
171enum {
172	ALC882_3ST_DIG,
173	ALC882_6ST_DIG,
174	ALC882_ARIMA,
175	ALC882_W2JC,
176	ALC882_TARGA,
177	ALC882_ASUS_A7J,
178	ALC882_ASUS_A7M,
179	ALC885_MACPRO,
180	ALC885_MBP3,
181	ALC885_IMAC24,
182	ALC882_AUTO,
183	ALC882_MODEL_LAST,
184};
185
186/* ALC883 models */
187enum {
188	ALC883_3ST_2ch_DIG,
189	ALC883_3ST_6ch_DIG,
190	ALC883_3ST_6ch,
191	ALC883_6ST_DIG,
192	ALC883_TARGA_DIG,
193	ALC883_TARGA_2ch_DIG,
194	ALC883_ACER,
195	ALC883_ACER_ASPIRE,
196	ALC883_MEDION,
197	ALC883_MEDION_MD2,
198	ALC883_LAPTOP_EAPD,
199	ALC883_LENOVO_101E_2ch,
200	ALC883_LENOVO_NB0763,
201	ALC888_LENOVO_MS7195_DIG,
202	ALC883_HAIER_W66,
203	ALC888_3ST_HP,
204	ALC888_6ST_DELL,
205	ALC883_MITAC,
206	ALC883_CLEVO_M720,
207	ALC883_FUJITSU_PI2515,
208	ALC883_AUTO,
209	ALC883_MODEL_LAST,
210};
211
212/* for GPIO Poll */
213#define GPIO_MASK	0x03
214
215struct alc_spec {
216	/* codec parameterization */
217	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
218	unsigned int num_mixers;
219
220	const struct hda_verb *init_verbs[5];	/* initialization verbs
221						 * don't forget NULL
222						 * termination!
223						 */
224	unsigned int num_init_verbs;
225
226	char *stream_name_analog;	/* analog PCM stream */
227	struct hda_pcm_stream *stream_analog_playback;
228	struct hda_pcm_stream *stream_analog_capture;
229	struct hda_pcm_stream *stream_analog_alt_playback;
230	struct hda_pcm_stream *stream_analog_alt_capture;
231
232	char *stream_name_digital;	/* digital PCM stream */
233	struct hda_pcm_stream *stream_digital_playback;
234	struct hda_pcm_stream *stream_digital_capture;
235
236	/* playback */
237	struct hda_multi_out multiout;	/* playback set-up
238					 * max_channels, dacs must be set
239					 * dig_out_nid and hp_nid are optional
240					 */
241	hda_nid_t alt_dac_nid;
242
243	/* capture */
244	unsigned int num_adc_nids;
245	hda_nid_t *adc_nids;
246	hda_nid_t *capsrc_nids;
247	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
248
249	/* capture source */
250	unsigned int num_mux_defs;
251	const struct hda_input_mux *input_mux;
252	unsigned int cur_mux[3];
253
254	/* channel model */
255	const struct hda_channel_mode *channel_mode;
256	int num_channel_mode;
257	int need_dac_fix;
258
259	/* PCM information */
260	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
261
262	/* dynamic controls, init_verbs and input_mux */
263	struct auto_pin_cfg autocfg;
264	unsigned int num_kctl_alloc, num_kctl_used;
265	struct snd_kcontrol_new *kctl_alloc;
266	struct hda_input_mux private_imux;
267	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
268
269	/* hooks */
270	void (*init_hook)(struct hda_codec *codec);
271	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
272
273	/* for pin sensing */
274	unsigned int sense_updated: 1;
275	unsigned int jack_present: 1;
276	unsigned int master_sw: 1;
277
278	/* for virtual master */
279	hda_nid_t vmaster_nid;
280#ifdef CONFIG_SND_HDA_POWER_SAVE
281	struct hda_loopback_check loopback;
282#endif
283};
284
285/*
286 * configuration template - to be copied to the spec instance
287 */
288struct alc_config_preset {
289	struct snd_kcontrol_new *mixers[5]; /* should be identical size
290					     * with spec
291					     */
292	const struct hda_verb *init_verbs[5];
293	unsigned int num_dacs;
294	hda_nid_t *dac_nids;
295	hda_nid_t dig_out_nid;		/* optional */
296	hda_nid_t hp_nid;		/* optional */
297	unsigned int num_adc_nids;
298	hda_nid_t *adc_nids;
299	hda_nid_t *capsrc_nids;
300	hda_nid_t dig_in_nid;
301	unsigned int num_channel_mode;
302	const struct hda_channel_mode *channel_mode;
303	int need_dac_fix;
304	unsigned int num_mux_defs;
305	const struct hda_input_mux *input_mux;
306	void (*unsol_event)(struct hda_codec *, unsigned int);
307	void (*init_hook)(struct hda_codec *);
308#ifdef CONFIG_SND_HDA_POWER_SAVE
309	struct hda_amp_list *loopbacks;
310#endif
311};
312
313
314/*
315 * input MUX handling
316 */
317static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
318			     struct snd_ctl_elem_info *uinfo)
319{
320	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
321	struct alc_spec *spec = codec->spec;
322	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
323	if (mux_idx >= spec->num_mux_defs)
324		mux_idx = 0;
325	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
326}
327
328static int alc_mux_enum_get(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	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
334
335	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
336	return 0;
337}
338
339static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
340			    struct snd_ctl_elem_value *ucontrol)
341{
342	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
343	struct alc_spec *spec = codec->spec;
344	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
345	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
346	hda_nid_t nid = spec->capsrc_nids ?
347		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
348	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
349				     nid, &spec->cur_mux[adc_idx]);
350}
351
352
353/*
354 * channel mode setting
355 */
356static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
357			    struct snd_ctl_elem_info *uinfo)
358{
359	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
360	struct alc_spec *spec = codec->spec;
361	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
362				    spec->num_channel_mode);
363}
364
365static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
366			   struct snd_ctl_elem_value *ucontrol)
367{
368	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
369	struct alc_spec *spec = codec->spec;
370	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
371				   spec->num_channel_mode,
372				   spec->multiout.max_channels);
373}
374
375static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
376			   struct snd_ctl_elem_value *ucontrol)
377{
378	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
379	struct alc_spec *spec = codec->spec;
380	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
381				      spec->num_channel_mode,
382				      &spec->multiout.max_channels);
383	if (err >= 0 && spec->need_dac_fix)
384		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
385	return err;
386}
387
388/*
389 * Control the mode of pin widget settings via the mixer.  "pc" is used
390 * instead of "%" to avoid consequences of accidently treating the % as
391 * being part of a format specifier.  Maximum allowed length of a value is
392 * 63 characters plus NULL terminator.
393 *
394 * Note: some retasking pin complexes seem to ignore requests for input
395 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
396 * are requested.  Therefore order this list so that this behaviour will not
397 * cause problems when mixer clients move through the enum sequentially.
398 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
399 * March 2006.
400 */
401static char *alc_pin_mode_names[] = {
402	"Mic 50pc bias", "Mic 80pc bias",
403	"Line in", "Line out", "Headphone out",
404};
405static unsigned char alc_pin_mode_values[] = {
406	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
407};
408/* The control can present all 5 options, or it can limit the options based
409 * in the pin being assumed to be exclusively an input or an output pin.  In
410 * addition, "input" pins may or may not process the mic bias option
411 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
412 * accept requests for bias as of chip versions up to March 2006) and/or
413 * wiring in the computer.
414 */
415#define ALC_PIN_DIR_IN              0x00
416#define ALC_PIN_DIR_OUT             0x01
417#define ALC_PIN_DIR_INOUT           0x02
418#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
419#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
420
421/* Info about the pin modes supported by the different pin direction modes.
422 * For each direction the minimum and maximum values are given.
423 */
424static signed char alc_pin_mode_dir_info[5][2] = {
425	{ 0, 2 },    /* ALC_PIN_DIR_IN */
426	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
427	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
428	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
429	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
430};
431#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
432#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
433#define alc_pin_mode_n_items(_dir) \
434	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
435
436static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
437			     struct snd_ctl_elem_info *uinfo)
438{
439	unsigned int item_num = uinfo->value.enumerated.item;
440	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
441
442	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
443	uinfo->count = 1;
444	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
445
446	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
447		item_num = alc_pin_mode_min(dir);
448	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
449	return 0;
450}
451
452static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
453			    struct snd_ctl_elem_value *ucontrol)
454{
455	unsigned int i;
456	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457	hda_nid_t nid = kcontrol->private_value & 0xffff;
458	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
459	long *valp = ucontrol->value.integer.value;
460	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
461						 AC_VERB_GET_PIN_WIDGET_CONTROL,
462						 0x00);
463
464	/* Find enumerated value for current pinctl setting */
465	i = alc_pin_mode_min(dir);
466	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
467		i++;
468	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
469	return 0;
470}
471
472static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
473			    struct snd_ctl_elem_value *ucontrol)
474{
475	signed int change;
476	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
477	hda_nid_t nid = kcontrol->private_value & 0xffff;
478	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
479	long val = *ucontrol->value.integer.value;
480	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
481						 AC_VERB_GET_PIN_WIDGET_CONTROL,
482						 0x00);
483
484	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
485		val = alc_pin_mode_min(dir);
486
487	change = pinctl != alc_pin_mode_values[val];
488	if (change) {
489		/* Set pin mode to that requested */
490		snd_hda_codec_write_cache(codec, nid, 0,
491					  AC_VERB_SET_PIN_WIDGET_CONTROL,
492					  alc_pin_mode_values[val]);
493
494		/* Also enable the retasking pin's input/output as required
495		 * for the requested pin mode.  Enum values of 2 or less are
496		 * input modes.
497		 *
498		 * Dynamically switching the input/output buffers probably
499		 * reduces noise slightly (particularly on input) so we'll
500		 * do it.  However, having both input and output buffers
501		 * enabled simultaneously doesn't seem to be problematic if
502		 * this turns out to be necessary in the future.
503		 */
504		if (val <= 2) {
505			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
506						 HDA_AMP_MUTE, HDA_AMP_MUTE);
507			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
508						 HDA_AMP_MUTE, 0);
509		} else {
510			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
511						 HDA_AMP_MUTE, HDA_AMP_MUTE);
512			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
513						 HDA_AMP_MUTE, 0);
514		}
515	}
516	return change;
517}
518
519#define ALC_PIN_MODE(xname, nid, dir) \
520	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
521	  .info = alc_pin_mode_info, \
522	  .get = alc_pin_mode_get, \
523	  .put = alc_pin_mode_put, \
524	  .private_value = nid | (dir<<16) }
525
526/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
527 * together using a mask with more than one bit set.  This control is
528 * currently used only by the ALC260 test model.  At this stage they are not
529 * needed for any "production" models.
530 */
531#ifdef CONFIG_SND_DEBUG
532#define alc_gpio_data_info	snd_ctl_boolean_mono_info
533
534static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
535			     struct snd_ctl_elem_value *ucontrol)
536{
537	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538	hda_nid_t nid = kcontrol->private_value & 0xffff;
539	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
540	long *valp = ucontrol->value.integer.value;
541	unsigned int val = snd_hda_codec_read(codec, nid, 0,
542					      AC_VERB_GET_GPIO_DATA, 0x00);
543
544	*valp = (val & mask) != 0;
545	return 0;
546}
547static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
548			     struct snd_ctl_elem_value *ucontrol)
549{
550	signed int change;
551	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
552	hda_nid_t nid = kcontrol->private_value & 0xffff;
553	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
554	long val = *ucontrol->value.integer.value;
555	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
556						    AC_VERB_GET_GPIO_DATA,
557						    0x00);
558
559	/* Set/unset the masked GPIO bit(s) as needed */
560	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
561	if (val == 0)
562		gpio_data &= ~mask;
563	else
564		gpio_data |= mask;
565	snd_hda_codec_write_cache(codec, nid, 0,
566				  AC_VERB_SET_GPIO_DATA, gpio_data);
567
568	return change;
569}
570#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
571	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
572	  .info = alc_gpio_data_info, \
573	  .get = alc_gpio_data_get, \
574	  .put = alc_gpio_data_put, \
575	  .private_value = nid | (mask<<16) }
576#endif   /* CONFIG_SND_DEBUG */
577
578/* A switch control to allow the enabling of the digital IO pins on the
579 * ALC260.  This is incredibly simplistic; the intention of this control is
580 * to provide something in the test model allowing digital outputs to be
581 * identified if present.  If models are found which can utilise these
582 * outputs a more complete mixer control can be devised for those models if
583 * necessary.
584 */
585#ifdef CONFIG_SND_DEBUG
586#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
587
588static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
589			      struct snd_ctl_elem_value *ucontrol)
590{
591	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
592	hda_nid_t nid = kcontrol->private_value & 0xffff;
593	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
594	long *valp = ucontrol->value.integer.value;
595	unsigned int val = snd_hda_codec_read(codec, nid, 0,
596					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
597
598	*valp = (val & mask) != 0;
599	return 0;
600}
601static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
602			      struct snd_ctl_elem_value *ucontrol)
603{
604	signed int change;
605	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
606	hda_nid_t nid = kcontrol->private_value & 0xffff;
607	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
608	long val = *ucontrol->value.integer.value;
609	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
610						    AC_VERB_GET_DIGI_CONVERT_1,
611						    0x00);
612
613	/* Set/unset the masked control bit(s) as needed */
614	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
615	if (val==0)
616		ctrl_data &= ~mask;
617	else
618		ctrl_data |= mask;
619	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
620				  ctrl_data);
621
622	return change;
623}
624#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
625	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
626	  .info = alc_spdif_ctrl_info, \
627	  .get = alc_spdif_ctrl_get, \
628	  .put = alc_spdif_ctrl_put, \
629	  .private_value = nid | (mask<<16) }
630#endif   /* CONFIG_SND_DEBUG */
631
632/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
633 * Again, this is only used in the ALC26x test models to help identify when
634 * the EAPD line must be asserted for features to work.
635 */
636#ifdef CONFIG_SND_DEBUG
637#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
638
639static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
640			      struct snd_ctl_elem_value *ucontrol)
641{
642	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
643	hda_nid_t nid = kcontrol->private_value & 0xffff;
644	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
645	long *valp = ucontrol->value.integer.value;
646	unsigned int val = snd_hda_codec_read(codec, nid, 0,
647					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
648
649	*valp = (val & mask) != 0;
650	return 0;
651}
652
653static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
654			      struct snd_ctl_elem_value *ucontrol)
655{
656	int change;
657	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
658	hda_nid_t nid = kcontrol->private_value & 0xffff;
659	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
660	long val = *ucontrol->value.integer.value;
661	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
662						    AC_VERB_GET_EAPD_BTLENABLE,
663						    0x00);
664
665	/* Set/unset the masked control bit(s) as needed */
666	change = (!val ? 0 : mask) != (ctrl_data & mask);
667	if (!val)
668		ctrl_data &= ~mask;
669	else
670		ctrl_data |= mask;
671	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
672				  ctrl_data);
673
674	return change;
675}
676
677#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
678	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
679	  .info = alc_eapd_ctrl_info, \
680	  .get = alc_eapd_ctrl_get, \
681	  .put = alc_eapd_ctrl_put, \
682	  .private_value = nid | (mask<<16) }
683#endif   /* CONFIG_SND_DEBUG */
684
685/*
686 * set up from the preset table
687 */
688static void setup_preset(struct alc_spec *spec,
689			 const struct alc_config_preset *preset)
690{
691	int i;
692
693	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
694		spec->mixers[spec->num_mixers++] = preset->mixers[i];
695	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
696	     i++)
697		spec->init_verbs[spec->num_init_verbs++] =
698			preset->init_verbs[i];
699
700	spec->channel_mode = preset->channel_mode;
701	spec->num_channel_mode = preset->num_channel_mode;
702	spec->need_dac_fix = preset->need_dac_fix;
703
704	spec->multiout.max_channels = spec->channel_mode[0].channels;
705
706	spec->multiout.num_dacs = preset->num_dacs;
707	spec->multiout.dac_nids = preset->dac_nids;
708	spec->multiout.dig_out_nid = preset->dig_out_nid;
709	spec->multiout.hp_nid = preset->hp_nid;
710
711	spec->num_mux_defs = preset->num_mux_defs;
712	if (!spec->num_mux_defs)
713		spec->num_mux_defs = 1;
714	spec->input_mux = preset->input_mux;
715
716	spec->num_adc_nids = preset->num_adc_nids;
717	spec->adc_nids = preset->adc_nids;
718	spec->capsrc_nids = preset->capsrc_nids;
719	spec->dig_in_nid = preset->dig_in_nid;
720
721	spec->unsol_event = preset->unsol_event;
722	spec->init_hook = preset->init_hook;
723#ifdef CONFIG_SND_HDA_POWER_SAVE
724	spec->loopback.amplist = preset->loopbacks;
725#endif
726}
727
728/* Enable GPIO mask and set output */
729static struct hda_verb alc_gpio1_init_verbs[] = {
730	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
731	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
732	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
733	{ }
734};
735
736static struct hda_verb alc_gpio2_init_verbs[] = {
737	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
738	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
739	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
740	{ }
741};
742
743static struct hda_verb alc_gpio3_init_verbs[] = {
744	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
745	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
746	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
747	{ }
748};
749
750static void alc_sku_automute(struct hda_codec *codec)
751{
752	struct alc_spec *spec = codec->spec;
753	unsigned int present;
754	unsigned int hp_nid = spec->autocfg.hp_pins[0];
755	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
756
757	/* need to execute and sync at first */
758	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
759	present = snd_hda_codec_read(codec, hp_nid, 0,
760				     AC_VERB_GET_PIN_SENSE, 0);
761	spec->jack_present = (present & 0x80000000) != 0;
762	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
763			    spec->jack_present ? 0 : PIN_OUT);
764}
765
766/* unsolicited event for HP jack sensing */
767static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
768{
769	if (codec->vendor_id == 0x10ec0880)
770		res >>= 28;
771	else
772		res >>= 26;
773	if (res != ALC880_HP_EVENT)
774		return;
775
776	alc_sku_automute(codec);
777}
778
779/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
780 *	31 ~ 16 :	Manufacture ID
781 *	15 ~ 8	:	SKU ID
782 *	7  ~ 0	:	Assembly ID
783 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
784 */
785static void alc_subsystem_id(struct hda_codec *codec,
786			     unsigned int porta, unsigned int porte,
787			     unsigned int portd)
788{
789	unsigned int ass, tmp, i;
790	unsigned nid;
791	struct alc_spec *spec = codec->spec;
792
793	ass = codec->subsystem_id & 0xffff;
794	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
795		goto do_sku;
796
797	/*
798	 * 31~30	: port conetcivity
799	 * 29~21	: reserve
800	 * 20		: PCBEEP input
801	 * 19~16	: Check sum (15:1)
802	 * 15~1		: Custom
803	 * 0		: override
804	*/
805	nid = 0x1d;
806	if (codec->vendor_id == 0x10ec0260)
807		nid = 0x17;
808	ass = snd_hda_codec_read(codec, nid, 0,
809				 AC_VERB_GET_CONFIG_DEFAULT, 0);
810	if (!(ass & 1) && !(ass & 0x100000))
811		return;
812	if ((ass >> 30) != 1)	/* no physical connection */
813		return;
814
815	/* check sum */
816	tmp = 0;
817	for (i = 1; i < 16; i++) {
818		if ((ass >> i) & 1)
819			tmp++;
820	}
821	if (((ass >> 16) & 0xf) != tmp)
822		return;
823do_sku:
824	/*
825	 * 0 : override
826	 * 1 :	Swap Jack
827	 * 2 : 0 --> Desktop, 1 --> Laptop
828	 * 3~5 : External Amplifier control
829	 * 7~6 : Reserved
830	*/
831	tmp = (ass & 0x38) >> 3;	/* external Amp control */
832	switch (tmp) {
833	case 1:
834		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
835		break;
836	case 3:
837		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
838		break;
839	case 7:
840		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
841		break;
842	case 5:	/* set EAPD output high */
843		switch (codec->vendor_id) {
844		case 0x10ec0260:
845			snd_hda_codec_write(codec, 0x0f, 0,
846					    AC_VERB_SET_EAPD_BTLENABLE, 2);
847			snd_hda_codec_write(codec, 0x10, 0,
848					    AC_VERB_SET_EAPD_BTLENABLE, 2);
849			break;
850		case 0x10ec0262:
851		case 0x10ec0267:
852		case 0x10ec0268:
853		case 0x10ec0269:
854		case 0x10ec0862:
855		case 0x10ec0662:
856		case 0x10ec0889:
857			snd_hda_codec_write(codec, 0x14, 0,
858					    AC_VERB_SET_EAPD_BTLENABLE, 2);
859			snd_hda_codec_write(codec, 0x15, 0,
860					    AC_VERB_SET_EAPD_BTLENABLE, 2);
861			break;
862		}
863		switch (codec->vendor_id) {
864		case 0x10ec0260:
865			snd_hda_codec_write(codec, 0x1a, 0,
866					    AC_VERB_SET_COEF_INDEX, 7);
867			tmp = snd_hda_codec_read(codec, 0x1a, 0,
868						 AC_VERB_GET_PROC_COEF, 0);
869			snd_hda_codec_write(codec, 0x1a, 0,
870					    AC_VERB_SET_COEF_INDEX, 7);
871			snd_hda_codec_write(codec, 0x1a, 0,
872					    AC_VERB_SET_PROC_COEF,
873					    tmp | 0x2010);
874			break;
875		case 0x10ec0262:
876		case 0x10ec0880:
877		case 0x10ec0882:
878		case 0x10ec0883:
879		case 0x10ec0885:
880		case 0x10ec0888:
881		case 0x10ec0889:
882			snd_hda_codec_write(codec, 0x20, 0,
883					    AC_VERB_SET_COEF_INDEX, 7);
884			tmp = snd_hda_codec_read(codec, 0x20, 0,
885						 AC_VERB_GET_PROC_COEF, 0);
886			snd_hda_codec_write(codec, 0x20, 0,
887					    AC_VERB_SET_COEF_INDEX, 7);
888			snd_hda_codec_write(codec, 0x20, 0,
889					    AC_VERB_SET_PROC_COEF,
890					    tmp | 0x2010);
891			break;
892		case 0x10ec0267:
893		case 0x10ec0268:
894			snd_hda_codec_write(codec, 0x20, 0,
895					    AC_VERB_SET_COEF_INDEX, 7);
896			tmp = snd_hda_codec_read(codec, 0x20, 0,
897						 AC_VERB_GET_PROC_COEF, 0);
898			snd_hda_codec_write(codec, 0x20, 0,
899					    AC_VERB_SET_COEF_INDEX, 7);
900			snd_hda_codec_write(codec, 0x20, 0,
901					    AC_VERB_SET_PROC_COEF,
902					    tmp | 0x3000);
903			break;
904		}
905	default:
906		break;
907	}
908
909	/* is laptop or Desktop and enable the function "Mute internal speaker
910	 * when the external headphone out jack is plugged"
911	 */
912	if (!(ass & 0x8000))
913		return;
914	/*
915	 * 10~8 : Jack location
916	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
917	 * 14~13: Resvered
918	 * 15   : 1 --> enable the function "Mute internal speaker
919	 *	        when the external headphone out jack is plugged"
920	 */
921	if (!spec->autocfg.speaker_pins[0]) {
922		if (spec->autocfg.line_out_pins[0])
923			spec->autocfg.speaker_pins[0] =
924				spec->autocfg.line_out_pins[0];
925		else
926			return;
927	}
928
929	if (!spec->autocfg.hp_pins[0]) {
930		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
931		if (tmp == 0)
932			spec->autocfg.hp_pins[0] = porta;
933		else if (tmp == 1)
934			spec->autocfg.hp_pins[0] = porte;
935		else if (tmp == 2)
936			spec->autocfg.hp_pins[0] = portd;
937		else
938			return;
939	}
940
941	snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
942			    AC_VERB_SET_UNSOLICITED_ENABLE,
943			    AC_USRSP_EN | ALC880_HP_EVENT);
944	spec->unsol_event = alc_sku_unsol_event;
945}
946
947/*
948 * Fix-up pin default configurations
949 */
950
951struct alc_pincfg {
952	hda_nid_t nid;
953	u32 val;
954};
955
956static void alc_fix_pincfg(struct hda_codec *codec,
957			   const struct snd_pci_quirk *quirk,
958			   const struct alc_pincfg **pinfix)
959{
960	const struct alc_pincfg *cfg;
961
962	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
963	if (!quirk)
964		return;
965
966	cfg = pinfix[quirk->value];
967	for (; cfg->nid; cfg++) {
968		int i;
969		u32 val = cfg->val;
970		for (i = 0; i < 4; i++) {
971			snd_hda_codec_write(codec, cfg->nid, 0,
972				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
973				    val & 0xff);
974			val >>= 8;
975		}
976	}
977}
978
979/*
980 * ALC880 3-stack model
981 *
982 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
983 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
984 *                 F-Mic = 0x1b, HP = 0x19
985 */
986
987static hda_nid_t alc880_dac_nids[4] = {
988	/* front, rear, clfe, rear_surr */
989	0x02, 0x05, 0x04, 0x03
990};
991
992static hda_nid_t alc880_adc_nids[3] = {
993	/* ADC0-2 */
994	0x07, 0x08, 0x09,
995};
996
997/* The datasheet says the node 0x07 is connected from inputs,
998 * but it shows zero connection in the real implementation on some devices.
999 * Note: this is a 915GAV bug, fixed on 915GLV
1000 */
1001static hda_nid_t alc880_adc_nids_alt[2] = {
1002	/* ADC1-2 */
1003	0x08, 0x09,
1004};
1005
1006#define ALC880_DIGOUT_NID	0x06
1007#define ALC880_DIGIN_NID	0x0a
1008
1009static struct hda_input_mux alc880_capture_source = {
1010	.num_items = 4,
1011	.items = {
1012		{ "Mic", 0x0 },
1013		{ "Front Mic", 0x3 },
1014		{ "Line", 0x2 },
1015		{ "CD", 0x4 },
1016	},
1017};
1018
1019/* channel source setting (2/6 channel selection for 3-stack) */
1020/* 2ch mode */
1021static struct hda_verb alc880_threestack_ch2_init[] = {
1022	/* set line-in to input, mute it */
1023	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1024	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1025	/* set mic-in to input vref 80%, mute it */
1026	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1027	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1028	{ } /* end */
1029};
1030
1031/* 6ch mode */
1032static struct hda_verb alc880_threestack_ch6_init[] = {
1033	/* set line-in to output, unmute it */
1034	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1035	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1036	/* set mic-in to output, unmute it */
1037	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1038	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1039	{ } /* end */
1040};
1041
1042static struct hda_channel_mode alc880_threestack_modes[2] = {
1043	{ 2, alc880_threestack_ch2_init },
1044	{ 6, alc880_threestack_ch6_init },
1045};
1046
1047static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1048	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1049	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1050	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1051	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1052	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1053	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1054	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1055	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1056	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1057	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1058	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1059	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1060	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1061	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1062	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1063	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1064	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1065	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1066	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1067	{
1068		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1069		.name = "Channel Mode",
1070		.info = alc_ch_mode_info,
1071		.get = alc_ch_mode_get,
1072		.put = alc_ch_mode_put,
1073	},
1074	{ } /* end */
1075};
1076
1077/* capture mixer elements */
1078static struct snd_kcontrol_new alc880_capture_mixer[] = {
1079	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1080	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1081	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1082	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1083	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1084	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1085	{
1086		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1087		/* The multiple "Capture Source" controls confuse alsamixer
1088		 * So call somewhat different..
1089		 */
1090		/* .name = "Capture Source", */
1091		.name = "Input Source",
1092		.count = 3,
1093		.info = alc_mux_enum_info,
1094		.get = alc_mux_enum_get,
1095		.put = alc_mux_enum_put,
1096	},
1097	{ } /* end */
1098};
1099
1100/* capture mixer elements (in case NID 0x07 not available) */
1101static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1102	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1103	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1104	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1105	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1106	{
1107		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1108		/* The multiple "Capture Source" controls confuse alsamixer
1109		 * So call somewhat different..
1110		 */
1111		/* .name = "Capture Source", */
1112		.name = "Input Source",
1113		.count = 2,
1114		.info = alc_mux_enum_info,
1115		.get = alc_mux_enum_get,
1116		.put = alc_mux_enum_put,
1117	},
1118	{ } /* end */
1119};
1120
1121
1122
1123/*
1124 * ALC880 5-stack model
1125 *
1126 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1127 *      Side = 0x02 (0xd)
1128 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1129 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1130 */
1131
1132/* additional mixers to alc880_three_stack_mixer */
1133static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1134	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1135	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1136	{ } /* end */
1137};
1138
1139/* channel source setting (6/8 channel selection for 5-stack) */
1140/* 6ch mode */
1141static struct hda_verb alc880_fivestack_ch6_init[] = {
1142	/* set line-in to input, mute it */
1143	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1144	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1145	{ } /* end */
1146};
1147
1148/* 8ch mode */
1149static struct hda_verb alc880_fivestack_ch8_init[] = {
1150	/* set line-in to output, unmute it */
1151	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1152	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1153	{ } /* end */
1154};
1155
1156static struct hda_channel_mode alc880_fivestack_modes[2] = {
1157	{ 6, alc880_fivestack_ch6_init },
1158	{ 8, alc880_fivestack_ch8_init },
1159};
1160
1161
1162/*
1163 * ALC880 6-stack model
1164 *
1165 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1166 *      Side = 0x05 (0x0f)
1167 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1168 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1169 */
1170
1171static hda_nid_t alc880_6st_dac_nids[4] = {
1172	/* front, rear, clfe, rear_surr */
1173	0x02, 0x03, 0x04, 0x05
1174};
1175
1176static struct hda_input_mux alc880_6stack_capture_source = {
1177	.num_items = 4,
1178	.items = {
1179		{ "Mic", 0x0 },
1180		{ "Front Mic", 0x1 },
1181		{ "Line", 0x2 },
1182		{ "CD", 0x4 },
1183	},
1184};
1185
1186/* fixed 8-channels */
1187static struct hda_channel_mode alc880_sixstack_modes[1] = {
1188	{ 8, NULL },
1189};
1190
1191static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1192	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1193	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1194	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1195	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1196	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1197	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1198	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1199	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1200	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1201	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1202	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1203	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1204	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1205	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1206	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1207	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1208	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1209	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1210	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1211	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1212	{
1213		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1214		.name = "Channel Mode",
1215		.info = alc_ch_mode_info,
1216		.get = alc_ch_mode_get,
1217		.put = alc_ch_mode_put,
1218	},
1219	{ } /* end */
1220};
1221
1222
1223/*
1224 * ALC880 W810 model
1225 *
1226 * W810 has rear IO for:
1227 * Front (DAC 02)
1228 * Surround (DAC 03)
1229 * Center/LFE (DAC 04)
1230 * Digital out (06)
1231 *
1232 * The system also has a pair of internal speakers, and a headphone jack.
1233 * These are both connected to Line2 on the codec, hence to DAC 02.
1234 *
1235 * There is a variable resistor to control the speaker or headphone
1236 * volume. This is a hardware-only device without a software API.
1237 *
1238 * Plugging headphones in will disable the internal speakers. This is
1239 * implemented in hardware, not via the driver using jack sense. In
1240 * a similar fashion, plugging into the rear socket marked "front" will
1241 * disable both the speakers and headphones.
1242 *
1243 * For input, there's a microphone jack, and an "audio in" jack.
1244 * These may not do anything useful with this driver yet, because I
1245 * haven't setup any initialization verbs for these yet...
1246 */
1247
1248static hda_nid_t alc880_w810_dac_nids[3] = {
1249	/* front, rear/surround, clfe */
1250	0x02, 0x03, 0x04
1251};
1252
1253/* fixed 6 channels */
1254static struct hda_channel_mode alc880_w810_modes[1] = {
1255	{ 6, NULL }
1256};
1257
1258/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1259static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1260	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1261	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1262	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1263	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1264	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1265	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1266	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1267	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1268	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1269	{ } /* end */
1270};
1271
1272
1273/*
1274 * Z710V model
1275 *
1276 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1277 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1278 *                 Line = 0x1a
1279 */
1280
1281static hda_nid_t alc880_z71v_dac_nids[1] = {
1282	0x02
1283};
1284#define ALC880_Z71V_HP_DAC	0x03
1285
1286/* fixed 2 channels */
1287static struct hda_channel_mode alc880_2_jack_modes[1] = {
1288	{ 2, NULL }
1289};
1290
1291static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1292	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1293	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1294	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1295	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1296	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1297	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1298	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1299	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1300	{ } /* end */
1301};
1302
1303
1304/*
1305 * ALC880 F1734 model
1306 *
1307 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1308 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1309 */
1310
1311static hda_nid_t alc880_f1734_dac_nids[1] = {
1312	0x03
1313};
1314#define ALC880_F1734_HP_DAC	0x02
1315
1316static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1317	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1318	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1319	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1320	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1321	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1322	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1323	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1324	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1325	{ } /* end */
1326};
1327
1328static struct hda_input_mux alc880_f1734_capture_source = {
1329	.num_items = 2,
1330	.items = {
1331		{ "Mic", 0x1 },
1332		{ "CD", 0x4 },
1333	},
1334};
1335
1336
1337/*
1338 * ALC880 ASUS model
1339 *
1340 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1341 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1342 *  Mic = 0x18, Line = 0x1a
1343 */
1344
1345#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1346#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1347
1348static struct snd_kcontrol_new alc880_asus_mixer[] = {
1349	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1350	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1351	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1352	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1353	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1354	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1355	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1356	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1357	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1358	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1359	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1360	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1361	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1362	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1363	{
1364		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1365		.name = "Channel Mode",
1366		.info = alc_ch_mode_info,
1367		.get = alc_ch_mode_get,
1368		.put = alc_ch_mode_put,
1369	},
1370	{ } /* end */
1371};
1372
1373/*
1374 * ALC880 ASUS W1V model
1375 *
1376 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1377 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1378 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1379 */
1380
1381/* additional mixers to alc880_asus_mixer */
1382static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1383	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1384	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1385	{ } /* end */
1386};
1387
1388/* additional mixers to alc880_asus_mixer */
1389static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1390	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1391	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1392	{ } /* end */
1393};
1394
1395/* TCL S700 */
1396static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1397	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1398	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1399	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1400	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1401	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1402	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1403	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1404	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1405	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1406	{
1407		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1408		/* The multiple "Capture Source" controls confuse alsamixer
1409		 * So call somewhat different..
1410		 */
1411		/* .name = "Capture Source", */
1412		.name = "Input Source",
1413		.count = 1,
1414		.info = alc_mux_enum_info,
1415		.get = alc_mux_enum_get,
1416		.put = alc_mux_enum_put,
1417	},
1418	{ } /* end */
1419};
1420
1421/* Uniwill */
1422static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1423	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1424	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1425	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1426	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1427	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1428	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1429	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1430	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1431	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1432	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1433	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1434	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1435	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1436	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1437	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1438	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1439	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1440	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1441	{
1442		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1443		.name = "Channel Mode",
1444		.info = alc_ch_mode_info,
1445		.get = alc_ch_mode_get,
1446		.put = alc_ch_mode_put,
1447	},
1448	{ } /* end */
1449};
1450
1451static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1452	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1453	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1454	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1455	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1456	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1457	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1458	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1459	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1460	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1461	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1462	{ } /* end */
1463};
1464
1465static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1466	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1467	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1468	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1469	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1470	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1471	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1472	{ } /* end */
1473};
1474
1475/*
1476 * virtual master controls
1477 */
1478
1479/*
1480 * slave controls for virtual master
1481 */
1482static const char *alc_slave_vols[] = {
1483	"Front Playback Volume",
1484	"Surround Playback Volume",
1485	"Center Playback Volume",
1486	"LFE Playback Volume",
1487	"Side Playback Volume",
1488	"Headphone Playback Volume",
1489	"Speaker Playback Volume",
1490	"Mono Playback Volume",
1491	"Line-Out Playback Volume",
1492	NULL,
1493};
1494
1495static const char *alc_slave_sws[] = {
1496	"Front Playback Switch",
1497	"Surround Playback Switch",
1498	"Center Playback Switch",
1499	"LFE Playback Switch",
1500	"Side Playback Switch",
1501	"Headphone Playback Switch",
1502	"Speaker Playback Switch",
1503	"Mono Playback Switch",
1504	"IEC958 Playback Switch",
1505	NULL,
1506};
1507
1508/*
1509 * build control elements
1510 */
1511static int alc_build_controls(struct hda_codec *codec)
1512{
1513	struct alc_spec *spec = codec->spec;
1514	int err;
1515	int i;
1516
1517	for (i = 0; i < spec->num_mixers; i++) {
1518		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1519		if (err < 0)
1520			return err;
1521	}
1522
1523	if (spec->multiout.dig_out_nid) {
1524		err = snd_hda_create_spdif_out_ctls(codec,
1525						    spec->multiout.dig_out_nid);
1526		if (err < 0)
1527			return err;
1528		err = snd_hda_create_spdif_share_sw(codec,
1529						    &spec->multiout);
1530		if (err < 0)
1531			return err;
1532		spec->multiout.share_spdif = 1;
1533	}
1534	if (spec->dig_in_nid) {
1535		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1536		if (err < 0)
1537			return err;
1538	}
1539
1540	/* if we have no master control, let's create it */
1541	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1542		unsigned int vmaster_tlv[4];
1543		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1544					HDA_OUTPUT, vmaster_tlv);
1545		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1546					  vmaster_tlv, alc_slave_vols);
1547		if (err < 0)
1548			return err;
1549	}
1550	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1551		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1552					  NULL, alc_slave_sws);
1553		if (err < 0)
1554			return err;
1555	}
1556
1557	return 0;
1558}
1559
1560
1561/*
1562 * initialize the codec volumes, etc
1563 */
1564
1565/*
1566 * generic initialization of ADC, input mixers and output mixers
1567 */
1568static struct hda_verb alc880_volume_init_verbs[] = {
1569	/*
1570	 * Unmute ADC0-2 and set the default input to mic-in
1571	 */
1572	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1573	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1574	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1575	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1576	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1577	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1578
1579	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1580	 * mixer widget
1581	 * Note: PASD motherboards uses the Line In 2 as the input for front
1582	 * panel mic (mic 2)
1583	 */
1584	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1585	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1586	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1587	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1588	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1589	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1590	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1591	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1592
1593	/*
1594	 * Set up output mixers (0x0c - 0x0f)
1595	 */
1596	/* set vol=0 to output mixers */
1597	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1598	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1599	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1600	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1601	/* set up input amps for analog loopback */
1602	/* Amp Indices: DAC = 0, mixer = 1 */
1603	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1604	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1605	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1606	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1607	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1608	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1609	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1610	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1611
1612	{ }
1613};
1614
1615/*
1616 * 3-stack pin configuration:
1617 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1618 */
1619static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1620	/*
1621	 * preset connection lists of input pins
1622	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1623	 */
1624	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1625	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1626	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1627
1628	/*
1629	 * Set pin mode and muting
1630	 */
1631	/* set front pin widgets 0x14 for output */
1632	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1633	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1634	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1635	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1636	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1637	/* Mic2 (as headphone out) for HP output */
1638	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1639	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1640	/* Line In pin widget for input */
1641	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1642	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1643	/* Line2 (as front mic) pin widget for input and vref at 80% */
1644	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1645	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1646	/* CD pin widget for input */
1647	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1648
1649	{ }
1650};
1651
1652/*
1653 * 5-stack pin configuration:
1654 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1655 * line-in/side = 0x1a, f-mic = 0x1b
1656 */
1657static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1658	/*
1659	 * preset connection lists of input pins
1660	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1661	 */
1662	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1663	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1664
1665	/*
1666	 * Set pin mode and muting
1667	 */
1668	/* set pin widgets 0x14-0x17 for output */
1669	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1670	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1671	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1672	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1673	/* unmute pins for output (no gain on this amp) */
1674	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1675	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1677	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1678
1679	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1680	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1681	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1682	/* Mic2 (as headphone out) for HP output */
1683	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1684	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1685	/* Line In pin widget for input */
1686	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1687	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1688	/* Line2 (as front mic) pin widget for input and vref at 80% */
1689	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1690	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1691	/* CD pin widget for input */
1692	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1693
1694	{ }
1695};
1696
1697/*
1698 * W810 pin configuration:
1699 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1700 */
1701static struct hda_verb alc880_pin_w810_init_verbs[] = {
1702	/* hphone/speaker input selector: front DAC */
1703	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1704
1705	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1706	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1707	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1708	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1709	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1710	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1711
1712	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1713	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1714
1715	{ }
1716};
1717
1718/*
1719 * Z71V pin configuration:
1720 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1721 */
1722static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1723	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1724	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1726	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1727
1728	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1729	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1730	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1731	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1732
1733	{ }
1734};
1735
1736/*
1737 * 6-stack pin configuration:
1738 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1739 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1740 */
1741static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1742	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1743
1744	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1745	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1746	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1747	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1748	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1749	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1750	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1752
1753	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1754	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1755	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1756	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1757	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1758	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1759	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1760	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1761	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1762
1763	{ }
1764};
1765
1766/*
1767 * Uniwill pin configuration:
1768 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1769 * line = 0x1a
1770 */
1771static struct hda_verb alc880_uniwill_init_verbs[] = {
1772	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1773
1774	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1775	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1776	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1777	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1778	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1779	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1780	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1781	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1782	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1783	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1784	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1785	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1786	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1787	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1788
1789	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1790	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1791	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1792	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1793	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1794	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1795	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1796	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1797	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1798
1799	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1800	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1801
1802	{ }
1803};
1804
1805/*
1806* Uniwill P53
1807* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1808 */
1809static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1810	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1811
1812	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1813	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1814	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1815	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1816	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1817	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1819	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1820	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1821	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1822	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1823	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1824
1825	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1826	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1827	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1828	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1829	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1830	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1831
1832	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1833	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1834
1835	{ }
1836};
1837
1838static struct hda_verb alc880_beep_init_verbs[] = {
1839	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1840	{ }
1841};
1842
1843/* toggle speaker-output according to the hp-jack state */
1844static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1845{
1846 	unsigned int present;
1847	unsigned char bits;
1848
1849 	present = snd_hda_codec_read(codec, 0x14, 0,
1850				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1851	bits = present ? HDA_AMP_MUTE : 0;
1852	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1853				 HDA_AMP_MUTE, bits);
1854	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1855				 HDA_AMP_MUTE, bits);
1856}
1857
1858/* auto-toggle front mic */
1859static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1860{
1861 	unsigned int present;
1862	unsigned char bits;
1863
1864	present = snd_hda_codec_read(codec, 0x18, 0,
1865				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1866	bits = present ? HDA_AMP_MUTE : 0;
1867	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1868}
1869
1870static void alc880_uniwill_automute(struct hda_codec *codec)
1871{
1872	alc880_uniwill_hp_automute(codec);
1873	alc880_uniwill_mic_automute(codec);
1874}
1875
1876static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1877				       unsigned int res)
1878{
1879	/* Looks like the unsol event is incompatible with the standard
1880	 * definition.  4bit tag is placed at 28 bit!
1881	 */
1882	switch (res >> 28) {
1883	case ALC880_HP_EVENT:
1884		alc880_uniwill_hp_automute(codec);
1885		break;
1886	case ALC880_MIC_EVENT:
1887		alc880_uniwill_mic_automute(codec);
1888		break;
1889	}
1890}
1891
1892static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1893{
1894 	unsigned int present;
1895	unsigned char bits;
1896
1897 	present = snd_hda_codec_read(codec, 0x14, 0,
1898				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1899	bits = present ? HDA_AMP_MUTE : 0;
1900	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1901}
1902
1903static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1904{
1905	unsigned int present;
1906
1907	present = snd_hda_codec_read(codec, 0x21, 0,
1908				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1909	present &= HDA_AMP_VOLMASK;
1910	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1911				 HDA_AMP_VOLMASK, present);
1912	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1913				 HDA_AMP_VOLMASK, present);
1914}
1915
1916static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1917					   unsigned int res)
1918{
1919	/* Looks like the unsol event is incompatible with the standard
1920	 * definition.  4bit tag is placed at 28 bit!
1921	 */
1922	if ((res >> 28) == ALC880_HP_EVENT)
1923		alc880_uniwill_p53_hp_automute(codec);
1924	if ((res >> 28) == ALC880_DCVOL_EVENT)
1925		alc880_uniwill_p53_dcvol_automute(codec);
1926}
1927
1928/*
1929 * F1734 pin configuration:
1930 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1931 */
1932static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1933	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
1934	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1935	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1936	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1937	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1938
1939	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1940	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1941	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1942	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1943
1944	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1945	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1946	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1947	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1948	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1949	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1950	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1951	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1952	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1953
1954	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
1955	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
1956
1957	{ }
1958};
1959
1960/*
1961 * ASUS pin configuration:
1962 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1963 */
1964static struct hda_verb alc880_pin_asus_init_verbs[] = {
1965	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1966	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1967	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1968	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1969
1970	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1971	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1972	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1973	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1974	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1975	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1976	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1977	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1978
1979	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1980	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1981	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1982	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1983	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1984	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1985	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1986	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1987	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1988
1989	{ }
1990};
1991
1992/* Enable GPIO mask and set output */
1993#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1994#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1995
1996/* Clevo m520g init */
1997static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1998	/* headphone output */
1999	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2000	/* line-out */
2001	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2002	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003	/* Line-in */
2004	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2005	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2006	/* CD */
2007	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2008	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2009	/* Mic1 (rear panel) */
2010	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2011	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2012	/* Mic2 (front panel) */
2013	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2014	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2015	/* headphone */
2016	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2017	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2018        /* change to EAPD mode */
2019	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2020	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2021
2022	{ }
2023};
2024
2025static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2026	/* change to EAPD mode */
2027	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2028	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2029
2030	/* Headphone output */
2031	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2032	/* Front output*/
2033	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2034	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2035
2036	/* Line In pin widget for input */
2037	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2038	/* CD pin widget for input */
2039	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2040	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2041	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2042
2043	/* change to EAPD mode */
2044	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2045	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2046
2047	{ }
2048};
2049
2050/*
2051 * LG m1 express dual
2052 *
2053 * Pin assignment:
2054 *   Rear Line-In/Out (blue): 0x14
2055 *   Build-in Mic-In: 0x15
2056 *   Speaker-out: 0x17
2057 *   HP-Out (green): 0x1b
2058 *   Mic-In/Out (red): 0x19
2059 *   SPDIF-Out: 0x1e
2060 */
2061
2062/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2063static hda_nid_t alc880_lg_dac_nids[3] = {
2064	0x05, 0x02, 0x03
2065};
2066
2067/* seems analog CD is not working */
2068static struct hda_input_mux alc880_lg_capture_source = {
2069	.num_items = 3,
2070	.items = {
2071		{ "Mic", 0x1 },
2072		{ "Line", 0x5 },
2073		{ "Internal Mic", 0x6 },
2074	},
2075};
2076
2077/* 2,4,6 channel modes */
2078static struct hda_verb alc880_lg_ch2_init[] = {
2079	/* set line-in and mic-in to input */
2080	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2081	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2082	{ }
2083};
2084
2085static struct hda_verb alc880_lg_ch4_init[] = {
2086	/* set line-in to out and mic-in to input */
2087	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2088	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2089	{ }
2090};
2091
2092static struct hda_verb alc880_lg_ch6_init[] = {
2093	/* set line-in and mic-in to output */
2094	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2095	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2096	{ }
2097};
2098
2099static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2100	{ 2, alc880_lg_ch2_init },
2101	{ 4, alc880_lg_ch4_init },
2102	{ 6, alc880_lg_ch6_init },
2103};
2104
2105static struct snd_kcontrol_new alc880_lg_mixer[] = {
2106	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2107	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2108	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2109	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2110	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2111	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2112	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2113	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2114	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2115	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2116	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2117	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2118	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2119	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2120	{
2121		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2122		.name = "Channel Mode",
2123		.info = alc_ch_mode_info,
2124		.get = alc_ch_mode_get,
2125		.put = alc_ch_mode_put,
2126	},
2127	{ } /* end */
2128};
2129
2130static struct hda_verb alc880_lg_init_verbs[] = {
2131	/* set capture source to mic-in */
2132	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2133	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2134	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2135	/* mute all amp mixer inputs */
2136	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2137	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2138	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2139	/* line-in to input */
2140	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2141	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2142	/* built-in mic */
2143	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2144	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2145	/* speaker-out */
2146	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2147	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2148	/* mic-in to input */
2149	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2150	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2151	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2152	/* HP-out */
2153	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2154	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2155	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156	/* jack sense */
2157	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2158	{ }
2159};
2160
2161/* toggle speaker-output according to the hp-jack state */
2162static void alc880_lg_automute(struct hda_codec *codec)
2163{
2164	unsigned int present;
2165	unsigned char bits;
2166
2167	present = snd_hda_codec_read(codec, 0x1b, 0,
2168				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2169	bits = present ? HDA_AMP_MUTE : 0;
2170	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2171				 HDA_AMP_MUTE, bits);
2172}
2173
2174static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2175{
2176	/* Looks like the unsol event is incompatible with the standard
2177	 * definition.  4bit tag is placed at 28 bit!
2178	 */
2179	if ((res >> 28) == 0x01)
2180		alc880_lg_automute(codec);
2181}
2182
2183/*
2184 * LG LW20
2185 *
2186 * Pin assignment:
2187 *   Speaker-out: 0x14
2188 *   Mic-In: 0x18
2189 *   Built-in Mic-In: 0x19
2190 *   Line-In: 0x1b
2191 *   HP-Out: 0x1a
2192 *   SPDIF-Out: 0x1e
2193 */
2194
2195static struct hda_input_mux alc880_lg_lw_capture_source = {
2196	.num_items = 3,
2197	.items = {
2198		{ "Mic", 0x0 },
2199		{ "Internal Mic", 0x1 },
2200		{ "Line In", 0x2 },
2201	},
2202};
2203
2204#define alc880_lg_lw_modes alc880_threestack_modes
2205
2206static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2207	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2208	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2209	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2210	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2211	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2212	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2213	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2214	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2215	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2216	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2217	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2218	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2219	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2220	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2221	{
2222		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2223		.name = "Channel Mode",
2224		.info = alc_ch_mode_info,
2225		.get = alc_ch_mode_get,
2226		.put = alc_ch_mode_put,
2227	},
2228	{ } /* end */
2229};
2230
2231static struct hda_verb alc880_lg_lw_init_verbs[] = {
2232	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2233	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2234	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2235
2236	/* set capture source to mic-in */
2237	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2238	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2239	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2240	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2241	/* speaker-out */
2242	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2243	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2244	/* HP-out */
2245	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2246	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2247	/* mic-in to input */
2248	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2249	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2250	/* built-in mic */
2251	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2252	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2253	/* jack sense */
2254	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2255	{ }
2256};
2257
2258/* toggle speaker-output according to the hp-jack state */
2259static void alc880_lg_lw_automute(struct hda_codec *codec)
2260{
2261	unsigned int present;
2262	unsigned char bits;
2263
2264	present = snd_hda_codec_read(codec, 0x1b, 0,
2265				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2266	bits = present ? HDA_AMP_MUTE : 0;
2267	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2268				 HDA_AMP_MUTE, bits);
2269}
2270
2271static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2272{
2273	/* Looks like the unsol event is incompatible with the standard
2274	 * definition.  4bit tag is placed at 28 bit!
2275	 */
2276	if ((res >> 28) == 0x01)
2277		alc880_lg_lw_automute(codec);
2278}
2279
2280static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2281	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2282	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2283	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2284	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2285	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2286	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2287	{ } /* end */
2288};
2289
2290static struct hda_input_mux alc880_medion_rim_capture_source = {
2291	.num_items = 2,
2292	.items = {
2293		{ "Mic", 0x0 },
2294		{ "Internal Mic", 0x1 },
2295	},
2296};
2297
2298static struct hda_verb alc880_medion_rim_init_verbs[] = {
2299	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2300
2301	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2302	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303
2304	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2305	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2306	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2307	/* Mic2 (as headphone out) for HP output */
2308	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2309	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2310	/* Internal Speaker */
2311	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2312	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2313
2314	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2315	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2316
2317	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2318	{ }
2319};
2320
2321/* toggle speaker-output according to the hp-jack state */
2322static void alc880_medion_rim_automute(struct hda_codec *codec)
2323{
2324	unsigned int present;
2325	unsigned char bits;
2326
2327	present = snd_hda_codec_read(codec, 0x14, 0,
2328				     AC_VERB_GET_PIN_SENSE, 0)
2329		& AC_PINSENSE_PRESENCE;
2330	bits = present ? HDA_AMP_MUTE : 0;
2331	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2332				 HDA_AMP_MUTE, bits);
2333	if (present)
2334		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2335	else
2336		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2337}
2338
2339static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2340					  unsigned int res)
2341{
2342	/* Looks like the unsol event is incompatible with the standard
2343	 * definition.  4bit tag is placed at 28 bit!
2344	 */
2345	if ((res >> 28) == ALC880_HP_EVENT)
2346		alc880_medion_rim_automute(codec);
2347}
2348
2349#ifdef CONFIG_SND_HDA_POWER_SAVE
2350static struct hda_amp_list alc880_loopbacks[] = {
2351	{ 0x0b, HDA_INPUT, 0 },
2352	{ 0x0b, HDA_INPUT, 1 },
2353	{ 0x0b, HDA_INPUT, 2 },
2354	{ 0x0b, HDA_INPUT, 3 },
2355	{ 0x0b, HDA_INPUT, 4 },
2356	{ } /* end */
2357};
2358
2359static struct hda_amp_list alc880_lg_loopbacks[] = {
2360	{ 0x0b, HDA_INPUT, 1 },
2361	{ 0x0b, HDA_INPUT, 6 },
2362	{ 0x0b, HDA_INPUT, 7 },
2363	{ } /* end */
2364};
2365#endif
2366
2367/*
2368 * Common callbacks
2369 */
2370
2371static int alc_init(struct hda_codec *codec)
2372{
2373	struct alc_spec *spec = codec->spec;
2374	unsigned int i;
2375
2376	for (i = 0; i < spec->num_init_verbs; i++)
2377		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2378
2379	if (spec->init_hook)
2380		spec->init_hook(codec);
2381
2382	return 0;
2383}
2384
2385static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2386{
2387	struct alc_spec *spec = codec->spec;
2388
2389	if (spec->unsol_event)
2390		spec->unsol_event(codec, res);
2391}
2392
2393#ifdef CONFIG_SND_HDA_POWER_SAVE
2394static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2395{
2396	struct alc_spec *spec = codec->spec;
2397	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2398}
2399#endif
2400
2401/*
2402 * Analog playback callbacks
2403 */
2404static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2405				    struct hda_codec *codec,
2406				    struct snd_pcm_substream *substream)
2407{
2408	struct alc_spec *spec = codec->spec;
2409	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2410					     hinfo);
2411}
2412
2413static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2414				       struct hda_codec *codec,
2415				       unsigned int stream_tag,
2416				       unsigned int format,
2417				       struct snd_pcm_substream *substream)
2418{
2419	struct alc_spec *spec = codec->spec;
2420	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2421						stream_tag, format, substream);
2422}
2423
2424static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2425				       struct hda_codec *codec,
2426				       struct snd_pcm_substream *substream)
2427{
2428	struct alc_spec *spec = codec->spec;
2429	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2430}
2431
2432/*
2433 * Digital out
2434 */
2435static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2436					struct hda_codec *codec,
2437					struct snd_pcm_substream *substream)
2438{
2439	struct alc_spec *spec = codec->spec;
2440	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2441}
2442
2443static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2444					   struct hda_codec *codec,
2445					   unsigned int stream_tag,
2446					   unsigned int format,
2447					   struct snd_pcm_substream *substream)
2448{
2449	struct alc_spec *spec = codec->spec;
2450	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2451					     stream_tag, format, substream);
2452}
2453
2454static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2455					 struct hda_codec *codec,
2456					 struct snd_pcm_substream *substream)
2457{
2458	struct alc_spec *spec = codec->spec;
2459	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2460}
2461
2462/*
2463 * Analog capture
2464 */
2465static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2466				      struct hda_codec *codec,
2467				      unsigned int stream_tag,
2468				      unsigned int format,
2469				      struct snd_pcm_substream *substream)
2470{
2471	struct alc_spec *spec = codec->spec;
2472
2473	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2474				   stream_tag, 0, format);
2475	return 0;
2476}
2477
2478static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2479				      struct hda_codec *codec,
2480				      struct snd_pcm_substream *substream)
2481{
2482	struct alc_spec *spec = codec->spec;
2483
2484	snd_hda_codec_cleanup_stream(codec,
2485				     spec->adc_nids[substream->number + 1]);
2486	return 0;
2487}
2488
2489
2490/*
2491 */
2492static struct hda_pcm_stream alc880_pcm_analog_playback = {
2493	.substreams = 1,
2494	.channels_min = 2,
2495	.channels_max = 8,
2496	/* NID is set in alc_build_pcms */
2497	.ops = {
2498		.open = alc880_playback_pcm_open,
2499		.prepare = alc880_playback_pcm_prepare,
2500		.cleanup = alc880_playback_pcm_cleanup
2501	},
2502};
2503
2504static struct hda_pcm_stream alc880_pcm_analog_capture = {
2505	.substreams = 1,
2506	.channels_min = 2,
2507	.channels_max = 2,
2508	/* NID is set in alc_build_pcms */
2509};
2510
2511static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2512	.substreams = 1,
2513	.channels_min = 2,
2514	.channels_max = 2,
2515	/* NID is set in alc_build_pcms */
2516};
2517
2518static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2519	.substreams = 2, /* can be overridden */
2520	.channels_min = 2,
2521	.channels_max = 2,
2522	/* NID is set in alc_build_pcms */
2523	.ops = {
2524		.prepare = alc880_alt_capture_pcm_prepare,
2525		.cleanup = alc880_alt_capture_pcm_cleanup
2526	},
2527};
2528
2529static struct hda_pcm_stream alc880_pcm_digital_playback = {
2530	.substreams = 1,
2531	.channels_min = 2,
2532	.channels_max = 2,
2533	/* NID is set in alc_build_pcms */
2534	.ops = {
2535		.open = alc880_dig_playback_pcm_open,
2536		.close = alc880_dig_playback_pcm_close,
2537		.prepare = alc880_dig_playback_pcm_prepare
2538	},
2539};
2540
2541static struct hda_pcm_stream alc880_pcm_digital_capture = {
2542	.substreams = 1,
2543	.channels_min = 2,
2544	.channels_max = 2,
2545	/* NID is set in alc_build_pcms */
2546};
2547
2548/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2549static struct hda_pcm_stream alc_pcm_null_stream = {
2550	.substreams = 0,
2551	.channels_min = 0,
2552	.channels_max = 0,
2553};
2554
2555static int alc_build_pcms(struct hda_codec *codec)
2556{
2557	struct alc_spec *spec = codec->spec;
2558	struct hda_pcm *info = spec->pcm_rec;
2559	int i;
2560
2561	codec->num_pcms = 1;
2562	codec->pcm_info = info;
2563
2564	info->name = spec->stream_name_analog;
2565	if (spec->stream_analog_playback) {
2566		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2567		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2568		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2569	}
2570	if (spec->stream_analog_capture) {
2571		snd_assert(spec->adc_nids, return -EINVAL);
2572		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2573		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2574	}
2575
2576	if (spec->channel_mode) {
2577		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2578		for (i = 0; i < spec->num_channel_mode; i++) {
2579			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2580				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2581			}
2582		}
2583	}
2584
2585	/* SPDIF for stream index #1 */
2586	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2587		codec->num_pcms = 2;
2588		info = spec->pcm_rec + 1;
2589		info->name = spec->stream_name_digital;
2590		info->pcm_type = HDA_PCM_TYPE_SPDIF;
2591		if (spec->multiout.dig_out_nid &&
2592		    spec->stream_digital_playback) {
2593			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2594			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2595		}
2596		if (spec->dig_in_nid &&
2597		    spec->stream_digital_capture) {
2598			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2599			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2600		}
2601	}
2602
2603	/* If the use of more than one ADC is requested for the current
2604	 * model, configure a second analog capture-only PCM.
2605	 */
2606	/* Additional Analaog capture for index #2 */
2607	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2608	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2609		codec->num_pcms = 3;
2610		info = spec->pcm_rec + 2;
2611		info->name = spec->stream_name_analog;
2612		if (spec->alt_dac_nid) {
2613			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2614				*spec->stream_analog_alt_playback;
2615			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2616				spec->alt_dac_nid;
2617		} else {
2618			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2619				alc_pcm_null_stream;
2620			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2621		}
2622		if (spec->num_adc_nids > 1) {
2623			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2624				*spec->stream_analog_alt_capture;
2625			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2626				spec->adc_nids[1];
2627			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2628				spec->num_adc_nids - 1;
2629		} else {
2630			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2631				alc_pcm_null_stream;
2632			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2633		}
2634	}
2635
2636	return 0;
2637}
2638
2639static void alc_free(struct hda_codec *codec)
2640{
2641	struct alc_spec *spec = codec->spec;
2642	unsigned int i;
2643
2644	if (!spec)
2645		return;
2646
2647	if (spec->kctl_alloc) {
2648		for (i = 0; i < spec->num_kctl_used; i++)
2649			kfree(spec->kctl_alloc[i].name);
2650		kfree(spec->kctl_alloc);
2651	}
2652	kfree(spec);
2653	codec->spec = NULL; /* to be sure */
2654}
2655
2656/*
2657 */
2658static struct hda_codec_ops alc_patch_ops = {
2659	.build_controls = alc_build_controls,
2660	.build_pcms = alc_build_pcms,
2661	.init = alc_init,
2662	.free = alc_free,
2663	.unsol_event = alc_unsol_event,
2664#ifdef CONFIG_SND_HDA_POWER_SAVE
2665	.check_power_status = alc_check_power_status,
2666#endif
2667};
2668
2669
2670/*
2671 * Test configuration for debugging
2672 *
2673 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2674 * enum controls.
2675 */
2676#ifdef CONFIG_SND_DEBUG
2677static hda_nid_t alc880_test_dac_nids[4] = {
2678	0x02, 0x03, 0x04, 0x05
2679};
2680
2681static struct hda_input_mux alc880_test_capture_source = {
2682	.num_items = 7,
2683	.items = {
2684		{ "In-1", 0x0 },
2685		{ "In-2", 0x1 },
2686		{ "In-3", 0x2 },
2687		{ "In-4", 0x3 },
2688		{ "CD", 0x4 },
2689		{ "Front", 0x5 },
2690		{ "Surround", 0x6 },
2691	},
2692};
2693
2694static struct hda_channel_mode alc880_test_modes[4] = {
2695	{ 2, NULL },
2696	{ 4, NULL },
2697	{ 6, NULL },
2698	{ 8, NULL },
2699};
2700
2701static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2702				 struct snd_ctl_elem_info *uinfo)
2703{
2704	static char *texts[] = {
2705		"N/A", "Line Out", "HP Out",
2706		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2707	};
2708	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2709	uinfo->count = 1;
2710	uinfo->value.enumerated.items = 8;
2711	if (uinfo->value.enumerated.item >= 8)
2712		uinfo->value.enumerated.item = 7;
2713	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2714	return 0;
2715}
2716
2717static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2718				struct snd_ctl_elem_value *ucontrol)
2719{
2720	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2721	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2722	unsigned int pin_ctl, item = 0;
2723
2724	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2725				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2726	if (pin_ctl & AC_PINCTL_OUT_EN) {
2727		if (pin_ctl & AC_PINCTL_HP_EN)
2728			item = 2;
2729		else
2730			item = 1;
2731	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2732		switch (pin_ctl & AC_PINCTL_VREFEN) {
2733		case AC_PINCTL_VREF_HIZ: item = 3; break;
2734		case AC_PINCTL_VREF_50:  item = 4; break;
2735		case AC_PINCTL_VREF_GRD: item = 5; break;
2736		case AC_PINCTL_VREF_80:  item = 6; break;
2737		case AC_PINCTL_VREF_100: item = 7; break;
2738		}
2739	}
2740	ucontrol->value.enumerated.item[0] = item;
2741	return 0;
2742}
2743
2744static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2745				struct snd_ctl_elem_value *ucontrol)
2746{
2747	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2748	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2749	static unsigned int ctls[] = {
2750		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2751		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2752		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2753		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2754		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2755		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2756	};
2757	unsigned int old_ctl, new_ctl;
2758
2759	old_ctl = snd_hda_codec_read(codec, nid, 0,
2760				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2761	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2762	if (old_ctl != new_ctl) {
2763		int val;
2764		snd_hda_codec_write_cache(codec, nid, 0,
2765					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2766					  new_ctl);
2767		val = ucontrol->value.enumerated.item[0] >= 3 ?
2768			HDA_AMP_MUTE : 0;
2769		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2770					 HDA_AMP_MUTE, val);
2771		return 1;
2772	}
2773	return 0;
2774}
2775
2776static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2777				 struct snd_ctl_elem_info *uinfo)
2778{
2779	static char *texts[] = {
2780		"Front", "Surround", "CLFE", "Side"
2781	};
2782	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2783	uinfo->count = 1;
2784	uinfo->value.enumerated.items = 4;
2785	if (uinfo->value.enumerated.item >= 4)
2786		uinfo->value.enumerated.item = 3;
2787	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2788	return 0;
2789}
2790
2791static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2792				struct snd_ctl_elem_value *ucontrol)
2793{
2794	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2795	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2796	unsigned int sel;
2797
2798	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2799	ucontrol->value.enumerated.item[0] = sel & 3;
2800	return 0;
2801}
2802
2803static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2804				struct snd_ctl_elem_value *ucontrol)
2805{
2806	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2807	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2808	unsigned int sel;
2809
2810	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2811	if (ucontrol->value.enumerated.item[0] != sel) {
2812		sel = ucontrol->value.enumerated.item[0] & 3;
2813		snd_hda_codec_write_cache(codec, nid, 0,
2814					  AC_VERB_SET_CONNECT_SEL, sel);
2815		return 1;
2816	}
2817	return 0;
2818}
2819
2820#define PIN_CTL_TEST(xname,nid) {			\
2821		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2822			.name = xname,		       \
2823			.info = alc_test_pin_ctl_info, \
2824			.get = alc_test_pin_ctl_get,   \
2825			.put = alc_test_pin_ctl_put,   \
2826			.private_value = nid	       \
2827			}
2828
2829#define PIN_SRC_TEST(xname,nid) {			\
2830		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2831			.name = xname,		       \
2832			.info = alc_test_pin_src_info, \
2833			.get = alc_test_pin_src_get,   \
2834			.put = alc_test_pin_src_put,   \
2835			.private_value = nid	       \
2836			}
2837
2838static struct snd_kcontrol_new alc880_test_mixer[] = {
2839	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2840	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2841	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2842	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2843	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2844	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2845	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2846	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2847	PIN_CTL_TEST("Front Pin Mode", 0x14),
2848	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2849	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2850	PIN_CTL_TEST("Side Pin Mode", 0x17),
2851	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2852	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2853	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2854	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2855	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2856	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2857	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2858	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2859	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2860	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2861	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2862	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2863	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2864	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2865	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2866	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2867	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2868	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2869	{
2870		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2871		.name = "Channel Mode",
2872		.info = alc_ch_mode_info,
2873		.get = alc_ch_mode_get,
2874		.put = alc_ch_mode_put,
2875	},
2876	{ } /* end */
2877};
2878
2879static struct hda_verb alc880_test_init_verbs[] = {
2880	/* Unmute inputs of 0x0c - 0x0f */
2881	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2882	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2883	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2884	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2885	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2886	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2887	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2888	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2889	/* Vol output for 0x0c-0x0f */
2890	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2891	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2892	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2893	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2894	/* Set output pins 0x14-0x17 */
2895	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2896	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2897	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2898	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2899	/* Unmute output pins 0x14-0x17 */
2900	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2901	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2902	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2903	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2904	/* Set input pins 0x18-0x1c */
2905	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2906	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2907	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2908	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2909	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2910	/* Mute input pins 0x18-0x1b */
2911	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2912	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2913	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2914	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2915	/* ADC set up */
2916	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2917	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2918	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2919	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2920	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2921	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2922	/* Analog input/passthru */
2923	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2924	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2925	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2926	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2927	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2928	{ }
2929};
2930#endif
2931
2932/*
2933 */
2934
2935static const char *alc880_models[ALC880_MODEL_LAST] = {
2936	[ALC880_3ST]		= "3stack",
2937	[ALC880_TCL_S700]	= "tcl",
2938	[ALC880_3ST_DIG]	= "3stack-digout",
2939	[ALC880_CLEVO]		= "clevo",
2940	[ALC880_5ST]		= "5stack",
2941	[ALC880_5ST_DIG]	= "5stack-digout",
2942	[ALC880_W810]		= "w810",
2943	[ALC880_Z71V]		= "z71v",
2944	[ALC880_6ST]		= "6stack",
2945	[ALC880_6ST_DIG]	= "6stack-digout",
2946	[ALC880_ASUS]		= "asus",
2947	[ALC880_ASUS_W1V]	= "asus-w1v",
2948	[ALC880_ASUS_DIG]	= "asus-dig",
2949	[ALC880_ASUS_DIG2]	= "asus-dig2",
2950	[ALC880_UNIWILL_DIG]	= "uniwill",
2951	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2952	[ALC880_FUJITSU]	= "fujitsu",
2953	[ALC880_F1734]		= "F1734",
2954	[ALC880_LG]		= "lg",
2955	[ALC880_LG_LW]		= "lg-lw",
2956	[ALC880_MEDION_RIM]	= "medion",
2957#ifdef CONFIG_SND_DEBUG
2958	[ALC880_TEST]		= "test",
2959#endif
2960	[ALC880_AUTO]		= "auto",
2961};
2962
2963static struct snd_pci_quirk alc880_cfg_tbl[] = {
2964	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2965	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2966	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2967	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2968	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2969	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2970	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2971	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2972	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2973	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2974	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2975	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2976	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2977	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2978	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2979	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2980	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2981	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2982	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2983	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2984	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2985	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
2986	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2987	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2988	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2989	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2990	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2991	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2992	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2993	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2994	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2995	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2996	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2997	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2998	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2999	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3000	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3001	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3002	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3003	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3004	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3005	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3006	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3007	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3008	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3009	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3010	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3011	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3012	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3013	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3014	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3015	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3016	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3017	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3018	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3019	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3020	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3021	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3022	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3023	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3024	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3025	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3026	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3027	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3028	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3029	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3030	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3031	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3032	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3033	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3034	{}
3035};
3036
3037/*
3038 * ALC880 codec presets
3039 */
3040static struct alc_config_preset alc880_presets[] = {
3041	[ALC880_3ST] = {
3042		.mixers = { alc880_three_stack_mixer },
3043		.init_verbs = { alc880_volume_init_verbs,
3044				alc880_pin_3stack_init_verbs },
3045		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3046		.dac_nids = alc880_dac_nids,
3047		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3048		.channel_mode = alc880_threestack_modes,
3049		.need_dac_fix = 1,
3050		.input_mux = &alc880_capture_source,
3051	},
3052	[ALC880_3ST_DIG] = {
3053		.mixers = { alc880_three_stack_mixer },
3054		.init_verbs = { alc880_volume_init_verbs,
3055				alc880_pin_3stack_init_verbs },
3056		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3057		.dac_nids = alc880_dac_nids,
3058		.dig_out_nid = ALC880_DIGOUT_NID,
3059		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3060		.channel_mode = alc880_threestack_modes,
3061		.need_dac_fix = 1,
3062		.input_mux = &alc880_capture_source,
3063	},
3064	[ALC880_TCL_S700] = {
3065		.mixers = { alc880_tcl_s700_mixer },
3066		.init_verbs = { alc880_volume_init_verbs,
3067				alc880_pin_tcl_S700_init_verbs,
3068				alc880_gpio2_init_verbs },
3069		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3070		.dac_nids = alc880_dac_nids,
3071		.hp_nid = 0x03,
3072		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3073		.channel_mode = alc880_2_jack_modes,
3074		.input_mux = &alc880_capture_source,
3075	},
3076	[ALC880_5ST] = {
3077		.mixers = { alc880_three_stack_mixer,
3078			    alc880_five_stack_mixer},
3079		.init_verbs = { alc880_volume_init_verbs,
3080				alc880_pin_5stack_init_verbs },
3081		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3082		.dac_nids = alc880_dac_nids,
3083		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3084		.channel_mode = alc880_fivestack_modes,
3085		.input_mux = &alc880_capture_source,
3086	},
3087	[ALC880_5ST_DIG] = {
3088		.mixers = { alc880_three_stack_mixer,
3089			    alc880_five_stack_mixer },
3090		.init_verbs = { alc880_volume_init_verbs,
3091				alc880_pin_5stack_init_verbs },
3092		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3093		.dac_nids = alc880_dac_nids,
3094		.dig_out_nid = ALC880_DIGOUT_NID,
3095		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3096		.channel_mode = alc880_fivestack_modes,
3097		.input_mux = &alc880_capture_source,
3098	},
3099	[ALC880_6ST] = {
3100		.mixers = { alc880_six_stack_mixer },
3101		.init_verbs = { alc880_volume_init_verbs,
3102				alc880_pin_6stack_init_verbs },
3103		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3104		.dac_nids = alc880_6st_dac_nids,
3105		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3106		.channel_mode = alc880_sixstack_modes,
3107		.input_mux = &alc880_6stack_capture_source,
3108	},
3109	[ALC880_6ST_DIG] = {
3110		.mixers = { alc880_six_stack_mixer },
3111		.init_verbs = { alc880_volume_init_verbs,
3112				alc880_pin_6stack_init_verbs },
3113		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3114		.dac_nids = alc880_6st_dac_nids,
3115		.dig_out_nid = ALC880_DIGOUT_NID,
3116		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3117		.channel_mode = alc880_sixstack_modes,
3118		.input_mux = &alc880_6stack_capture_source,
3119	},
3120	[ALC880_W810] = {
3121		.mixers = { alc880_w810_base_mixer },
3122		.init_verbs = { alc880_volume_init_verbs,
3123				alc880_pin_w810_init_verbs,
3124				alc880_gpio2_init_verbs },
3125		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3126		.dac_nids = alc880_w810_dac_nids,
3127		.dig_out_nid = ALC880_DIGOUT_NID,
3128		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3129		.channel_mode = alc880_w810_modes,
3130		.input_mux = &alc880_capture_source,
3131	},
3132	[ALC880_Z71V] = {
3133		.mixers = { alc880_z71v_mixer },
3134		.init_verbs = { alc880_volume_init_verbs,
3135				alc880_pin_z71v_init_verbs },
3136		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3137		.dac_nids = alc880_z71v_dac_nids,
3138		.dig_out_nid = ALC880_DIGOUT_NID,
3139		.hp_nid = 0x03,
3140		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3141		.channel_mode = alc880_2_jack_modes,
3142		.input_mux = &alc880_capture_source,
3143	},
3144	[ALC880_F1734] = {
3145		.mixers = { alc880_f1734_mixer },
3146		.init_verbs = { alc880_volume_init_verbs,
3147				alc880_pin_f1734_init_verbs },
3148		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3149		.dac_nids = alc880_f1734_dac_nids,
3150		.hp_nid = 0x02,
3151		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3152		.channel_mode = alc880_2_jack_modes,
3153		.input_mux = &alc880_f1734_capture_source,
3154		.unsol_event = alc880_uniwill_p53_unsol_event,
3155		.init_hook = alc880_uniwill_p53_hp_automute,
3156	},
3157	[ALC880_ASUS] = {
3158		.mixers = { alc880_asus_mixer },
3159		.init_verbs = { alc880_volume_init_verbs,
3160				alc880_pin_asus_init_verbs,
3161				alc880_gpio1_init_verbs },
3162		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3163		.dac_nids = alc880_asus_dac_nids,
3164		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3165		.channel_mode = alc880_asus_modes,
3166		.need_dac_fix = 1,
3167		.input_mux = &alc880_capture_source,
3168	},
3169	[ALC880_ASUS_DIG] = {
3170		.mixers = { alc880_asus_mixer },
3171		.init_verbs = { alc880_volume_init_verbs,
3172				alc880_pin_asus_init_verbs,
3173				alc880_gpio1_init_verbs },
3174		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3175		.dac_nids = alc880_asus_dac_nids,
3176		.dig_out_nid = ALC880_DIGOUT_NID,
3177		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3178		.channel_mode = alc880_asus_modes,
3179		.need_dac_fix = 1,
3180		.input_mux = &alc880_capture_source,
3181	},
3182	[ALC880_ASUS_DIG2] = {
3183		.mixers = { alc880_asus_mixer },
3184		.init_verbs = { alc880_volume_init_verbs,
3185				alc880_pin_asus_init_verbs,
3186				alc880_gpio2_init_verbs }, /* use GPIO2 */
3187		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3188		.dac_nids = alc880_asus_dac_nids,
3189		.dig_out_nid = ALC880_DIGOUT_NID,
3190		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3191		.channel_mode = alc880_asus_modes,
3192		.need_dac_fix = 1,
3193		.input_mux = &alc880_capture_source,
3194	},
3195	[ALC880_ASUS_W1V] = {
3196		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3197		.init_verbs = { alc880_volume_init_verbs,
3198				alc880_pin_asus_init_verbs,
3199				alc880_gpio1_init_verbs },
3200		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3201		.dac_nids = alc880_asus_dac_nids,
3202		.dig_out_nid = ALC880_DIGOUT_NID,
3203		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3204		.channel_mode = alc880_asus_modes,
3205		.need_dac_fix = 1,
3206		.input_mux = &alc880_capture_source,
3207	},
3208	[ALC880_UNIWILL_DIG] = {
3209		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3210		.init_verbs = { alc880_volume_init_verbs,
3211				alc880_pin_asus_init_verbs },
3212		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3213		.dac_nids = alc880_asus_dac_nids,
3214		.dig_out_nid = ALC880_DIGOUT_NID,
3215		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3216		.channel_mode = alc880_asus_modes,
3217		.need_dac_fix = 1,
3218		.input_mux = &alc880_capture_source,
3219	},
3220	[ALC880_UNIWILL] = {
3221		.mixers = { alc880_uniwill_mixer },
3222		.init_verbs = { alc880_volume_init_verbs,
3223				alc880_uniwill_init_verbs },
3224		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3225		.dac_nids = alc880_asus_dac_nids,
3226		.dig_out_nid = ALC880_DIGOUT_NID,
3227		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3228		.channel_mode = alc880_threestack_modes,
3229		.need_dac_fix = 1,
3230		.input_mux = &alc880_capture_source,
3231		.unsol_event = alc880_uniwill_unsol_event,
3232		.init_hook = alc880_uniwill_automute,
3233	},
3234	[ALC880_UNIWILL_P53] = {
3235		.mixers = { alc880_uniwill_p53_mixer },
3236		.init_verbs = { alc880_volume_init_verbs,
3237				alc880_uniwill_p53_init_verbs },
3238		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3239		.dac_nids = alc880_asus_dac_nids,
3240		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3241		.channel_mode = alc880_threestack_modes,
3242		.input_mux = &alc880_capture_source,
3243		.unsol_event = alc880_uniwill_p53_unsol_event,
3244		.init_hook = alc880_uniwill_p53_hp_automute,
3245	},
3246	[ALC880_FUJITSU] = {
3247		.mixers = { alc880_fujitsu_mixer,
3248			    alc880_pcbeep_mixer, },
3249		.init_verbs = { alc880_volume_init_verbs,
3250				alc880_uniwill_p53_init_verbs,
3251	       			alc880_beep_init_verbs },
3252		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3253		.dac_nids = alc880_dac_nids,
3254		.dig_out_nid = ALC880_DIGOUT_NID,
3255		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3256		.channel_mode = alc880_2_jack_modes,
3257		.input_mux = &alc880_capture_source,
3258		.unsol_event = alc880_uniwill_p53_unsol_event,
3259		.init_hook = alc880_uniwill_p53_hp_automute,
3260	},
3261	[ALC880_CLEVO] = {
3262		.mixers = { alc880_three_stack_mixer },
3263		.init_verbs = { alc880_volume_init_verbs,
3264				alc880_pin_clevo_init_verbs },
3265		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3266		.dac_nids = alc880_dac_nids,
3267		.hp_nid = 0x03,
3268		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3269		.channel_mode = alc880_threestack_modes,
3270		.need_dac_fix = 1,
3271		.input_mux = &alc880_capture_source,
3272	},
3273	[ALC880_LG] = {
3274		.mixers = { alc880_lg_mixer },
3275		.init_verbs = { alc880_volume_init_verbs,
3276				alc880_lg_init_verbs },
3277		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3278		.dac_nids = alc880_lg_dac_nids,
3279		.dig_out_nid = ALC880_DIGOUT_NID,
3280		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3281		.channel_mode = alc880_lg_ch_modes,
3282		.need_dac_fix = 1,
3283		.input_mux = &alc880_lg_capture_source,
3284		.unsol_event = alc880_lg_unsol_event,
3285		.init_hook = alc880_lg_automute,
3286#ifdef CONFIG_SND_HDA_POWER_SAVE
3287		.loopbacks = alc880_lg_loopbacks,
3288#endif
3289	},
3290	[ALC880_LG_LW] = {
3291		.mixers = { alc880_lg_lw_mixer },
3292		.init_verbs = { alc880_volume_init_verbs,
3293				alc880_lg_lw_init_verbs },
3294		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3295		.dac_nids = alc880_dac_nids,
3296		.dig_out_nid = ALC880_DIGOUT_NID,
3297		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3298		.channel_mode = alc880_lg_lw_modes,
3299		.input_mux = &alc880_lg_lw_capture_source,
3300		.unsol_event = alc880_lg_lw_unsol_event,
3301		.init_hook = alc880_lg_lw_automute,
3302	},
3303	[ALC880_MEDION_RIM] = {
3304		.mixers = { alc880_medion_rim_mixer },
3305		.init_verbs = { alc880_volume_init_verbs,
3306				alc880_medion_rim_init_verbs,
3307				alc_gpio2_init_verbs },
3308		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3309		.dac_nids = alc880_dac_nids,
3310		.dig_out_nid = ALC880_DIGOUT_NID,
3311		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3312		.channel_mode = alc880_2_jack_modes,
3313		.input_mux = &alc880_medion_rim_capture_source,
3314		.unsol_event = alc880_medion_rim_unsol_event,
3315		.init_hook = alc880_medion_rim_automute,
3316	},
3317#ifdef CONFIG_SND_DEBUG
3318	[ALC880_TEST] = {
3319		.mixers = { alc880_test_mixer },
3320		.init_verbs = { alc880_test_init_verbs },
3321		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3322		.dac_nids = alc880_test_dac_nids,
3323		.dig_out_nid = ALC880_DIGOUT_NID,
3324		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3325		.channel_mode = alc880_test_modes,
3326		.input_mux = &alc880_test_capture_source,
3327	},
3328#endif
3329};
3330
3331/*
3332 * Automatic parse of I/O pins from the BIOS configuration
3333 */
3334
3335#define NUM_CONTROL_ALLOC	32
3336#define NUM_VERB_ALLOC		32
3337
3338enum {
3339	ALC_CTL_WIDGET_VOL,
3340	ALC_CTL_WIDGET_MUTE,
3341	ALC_CTL_BIND_MUTE,
3342};
3343static struct snd_kcontrol_new alc880_control_templates[] = {
3344	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3345	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3346	HDA_BIND_MUTE(NULL, 0, 0, 0),
3347};
3348
3349/* add dynamic controls */
3350static int add_control(struct alc_spec *spec, int type, const char *name,
3351		       unsigned long val)
3352{
3353	struct snd_kcontrol_new *knew;
3354
3355	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3356		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3357
3358		/* array + terminator */
3359		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3360		if (!knew)
3361			return -ENOMEM;
3362		if (spec->kctl_alloc) {
3363			memcpy(knew, spec->kctl_alloc,
3364			       sizeof(*knew) * spec->num_kctl_alloc);
3365			kfree(spec->kctl_alloc);
3366		}
3367		spec->kctl_alloc = knew;
3368		spec->num_kctl_alloc = num;
3369	}
3370
3371	knew = &spec->kctl_alloc[spec->num_kctl_used];
3372	*knew = alc880_control_templates[type];
3373	knew->name = kstrdup(name, GFP_KERNEL);
3374	if (!knew->name)
3375		return -ENOMEM;
3376	knew->private_value = val;
3377	spec->num_kctl_used++;
3378	return 0;
3379}
3380
3381#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3382#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3383#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3384#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3385#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3386#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3387#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3388#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3389#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3390#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3391#define ALC880_PIN_CD_NID		0x1c
3392
3393/* fill in the dac_nids table from the parsed pin configuration */
3394static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3395				     const struct auto_pin_cfg *cfg)
3396{
3397	hda_nid_t nid;
3398	int assigned[4];
3399	int i, j;
3400
3401	memset(assigned, 0, sizeof(assigned));
3402	spec->multiout.dac_nids = spec->private_dac_nids;
3403
3404	/* check the pins hardwired to audio widget */
3405	for (i = 0; i < cfg->line_outs; i++) {
3406		nid = cfg->line_out_pins[i];
3407		if (alc880_is_fixed_pin(nid)) {
3408			int idx = alc880_fixed_pin_idx(nid);
3409			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3410			assigned[idx] = 1;
3411		}
3412	}
3413	/* left pins can be connect to any audio widget */
3414	for (i = 0; i < cfg->line_outs; i++) {
3415		nid = cfg->line_out_pins[i];
3416		if (alc880_is_fixed_pin(nid))
3417			continue;
3418		/* search for an empty channel */
3419		for (j = 0; j < cfg->line_outs; j++) {
3420			if (!assigned[j]) {
3421				spec->multiout.dac_nids[i] =
3422					alc880_idx_to_dac(j);
3423				assigned[j] = 1;
3424				break;
3425			}
3426		}
3427	}
3428	spec->multiout.num_dacs = cfg->line_outs;
3429	return 0;
3430}
3431
3432/* add playback controls from the parsed DAC table */
3433static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3434					     const struct auto_pin_cfg *cfg)
3435{
3436	char name[32];
3437	static const char *chname[4] = {
3438		"Front", "Surround", NULL /*CLFE*/, "Side"
3439	};
3440	hda_nid_t nid;
3441	int i, err;
3442
3443	for (i = 0; i < cfg->line_outs; i++) {
3444		if (!spec->multiout.dac_nids[i])
3445			continue;
3446		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3447		if (i == 2) {
3448			/* Center/LFE */
3449			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3450					  "Center Playback Volume",
3451					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3452							      HDA_OUTPUT));
3453			if (err < 0)
3454				return err;
3455			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3456					  "LFE Playback Volume",
3457					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3458							      HDA_OUTPUT));
3459			if (err < 0)
3460				return err;
3461			err = add_control(spec, ALC_CTL_BIND_MUTE,
3462					  "Center Playback Switch",
3463					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3464							      HDA_INPUT));
3465			if (err < 0)
3466				return err;
3467			err = add_control(spec, ALC_CTL_BIND_MUTE,
3468					  "LFE Playback Switch",
3469					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3470							      HDA_INPUT));
3471			if (err < 0)
3472				return err;
3473		} else {
3474			sprintf(name, "%s Playback Volume", chname[i]);
3475			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3476					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3477							      HDA_OUTPUT));
3478			if (err < 0)
3479				return err;
3480			sprintf(name, "%s Playback Switch", chname[i]);
3481			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3482					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3483							      HDA_INPUT));
3484			if (err < 0)
3485				return err;
3486		}
3487	}
3488	return 0;
3489}
3490
3491/* add playback controls for speaker and HP outputs */
3492static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3493					const char *pfx)
3494{
3495	hda_nid_t nid;
3496	int err;
3497	char name[32];
3498
3499	if (!pin)
3500		return 0;
3501
3502	if (alc880_is_fixed_pin(pin)) {
3503		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3504		/* specify the DAC as the extra output */
3505		if (!spec->multiout.hp_nid)
3506			spec->multiout.hp_nid = nid;
3507		else
3508			spec->multiout.extra_out_nid[0] = nid;
3509		/* control HP volume/switch on the output mixer amp */
3510		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3511		sprintf(name, "%s Playback Volume", pfx);
3512		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3513				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3514		if (err < 0)
3515			return err;
3516		sprintf(name, "%s Playback Switch", pfx);
3517		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3518				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3519		if (err < 0)
3520			return err;
3521	} else if (alc880_is_multi_pin(pin)) {
3522		/* set manual connection */
3523		/* we have only a switch on HP-out PIN */
3524		sprintf(name, "%s Playback Switch", pfx);
3525		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3526				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3527		if (err < 0)
3528			return err;
3529	}
3530	return 0;
3531}
3532
3533/* create input playback/capture controls for the given pin */
3534static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3535			    const char *ctlname,
3536			    int idx, hda_nid_t mix_nid)
3537{
3538	char name[32];
3539	int err;
3540
3541	sprintf(name, "%s Playback Volume", ctlname);
3542	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3543			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3544	if (err < 0)
3545		return err;
3546	sprintf(name, "%s Playback Switch", ctlname);
3547	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3548			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3549	if (err < 0)
3550		return err;
3551	return 0;
3552}
3553
3554/* create playback/capture controls for input pins */
3555static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3556						const struct auto_pin_cfg *cfg)
3557{
3558	struct hda_input_mux *imux = &spec->private_imux;
3559	int i, err, idx;
3560
3561	for (i = 0; i < AUTO_PIN_LAST; i++) {
3562		if (alc880_is_input_pin(cfg->input_pins[i])) {
3563			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3564			err = new_analog_input(spec, cfg->input_pins[i],
3565					       auto_pin_cfg_labels[i],
3566					       idx, 0x0b);
3567			if (err < 0)
3568				return err;
3569			imux->items[imux->num_items].label =
3570				auto_pin_cfg_labels[i];
3571			imux->items[imux->num_items].index =
3572				alc880_input_pin_idx(cfg->input_pins[i]);
3573			imux->num_items++;
3574		}
3575	}
3576	return 0;
3577}
3578
3579static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3580			       unsigned int pin_type)
3581{
3582	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3583			    pin_type);
3584	/* unmute pin */
3585	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3586			    AMP_OUT_UNMUTE);
3587}
3588
3589static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3590					      hda_nid_t nid, int pin_type,
3591					      int dac_idx)
3592{
3593	alc_set_pin_output(codec, nid, pin_type);
3594	/* need the manual connection? */
3595	if (alc880_is_multi_pin(nid)) {
3596		struct alc_spec *spec = codec->spec;
3597		int idx = alc880_multi_pin_idx(nid);
3598		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3599				    AC_VERB_SET_CONNECT_SEL,
3600				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3601	}
3602}
3603
3604static int get_pin_type(int line_out_type)
3605{
3606	if (line_out_type == AUTO_PIN_HP_OUT)
3607		return PIN_HP;
3608	else
3609		return PIN_OUT;
3610}
3611
3612static void alc880_auto_init_multi_out(struct hda_codec *codec)
3613{
3614	struct alc_spec *spec = codec->spec;
3615	int i;
3616
3617	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3618	for (i = 0; i < spec->autocfg.line_outs; i++) {
3619		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3620		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3621		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3622	}
3623}
3624
3625static void alc880_auto_init_extra_out(struct hda_codec *codec)
3626{
3627	struct alc_spec *spec = codec->spec;
3628	hda_nid_t pin;
3629
3630	pin = spec->autocfg.speaker_pins[0];
3631	if (pin) /* connect to front */
3632		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3633	pin = spec->autocfg.hp_pins[0];
3634	if (pin) /* connect to front */
3635		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3636}
3637
3638static void alc880_auto_init_analog_input(struct hda_codec *codec)
3639{
3640	struct alc_spec *spec = codec->spec;
3641	int i;
3642
3643	for (i = 0; i < AUTO_PIN_LAST; i++) {
3644		hda_nid_t nid = spec->autocfg.input_pins[i];
3645		if (alc880_is_input_pin(nid)) {
3646			snd_hda_codec_write(codec, nid, 0,
3647					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3648					    i <= AUTO_PIN_FRONT_MIC ?
3649					    PIN_VREF80 : PIN_IN);
3650			if (nid != ALC880_PIN_CD_NID)
3651				snd_hda_codec_write(codec, nid, 0,
3652						    AC_VERB_SET_AMP_GAIN_MUTE,
3653						    AMP_OUT_MUTE);
3654		}
3655	}
3656}
3657
3658/* parse the BIOS configuration and set up the alc_spec */
3659/* return 1 if successful, 0 if the proper config is not found,
3660 * or a negative error code
3661 */
3662static int alc880_parse_auto_config(struct hda_codec *codec)
3663{
3664	struct alc_spec *spec = codec->spec;
3665	int err;
3666	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3667
3668	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3669					   alc880_ignore);
3670	if (err < 0)
3671		return err;
3672	if (!spec->autocfg.line_outs)
3673		return 0; /* can't find valid BIOS pin config */
3674
3675	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3676	if (err < 0)
3677		return err;
3678	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3679	if (err < 0)
3680		return err;
3681	err = alc880_auto_create_extra_out(spec,
3682					   spec->autocfg.speaker_pins[0],
3683					   "Speaker");
3684	if (err < 0)
3685		return err;
3686	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3687					   "Headphone");
3688	if (err < 0)
3689		return err;
3690	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3691	if (err < 0)
3692		return err;
3693
3694	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3695
3696	if (spec->autocfg.dig_out_pin)
3697		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3698	if (spec->autocfg.dig_in_pin)
3699		spec->dig_in_nid = ALC880_DIGIN_NID;
3700
3701	if (spec->kctl_alloc)
3702		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3703
3704	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3705
3706	spec->num_mux_defs = 1;
3707	spec->input_mux = &spec->private_imux;
3708
3709	return 1;
3710}
3711
3712/* additional initialization for auto-configuration model */
3713static void alc880_auto_init(struct hda_codec *codec)
3714{
3715	struct alc_spec *spec = codec->spec;
3716	alc880_auto_init_multi_out(codec);
3717	alc880_auto_init_extra_out(codec);
3718	alc880_auto_init_analog_input(codec);
3719	if (spec->unsol_event)
3720		alc_sku_automute(codec);
3721}
3722
3723/*
3724 * OK, here we have finally the patch for ALC880
3725 */
3726
3727static int patch_alc880(struct hda_codec *codec)
3728{
3729	struct alc_spec *spec;
3730	int board_config;
3731	int err;
3732
3733	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3734	if (spec == NULL)
3735		return -ENOMEM;
3736
3737	codec->spec = spec;
3738
3739	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3740						  alc880_models,
3741						  alc880_cfg_tbl);
3742	if (board_config < 0) {
3743		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3744		       "trying auto-probe from BIOS...\n");
3745		board_config = ALC880_AUTO;
3746	}
3747
3748	if (board_config == ALC880_AUTO) {
3749		/* automatic parse from the BIOS config */
3750		err = alc880_parse_auto_config(codec);
3751		if (err < 0) {
3752			alc_free(codec);
3753			return err;
3754		} else if (!err) {
3755			printk(KERN_INFO
3756			       "hda_codec: Cannot set up configuration "
3757			       "from BIOS.  Using 3-stack mode...\n");
3758			board_config = ALC880_3ST;
3759		}
3760	}
3761
3762	if (board_config != ALC880_AUTO)
3763		setup_preset(spec, &alc880_presets[board_config]);
3764
3765	spec->stream_name_analog = "ALC880 Analog";
3766	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3767	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3768	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3769
3770	spec->stream_name_digital = "ALC880 Digital";
3771	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3772	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3773
3774	if (!spec->adc_nids && spec->input_mux) {
3775		/* check whether NID 0x07 is valid */
3776		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3777		/* get type */
3778		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3779		if (wcap != AC_WID_AUD_IN) {
3780			spec->adc_nids = alc880_adc_nids_alt;
3781			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3782			spec->mixers[spec->num_mixers] =
3783				alc880_capture_alt_mixer;
3784			spec->num_mixers++;
3785		} else {
3786			spec->adc_nids = alc880_adc_nids;
3787			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3788			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3789			spec->num_mixers++;
3790		}
3791	}
3792
3793	spec->vmaster_nid = 0x0c;
3794
3795	codec->patch_ops = alc_patch_ops;
3796	if (board_config == ALC880_AUTO)
3797		spec->init_hook = alc880_auto_init;
3798#ifdef CONFIG_SND_HDA_POWER_SAVE
3799	if (!spec->loopback.amplist)
3800		spec->loopback.amplist = alc880_loopbacks;
3801#endif
3802
3803	return 0;
3804}
3805
3806
3807/*
3808 * ALC260 support
3809 */
3810
3811static hda_nid_t alc260_dac_nids[1] = {
3812	/* front */
3813	0x02,
3814};
3815
3816static hda_nid_t alc260_adc_nids[1] = {
3817	/* ADC0 */
3818	0x04,
3819};
3820
3821static hda_nid_t alc260_adc_nids_alt[1] = {
3822	/* ADC1 */
3823	0x05,
3824};
3825
3826static hda_nid_t alc260_hp_adc_nids[2] = {
3827	/* ADC1, 0 */
3828	0x05, 0x04
3829};
3830
3831/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3832 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3833 */
3834static hda_nid_t alc260_dual_adc_nids[2] = {
3835	/* ADC0, ADC1 */
3836	0x04, 0x05
3837};
3838
3839#define ALC260_DIGOUT_NID	0x03
3840#define ALC260_DIGIN_NID	0x06
3841
3842static struct hda_input_mux alc260_capture_source = {
3843	.num_items = 4,
3844	.items = {
3845		{ "Mic", 0x0 },
3846		{ "Front Mic", 0x1 },
3847		{ "Line", 0x2 },
3848		{ "CD", 0x4 },
3849	},
3850};
3851
3852/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3853 * headphone jack and the internal CD lines since these are the only pins at
3854 * which audio can appear.  For flexibility, also allow the option of
3855 * recording the mixer output on the second ADC (ADC0 doesn't have a
3856 * connection to the mixer output).
3857 */
3858static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3859	{
3860		.num_items = 3,
3861		.items = {
3862			{ "Mic/Line", 0x0 },
3863			{ "CD", 0x4 },
3864			{ "Headphone", 0x2 },
3865		},
3866	},
3867	{
3868		.num_items = 4,
3869		.items = {
3870			{ "Mic/Line", 0x0 },
3871			{ "CD", 0x4 },
3872			{ "Headphone", 0x2 },
3873			{ "Mixer", 0x5 },
3874		},
3875	},
3876
3877};
3878
3879/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3880 * the Fujitsu S702x, but jacks are marked differently.
3881 */
3882static struct hda_input_mux alc260_acer_capture_sources[2] = {
3883	{
3884		.num_items = 4,
3885		.items = {
3886			{ "Mic", 0x0 },
3887			{ "Line", 0x2 },
3888			{ "CD", 0x4 },
3889			{ "Headphone", 0x5 },
3890		},
3891	},
3892	{
3893		.num_items = 5,
3894		.items = {
3895			{ "Mic", 0x0 },
3896			{ "Line", 0x2 },
3897			{ "CD", 0x4 },
3898			{ "Headphone", 0x6 },
3899			{ "Mixer", 0x5 },
3900		},
3901	},
3902};
3903/*
3904 * This is just place-holder, so there's something for alc_build_pcms to look
3905 * at when it calculates the maximum number of channels. ALC260 has no mixer
3906 * element which allows changing the channel mode, so the verb list is
3907 * never used.
3908 */
3909static struct hda_channel_mode alc260_modes[1] = {
3910	{ 2, NULL },
3911};
3912
3913
3914/* Mixer combinations
3915 *
3916 * basic: base_output + input + pc_beep + capture
3917 * HP: base_output + input + capture_alt
3918 * HP_3013: hp_3013 + input + capture
3919 * fujitsu: fujitsu + capture
3920 * acer: acer + capture
3921 */
3922
3923static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3924	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3925	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3926	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3927	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3928	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3929	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3930	{ } /* end */
3931};
3932
3933static struct snd_kcontrol_new alc260_input_mixer[] = {
3934	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3935	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3936	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3937	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3938	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3939	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3940	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3941	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3942	{ } /* end */
3943};
3944
3945static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3946	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3947	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3948	{ } /* end */
3949};
3950
3951/* update HP, line and mono out pins according to the master switch */
3952static void alc260_hp_master_update(struct hda_codec *codec,
3953				    hda_nid_t hp, hda_nid_t line,
3954				    hda_nid_t mono)
3955{
3956	struct alc_spec *spec = codec->spec;
3957	unsigned int val = spec->master_sw ? PIN_HP : 0;
3958	/* change HP and line-out pins */
3959	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3960			    val);
3961	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3962			    val);
3963	/* mono (speaker) depending on the HP jack sense */
3964	val = (val && !spec->jack_present) ? PIN_OUT : 0;
3965	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3966			    val);
3967}
3968
3969static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3970				   struct snd_ctl_elem_value *ucontrol)
3971{
3972	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3973	struct alc_spec *spec = codec->spec;
3974	*ucontrol->value.integer.value = spec->master_sw;
3975	return 0;
3976}
3977
3978static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3979				   struct snd_ctl_elem_value *ucontrol)
3980{
3981	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3982	struct alc_spec *spec = codec->spec;
3983	int val = !!*ucontrol->value.integer.value;
3984	hda_nid_t hp, line, mono;
3985
3986	if (val == spec->master_sw)
3987		return 0;
3988	spec->master_sw = val;
3989	hp = (kcontrol->private_value >> 16) & 0xff;
3990	line = (kcontrol->private_value >> 8) & 0xff;
3991	mono = kcontrol->private_value & 0xff;
3992	alc260_hp_master_update(codec, hp, line, mono);
3993	return 1;
3994}
3995
3996static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3997	{
3998		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3999		.name = "Master Playback Switch",
4000		.info = snd_ctl_boolean_mono_info,
4001		.get = alc260_hp_master_sw_get,
4002		.put = alc260_hp_master_sw_put,
4003		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4004	},
4005	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4006	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4007	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4008	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4009	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4010			      HDA_OUTPUT),
4011	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4012	{ } /* end */
4013};
4014
4015static struct hda_verb alc260_hp_unsol_verbs[] = {
4016	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4017	{},
4018};
4019
4020static void alc260_hp_automute(struct hda_codec *codec)
4021{
4022	struct alc_spec *spec = codec->spec;
4023	unsigned int present;
4024
4025	present = snd_hda_codec_read(codec, 0x10, 0,
4026				     AC_VERB_GET_PIN_SENSE, 0);
4027	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4028	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4029}
4030
4031static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4032{
4033	if ((res >> 26) == ALC880_HP_EVENT)
4034		alc260_hp_automute(codec);
4035}
4036
4037static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4038	{
4039		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4040		.name = "Master Playback Switch",
4041		.info = snd_ctl_boolean_mono_info,
4042		.get = alc260_hp_master_sw_get,
4043		.put = alc260_hp_master_sw_put,
4044		.private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4045	},
4046	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4047	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4048	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4049	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4050	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4051	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4052	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4053	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4054	{ } /* end */
4055};
4056
4057static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4058	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4059	{},
4060};
4061
4062static void alc260_hp_3013_automute(struct hda_codec *codec)
4063{
4064	struct alc_spec *spec = codec->spec;
4065	unsigned int present;
4066
4067	present = snd_hda_codec_read(codec, 0x15, 0,
4068				     AC_VERB_GET_PIN_SENSE, 0);
4069	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4070	alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4071}
4072
4073static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4074				       unsigned int res)
4075{
4076	if ((res >> 26) == ALC880_HP_EVENT)
4077		alc260_hp_3013_automute(codec);
4078}
4079
4080/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4081 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4082 */
4083static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4084	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4085	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4086	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4087	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4088	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4089	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4090	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4091	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4092	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4093	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4094	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4095	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4096	{ } /* end */
4097};
4098
4099/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4100 * versions of the ALC260 don't act on requests to enable mic bias from NID
4101 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4102 * datasheet doesn't mention this restriction.  At this stage it's not clear
4103 * whether this behaviour is intentional or is a hardware bug in chip
4104 * revisions available in early 2006.  Therefore for now allow the
4105 * "Headphone Jack Mode" control to span all choices, but if it turns out
4106 * that the lack of mic bias for this NID is intentional we could change the
4107 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4108 *
4109 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4110 * don't appear to make the mic bias available from the "line" jack, even
4111 * though the NID used for this jack (0x14) can supply it.  The theory is
4112 * that perhaps Acer have included blocking capacitors between the ALC260
4113 * and the output jack.  If this turns out to be the case for all such
4114 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4115 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4116 *
4117 * The C20x Tablet series have a mono internal speaker which is controlled
4118 * via the chip's Mono sum widget and pin complex, so include the necessary
4119 * controls for such models.  On models without a "mono speaker" the control
4120 * won't do anything.
4121 */
4122static struct snd_kcontrol_new alc260_acer_mixer[] = {
4123	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4124	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4125	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4126	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4127			      HDA_OUTPUT),
4128	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4129			   HDA_INPUT),
4130	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4131	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4132	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4133	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4134	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4135	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4136	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4137	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4138	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4139	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4140	{ } /* end */
4141};
4142
4143/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4144 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4145 */
4146static struct snd_kcontrol_new alc260_will_mixer[] = {
4147	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4148	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4149	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4150	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4151	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4152	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4153	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4154	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4155	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4156	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4157	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4158	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4159	{ } /* end */
4160};
4161
4162/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4163 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4164 */
4165static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4166	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4167	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4168	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4169	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4170	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4171	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4172	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4173	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4174	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4175	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4176	{ } /* end */
4177};
4178
4179/* capture mixer elements */
4180static struct snd_kcontrol_new alc260_capture_mixer[] = {
4181	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4182	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4183	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4184	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4185	{
4186		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4187		/* The multiple "Capture Source" controls confuse alsamixer
4188		 * So call somewhat different..
4189		 */
4190		/* .name = "Capture Source", */
4191		.name = "Input Source",
4192		.count = 2,
4193		.info = alc_mux_enum_info,
4194		.get = alc_mux_enum_get,
4195		.put = alc_mux_enum_put,
4196	},
4197	{ } /* end */
4198};
4199
4200static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4201	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4202	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4203	{
4204		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4205		/* The multiple "Capture Source" controls confuse alsamixer
4206		 * So call somewhat different..
4207		 */
4208		/* .name = "Capture Source", */
4209		.name = "Input Source",
4210		.count = 1,
4211		.info = alc_mux_enum_info,
4212		.get = alc_mux_enum_get,
4213		.put = alc_mux_enum_put,
4214	},
4215	{ } /* end */
4216};
4217
4218/*
4219 * initialization verbs
4220 */
4221static struct hda_verb alc260_init_verbs[] = {
4222	/* Line In pin widget for input */
4223	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4224	/* CD pin widget for input */
4225	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4226	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4227	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4228	/* Mic2 (front panel) pin widget for input and vref at 80% */
4229	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4230	/* LINE-2 is used for line-out in rear */
4231	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4232	/* select line-out */
4233	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4234	/* LINE-OUT pin */
4235	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4236	/* enable HP */
4237	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4238	/* enable Mono */
4239	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4240	/* mute capture amp left and right */
4241	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4242	/* set connection select to line in (default select for this ADC) */
4243	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4244	/* mute capture amp left and right */
4245	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4246	/* set connection select to line in (default select for this ADC) */
4247	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4248	/* set vol=0 Line-Out mixer amp left and right */
4249	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4250	/* unmute pin widget amp left and right (no gain on this amp) */
4251	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4252	/* set vol=0 HP mixer amp left and right */
4253	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4254	/* unmute pin widget amp left and right (no gain on this amp) */
4255	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4256	/* set vol=0 Mono mixer amp left and right */
4257	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4258	/* unmute pin widget amp left and right (no gain on this amp) */
4259	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4260	/* unmute LINE-2 out pin */
4261	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4262	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4263	 * Line In 2 = 0x03
4264	 */
4265	/* mute analog inputs */
4266	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4267	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4268	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4269	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4270	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4271	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4272	/* mute Front out path */
4273	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4274	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4275	/* mute Headphone out path */
4276	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4277	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4278	/* mute Mono out path */
4279	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4280	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4281	{ }
4282};
4283
4284#if 0 /* should be identical with alc260_init_verbs? */
4285static struct hda_verb alc260_hp_init_verbs[] = {
4286	/* Headphone and output */
4287	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4288	/* mono output */
4289	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4290	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4291	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4292	/* Mic2 (front panel) pin widget for input and vref at 80% */
4293	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4294	/* Line In pin widget for input */
4295	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4296	/* Line-2 pin widget for output */
4297	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4298	/* CD pin widget for input */
4299	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4300	/* unmute amp left and right */
4301	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4302	/* set connection select to line in (default select for this ADC) */
4303	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4304	/* unmute Line-Out mixer amp left and right (volume = 0) */
4305	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4306	/* mute pin widget amp left and right (no gain on this amp) */
4307	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4308	/* unmute HP mixer amp left and right (volume = 0) */
4309	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4310	/* mute pin widget amp left and right (no gain on this amp) */
4311	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4312	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4313	 * Line In 2 = 0x03
4314	 */
4315	/* mute analog inputs */
4316	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4317	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4318	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4319	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4320	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4321	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4322	/* Unmute Front out path */
4323	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4324	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4325	/* Unmute Headphone out path */
4326	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4327	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4328	/* Unmute Mono out path */
4329	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4330	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4331	{ }
4332};
4333#endif
4334
4335static struct hda_verb alc260_hp_3013_init_verbs[] = {
4336	/* Line out and output */
4337	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4338	/* mono output */
4339	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4340	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4341	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4342	/* Mic2 (front panel) pin widget for input and vref at 80% */
4343	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4344	/* Line In pin widget for input */
4345	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4346	/* Headphone pin widget for output */
4347	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4348	/* CD pin widget for input */
4349	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4350	/* unmute amp left and right */
4351	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4352	/* set connection select to line in (default select for this ADC) */
4353	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4354	/* unmute Line-Out mixer amp left and right (volume = 0) */
4355	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4356	/* mute pin widget amp left and right (no gain on this amp) */
4357	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4358	/* unmute HP mixer amp left and right (volume = 0) */
4359	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4360	/* mute pin widget amp left and right (no gain on this amp) */
4361	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4362	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4363	 * Line In 2 = 0x03
4364	 */
4365	/* mute analog inputs */
4366	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4367	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4368	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4369	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4370	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4371	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4372	/* Unmute Front out path */
4373	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4374	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4375	/* Unmute Headphone out path */
4376	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4377	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4378	/* Unmute Mono out path */
4379	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4380	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4381	{ }
4382};
4383
4384/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4385 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4386 * audio = 0x16, internal speaker = 0x10.
4387 */
4388static struct hda_verb alc260_fujitsu_init_verbs[] = {
4389	/* Disable all GPIOs */
4390	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4391	/* Internal speaker is connected to headphone pin */
4392	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4393	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4394	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4395	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4396	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4397	/* Ensure all other unused pins are disabled and muted. */
4398	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4399	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4400	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4401	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4402	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4403	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4404	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4405	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4406
4407	/* Disable digital (SPDIF) pins */
4408	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4409	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4410
4411	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4412	 * when acting as an output.
4413	 */
4414	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4415
4416	/* Start with output sum widgets muted and their output gains at min */
4417	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4418	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4419	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4420	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4421	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4422	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4423	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4424	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4425	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4426
4427	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4428	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4429	/* Unmute Line1 pin widget output buffer since it starts as an output.
4430	 * If the pin mode is changed by the user the pin mode control will
4431	 * take care of enabling the pin's input/output buffers as needed.
4432	 * Therefore there's no need to enable the input buffer at this
4433	 * stage.
4434	 */
4435	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4436	/* Unmute input buffer of pin widget used for Line-in (no equiv
4437	 * mixer ctrl)
4438	 */
4439	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4440
4441	/* Mute capture amp left and right */
4442	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4443	/* Set ADC connection select to match default mixer setting - line
4444	 * in (on mic1 pin)
4445	 */
4446	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4447
4448	/* Do the same for the second ADC: mute capture input amp and
4449	 * set ADC connection to line in (on mic1 pin)
4450	 */
4451	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4452	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4453
4454	/* Mute all inputs to mixer widget (even unconnected ones) */
4455	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4456	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4457	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4458	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4459	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4460	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4461	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4462	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4463
4464	{ }
4465};
4466
4467/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4468 * similar laptops (adapted from Fujitsu init verbs).
4469 */
4470static struct hda_verb alc260_acer_init_verbs[] = {
4471	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4472	 * the headphone jack.  Turn this on and rely on the standard mute
4473	 * methods whenever the user wants to turn these outputs off.
4474	 */
4475	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4476	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4477	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4478	/* Internal speaker/Headphone jack is connected to Line-out pin */
4479	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4480	/* Internal microphone/Mic jack is connected to Mic1 pin */
4481	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4482	/* Line In jack is connected to Line1 pin */
4483	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4484	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4485	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4486	/* Ensure all other unused pins are disabled and muted. */
4487	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4488	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4489	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4490	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4491	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4492	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4493	/* Disable digital (SPDIF) pins */
4494	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4495	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4496
4497	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4498	 * bus when acting as outputs.
4499	 */
4500	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4501	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4502
4503	/* Start with output sum widgets muted and their output gains at min */
4504	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4505	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4506	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4507	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4508	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4509	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4510	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4511	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4512	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4513
4514	/* Unmute Line-out pin widget amp left and right
4515	 * (no equiv mixer ctrl)
4516	 */
4517	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4518	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4519	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4520	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4521	 * inputs. If the pin mode is changed by the user the pin mode control
4522	 * will take care of enabling the pin's input/output buffers as needed.
4523	 * Therefore there's no need to enable the input buffer at this
4524	 * stage.
4525	 */
4526	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4527	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4528
4529	/* Mute capture amp left and right */
4530	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4531	/* Set ADC connection select to match default mixer setting - mic
4532	 * (on mic1 pin)
4533	 */
4534	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4535
4536	/* Do similar with the second ADC: mute capture input amp and
4537	 * set ADC connection to mic to match ALSA's default state.
4538	 */
4539	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4540	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4541
4542	/* Mute all inputs to mixer widget (even unconnected ones) */
4543	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4544	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4545	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4546	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4547	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4548	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4549	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4550	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4551
4552	{ }
4553};
4554
4555static struct hda_verb alc260_will_verbs[] = {
4556	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4557	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4558	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4559	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4560	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4561	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4562	{}
4563};
4564
4565static struct hda_verb alc260_replacer_672v_verbs[] = {
4566	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4567	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4568	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4569
4570	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4571	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4572	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4573
4574	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4575	{}
4576};
4577
4578/* toggle speaker-output according to the hp-jack state */
4579static void alc260_replacer_672v_automute(struct hda_codec *codec)
4580{
4581        unsigned int present;
4582
4583	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4584        present = snd_hda_codec_read(codec, 0x0f, 0,
4585                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4586	if (present) {
4587		snd_hda_codec_write_cache(codec, 0x01, 0,
4588					  AC_VERB_SET_GPIO_DATA, 1);
4589		snd_hda_codec_write_cache(codec, 0x0f, 0,
4590					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4591					  PIN_HP);
4592	} else {
4593		snd_hda_codec_write_cache(codec, 0x01, 0,
4594					  AC_VERB_SET_GPIO_DATA, 0);
4595		snd_hda_codec_write_cache(codec, 0x0f, 0,
4596					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4597					  PIN_OUT);
4598	}
4599}
4600
4601static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4602                                       unsigned int res)
4603{
4604        if ((res >> 26) == ALC880_HP_EVENT)
4605                alc260_replacer_672v_automute(codec);
4606}
4607
4608/* Test configuration for debugging, modelled after the ALC880 test
4609 * configuration.
4610 */
4611#ifdef CONFIG_SND_DEBUG
4612static hda_nid_t alc260_test_dac_nids[1] = {
4613	0x02,
4614};
4615static hda_nid_t alc260_test_adc_nids[2] = {
4616	0x04, 0x05,
4617};
4618/* For testing the ALC260, each input MUX needs its own definition since
4619 * the signal assignments are different.  This assumes that the first ADC
4620 * is NID 0x04.
4621 */
4622static struct hda_input_mux alc260_test_capture_sources[2] = {
4623	{
4624		.num_items = 7,
4625		.items = {
4626			{ "MIC1 pin", 0x0 },
4627			{ "MIC2 pin", 0x1 },
4628			{ "LINE1 pin", 0x2 },
4629			{ "LINE2 pin", 0x3 },
4630			{ "CD pin", 0x4 },
4631			{ "LINE-OUT pin", 0x5 },
4632			{ "HP-OUT pin", 0x6 },
4633		},
4634        },
4635	{
4636		.num_items = 8,
4637		.items = {
4638			{ "MIC1 pin", 0x0 },
4639			{ "MIC2 pin", 0x1 },
4640			{ "LINE1 pin", 0x2 },
4641			{ "LINE2 pin", 0x3 },
4642			{ "CD pin", 0x4 },
4643			{ "Mixer", 0x5 },
4644			{ "LINE-OUT pin", 0x6 },
4645			{ "HP-OUT pin", 0x7 },
4646		},
4647        },
4648};
4649static struct snd_kcontrol_new alc260_test_mixer[] = {
4650	/* Output driver widgets */
4651	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4652	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4653	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4654	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4655	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4656	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4657
4658	/* Modes for retasking pin widgets
4659	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4660         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4661         * mention this restriction.  At this stage it's not clear whether
4662         * this behaviour is intentional or is a hardware bug in chip
4663         * revisions available at least up until early 2006.  Therefore for
4664         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4665         * choices, but if it turns out that the lack of mic bias for these
4666         * NIDs is intentional we could change their modes from
4667         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4668	 */
4669	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4670	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4671	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4672	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4673	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4674	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4675
4676	/* Loopback mixer controls */
4677	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4678	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4679	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4680	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4681	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4682	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4683	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4684	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4685	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4686	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4687	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4688	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4689	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4690	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4691	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4692	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4693
4694	/* Controls for GPIO pins, assuming they are configured as outputs */
4695	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4696	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4697	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4698	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4699
4700	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4701	 * is ambigious as to which NID is which; testing on laptops which
4702	 * make this output available should provide clarification.
4703	 */
4704	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4705	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4706
4707	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
4708	 * this output to turn on an external amplifier.
4709	 */
4710	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4711	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4712
4713	{ } /* end */
4714};
4715static struct hda_verb alc260_test_init_verbs[] = {
4716	/* Enable all GPIOs as outputs with an initial value of 0 */
4717	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4718	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4719	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4720
4721	/* Enable retasking pins as output, initially without power amp */
4722	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4723	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4724	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4725	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4726	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4727	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4728
4729	/* Disable digital (SPDIF) pins initially, but users can enable
4730	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4731	 * payload also sets the generation to 0, output to be in "consumer"
4732	 * PCM format, copyright asserted, no pre-emphasis and no validity
4733	 * control.
4734	 */
4735	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4736	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4737
4738	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4739	 * OUT1 sum bus when acting as an output.
4740	 */
4741	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4742	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4743	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4744	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4745
4746	/* Start with output sum widgets muted and their output gains at min */
4747	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4748	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4749	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4750	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4751	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4752	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4753	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4754	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4755	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4756
4757	/* Unmute retasking pin widget output buffers since the default
4758	 * state appears to be output.  As the pin mode is changed by the
4759	 * user the pin mode control will take care of enabling the pin's
4760	 * input/output buffers as needed.
4761	 */
4762	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4763	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4764	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4765	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4766	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4767	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4768	/* Also unmute the mono-out pin widget */
4769	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4770
4771	/* Mute capture amp left and right */
4772	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4773	/* Set ADC connection select to match default mixer setting (mic1
4774	 * pin)
4775	 */
4776	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4777
4778	/* Do the same for the second ADC: mute capture input amp and
4779	 * set ADC connection to mic1 pin
4780	 */
4781	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4782	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4783
4784	/* Mute all inputs to mixer widget (even unconnected ones) */
4785	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4786	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4787	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4788	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4789	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4790	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4791	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4792	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4793
4794	{ }
4795};
4796#endif
4797
4798#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
4799#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
4800
4801#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4802#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4803
4804/*
4805 * for BIOS auto-configuration
4806 */
4807
4808static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4809					const char *pfx)
4810{
4811	hda_nid_t nid_vol;
4812	unsigned long vol_val, sw_val;
4813	char name[32];
4814	int err;
4815
4816	if (nid >= 0x0f && nid < 0x11) {
4817		nid_vol = nid - 0x7;
4818		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4819		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4820	} else if (nid == 0x11) {
4821		nid_vol = nid - 0x7;
4822		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4823		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4824	} else if (nid >= 0x12 && nid <= 0x15) {
4825		nid_vol = 0x08;
4826		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4827		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4828	} else
4829		return 0; /* N/A */
4830
4831	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4832	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4833	if (err < 0)
4834		return err;
4835	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4836	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4837	if (err < 0)
4838		return err;
4839	return 1;
4840}
4841
4842/* add playback controls from the parsed DAC table */
4843static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4844					     const struct auto_pin_cfg *cfg)
4845{
4846	hda_nid_t nid;
4847	int err;
4848
4849	spec->multiout.num_dacs = 1;
4850	spec->multiout.dac_nids = spec->private_dac_nids;
4851	spec->multiout.dac_nids[0] = 0x02;
4852
4853	nid = cfg->line_out_pins[0];
4854	if (nid) {
4855		err = alc260_add_playback_controls(spec, nid, "Front");
4856		if (err < 0)
4857			return err;
4858	}
4859
4860	nid = cfg->speaker_pins[0];
4861	if (nid) {
4862		err = alc260_add_playback_controls(spec, nid, "Speaker");
4863		if (err < 0)
4864			return err;
4865	}
4866
4867	nid = cfg->hp_pins[0];
4868	if (nid) {
4869		err = alc260_add_playback_controls(spec, nid, "Headphone");
4870		if (err < 0)
4871			return err;
4872	}
4873	return 0;
4874}
4875
4876/* create playback/capture controls for input pins */
4877static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4878						const struct auto_pin_cfg *cfg)
4879{
4880	struct hda_input_mux *imux = &spec->private_imux;
4881	int i, err, idx;
4882
4883	for (i = 0; i < AUTO_PIN_LAST; i++) {
4884		if (cfg->input_pins[i] >= 0x12) {
4885			idx = cfg->input_pins[i] - 0x12;
4886			err = new_analog_input(spec, cfg->input_pins[i],
4887					       auto_pin_cfg_labels[i], idx,
4888					       0x07);
4889			if (err < 0)
4890				return err;
4891			imux->items[imux->num_items].label =
4892				auto_pin_cfg_labels[i];
4893			imux->items[imux->num_items].index = idx;
4894			imux->num_items++;
4895		}
4896		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4897			idx = cfg->input_pins[i] - 0x09;
4898			err = new_analog_input(spec, cfg->input_pins[i],
4899					       auto_pin_cfg_labels[i], idx,
4900					       0x07);
4901			if (err < 0)
4902				return err;
4903			imux->items[imux->num_items].label =
4904				auto_pin_cfg_labels[i];
4905			imux->items[imux->num_items].index = idx;
4906			imux->num_items++;
4907		}
4908	}
4909	return 0;
4910}
4911
4912static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4913					      hda_nid_t nid, int pin_type,
4914					      int sel_idx)
4915{
4916	alc_set_pin_output(codec, nid, pin_type);
4917	/* need the manual connection? */
4918	if (nid >= 0x12) {
4919		int idx = nid - 0x12;
4920		snd_hda_codec_write(codec, idx + 0x0b, 0,
4921				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4922	}
4923}
4924
4925static void alc260_auto_init_multi_out(struct hda_codec *codec)
4926{
4927	struct alc_spec *spec = codec->spec;
4928	hda_nid_t nid;
4929
4930	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4931	nid = spec->autocfg.line_out_pins[0];
4932	if (nid) {
4933		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4934		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4935	}
4936
4937	nid = spec->autocfg.speaker_pins[0];
4938	if (nid)
4939		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4940
4941	nid = spec->autocfg.hp_pins[0];
4942	if (nid)
4943		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4944}
4945
4946#define ALC260_PIN_CD_NID		0x16
4947static void alc260_auto_init_analog_input(struct hda_codec *codec)
4948{
4949	struct alc_spec *spec = codec->spec;
4950	int i;
4951
4952	for (i = 0; i < AUTO_PIN_LAST; i++) {
4953		hda_nid_t nid = spec->autocfg.input_pins[i];
4954		if (nid >= 0x12) {
4955			snd_hda_codec_write(codec, nid, 0,
4956					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4957					    i <= AUTO_PIN_FRONT_MIC ?
4958					    PIN_VREF80 : PIN_IN);
4959			if (nid != ALC260_PIN_CD_NID)
4960				snd_hda_codec_write(codec, nid, 0,
4961						    AC_VERB_SET_AMP_GAIN_MUTE,
4962						    AMP_OUT_MUTE);
4963		}
4964	}
4965}
4966
4967/*
4968 * generic initialization of ADC, input mixers and output mixers
4969 */
4970static struct hda_verb alc260_volume_init_verbs[] = {
4971	/*
4972	 * Unmute ADC0-1 and set the default input to mic-in
4973	 */
4974	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4975	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4976	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4977	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4978
4979	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4980	 * mixer widget
4981	 * Note: PASD motherboards uses the Line In 2 as the input for
4982	 * front panel mic (mic 2)
4983	 */
4984	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4985	/* mute analog inputs */
4986	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4987	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4988	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4989	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4990	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4991
4992	/*
4993	 * Set up output mixers (0x08 - 0x0a)
4994	 */
4995	/* set vol=0 to output mixers */
4996	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4997	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4998	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4999	/* set up input amps for analog loopback */
5000	/* Amp Indices: DAC = 0, mixer = 1 */
5001	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5002	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5003	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5004	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5005	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5006	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5007
5008	{ }
5009};
5010
5011static int alc260_parse_auto_config(struct hda_codec *codec)
5012{
5013	struct alc_spec *spec = codec->spec;
5014	unsigned int wcap;
5015	int err;
5016	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5017
5018	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5019					   alc260_ignore);
5020	if (err < 0)
5021		return err;
5022	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5023	if (err < 0)
5024		return err;
5025	if (!spec->kctl_alloc)
5026		return 0; /* can't find valid BIOS pin config */
5027	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5028	if (err < 0)
5029		return err;
5030
5031	spec->multiout.max_channels = 2;
5032
5033	if (spec->autocfg.dig_out_pin)
5034		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5035	if (spec->kctl_alloc)
5036		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5037
5038	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5039
5040	spec->num_mux_defs = 1;
5041	spec->input_mux = &spec->private_imux;
5042
5043	/* check whether NID 0x04 is valid */
5044	wcap = get_wcaps(codec, 0x04);
5045	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5046	if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5047		spec->adc_nids = alc260_adc_nids_alt;
5048		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5049		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5050	} else {
5051		spec->adc_nids = alc260_adc_nids;
5052		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5053		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5054	}
5055	spec->num_mixers++;
5056
5057	return 1;
5058}
5059
5060/* additional initialization for auto-configuration model */
5061static void alc260_auto_init(struct hda_codec *codec)
5062{
5063	struct alc_spec *spec = codec->spec;
5064	alc260_auto_init_multi_out(codec);
5065	alc260_auto_init_analog_input(codec);
5066	if (spec->unsol_event)
5067		alc_sku_automute(codec);
5068}
5069
5070#ifdef CONFIG_SND_HDA_POWER_SAVE
5071static struct hda_amp_list alc260_loopbacks[] = {
5072	{ 0x07, HDA_INPUT, 0 },
5073	{ 0x07, HDA_INPUT, 1 },
5074	{ 0x07, HDA_INPUT, 2 },
5075	{ 0x07, HDA_INPUT, 3 },
5076	{ 0x07, HDA_INPUT, 4 },
5077	{ } /* end */
5078};
5079#endif
5080
5081/*
5082 * ALC260 configurations
5083 */
5084static const char *alc260_models[ALC260_MODEL_LAST] = {
5085	[ALC260_BASIC]		= "basic",
5086	[ALC260_HP]		= "hp",
5087	[ALC260_HP_3013]	= "hp-3013",
5088	[ALC260_FUJITSU_S702X]	= "fujitsu",
5089	[ALC260_ACER]		= "acer",
5090	[ALC260_WILL]		= "will",
5091	[ALC260_REPLACER_672V]	= "replacer",
5092#ifdef CONFIG_SND_DEBUG
5093	[ALC260_TEST]		= "test",
5094#endif
5095	[ALC260_AUTO]		= "auto",
5096};
5097
5098static struct snd_pci_quirk alc260_cfg_tbl[] = {
5099	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5100	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5101	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5102	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5103	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5104	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
5105	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5106	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5107	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5108	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5109	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5110	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5111	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5112	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5113	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5114	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5115	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5116	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5117	{}
5118};
5119
5120static struct alc_config_preset alc260_presets[] = {
5121	[ALC260_BASIC] = {
5122		.mixers = { alc260_base_output_mixer,
5123			    alc260_input_mixer,
5124			    alc260_pc_beep_mixer,
5125			    alc260_capture_mixer },
5126		.init_verbs = { alc260_init_verbs },
5127		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5128		.dac_nids = alc260_dac_nids,
5129		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5130		.adc_nids = alc260_adc_nids,
5131		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5132		.channel_mode = alc260_modes,
5133		.input_mux = &alc260_capture_source,
5134	},
5135	[ALC260_HP] = {
5136		.mixers = { alc260_hp_output_mixer,
5137			    alc260_input_mixer,
5138			    alc260_capture_alt_mixer },
5139		.init_verbs = { alc260_init_verbs,
5140				alc260_hp_unsol_verbs },
5141		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5142		.dac_nids = alc260_dac_nids,
5143		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5144		.adc_nids = alc260_hp_adc_nids,
5145		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5146		.channel_mode = alc260_modes,
5147		.input_mux = &alc260_capture_source,
5148		.unsol_event = alc260_hp_unsol_event,
5149		.init_hook = alc260_hp_automute,
5150	},
5151	[ALC260_HP_3013] = {
5152		.mixers = { alc260_hp_3013_mixer,
5153			    alc260_input_mixer,
5154			    alc260_capture_alt_mixer },
5155		.init_verbs = { alc260_hp_3013_init_verbs,
5156				alc260_hp_3013_unsol_verbs },
5157		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5158		.dac_nids = alc260_dac_nids,
5159		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5160		.adc_nids = alc260_hp_adc_nids,
5161		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5162		.channel_mode = alc260_modes,
5163		.input_mux = &alc260_capture_source,
5164		.unsol_event = alc260_hp_3013_unsol_event,
5165		.init_hook = alc260_hp_3013_automute,
5166	},
5167	[ALC260_FUJITSU_S702X] = {
5168		.mixers = { alc260_fujitsu_mixer,
5169			    alc260_capture_mixer },
5170		.init_verbs = { alc260_fujitsu_init_verbs },
5171		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5172		.dac_nids = alc260_dac_nids,
5173		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5174		.adc_nids = alc260_dual_adc_nids,
5175		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5176		.channel_mode = alc260_modes,
5177		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5178		.input_mux = alc260_fujitsu_capture_sources,
5179	},
5180	[ALC260_ACER] = {
5181		.mixers = { alc260_acer_mixer,
5182			    alc260_capture_mixer },
5183		.init_verbs = { alc260_acer_init_verbs },
5184		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5185		.dac_nids = alc260_dac_nids,
5186		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5187		.adc_nids = alc260_dual_adc_nids,
5188		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5189		.channel_mode = alc260_modes,
5190		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5191		.input_mux = alc260_acer_capture_sources,
5192	},
5193	[ALC260_WILL] = {
5194		.mixers = { alc260_will_mixer,
5195			    alc260_capture_mixer },
5196		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5197		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5198		.dac_nids = alc260_dac_nids,
5199		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5200		.adc_nids = alc260_adc_nids,
5201		.dig_out_nid = ALC260_DIGOUT_NID,
5202		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5203		.channel_mode = alc260_modes,
5204		.input_mux = &alc260_capture_source,
5205	},
5206	[ALC260_REPLACER_672V] = {
5207		.mixers = { alc260_replacer_672v_mixer,
5208			    alc260_capture_mixer },
5209		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5210		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5211		.dac_nids = alc260_dac_nids,
5212		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5213		.adc_nids = alc260_adc_nids,
5214		.dig_out_nid = ALC260_DIGOUT_NID,
5215		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5216		.channel_mode = alc260_modes,
5217		.input_mux = &alc260_capture_source,
5218		.unsol_event = alc260_replacer_672v_unsol_event,
5219		.init_hook = alc260_replacer_672v_automute,
5220	},
5221#ifdef CONFIG_SND_DEBUG
5222	[ALC260_TEST] = {
5223		.mixers = { alc260_test_mixer,
5224			    alc260_capture_mixer },
5225		.init_verbs = { alc260_test_init_verbs },
5226		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5227		.dac_nids = alc260_test_dac_nids,
5228		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5229		.adc_nids = alc260_test_adc_nids,
5230		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5231		.channel_mode = alc260_modes,
5232		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5233		.input_mux = alc260_test_capture_sources,
5234	},
5235#endif
5236};
5237
5238static int patch_alc260(struct hda_codec *codec)
5239{
5240	struct alc_spec *spec;
5241	int err, board_config;
5242
5243	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5244	if (spec == NULL)
5245		return -ENOMEM;
5246
5247	codec->spec = spec;
5248
5249	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5250						  alc260_models,
5251						  alc260_cfg_tbl);
5252	if (board_config < 0) {
5253		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5254			   "trying auto-probe from BIOS...\n");
5255		board_config = ALC260_AUTO;
5256	}
5257
5258	if (board_config == ALC260_AUTO) {
5259		/* automatic parse from the BIOS config */
5260		err = alc260_parse_auto_config(codec);
5261		if (err < 0) {
5262			alc_free(codec);
5263			return err;
5264		} else if (!err) {
5265			printk(KERN_INFO
5266			       "hda_codec: Cannot set up configuration "
5267			       "from BIOS.  Using base mode...\n");
5268			board_config = ALC260_BASIC;
5269		}
5270	}
5271
5272	if (board_config != ALC260_AUTO)
5273		setup_preset(spec, &alc260_presets[board_config]);
5274
5275	spec->stream_name_analog = "ALC260 Analog";
5276	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5277	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5278
5279	spec->stream_name_digital = "ALC260 Digital";
5280	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5281	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5282
5283	spec->vmaster_nid = 0x08;
5284
5285	codec->patch_ops = alc_patch_ops;
5286	if (board_config == ALC260_AUTO)
5287		spec->init_hook = alc260_auto_init;
5288#ifdef CONFIG_SND_HDA_POWER_SAVE
5289	if (!spec->loopback.amplist)
5290		spec->loopback.amplist = alc260_loopbacks;
5291#endif
5292
5293	return 0;
5294}
5295
5296
5297/*
5298 * ALC882 support
5299 *
5300 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5301 * configuration.  Each pin widget can choose any input DACs and a mixer.
5302 * Each ADC is connected from a mixer of all inputs.  This makes possible
5303 * 6-channel independent captures.
5304 *
5305 * In addition, an independent DAC for the multi-playback (not used in this
5306 * driver yet).
5307 */
5308#define ALC882_DIGOUT_NID	0x06
5309#define ALC882_DIGIN_NID	0x0a
5310
5311static struct hda_channel_mode alc882_ch_modes[1] = {
5312	{ 8, NULL }
5313};
5314
5315static hda_nid_t alc882_dac_nids[4] = {
5316	/* front, rear, clfe, rear_surr */
5317	0x02, 0x03, 0x04, 0x05
5318};
5319
5320/* identical with ALC880 */
5321#define alc882_adc_nids		alc880_adc_nids
5322#define alc882_adc_nids_alt	alc880_adc_nids_alt
5323
5324static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5325static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5326
5327/* input MUX */
5328/* FIXME: should be a matrix-type input source selection */
5329
5330static struct hda_input_mux alc882_capture_source = {
5331	.num_items = 4,
5332	.items = {
5333		{ "Mic", 0x0 },
5334		{ "Front Mic", 0x1 },
5335		{ "Line", 0x2 },
5336		{ "CD", 0x4 },
5337	},
5338};
5339#define alc882_mux_enum_info alc_mux_enum_info
5340#define alc882_mux_enum_get alc_mux_enum_get
5341
5342static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5343			       struct snd_ctl_elem_value *ucontrol)
5344{
5345	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5346	struct alc_spec *spec = codec->spec;
5347	const struct hda_input_mux *imux = spec->input_mux;
5348	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5349	hda_nid_t nid = spec->capsrc_nids ?
5350		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5351	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5352	unsigned int i, idx;
5353
5354	idx = ucontrol->value.enumerated.item[0];
5355	if (idx >= imux->num_items)
5356		idx = imux->num_items - 1;
5357	if (*cur_val == idx)
5358		return 0;
5359	for (i = 0; i < imux->num_items; i++) {
5360		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5361		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5362					 imux->items[i].index,
5363					 HDA_AMP_MUTE, v);
5364	}
5365	*cur_val = idx;
5366	return 1;
5367}
5368
5369/*
5370 * 2ch mode
5371 */
5372static struct hda_verb alc882_3ST_ch2_init[] = {
5373	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5374	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5375	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5376	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5377	{ } /* end */
5378};
5379
5380/*
5381 * 6ch mode
5382 */
5383static struct hda_verb alc882_3ST_ch6_init[] = {
5384	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5385	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5386	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5387	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5388	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5389	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5390	{ } /* end */
5391};
5392
5393static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5394	{ 2, alc882_3ST_ch2_init },
5395	{ 6, alc882_3ST_ch6_init },
5396};
5397
5398/*
5399 * 6ch mode
5400 */
5401static struct hda_verb alc882_sixstack_ch6_init[] = {
5402	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5403	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5404	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5405	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5406	{ } /* end */
5407};
5408
5409/*
5410 * 8ch mode
5411 */
5412static struct hda_verb alc882_sixstack_ch8_init[] = {
5413	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5414	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5415	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5416	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5417	{ } /* end */
5418};
5419
5420static struct hda_channel_mode alc882_sixstack_modes[2] = {
5421	{ 6, alc882_sixstack_ch6_init },
5422	{ 8, alc882_sixstack_ch8_init },
5423};
5424
5425/*
5426 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5427 */
5428
5429/*
5430 * 2ch mode
5431 */
5432static struct hda_verb alc885_mbp_ch2_init[] = {
5433	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5434	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5435	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5436	{ } /* end */
5437};
5438
5439/*
5440 * 6ch mode
5441 */
5442static struct hda_verb alc885_mbp_ch6_init[] = {
5443	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5444	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5445	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5446	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5447	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5448	{ } /* end */
5449};
5450
5451static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5452	{ 2, alc885_mbp_ch2_init },
5453	{ 6, alc885_mbp_ch6_init },
5454};
5455
5456
5457/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5458 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5459 */
5460static struct snd_kcontrol_new alc882_base_mixer[] = {
5461	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5462	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5463	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5464	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5465	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5466	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5467	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5468	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5469	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5470	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5471	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5472	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5473	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5474	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5475	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5476	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5477	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5478	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5479	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5480	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5481	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5482	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5483	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5484	{ } /* end */
5485};
5486
5487static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5488	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5489	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5490	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5491	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5492	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5493	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5494	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5495	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5496	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5497	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5498	{ } /* end */
5499};
5500static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5501	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5502	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5503	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5504	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5505	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5506	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5507	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5508	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5509	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5510	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5511	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5512	{ } /* end */
5513};
5514
5515static struct snd_kcontrol_new alc882_targa_mixer[] = {
5516	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5517	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5518	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5519	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5520	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5521	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5522	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5523	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5524	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5525	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5526	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5527	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5528	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5529	{ } /* end */
5530};
5531
5532/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5533 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5534 */
5535static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5536	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5537	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5538	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5539	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5540	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5541	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5542	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5543	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5544	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5545	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5546	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5547	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5548	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5549	{ } /* end */
5550};
5551
5552static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5553	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5554	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5555	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5556	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5557	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5558	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5559	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5560	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5561	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5562	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5563	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5564	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5565	{ } /* end */
5566};
5567
5568static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5569	{
5570		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5571		.name = "Channel Mode",
5572		.info = alc_ch_mode_info,
5573		.get = alc_ch_mode_get,
5574		.put = alc_ch_mode_put,
5575	},
5576	{ } /* end */
5577};
5578
5579static struct hda_verb alc882_init_verbs[] = {
5580	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5581	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5582	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5583	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5584	/* Rear mixer */
5585	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5586	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5587	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5588	/* CLFE mixer */
5589	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5590	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5591	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5592	/* Side mixer */
5593	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5594	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5595	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5596
5597	/* Front Pin: output 0 (0x0c) */
5598	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5599	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5600	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5601	/* Rear Pin: output 1 (0x0d) */
5602	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5603	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5604	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5605	/* CLFE Pin: output 2 (0x0e) */
5606	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5607	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5608	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5609	/* Side Pin: output 3 (0x0f) */
5610	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5611	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5612	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5613	/* Mic (rear) pin: input vref at 80% */
5614	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5615	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5616	/* Front Mic pin: input vref at 80% */
5617	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5618	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5619	/* Line In pin: input */
5620	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5621	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5622	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5623	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5624	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5625	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5626	/* CD pin widget for input */
5627	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5628
5629	/* FIXME: use matrix-type input source selection */
5630	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5631	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5632	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5633	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5634	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5635	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5636	/* Input mixer2 */
5637	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5638	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5639	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5640	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5641	/* Input mixer3 */
5642	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5643	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5644	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5645	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5646	/* ADC1: mute amp left and right */
5647	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5648	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5649	/* ADC2: mute amp left and right */
5650	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5651	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5652	/* ADC3: mute amp left and right */
5653	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5654	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5655
5656	{ }
5657};
5658
5659static struct hda_verb alc882_eapd_verbs[] = {
5660	/* change to EAPD mode */
5661	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5662	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5663	{ }
5664};
5665
5666/* Mac Pro test */
5667static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5668	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5669	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5670	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5671	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5672	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5673	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5674	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5675	{ } /* end */
5676};
5677
5678static struct hda_verb alc882_macpro_init_verbs[] = {
5679	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5680	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5681	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5682	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5683	/* Front Pin: output 0 (0x0c) */
5684	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5685	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5686	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5687	/* Front Mic pin: input vref at 80% */
5688	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5689	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5690	/* Speaker:  output */
5691	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5692	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5693	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5694	/* Headphone output (output 0 - 0x0c) */
5695	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5696	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5697	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5698
5699	/* FIXME: use matrix-type input source selection */
5700	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5701	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5702	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5703	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5704	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5705	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5706	/* Input mixer2 */
5707	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5708	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5709	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5710	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5711	/* Input mixer3 */
5712	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5713	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5714	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5715	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5716	/* ADC1: mute amp left and right */
5717	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5718	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5719	/* ADC2: mute amp left and right */
5720	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5721	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5722	/* ADC3: mute amp left and right */
5723	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5724	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5725
5726	{ }
5727};
5728
5729/* Macbook Pro rev3 */
5730static struct hda_verb alc885_mbp3_init_verbs[] = {
5731	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5732	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5733	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5734	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5735	/* Rear mixer */
5736	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5737	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5738	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5739	/* Front Pin: output 0 (0x0c) */
5740	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5741	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5742	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5743	/* HP Pin: output 0 (0x0d) */
5744	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5745	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5746	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5747	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5748	/* Mic (rear) pin: input vref at 80% */
5749	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5750	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5751	/* Front Mic pin: input vref at 80% */
5752	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5753	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5754	/* Line In pin: use output 1 when in LineOut mode */
5755	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5756	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5757	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5758
5759	/* FIXME: use matrix-type input source selection */
5760	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5761	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5762	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5763	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5764	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5765	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5766	/* Input mixer2 */
5767	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5768	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5769	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5770	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5771	/* Input mixer3 */
5772	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5773	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5774	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5775	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5776	/* ADC1: mute amp left and right */
5777	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5778	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5779	/* ADC2: mute amp left and right */
5780	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5781	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5782	/* ADC3: mute amp left and right */
5783	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5784	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5785
5786	{ }
5787};
5788
5789/* iMac 24 mixer. */
5790static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5791	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5792	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5793	{ } /* end */
5794};
5795
5796/* iMac 24 init verbs. */
5797static struct hda_verb alc885_imac24_init_verbs[] = {
5798	/* Internal speakers: output 0 (0x0c) */
5799	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5800	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5801	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5802	/* Internal speakers: output 0 (0x0c) */
5803	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5804	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5805	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5806	/* Headphone: output 0 (0x0c) */
5807	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5808	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5809	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5810	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5811	/* Front Mic: input vref at 80% */
5812	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5813	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5814	{ }
5815};
5816
5817/* Toggle speaker-output according to the hp-jack state */
5818static void alc885_imac24_automute(struct hda_codec *codec)
5819{
5820 	unsigned int present;
5821
5822 	present = snd_hda_codec_read(codec, 0x14, 0,
5823				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5824	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5825				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5826	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5827				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5828}
5829
5830/* Processes unsolicited events. */
5831static void alc885_imac24_unsol_event(struct hda_codec *codec,
5832				      unsigned int res)
5833{
5834	/* Headphone insertion or removal. */
5835	if ((res >> 26) == ALC880_HP_EVENT)
5836		alc885_imac24_automute(codec);
5837}
5838
5839static void alc885_mbp3_automute(struct hda_codec *codec)
5840{
5841 	unsigned int present;
5842
5843 	present = snd_hda_codec_read(codec, 0x15, 0,
5844				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5845	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5846				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5847	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5848				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5849
5850}
5851static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5852				    unsigned int res)
5853{
5854	/* Headphone insertion or removal. */
5855	if ((res >> 26) == ALC880_HP_EVENT)
5856		alc885_mbp3_automute(codec);
5857}
5858
5859
5860static struct hda_verb alc882_targa_verbs[] = {
5861	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5862	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5863
5864	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5865	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5866
5867	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5868	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5869	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5870
5871	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5872	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5873	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5874	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5875	{ } /* end */
5876};
5877
5878/* toggle speaker-output according to the hp-jack state */
5879static void alc882_targa_automute(struct hda_codec *codec)
5880{
5881 	unsigned int present;
5882
5883 	present = snd_hda_codec_read(codec, 0x14, 0,
5884				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5885	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5886				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5887	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5888				  present ? 1 : 3);
5889}
5890
5891static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5892{
5893	/* Looks like the unsol event is incompatible with the standard
5894	 * definition.  4bit tag is placed at 26 bit!
5895	 */
5896	if (((res >> 26) == ALC880_HP_EVENT)) {
5897		alc882_targa_automute(codec);
5898	}
5899}
5900
5901static struct hda_verb alc882_asus_a7j_verbs[] = {
5902	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5903	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5904
5905	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5906	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5907	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5908
5909	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5910	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5911	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5912
5913	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5914	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5915	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5916	{ } /* end */
5917};
5918
5919static struct hda_verb alc882_asus_a7m_verbs[] = {
5920	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5921	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5922
5923	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5924	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5925	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5926
5927	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5928	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5929	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5930
5931	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5932	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5933	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5934 	{ } /* end */
5935};
5936
5937static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5938{
5939	unsigned int gpiostate, gpiomask, gpiodir;
5940
5941	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5942				       AC_VERB_GET_GPIO_DATA, 0);
5943
5944	if (!muted)
5945		gpiostate |= (1 << pin);
5946	else
5947		gpiostate &= ~(1 << pin);
5948
5949	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5950				      AC_VERB_GET_GPIO_MASK, 0);
5951	gpiomask |= (1 << pin);
5952
5953	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5954				     AC_VERB_GET_GPIO_DIRECTION, 0);
5955	gpiodir |= (1 << pin);
5956
5957
5958	snd_hda_codec_write(codec, codec->afg, 0,
5959			    AC_VERB_SET_GPIO_MASK, gpiomask);
5960	snd_hda_codec_write(codec, codec->afg, 0,
5961			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5962
5963	msleep(1);
5964
5965	snd_hda_codec_write(codec, codec->afg, 0,
5966			    AC_VERB_SET_GPIO_DATA, gpiostate);
5967}
5968
5969/* set up GPIO at initialization */
5970static void alc885_macpro_init_hook(struct hda_codec *codec)
5971{
5972	alc882_gpio_mute(codec, 0, 0);
5973	alc882_gpio_mute(codec, 1, 0);
5974}
5975
5976/* set up GPIO and update auto-muting at initialization */
5977static void alc885_imac24_init_hook(struct hda_codec *codec)
5978{
5979	alc885_macpro_init_hook(codec);
5980	alc885_imac24_automute(codec);
5981}
5982
5983/*
5984 * generic initialization of ADC, input mixers and output mixers
5985 */
5986static struct hda_verb alc882_auto_init_verbs[] = {
5987	/*
5988	 * Unmute ADC0-2 and set the default input to mic-in
5989	 */
5990	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5991	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5992	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5993	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5994	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5995	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5996
5997	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5998	 * mixer widget
5999	 * Note: PASD motherboards uses the Line In 2 as the input for
6000	 * front panel mic (mic 2)
6001	 */
6002	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6003	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6004	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6005	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6006	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6007	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6008
6009	/*
6010	 * Set up output mixers (0x0c - 0x0f)
6011	 */
6012	/* set vol=0 to output mixers */
6013	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6014	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6015	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6016	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6017	/* set up input amps for analog loopback */
6018	/* Amp Indices: DAC = 0, mixer = 1 */
6019	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6020	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6021	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6022	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6023	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6024	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6025	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6026	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6027	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6028	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6029
6030	/* FIXME: use matrix-type input source selection */
6031	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6032	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6033	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6034	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6035	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6036	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6037	/* Input mixer2 */
6038	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6039	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6040	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6041	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6042	/* Input mixer3 */
6043	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6044	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6045	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6046	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6047
6048	{ }
6049};
6050
6051/* capture mixer elements */
6052static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6053	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6054	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6055	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6056	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6057	{
6058		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6059		/* The multiple "Capture Source" controls confuse alsamixer
6060		 * So call somewhat different..
6061		 */
6062		/* .name = "Capture Source", */
6063		.name = "Input Source",
6064		.count = 2,
6065		.info = alc882_mux_enum_info,
6066		.get = alc882_mux_enum_get,
6067		.put = alc882_mux_enum_put,
6068	},
6069	{ } /* end */
6070};
6071
6072static struct snd_kcontrol_new alc882_capture_mixer[] = {
6073	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6074	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6075	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6076	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6077	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6078	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6079	{
6080		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6081		/* The multiple "Capture Source" controls confuse alsamixer
6082		 * So call somewhat different..
6083		 */
6084		/* .name = "Capture Source", */
6085		.name = "Input Source",
6086		.count = 3,
6087		.info = alc882_mux_enum_info,
6088		.get = alc882_mux_enum_get,
6089		.put = alc882_mux_enum_put,
6090	},
6091	{ } /* end */
6092};
6093
6094#ifdef CONFIG_SND_HDA_POWER_SAVE
6095#define alc882_loopbacks	alc880_loopbacks
6096#endif
6097
6098/* pcm configuration: identiacal with ALC880 */
6099#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6100#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6101#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6102#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6103
6104/*
6105 * configuration and preset
6106 */
6107static const char *alc882_models[ALC882_MODEL_LAST] = {
6108	[ALC882_3ST_DIG]	= "3stack-dig",
6109	[ALC882_6ST_DIG]	= "6stack-dig",
6110	[ALC882_ARIMA]		= "arima",
6111	[ALC882_W2JC]		= "w2jc",
6112	[ALC882_TARGA]		= "targa",
6113	[ALC882_ASUS_A7J]	= "asus-a7j",
6114	[ALC882_ASUS_A7M]	= "asus-a7m",
6115	[ALC885_MACPRO]		= "macpro",
6116	[ALC885_MBP3]		= "mbp3",
6117	[ALC885_IMAC24]		= "imac24",
6118	[ALC882_AUTO]		= "auto",
6119};
6120
6121static struct snd_pci_quirk alc882_cfg_tbl[] = {
6122	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6123	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6124	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6125	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6126	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6127	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6128	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6129	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6130	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6131	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6132	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6133	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6134	{}
6135};
6136
6137static struct alc_config_preset alc882_presets[] = {
6138	[ALC882_3ST_DIG] = {
6139		.mixers = { alc882_base_mixer },
6140		.init_verbs = { alc882_init_verbs },
6141		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6142		.dac_nids = alc882_dac_nids,
6143		.dig_out_nid = ALC882_DIGOUT_NID,
6144		.dig_in_nid = ALC882_DIGIN_NID,
6145		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6146		.channel_mode = alc882_ch_modes,
6147		.need_dac_fix = 1,
6148		.input_mux = &alc882_capture_source,
6149	},
6150	[ALC882_6ST_DIG] = {
6151		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6152		.init_verbs = { alc882_init_verbs },
6153		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6154		.dac_nids = alc882_dac_nids,
6155		.dig_out_nid = ALC882_DIGOUT_NID,
6156		.dig_in_nid = ALC882_DIGIN_NID,
6157		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6158		.channel_mode = alc882_sixstack_modes,
6159		.input_mux = &alc882_capture_source,
6160	},
6161	[ALC882_ARIMA] = {
6162		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6163		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6164		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6165		.dac_nids = alc882_dac_nids,
6166		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6167		.channel_mode = alc882_sixstack_modes,
6168		.input_mux = &alc882_capture_source,
6169	},
6170	[ALC882_W2JC] = {
6171		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6172		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6173				alc880_gpio1_init_verbs },
6174		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6175		.dac_nids = alc882_dac_nids,
6176		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6177		.channel_mode = alc880_threestack_modes,
6178		.need_dac_fix = 1,
6179		.input_mux = &alc882_capture_source,
6180		.dig_out_nid = ALC882_DIGOUT_NID,
6181	},
6182	[ALC885_MBP3] = {
6183		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6184		.init_verbs = { alc885_mbp3_init_verbs,
6185				alc880_gpio1_init_verbs },
6186		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6187		.dac_nids = alc882_dac_nids,
6188		.channel_mode = alc885_mbp_6ch_modes,
6189		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6190		.input_mux = &alc882_capture_source,
6191		.dig_out_nid = ALC882_DIGOUT_NID,
6192		.dig_in_nid = ALC882_DIGIN_NID,
6193		.unsol_event = alc885_mbp3_unsol_event,
6194		.init_hook = alc885_mbp3_automute,
6195	},
6196	[ALC885_MACPRO] = {
6197		.mixers = { alc882_macpro_mixer },
6198		.init_verbs = { alc882_macpro_init_verbs },
6199		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6200		.dac_nids = alc882_dac_nids,
6201		.dig_out_nid = ALC882_DIGOUT_NID,
6202		.dig_in_nid = ALC882_DIGIN_NID,
6203		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6204		.channel_mode = alc882_ch_modes,
6205		.input_mux = &alc882_capture_source,
6206		.init_hook = alc885_macpro_init_hook,
6207	},
6208	[ALC885_IMAC24] = {
6209		.mixers = { alc885_imac24_mixer },
6210		.init_verbs = { alc885_imac24_init_verbs },
6211		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6212		.dac_nids = alc882_dac_nids,
6213		.dig_out_nid = ALC882_DIGOUT_NID,
6214		.dig_in_nid = ALC882_DIGIN_NID,
6215		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6216		.channel_mode = alc882_ch_modes,
6217		.input_mux = &alc882_capture_source,
6218		.unsol_event = alc885_imac24_unsol_event,
6219		.init_hook = alc885_imac24_init_hook,
6220	},
6221	[ALC882_TARGA] = {
6222		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6223			    alc882_capture_mixer },
6224		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6225		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6226		.dac_nids = alc882_dac_nids,
6227		.dig_out_nid = ALC882_DIGOUT_NID,
6228		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6229		.adc_nids = alc882_adc_nids,
6230		.capsrc_nids = alc882_capsrc_nids,
6231		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6232		.channel_mode = alc882_3ST_6ch_modes,
6233		.need_dac_fix = 1,
6234		.input_mux = &alc882_capture_source,
6235		.unsol_event = alc882_targa_unsol_event,
6236		.init_hook = alc882_targa_automute,
6237	},
6238	[ALC882_ASUS_A7J] = {
6239		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6240			    alc882_capture_mixer },
6241		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6242		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6243		.dac_nids = alc882_dac_nids,
6244		.dig_out_nid = ALC882_DIGOUT_NID,
6245		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6246		.adc_nids = alc882_adc_nids,
6247		.capsrc_nids = alc882_capsrc_nids,
6248		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6249		.channel_mode = alc882_3ST_6ch_modes,
6250		.need_dac_fix = 1,
6251		.input_mux = &alc882_capture_source,
6252	},
6253	[ALC882_ASUS_A7M] = {
6254		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6255		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6256				alc880_gpio1_init_verbs,
6257				alc882_asus_a7m_verbs },
6258		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6259		.dac_nids = alc882_dac_nids,
6260		.dig_out_nid = ALC882_DIGOUT_NID,
6261		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6262		.channel_mode = alc880_threestack_modes,
6263		.need_dac_fix = 1,
6264		.input_mux = &alc882_capture_source,
6265	},
6266};
6267
6268
6269/*
6270 * Pin config fixes
6271 */
6272enum {
6273	PINFIX_ABIT_AW9D_MAX
6274};
6275
6276static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6277	{ 0x15, 0x01080104 }, /* side */
6278	{ 0x16, 0x01011012 }, /* rear */
6279	{ 0x17, 0x01016011 }, /* clfe */
6280	{ }
6281};
6282
6283static const struct alc_pincfg *alc882_pin_fixes[] = {
6284	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6285};
6286
6287static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6288	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6289	{}
6290};
6291
6292/*
6293 * BIOS auto configuration
6294 */
6295static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6296					      hda_nid_t nid, int pin_type,
6297					      int dac_idx)
6298{
6299	/* set as output */
6300	struct alc_spec *spec = codec->spec;
6301	int idx;
6302
6303	alc_set_pin_output(codec, nid, pin_type);
6304	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6305		idx = 4;
6306	else
6307		idx = spec->multiout.dac_nids[dac_idx] - 2;
6308	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6309
6310}
6311
6312static void alc882_auto_init_multi_out(struct hda_codec *codec)
6313{
6314	struct alc_spec *spec = codec->spec;
6315	int i;
6316
6317	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6318	for (i = 0; i <= HDA_SIDE; i++) {
6319		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6320		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6321		if (nid)
6322			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6323							  i);
6324	}
6325}
6326
6327static void alc882_auto_init_hp_out(struct hda_codec *codec)
6328{
6329	struct alc_spec *spec = codec->spec;
6330	hda_nid_t pin;
6331
6332	pin = spec->autocfg.hp_pins[0];
6333	if (pin) /* connect to front */
6334		/* use dac 0 */
6335		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6336	pin = spec->autocfg.speaker_pins[0];
6337	if (pin)
6338		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6339}
6340
6341#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6342#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6343
6344static void alc882_auto_init_analog_input(struct hda_codec *codec)
6345{
6346	struct alc_spec *spec = codec->spec;
6347	int i;
6348
6349	for (i = 0; i < AUTO_PIN_LAST; i++) {
6350		hda_nid_t nid = spec->autocfg.input_pins[i];
6351		unsigned int vref;
6352		if (!nid)
6353			continue;
6354		vref = PIN_IN;
6355		if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6356			if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) &
6357			    AC_PINCAP_VREF_80)
6358				vref = PIN_VREF80;
6359		}
6360		snd_hda_codec_write(codec, nid, 0,
6361				    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6362		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6363			snd_hda_codec_write(codec, nid, 0,
6364					    AC_VERB_SET_AMP_GAIN_MUTE,
6365					    AMP_OUT_MUTE);
6366	}
6367}
6368
6369/* add mic boosts if needed */
6370static int alc_auto_add_mic_boost(struct hda_codec *codec)
6371{
6372	struct alc_spec *spec = codec->spec;
6373	int err;
6374	hda_nid_t nid;
6375
6376	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6377	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6378		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6379				  "Mic Boost",
6380				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6381		if (err < 0)
6382			return err;
6383	}
6384	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6385	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6386		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6387				  "Front Mic Boost",
6388				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6389		if (err < 0)
6390			return err;
6391	}
6392	return 0;
6393}
6394
6395/* almost identical with ALC880 parser... */
6396static int alc882_parse_auto_config(struct hda_codec *codec)
6397{
6398	struct alc_spec *spec = codec->spec;
6399	int err = alc880_parse_auto_config(codec);
6400
6401	if (err < 0)
6402		return err;
6403	else if (!err)
6404		return 0; /* no config found */
6405
6406	err = alc_auto_add_mic_boost(codec);
6407	if (err < 0)
6408		return err;
6409
6410	/* hack - override the init verbs */
6411	spec->init_verbs[0] = alc882_auto_init_verbs;
6412
6413	return 1; /* config found */
6414}
6415
6416/* additional initialization for auto-configuration model */
6417static void alc882_auto_init(struct hda_codec *codec)
6418{
6419	struct alc_spec *spec = codec->spec;
6420	alc882_auto_init_multi_out(codec);
6421	alc882_auto_init_hp_out(codec);
6422	alc882_auto_init_analog_input(codec);
6423	if (spec->unsol_event)
6424		alc_sku_automute(codec);
6425}
6426
6427static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6428
6429static int patch_alc882(struct hda_codec *codec)
6430{
6431	struct alc_spec *spec;
6432	int err, board_config;
6433
6434	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6435	if (spec == NULL)
6436		return -ENOMEM;
6437
6438	codec->spec = spec;
6439
6440	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6441						  alc882_models,
6442						  alc882_cfg_tbl);
6443
6444	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6445		/* Pick up systems that don't supply PCI SSID */
6446		switch (codec->subsystem_id) {
6447		case 0x106b0c00: /* Mac Pro */
6448			board_config = ALC885_MACPRO;
6449			break;
6450		case 0x106b1000: /* iMac 24 */
6451			board_config = ALC885_IMAC24;
6452			break;
6453		case 0x106b00a1: /* Macbook */
6454		case 0x106b2c00: /* Macbook Pro rev3 */
6455			board_config = ALC885_MBP3;
6456			break;
6457		default:
6458			/* ALC889A is handled better as ALC888-compatible */
6459			if (codec->revision_id == 0x100103) {
6460				alc_free(codec);
6461				return patch_alc883(codec);
6462			}
6463			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6464		       			 "trying auto-probe from BIOS...\n");
6465			board_config = ALC882_AUTO;
6466		}
6467	}
6468
6469	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6470
6471	if (board_config == ALC882_AUTO) {
6472		/* automatic parse from the BIOS config */
6473		err = alc882_parse_auto_config(codec);
6474		if (err < 0) {
6475			alc_free(codec);
6476			return err;
6477		} else if (!err) {
6478			printk(KERN_INFO
6479			       "hda_codec: Cannot set up configuration "
6480			       "from BIOS.  Using base mode...\n");
6481			board_config = ALC882_3ST_DIG;
6482		}
6483	}
6484
6485	if (board_config != ALC882_AUTO)
6486		setup_preset(spec, &alc882_presets[board_config]);
6487
6488	spec->stream_name_analog = "ALC882 Analog";
6489	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6490	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6491	/* FIXME: setup DAC5 */
6492	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6493	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6494
6495	spec->stream_name_digital = "ALC882 Digital";
6496	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6497	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6498
6499	if (!spec->adc_nids && spec->input_mux) {
6500		/* check whether NID 0x07 is valid */
6501		unsigned int wcap = get_wcaps(codec, 0x07);
6502		/* get type */
6503		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6504		if (wcap != AC_WID_AUD_IN) {
6505			spec->adc_nids = alc882_adc_nids_alt;
6506			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6507			spec->capsrc_nids = alc882_capsrc_nids_alt;
6508			spec->mixers[spec->num_mixers] =
6509				alc882_capture_alt_mixer;
6510			spec->num_mixers++;
6511		} else {
6512			spec->adc_nids = alc882_adc_nids;
6513			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6514			spec->capsrc_nids = alc882_capsrc_nids;
6515			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6516			spec->num_mixers++;
6517		}
6518	}
6519
6520	spec->vmaster_nid = 0x0c;
6521
6522	codec->patch_ops = alc_patch_ops;
6523	if (board_config == ALC882_AUTO)
6524		spec->init_hook = alc882_auto_init;
6525#ifdef CONFIG_SND_HDA_POWER_SAVE
6526	if (!spec->loopback.amplist)
6527		spec->loopback.amplist = alc882_loopbacks;
6528#endif
6529
6530	return 0;
6531}
6532
6533/*
6534 * ALC883 support
6535 *
6536 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6537 * configuration.  Each pin widget can choose any input DACs and a mixer.
6538 * Each ADC is connected from a mixer of all inputs.  This makes possible
6539 * 6-channel independent captures.
6540 *
6541 * In addition, an independent DAC for the multi-playback (not used in this
6542 * driver yet).
6543 */
6544#define ALC883_DIGOUT_NID	0x06
6545#define ALC883_DIGIN_NID	0x0a
6546
6547static hda_nid_t alc883_dac_nids[4] = {
6548	/* front, rear, clfe, rear_surr */
6549	0x02, 0x03, 0x04, 0x05
6550};
6551
6552static hda_nid_t alc883_adc_nids[2] = {
6553	/* ADC1-2 */
6554	0x08, 0x09,
6555};
6556
6557static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6558
6559/* input MUX */
6560/* FIXME: should be a matrix-type input source selection */
6561
6562static struct hda_input_mux alc883_capture_source = {
6563	.num_items = 4,
6564	.items = {
6565		{ "Mic", 0x0 },
6566		{ "Front Mic", 0x1 },
6567		{ "Line", 0x2 },
6568		{ "CD", 0x4 },
6569	},
6570};
6571
6572static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6573	.num_items = 2,
6574	.items = {
6575		{ "Mic", 0x1 },
6576		{ "Line", 0x2 },
6577	},
6578};
6579
6580static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6581	.num_items = 4,
6582	.items = {
6583		{ "Mic", 0x0 },
6584		{ "iMic", 0x1 },
6585		{ "Line", 0x2 },
6586		{ "CD", 0x4 },
6587	},
6588};
6589
6590static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6591	.num_items = 2,
6592	.items = {
6593		{ "Mic", 0x0 },
6594		{ "Int Mic", 0x1 },
6595	},
6596};
6597
6598#define alc883_mux_enum_info alc_mux_enum_info
6599#define alc883_mux_enum_get alc_mux_enum_get
6600/* ALC883 has the ALC882-type input selection */
6601#define alc883_mux_enum_put alc882_mux_enum_put
6602
6603/*
6604 * 2ch mode
6605 */
6606static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6607	{ 2, NULL }
6608};
6609
6610/*
6611 * 2ch mode
6612 */
6613static struct hda_verb alc883_3ST_ch2_init[] = {
6614	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6615	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6616	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6617	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6618	{ } /* end */
6619};
6620
6621/*
6622 * 4ch mode
6623 */
6624static struct hda_verb alc883_3ST_ch4_init[] = {
6625	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6626	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6627	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6628	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6629	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6630	{ } /* end */
6631};
6632
6633/*
6634 * 6ch mode
6635 */
6636static struct hda_verb alc883_3ST_ch6_init[] = {
6637	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6638	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6639	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6640	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6641	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6642	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6643	{ } /* end */
6644};
6645
6646static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6647	{ 2, alc883_3ST_ch2_init },
6648	{ 4, alc883_3ST_ch4_init },
6649	{ 6, alc883_3ST_ch6_init },
6650};
6651
6652/*
6653 * 6ch mode
6654 */
6655static struct hda_verb alc883_sixstack_ch6_init[] = {
6656	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6657	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6658	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6659	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6660	{ } /* end */
6661};
6662
6663/*
6664 * 8ch mode
6665 */
6666static struct hda_verb alc883_sixstack_ch8_init[] = {
6667	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6668	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6669	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6670	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6671	{ } /* end */
6672};
6673
6674static struct hda_channel_mode alc883_sixstack_modes[2] = {
6675	{ 6, alc883_sixstack_ch6_init },
6676	{ 8, alc883_sixstack_ch8_init },
6677};
6678
6679static struct hda_verb alc883_medion_eapd_verbs[] = {
6680        /* eanable EAPD on medion laptop */
6681	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6682	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6683	{ }
6684};
6685
6686/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6687 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6688 */
6689
6690static struct snd_kcontrol_new alc883_base_mixer[] = {
6691	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6692	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6693	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6694	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6695	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6696	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6697	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6698	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6699	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6700	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6701	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6702	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6703	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6704	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6705	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6706	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6707	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6708	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6709	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6710	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6711	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6712	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6713	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6714	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6715	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6716	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6717	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6718	{
6719		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6720		/* .name = "Capture Source", */
6721		.name = "Input Source",
6722		.count = 2,
6723		.info = alc883_mux_enum_info,
6724		.get = alc883_mux_enum_get,
6725		.put = alc883_mux_enum_put,
6726	},
6727	{ } /* end */
6728};
6729
6730static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6731	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6732	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6733	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6734	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6735	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6736	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6737	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6738	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6739	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6740	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6741	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6742	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6743	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6744	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6745	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6746	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6747	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6748	{
6749		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6750		/* .name = "Capture Source", */
6751		.name = "Input Source",
6752		.count = 2,
6753		.info = alc883_mux_enum_info,
6754		.get = alc883_mux_enum_get,
6755		.put = alc883_mux_enum_put,
6756	},
6757	{ } /* end */
6758};
6759
6760static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
6761	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6762	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6763	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6764	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6765	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6766	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6767	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6768	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6769	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6770	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6771	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6772	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6773	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6774	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6775	{
6776		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6777		/* .name = "Capture Source", */
6778		.name = "Input Source",
6779		.count = 2,
6780		.info = alc883_mux_enum_info,
6781		.get = alc883_mux_enum_get,
6782		.put = alc883_mux_enum_put,
6783	},
6784	{ } /* end */
6785};
6786
6787static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
6788	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6789	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6790	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6791	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6792	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6793	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6794	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6795	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6796	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6797	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6798	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6799	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6800	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6801	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6802	{
6803		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6804		/* .name = "Capture Source", */
6805		.name = "Input Source",
6806		.count = 2,
6807		.info = alc883_mux_enum_info,
6808		.get = alc883_mux_enum_get,
6809		.put = alc883_mux_enum_put,
6810	},
6811	{ } /* end */
6812};
6813
6814static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6815	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6816	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6817	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6818	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6819	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6820	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6821	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6822	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6823	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6824	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6825	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6826	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6827	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6828	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6829	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6830	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6831	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6832	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6833	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6834	{
6835		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6836		/* .name = "Capture Source", */
6837		.name = "Input Source",
6838		.count = 2,
6839		.info = alc883_mux_enum_info,
6840		.get = alc883_mux_enum_get,
6841		.put = alc883_mux_enum_put,
6842	},
6843	{ } /* end */
6844};
6845
6846static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6847	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6848	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6849	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6850	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6851	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6852	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6853	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6854	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6855	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6856	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6857	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6858	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6859	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6860	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6861	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6862	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6863	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6864	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6865	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6866	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6867	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6868	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6869	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6870	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6871	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6872	{
6873		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6874		/* .name = "Capture Source", */
6875		.name = "Input Source",
6876		.count = 2,
6877		.info = alc883_mux_enum_info,
6878		.get = alc883_mux_enum_get,
6879		.put = alc883_mux_enum_put,
6880	},
6881	{ } /* end */
6882};
6883
6884static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6885	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6886	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6887	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6888	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6889	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6890	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6891	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6892	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6893	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6894	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6895	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6896	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6897	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6898	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6899	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6900	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6901	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6902	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6903	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6904	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6905	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6906	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6907	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6908
6909	{
6910		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6911		/* .name = "Capture Source", */
6912		.name = "Input Source",
6913		.count = 1,
6914		.info = alc883_mux_enum_info,
6915		.get = alc883_mux_enum_get,
6916		.put = alc883_mux_enum_put,
6917	},
6918	{ } /* end */
6919};
6920
6921static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6922	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6923	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6924	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6925	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6926	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6927	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6928	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6929	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6930	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6932	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6933	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6934	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6935	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6936	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6937	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6938	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6939	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6940	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6941	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6942	{
6943		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6944		/* .name = "Capture Source", */
6945		.name = "Input Source",
6946		.count = 2,
6947		.info = alc883_mux_enum_info,
6948		.get = alc883_mux_enum_get,
6949		.put = alc883_mux_enum_put,
6950	},
6951	{ } /* end */
6952};
6953
6954static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6955	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6956	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6957	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6958	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6959	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6960	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6961	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6962	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6963	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6964	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6965	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6966	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6967	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6968	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6969	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6970	{
6971		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6972		/* .name = "Capture Source", */
6973		.name = "Input Source",
6974		.count = 2,
6975		.info = alc883_mux_enum_info,
6976		.get = alc883_mux_enum_get,
6977		.put = alc883_mux_enum_put,
6978	},
6979	{ } /* end */
6980};
6981
6982static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6983	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6984	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6985	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6986	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6987	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6988	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6989	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6990	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6991	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6992	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6993	{
6994		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6995		/* .name = "Capture Source", */
6996		.name = "Input Source",
6997		.count = 1,
6998		.info = alc883_mux_enum_info,
6999		.get = alc883_mux_enum_get,
7000		.put = alc883_mux_enum_put,
7001	},
7002	{ } /* end */
7003};
7004
7005static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7006	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7007	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7008	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7009	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7010	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7011	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7012	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7013	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7014	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7015	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7016	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7017	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7018	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7019	{
7020		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7021		/* .name = "Capture Source", */
7022		.name = "Input Source",
7023		.count = 2,
7024		.info = alc883_mux_enum_info,
7025		.get = alc883_mux_enum_get,
7026		.put = alc883_mux_enum_put,
7027	},
7028	{ } /* end */
7029};
7030
7031static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7032	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7033	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7034	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7035	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7036	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7037	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7038	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7039	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7040	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7041	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7042	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7043	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7044	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7045	{
7046		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7047		/* .name = "Capture Source", */
7048		.name = "Input Source",
7049		.count = 2,
7050		.info = alc883_mux_enum_info,
7051		.get = alc883_mux_enum_get,
7052		.put = alc883_mux_enum_put,
7053	},
7054	{ } /* end */
7055};
7056
7057static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7058	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7059	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7060	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7061	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7062	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7063	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7064	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7065	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7066	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7067	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7068	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7069	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7070	{
7071		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7072		/* .name = "Capture Source", */
7073		.name = "Input Source",
7074		.count = 2,
7075		.info = alc883_mux_enum_info,
7076		.get = alc883_mux_enum_get,
7077		.put = alc883_mux_enum_put,
7078	},
7079	{ } /* end */
7080};
7081
7082static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7083	{
7084		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7085		.name = "Channel Mode",
7086		.info = alc_ch_mode_info,
7087		.get = alc_ch_mode_get,
7088		.put = alc_ch_mode_put,
7089	},
7090	{ } /* end */
7091};
7092
7093static struct hda_verb alc883_init_verbs[] = {
7094	/* ADC1: mute amp left and right */
7095	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7096	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7097	/* ADC2: mute amp left and right */
7098	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7099	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7100	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7101	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7102	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7103	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7104	/* Rear mixer */
7105	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7106	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7107	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7108	/* CLFE mixer */
7109	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7110	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7111	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7112	/* Side mixer */
7113	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7114	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7115	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7116
7117	/* mute analog input loopbacks */
7118	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7119	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7120	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7121	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7122	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7123
7124	/* Front Pin: output 0 (0x0c) */
7125	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7126	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7127	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7128	/* Rear Pin: output 1 (0x0d) */
7129	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7130	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7131	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7132	/* CLFE Pin: output 2 (0x0e) */
7133	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7134	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7135	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7136	/* Side Pin: output 3 (0x0f) */
7137	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7138	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7139	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7140	/* Mic (rear) pin: input vref at 80% */
7141	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7142	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7143	/* Front Mic pin: input vref at 80% */
7144	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7145	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7146	/* Line In pin: input */
7147	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7148	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7149	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7150	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7151	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7152	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7153	/* CD pin widget for input */
7154	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7155
7156	/* FIXME: use matrix-type input source selection */
7157	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7158	/* Input mixer2 */
7159	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7160	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7161	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7162	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7163	/* Input mixer3 */
7164	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7165	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7166	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7167	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7168	{ }
7169};
7170
7171/* toggle speaker-output according to the hp-jack state */
7172static void alc883_mitac_hp_automute(struct hda_codec *codec)
7173{
7174	unsigned int present;
7175
7176	present = snd_hda_codec_read(codec, 0x15, 0,
7177				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7178	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7179				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7180	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7181				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7182}
7183
7184/* auto-toggle front mic */
7185/*
7186static void alc883_mitac_mic_automute(struct hda_codec *codec)
7187{
7188	unsigned int present;
7189	unsigned char bits;
7190
7191	present = snd_hda_codec_read(codec, 0x18, 0,
7192				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7193	bits = present ? HDA_AMP_MUTE : 0;
7194	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7195}
7196*/
7197
7198static void alc883_mitac_automute(struct hda_codec *codec)
7199{
7200	alc883_mitac_hp_automute(codec);
7201	/* alc883_mitac_mic_automute(codec); */
7202}
7203
7204static void alc883_mitac_unsol_event(struct hda_codec *codec,
7205					   unsigned int res)
7206{
7207	switch (res >> 26) {
7208	case ALC880_HP_EVENT:
7209		alc883_mitac_hp_automute(codec);
7210		break;
7211	case ALC880_MIC_EVENT:
7212		/* alc883_mitac_mic_automute(codec); */
7213		break;
7214	}
7215}
7216
7217static struct hda_verb alc883_mitac_verbs[] = {
7218	/* HP */
7219	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7220	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7221	/* Subwoofer */
7222	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7223	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7224
7225	/* enable unsolicited event */
7226	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7227	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7228
7229	{ } /* end */
7230};
7231
7232static struct hda_verb alc883_clevo_m720_verbs[] = {
7233	/* HP */
7234	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7235	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7236	/* Int speaker */
7237	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7238	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7239
7240	/* enable unsolicited event */
7241	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7242	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7243
7244	{ } /* end */
7245};
7246
7247static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7248	/* HP */
7249	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7250	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7251	/* Subwoofer */
7252	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7253	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7254
7255	/* enable unsolicited event */
7256	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7257
7258	{ } /* end */
7259};
7260
7261static struct hda_verb alc883_tagra_verbs[] = {
7262	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7263	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7264
7265	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7266	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7267
7268	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7269	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7270	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7271
7272	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7273	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7274	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7275	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7276
7277	{ } /* end */
7278};
7279
7280static struct hda_verb alc883_lenovo_101e_verbs[] = {
7281	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7282	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7283        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7284	{ } /* end */
7285};
7286
7287static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7288        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7289	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7290        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7291        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7292	{ } /* end */
7293};
7294
7295static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7296	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7297	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7298	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7299	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7300	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7301	{ } /* end */
7302};
7303
7304static struct hda_verb alc883_haier_w66_verbs[] = {
7305	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7306	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7307
7308	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7309
7310	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7311	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7312	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7313	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7314	{ } /* end */
7315};
7316
7317static struct hda_verb alc888_3st_hp_verbs[] = {
7318	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7319	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7320	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7321	{ }
7322};
7323
7324static struct hda_verb alc888_6st_dell_verbs[] = {
7325	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7326	{ }
7327};
7328
7329static struct hda_verb alc888_3st_hp_2ch_init[] = {
7330	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7331	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7332	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7333	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7334	{ }
7335};
7336
7337static struct hda_verb alc888_3st_hp_6ch_init[] = {
7338	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7339	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7340	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7341	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7342	{ }
7343};
7344
7345static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7346	{ 2, alc888_3st_hp_2ch_init },
7347	{ 6, alc888_3st_hp_6ch_init },
7348};
7349
7350/* toggle front-jack and RCA according to the hp-jack state */
7351static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7352{
7353 	unsigned int present;
7354
7355 	present = snd_hda_codec_read(codec, 0x1b, 0,
7356				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7357	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7358				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7359	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7360				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7361}
7362
7363/* toggle RCA according to the front-jack state */
7364static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7365{
7366 	unsigned int present;
7367
7368 	present = snd_hda_codec_read(codec, 0x14, 0,
7369				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7370	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7371				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7372}
7373
7374static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7375					     unsigned int res)
7376{
7377	if ((res >> 26) == ALC880_HP_EVENT)
7378		alc888_lenovo_ms7195_front_automute(codec);
7379	if ((res >> 26) == ALC880_FRONT_EVENT)
7380		alc888_lenovo_ms7195_rca_automute(codec);
7381}
7382
7383static struct hda_verb alc883_medion_md2_verbs[] = {
7384	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7385	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7386
7387	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7388
7389	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7390	{ } /* end */
7391};
7392
7393/* toggle speaker-output according to the hp-jack state */
7394static void alc883_medion_md2_automute(struct hda_codec *codec)
7395{
7396 	unsigned int present;
7397
7398 	present = snd_hda_codec_read(codec, 0x14, 0,
7399				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7400	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7401				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7402}
7403
7404static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7405					  unsigned int res)
7406{
7407	if ((res >> 26) == ALC880_HP_EVENT)
7408		alc883_medion_md2_automute(codec);
7409}
7410
7411/* toggle speaker-output according to the hp-jack state */
7412static void alc883_tagra_automute(struct hda_codec *codec)
7413{
7414 	unsigned int present;
7415	unsigned char bits;
7416
7417 	present = snd_hda_codec_read(codec, 0x14, 0,
7418				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7419	bits = present ? HDA_AMP_MUTE : 0;
7420	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7421				 HDA_AMP_MUTE, bits);
7422	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7423				  present ? 1 : 3);
7424}
7425
7426static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7427{
7428	if ((res >> 26) == ALC880_HP_EVENT)
7429		alc883_tagra_automute(codec);
7430}
7431
7432/* toggle speaker-output according to the hp-jack state */
7433static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7434{
7435	unsigned int present;
7436	unsigned char bits;
7437
7438	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7439		& AC_PINSENSE_PRESENCE;
7440	bits = present ? HDA_AMP_MUTE : 0;
7441	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7442				 HDA_AMP_MUTE, bits);
7443}
7444
7445static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7446{
7447	unsigned int present;
7448
7449	present = snd_hda_codec_read(codec, 0x18, 0,
7450				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7451	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7452				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7453}
7454
7455static void alc883_clevo_m720_automute(struct hda_codec *codec)
7456{
7457	alc883_clevo_m720_hp_automute(codec);
7458	alc883_clevo_m720_mic_automute(codec);
7459}
7460
7461static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7462					   unsigned int res)
7463{
7464	switch (res >> 26) {
7465	case ALC880_HP_EVENT:
7466		alc883_clevo_m720_hp_automute(codec);
7467		break;
7468	case ALC880_MIC_EVENT:
7469		alc883_clevo_m720_mic_automute(codec);
7470		break;
7471	}
7472}
7473
7474/* toggle speaker-output according to the hp-jack state */
7475static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7476{
7477 	unsigned int present;
7478	unsigned char bits;
7479
7480 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7481		& AC_PINSENSE_PRESENCE;
7482	bits = present ? HDA_AMP_MUTE : 0;
7483	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7484				 HDA_AMP_MUTE, bits);
7485}
7486
7487static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7488						  unsigned int res)
7489{
7490	if ((res >> 26) == ALC880_HP_EVENT)
7491		alc883_2ch_fujitsu_pi2515_automute(codec);
7492}
7493
7494static void alc883_haier_w66_automute(struct hda_codec *codec)
7495{
7496	unsigned int present;
7497	unsigned char bits;
7498
7499	present = snd_hda_codec_read(codec, 0x1b, 0,
7500				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7501	bits = present ? 0x80 : 0;
7502	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7503				 0x80, bits);
7504}
7505
7506static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7507					 unsigned int res)
7508{
7509	if ((res >> 26) == ALC880_HP_EVENT)
7510		alc883_haier_w66_automute(codec);
7511}
7512
7513static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7514{
7515 	unsigned int present;
7516	unsigned char bits;
7517
7518 	present = snd_hda_codec_read(codec, 0x14, 0,
7519				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7520	bits = present ? HDA_AMP_MUTE : 0;
7521	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7522				 HDA_AMP_MUTE, bits);
7523}
7524
7525static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7526{
7527 	unsigned int present;
7528	unsigned char bits;
7529
7530 	present = snd_hda_codec_read(codec, 0x1b, 0,
7531				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7532	bits = present ? HDA_AMP_MUTE : 0;
7533	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7534				 HDA_AMP_MUTE, bits);
7535	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7536				 HDA_AMP_MUTE, bits);
7537}
7538
7539static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7540					   unsigned int res)
7541{
7542	if ((res >> 26) == ALC880_HP_EVENT)
7543		alc883_lenovo_101e_all_automute(codec);
7544	if ((res >> 26) == ALC880_FRONT_EVENT)
7545		alc883_lenovo_101e_ispeaker_automute(codec);
7546}
7547
7548/* toggle speaker-output according to the hp-jack state */
7549static void alc883_acer_aspire_automute(struct hda_codec *codec)
7550{
7551 	unsigned int present;
7552
7553 	present = snd_hda_codec_read(codec, 0x14, 0,
7554				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7555	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7556				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7557	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7558				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7559}
7560
7561static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7562					   unsigned int res)
7563{
7564	if ((res >> 26) == ALC880_HP_EVENT)
7565		alc883_acer_aspire_automute(codec);
7566}
7567
7568static struct hda_verb alc883_acer_eapd_verbs[] = {
7569	/* HP Pin: output 0 (0x0c) */
7570	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7571	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7572	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7573	/* Front Pin: output 0 (0x0c) */
7574	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7575	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7576	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7577	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7578        /* eanable EAPD on medion laptop */
7579	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7580	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7581	/* enable unsolicited event */
7582	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7583	{ }
7584};
7585
7586static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7587{
7588 	unsigned int present;
7589
7590 	present = snd_hda_codec_read(codec, 0x1b, 0,
7591				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7592	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7593				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7594	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7595				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7596	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7597				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7598	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7599				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7600}
7601
7602static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7603					     unsigned int res)
7604{
7605	switch (res >> 26) {
7606	case ALC880_HP_EVENT:
7607		printk("hp_event\n");
7608		alc888_6st_dell_front_automute(codec);
7609		break;
7610	}
7611}
7612
7613/*
7614 * generic initialization of ADC, input mixers and output mixers
7615 */
7616static struct hda_verb alc883_auto_init_verbs[] = {
7617	/*
7618	 * Unmute ADC0-2 and set the default input to mic-in
7619	 */
7620	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7621	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7622	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7623	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7624
7625	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7626	 * mixer widget
7627	 * Note: PASD motherboards uses the Line In 2 as the input for
7628	 * front panel mic (mic 2)
7629	 */
7630	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7631	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7632	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7633	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7634	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7635	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7636
7637	/*
7638	 * Set up output mixers (0x0c - 0x0f)
7639	 */
7640	/* set vol=0 to output mixers */
7641	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7642	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7643	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7644	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7645	/* set up input amps for analog loopback */
7646	/* Amp Indices: DAC = 0, mixer = 1 */
7647	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7648	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7649	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7650	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7651	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7652	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7653	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7654	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7655	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7656	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7657
7658	/* FIXME: use matrix-type input source selection */
7659	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7660	/* Input mixer1 */
7661	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7662	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7663	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7664	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7665	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7666	/* Input mixer2 */
7667	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7668	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7669	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7670	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7671	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7672
7673	{ }
7674};
7675
7676/* capture mixer elements */
7677static struct snd_kcontrol_new alc883_capture_mixer[] = {
7678	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7679	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7680	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7681	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7682	{
7683		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7684		/* The multiple "Capture Source" controls confuse alsamixer
7685		 * So call somewhat different..
7686		 */
7687		/* .name = "Capture Source", */
7688		.name = "Input Source",
7689		.count = 2,
7690		.info = alc882_mux_enum_info,
7691		.get = alc882_mux_enum_get,
7692		.put = alc882_mux_enum_put,
7693	},
7694	{ } /* end */
7695};
7696
7697#ifdef CONFIG_SND_HDA_POWER_SAVE
7698#define alc883_loopbacks	alc880_loopbacks
7699#endif
7700
7701/* pcm configuration: identiacal with ALC880 */
7702#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
7703#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
7704#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
7705#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
7706#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
7707
7708/*
7709 * configuration and preset
7710 */
7711static const char *alc883_models[ALC883_MODEL_LAST] = {
7712	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
7713	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
7714	[ALC883_3ST_6ch]	= "3stack-6ch",
7715	[ALC883_6ST_DIG]	= "6stack-dig",
7716	[ALC883_TARGA_DIG]	= "targa-dig",
7717	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
7718	[ALC883_ACER]		= "acer",
7719	[ALC883_ACER_ASPIRE]	= "acer-aspire",
7720	[ALC883_MEDION]		= "medion",
7721	[ALC883_MEDION_MD2]	= "medion-md2",
7722	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
7723	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7724	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
7725	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7726	[ALC883_HAIER_W66] 	= "haier-w66",
7727	[ALC888_3ST_HP]		= "3stack-hp",
7728	[ALC888_6ST_DELL]	= "6stack-dell",
7729	[ALC883_MITAC]		= "mitac",
7730	[ALC883_CLEVO_M720]	= "clevo-m720",
7731	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
7732	[ALC883_AUTO]		= "auto",
7733};
7734
7735static struct snd_pci_quirk alc883_cfg_tbl[] = {
7736	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7737	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7738	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7739	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7740	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7741	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
7742	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7743	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7744	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7745	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
7746	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7747	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
7748	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7749	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7750	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7751	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7752	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7753	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7754	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7755	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7756	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
7757	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7758	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
7759	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7760	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7761	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7762	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7763	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7764	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7765	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7766	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7767	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7768	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7769	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7770	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7771	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
7772	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7773	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7774	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7775	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7776	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
7777	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
7778	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7779	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7780	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7781	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
7782	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7783	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7784	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7785	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7786	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7787	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7788	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7789	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7790	{}
7791};
7792
7793static struct alc_config_preset alc883_presets[] = {
7794	[ALC883_3ST_2ch_DIG] = {
7795		.mixers = { alc883_3ST_2ch_mixer },
7796		.init_verbs = { alc883_init_verbs },
7797		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7798		.dac_nids = alc883_dac_nids,
7799		.dig_out_nid = ALC883_DIGOUT_NID,
7800		.dig_in_nid = ALC883_DIGIN_NID,
7801		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7802		.channel_mode = alc883_3ST_2ch_modes,
7803		.input_mux = &alc883_capture_source,
7804	},
7805	[ALC883_3ST_6ch_DIG] = {
7806		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7807		.init_verbs = { alc883_init_verbs },
7808		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7809		.dac_nids = alc883_dac_nids,
7810		.dig_out_nid = ALC883_DIGOUT_NID,
7811		.dig_in_nid = ALC883_DIGIN_NID,
7812		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7813		.channel_mode = alc883_3ST_6ch_modes,
7814		.need_dac_fix = 1,
7815		.input_mux = &alc883_capture_source,
7816	},
7817	[ALC883_3ST_6ch] = {
7818		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7819		.init_verbs = { alc883_init_verbs },
7820		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7821		.dac_nids = alc883_dac_nids,
7822		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7823		.channel_mode = alc883_3ST_6ch_modes,
7824		.need_dac_fix = 1,
7825		.input_mux = &alc883_capture_source,
7826	},
7827	[ALC883_6ST_DIG] = {
7828		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
7829		.init_verbs = { alc883_init_verbs },
7830		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7831		.dac_nids = alc883_dac_nids,
7832		.dig_out_nid = ALC883_DIGOUT_NID,
7833		.dig_in_nid = ALC883_DIGIN_NID,
7834		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7835		.channel_mode = alc883_sixstack_modes,
7836		.input_mux = &alc883_capture_source,
7837	},
7838	[ALC883_TARGA_DIG] = {
7839		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7840		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7841		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7842		.dac_nids = alc883_dac_nids,
7843		.dig_out_nid = ALC883_DIGOUT_NID,
7844		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7845		.channel_mode = alc883_3ST_6ch_modes,
7846		.need_dac_fix = 1,
7847		.input_mux = &alc883_capture_source,
7848		.unsol_event = alc883_tagra_unsol_event,
7849		.init_hook = alc883_tagra_automute,
7850	},
7851	[ALC883_TARGA_2ch_DIG] = {
7852		.mixers = { alc883_tagra_2ch_mixer},
7853		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7854		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7855		.dac_nids = alc883_dac_nids,
7856		.dig_out_nid = ALC883_DIGOUT_NID,
7857		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7858		.channel_mode = alc883_3ST_2ch_modes,
7859		.input_mux = &alc883_capture_source,
7860		.unsol_event = alc883_tagra_unsol_event,
7861		.init_hook = alc883_tagra_automute,
7862	},
7863	[ALC883_ACER] = {
7864		.mixers = { alc883_base_mixer },
7865		/* On TravelMate laptops, GPIO 0 enables the internal speaker
7866		 * and the headphone jack.  Turn this on and rely on the
7867		 * standard mute methods whenever the user wants to turn
7868		 * these outputs off.
7869		 */
7870		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7871		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7872		.dac_nids = alc883_dac_nids,
7873		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7874		.channel_mode = alc883_3ST_2ch_modes,
7875		.input_mux = &alc883_capture_source,
7876	},
7877	[ALC883_ACER_ASPIRE] = {
7878		.mixers = { alc883_acer_aspire_mixer },
7879		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7880		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7881		.dac_nids = alc883_dac_nids,
7882		.dig_out_nid = ALC883_DIGOUT_NID,
7883		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7884		.channel_mode = alc883_3ST_2ch_modes,
7885		.input_mux = &alc883_capture_source,
7886		.unsol_event = alc883_acer_aspire_unsol_event,
7887		.init_hook = alc883_acer_aspire_automute,
7888	},
7889	[ALC883_MEDION] = {
7890		.mixers = { alc883_fivestack_mixer,
7891			    alc883_chmode_mixer },
7892		.init_verbs = { alc883_init_verbs,
7893				alc883_medion_eapd_verbs },
7894		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7895		.dac_nids = alc883_dac_nids,
7896		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7897		.channel_mode = alc883_sixstack_modes,
7898		.input_mux = &alc883_capture_source,
7899	},
7900	[ALC883_MEDION_MD2] = {
7901		.mixers = { alc883_medion_md2_mixer},
7902		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7903		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7904		.dac_nids = alc883_dac_nids,
7905		.dig_out_nid = ALC883_DIGOUT_NID,
7906		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7907		.channel_mode = alc883_3ST_2ch_modes,
7908		.input_mux = &alc883_capture_source,
7909		.unsol_event = alc883_medion_md2_unsol_event,
7910		.init_hook = alc883_medion_md2_automute,
7911	},
7912	[ALC883_LAPTOP_EAPD] = {
7913		.mixers = { alc883_base_mixer },
7914		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7915		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7916		.dac_nids = alc883_dac_nids,
7917		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7918		.channel_mode = alc883_3ST_2ch_modes,
7919		.input_mux = &alc883_capture_source,
7920	},
7921	[ALC883_CLEVO_M720] = {
7922		.mixers = { alc883_clevo_m720_mixer },
7923		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
7924		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7925		.dac_nids = alc883_dac_nids,
7926		.dig_out_nid = ALC883_DIGOUT_NID,
7927		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7928		.channel_mode = alc883_3ST_2ch_modes,
7929		.input_mux = &alc883_capture_source,
7930		.unsol_event = alc883_clevo_m720_unsol_event,
7931		.init_hook = alc883_clevo_m720_automute,
7932	},
7933	[ALC883_LENOVO_101E_2ch] = {
7934		.mixers = { alc883_lenovo_101e_2ch_mixer},
7935		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7936		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7937		.dac_nids = alc883_dac_nids,
7938		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7939		.channel_mode = alc883_3ST_2ch_modes,
7940		.input_mux = &alc883_lenovo_101e_capture_source,
7941		.unsol_event = alc883_lenovo_101e_unsol_event,
7942		.init_hook = alc883_lenovo_101e_all_automute,
7943	},
7944	[ALC883_LENOVO_NB0763] = {
7945		.mixers = { alc883_lenovo_nb0763_mixer },
7946		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7947		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7948		.dac_nids = alc883_dac_nids,
7949		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7950		.channel_mode = alc883_3ST_2ch_modes,
7951		.need_dac_fix = 1,
7952		.input_mux = &alc883_lenovo_nb0763_capture_source,
7953		.unsol_event = alc883_medion_md2_unsol_event,
7954		.init_hook = alc883_medion_md2_automute,
7955	},
7956	[ALC888_LENOVO_MS7195_DIG] = {
7957		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7958		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7959		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7960		.dac_nids = alc883_dac_nids,
7961		.dig_out_nid = ALC883_DIGOUT_NID,
7962		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7963		.channel_mode = alc883_3ST_6ch_modes,
7964		.need_dac_fix = 1,
7965		.input_mux = &alc883_capture_source,
7966		.unsol_event = alc883_lenovo_ms7195_unsol_event,
7967		.init_hook = alc888_lenovo_ms7195_front_automute,
7968	},
7969	[ALC883_HAIER_W66] = {
7970		.mixers = { alc883_tagra_2ch_mixer},
7971		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7972		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7973		.dac_nids = alc883_dac_nids,
7974		.dig_out_nid = ALC883_DIGOUT_NID,
7975		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7976		.channel_mode = alc883_3ST_2ch_modes,
7977		.input_mux = &alc883_capture_source,
7978		.unsol_event = alc883_haier_w66_unsol_event,
7979		.init_hook = alc883_haier_w66_automute,
7980	},
7981	[ALC888_3ST_HP] = {
7982		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7983		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7984		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7985		.dac_nids = alc883_dac_nids,
7986		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7987		.channel_mode = alc888_3st_hp_modes,
7988		.need_dac_fix = 1,
7989		.input_mux = &alc883_capture_source,
7990	},
7991	[ALC888_6ST_DELL] = {
7992		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
7993		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7994		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7995		.dac_nids = alc883_dac_nids,
7996		.dig_out_nid = ALC883_DIGOUT_NID,
7997		.dig_in_nid = ALC883_DIGIN_NID,
7998		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7999		.channel_mode = alc883_sixstack_modes,
8000		.input_mux = &alc883_capture_source,
8001		.unsol_event = alc888_6st_dell_unsol_event,
8002		.init_hook = alc888_6st_dell_front_automute,
8003	},
8004	[ALC883_MITAC] = {
8005		.mixers = { alc883_mitac_mixer },
8006		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8007		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8008		.dac_nids = alc883_dac_nids,
8009		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8010		.channel_mode = alc883_3ST_2ch_modes,
8011		.input_mux = &alc883_capture_source,
8012		.unsol_event = alc883_mitac_unsol_event,
8013		.init_hook = alc883_mitac_automute,
8014	},
8015	[ALC883_FUJITSU_PI2515] = {
8016		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8017		.init_verbs = { alc883_init_verbs,
8018				alc883_2ch_fujitsu_pi2515_verbs},
8019		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8020		.dac_nids = alc883_dac_nids,
8021		.dig_out_nid = ALC883_DIGOUT_NID,
8022		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8023		.channel_mode = alc883_3ST_2ch_modes,
8024		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8025		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8026		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
8027	},
8028};
8029
8030
8031/*
8032 * BIOS auto configuration
8033 */
8034static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8035					      hda_nid_t nid, int pin_type,
8036					      int dac_idx)
8037{
8038	/* set as output */
8039	struct alc_spec *spec = codec->spec;
8040	int idx;
8041
8042	alc_set_pin_output(codec, nid, pin_type);
8043	if (spec->multiout.dac_nids[dac_idx] == 0x25)
8044		idx = 4;
8045	else
8046		idx = spec->multiout.dac_nids[dac_idx] - 2;
8047	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8048
8049}
8050
8051static void alc883_auto_init_multi_out(struct hda_codec *codec)
8052{
8053	struct alc_spec *spec = codec->spec;
8054	int i;
8055
8056	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8057	for (i = 0; i <= HDA_SIDE; i++) {
8058		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8059		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8060		if (nid)
8061			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8062							  i);
8063	}
8064}
8065
8066static void alc883_auto_init_hp_out(struct hda_codec *codec)
8067{
8068	struct alc_spec *spec = codec->spec;
8069	hda_nid_t pin;
8070
8071	pin = spec->autocfg.hp_pins[0];
8072	if (pin) /* connect to front */
8073		/* use dac 0 */
8074		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8075	pin = spec->autocfg.speaker_pins[0];
8076	if (pin)
8077		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8078}
8079
8080#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
8081#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
8082
8083static void alc883_auto_init_analog_input(struct hda_codec *codec)
8084{
8085	struct alc_spec *spec = codec->spec;
8086	int i;
8087
8088	for (i = 0; i < AUTO_PIN_LAST; i++) {
8089		hda_nid_t nid = spec->autocfg.input_pins[i];
8090		if (alc883_is_input_pin(nid)) {
8091			snd_hda_codec_write(codec, nid, 0,
8092					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8093					    (i <= AUTO_PIN_FRONT_MIC ?
8094					     PIN_VREF80 : PIN_IN));
8095			if (nid != ALC883_PIN_CD_NID)
8096				snd_hda_codec_write(codec, nid, 0,
8097						    AC_VERB_SET_AMP_GAIN_MUTE,
8098						    AMP_OUT_MUTE);
8099		}
8100	}
8101}
8102
8103/* almost identical with ALC880 parser... */
8104static int alc883_parse_auto_config(struct hda_codec *codec)
8105{
8106	struct alc_spec *spec = codec->spec;
8107	int err = alc880_parse_auto_config(codec);
8108
8109	if (err < 0)
8110		return err;
8111	else if (!err)
8112		return 0; /* no config found */
8113
8114	err = alc_auto_add_mic_boost(codec);
8115	if (err < 0)
8116		return err;
8117
8118	/* hack - override the init verbs */
8119	spec->init_verbs[0] = alc883_auto_init_verbs;
8120	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8121	spec->num_mixers++;
8122
8123	return 1; /* config found */
8124}
8125
8126/* additional initialization for auto-configuration model */
8127static void alc883_auto_init(struct hda_codec *codec)
8128{
8129	struct alc_spec *spec = codec->spec;
8130	alc883_auto_init_multi_out(codec);
8131	alc883_auto_init_hp_out(codec);
8132	alc883_auto_init_analog_input(codec);
8133	if (spec->unsol_event)
8134		alc_sku_automute(codec);
8135}
8136
8137static int patch_alc883(struct hda_codec *codec)
8138{
8139	struct alc_spec *spec;
8140	int err, board_config;
8141
8142	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8143	if (spec == NULL)
8144		return -ENOMEM;
8145
8146	codec->spec = spec;
8147
8148	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8149						  alc883_models,
8150						  alc883_cfg_tbl);
8151	if (board_config < 0) {
8152		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8153		       "trying auto-probe from BIOS...\n");
8154		board_config = ALC883_AUTO;
8155	}
8156
8157	if (board_config == ALC883_AUTO) {
8158		/* automatic parse from the BIOS config */
8159		err = alc883_parse_auto_config(codec);
8160		if (err < 0) {
8161			alc_free(codec);
8162			return err;
8163		} else if (!err) {
8164			printk(KERN_INFO
8165			       "hda_codec: Cannot set up configuration "
8166			       "from BIOS.  Using base mode...\n");
8167			board_config = ALC883_3ST_2ch_DIG;
8168		}
8169	}
8170
8171	if (board_config != ALC883_AUTO)
8172		setup_preset(spec, &alc883_presets[board_config]);
8173
8174	spec->stream_name_analog = "ALC883 Analog";
8175	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8176	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8177	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8178
8179	spec->stream_name_digital = "ALC883 Digital";
8180	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8181	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8182
8183	spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8184	spec->adc_nids = alc883_adc_nids;
8185	spec->capsrc_nids = alc883_capsrc_nids;
8186
8187	spec->vmaster_nid = 0x0c;
8188
8189	codec->patch_ops = alc_patch_ops;
8190	if (board_config == ALC883_AUTO)
8191		spec->init_hook = alc883_auto_init;
8192#ifdef CONFIG_SND_HDA_POWER_SAVE
8193	if (!spec->loopback.amplist)
8194		spec->loopback.amplist = alc883_loopbacks;
8195#endif
8196
8197	return 0;
8198}
8199
8200/*
8201 * ALC262 support
8202 */
8203
8204#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8205#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8206
8207#define alc262_dac_nids		alc260_dac_nids
8208#define alc262_adc_nids		alc882_adc_nids
8209#define alc262_adc_nids_alt	alc882_adc_nids_alt
8210#define alc262_capsrc_nids	alc882_capsrc_nids
8211#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8212
8213#define alc262_modes		alc260_modes
8214#define alc262_capture_source	alc882_capture_source
8215
8216static struct snd_kcontrol_new alc262_base_mixer[] = {
8217	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8218	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8219	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8220	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8221	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8222	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8223	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8224	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8225	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8226	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8227	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8228	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8229	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8230	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8231	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8232	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8233	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8234	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8235	{ } /* end */
8236};
8237
8238static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8239	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8240	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8241	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8242	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8243	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8244	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8245	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8246	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8247	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8248	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8249	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8250	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8251	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8252	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8253	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8254	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8255	{ } /* end */
8256};
8257
8258/* update HP, line and mono-out pins according to the master switch */
8259static void alc262_hp_master_update(struct hda_codec *codec)
8260{
8261	struct alc_spec *spec = codec->spec;
8262	int val = spec->master_sw;
8263
8264	/* HP & line-out */
8265	snd_hda_codec_write_cache(codec, 0x1b, 0,
8266				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8267				  val ? PIN_HP : 0);
8268	snd_hda_codec_write_cache(codec, 0x15, 0,
8269				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8270				  val ? PIN_HP : 0);
8271	/* mono (speaker) depending on the HP jack sense */
8272	val = val && !spec->jack_present;
8273	snd_hda_codec_write_cache(codec, 0x16, 0,
8274				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8275				  val ? PIN_OUT : 0);
8276}
8277
8278static void alc262_hp_bpc_automute(struct hda_codec *codec)
8279{
8280	struct alc_spec *spec = codec->spec;
8281	unsigned int presence;
8282	presence = snd_hda_codec_read(codec, 0x1b, 0,
8283				      AC_VERB_GET_PIN_SENSE, 0);
8284	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8285	alc262_hp_master_update(codec);
8286}
8287
8288static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8289{
8290	if ((res >> 26) != ALC880_HP_EVENT)
8291		return;
8292	alc262_hp_bpc_automute(codec);
8293}
8294
8295static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8296{
8297	struct alc_spec *spec = codec->spec;
8298	unsigned int presence;
8299	presence = snd_hda_codec_read(codec, 0x15, 0,
8300				      AC_VERB_GET_PIN_SENSE, 0);
8301	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8302	alc262_hp_master_update(codec);
8303}
8304
8305static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8306					   unsigned int res)
8307{
8308	if ((res >> 26) != ALC880_HP_EVENT)
8309		return;
8310	alc262_hp_wildwest_automute(codec);
8311}
8312
8313static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8314				   struct snd_ctl_elem_value *ucontrol)
8315{
8316	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8317	struct alc_spec *spec = codec->spec;
8318	*ucontrol->value.integer.value = spec->master_sw;
8319	return 0;
8320}
8321
8322static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8323				   struct snd_ctl_elem_value *ucontrol)
8324{
8325	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8326	struct alc_spec *spec = codec->spec;
8327	int val = !!*ucontrol->value.integer.value;
8328
8329	if (val == spec->master_sw)
8330		return 0;
8331	spec->master_sw = val;
8332	alc262_hp_master_update(codec);
8333	return 1;
8334}
8335
8336static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8337	{
8338		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8339		.name = "Master Playback Switch",
8340		.info = snd_ctl_boolean_mono_info,
8341		.get = alc262_hp_master_sw_get,
8342		.put = alc262_hp_master_sw_put,
8343	},
8344	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8345	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8346	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8347	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8348			      HDA_OUTPUT),
8349	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8350			    HDA_OUTPUT),
8351	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8352	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8353	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8354	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8355	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8356	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8357	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8358	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8359	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8360	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8361	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8362	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8363	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8364	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8365	{ } /* end */
8366};
8367
8368static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8369	{
8370		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8371		.name = "Master Playback Switch",
8372		.info = snd_ctl_boolean_mono_info,
8373		.get = alc262_hp_master_sw_get,
8374		.put = alc262_hp_master_sw_put,
8375	},
8376	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8377	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8378	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8379	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8380	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8381			      HDA_OUTPUT),
8382	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8383			    HDA_OUTPUT),
8384	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8385	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8386	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8387	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8388	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8389	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8390	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8391	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8392	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8393	{ } /* end */
8394};
8395
8396static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8397	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8398	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8399	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8400	{ } /* end */
8401};
8402
8403/* mute/unmute internal speaker according to the hp jack and mute state */
8404static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8405{
8406	struct alc_spec *spec = codec->spec;
8407
8408	if (force || !spec->sense_updated) {
8409		unsigned int present;
8410		present = snd_hda_codec_read(codec, 0x15, 0,
8411					     AC_VERB_GET_PIN_SENSE, 0);
8412		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8413		spec->sense_updated = 1;
8414	}
8415	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8416				 spec->jack_present ? HDA_AMP_MUTE : 0);
8417}
8418
8419static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8420					unsigned int res)
8421{
8422	if ((res >> 26) != ALC880_HP_EVENT)
8423		return;
8424	alc262_hp_t5735_automute(codec, 1);
8425}
8426
8427static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8428{
8429	alc262_hp_t5735_automute(codec, 1);
8430}
8431
8432static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8433	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8434	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8435	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8436	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8437	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8438	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8439	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8440	{ } /* end */
8441};
8442
8443static struct hda_verb alc262_hp_t5735_verbs[] = {
8444	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8445	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8446
8447	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8448	{ }
8449};
8450
8451static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8452	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8453	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8454	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8455	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8456	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8457	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8458	{ } /* end */
8459};
8460
8461static struct hda_verb alc262_hp_rp5700_verbs[] = {
8462	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8463	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8464	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8465	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8466	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8467	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8468	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8469	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8470	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8471	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8472	{}
8473};
8474
8475static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8476	.num_items = 1,
8477	.items = {
8478		{ "Line", 0x1 },
8479	},
8480};
8481
8482/* bind hp and internal speaker mute (with plug check) */
8483static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8484				     struct snd_ctl_elem_value *ucontrol)
8485{
8486	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8487	long *valp = ucontrol->value.integer.value;
8488	int change;
8489
8490	/* change hp mute */
8491	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8492					  HDA_AMP_MUTE,
8493					  valp[0] ? 0 : HDA_AMP_MUTE);
8494	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8495					   HDA_AMP_MUTE,
8496					   valp[1] ? 0 : HDA_AMP_MUTE);
8497	if (change) {
8498		/* change speaker according to HP jack state */
8499		struct alc_spec *spec = codec->spec;
8500		unsigned int mute;
8501		if (spec->jack_present)
8502			mute = HDA_AMP_MUTE;
8503		else
8504			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8505						      HDA_OUTPUT, 0);
8506		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8507					 HDA_AMP_MUTE, mute);
8508	}
8509	return change;
8510}
8511
8512static struct snd_kcontrol_new alc262_sony_mixer[] = {
8513	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8514	{
8515		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8516		.name = "Master Playback Switch",
8517		.info = snd_hda_mixer_amp_switch_info,
8518		.get = snd_hda_mixer_amp_switch_get,
8519		.put = alc262_sony_master_sw_put,
8520		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8521	},
8522	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8523	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8524	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8525	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8526	{ } /* end */
8527};
8528
8529static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8530	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8531	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8532	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8533	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8534	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8535	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8536	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8537	{ } /* end */
8538};
8539
8540#define alc262_capture_mixer		alc882_capture_mixer
8541#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
8542
8543/*
8544 * generic initialization of ADC, input mixers and output mixers
8545 */
8546static struct hda_verb alc262_init_verbs[] = {
8547	/*
8548	 * Unmute ADC0-2 and set the default input to mic-in
8549	 */
8550	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8551	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8552	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8553	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8554	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8555	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8556
8557	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8558	 * mixer widget
8559	 * Note: PASD motherboards uses the Line In 2 as the input for
8560	 * front panel mic (mic 2)
8561	 */
8562	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8563	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8564	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8565	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8566	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8567	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8568
8569	/*
8570	 * Set up output mixers (0x0c - 0x0e)
8571	 */
8572	/* set vol=0 to output mixers */
8573	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8574	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8575	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8576	/* set up input amps for analog loopback */
8577	/* Amp Indices: DAC = 0, mixer = 1 */
8578	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8579	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8580	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8581	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8582	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8583	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8584
8585	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8586	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8587	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8588	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8589	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8590	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8591
8592	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8593	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8594	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8595	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8596	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8597
8598	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8599	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8600
8601	/* FIXME: use matrix-type input source selection */
8602	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8603	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8604	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8605	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8606	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8607	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8608	/* Input mixer2 */
8609	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8610	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8611	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8612	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8613	/* Input mixer3 */
8614	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8615	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8616	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8617	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8618
8619	{ }
8620};
8621
8622static struct hda_verb alc262_hippo_unsol_verbs[] = {
8623	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8624	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8625	{}
8626};
8627
8628static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8629	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8630	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8631	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8632
8633	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8634	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8635	{}
8636};
8637
8638static struct hda_verb alc262_sony_unsol_verbs[] = {
8639	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8640	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8641	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
8642
8643	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8644	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8645};
8646
8647/* mute/unmute internal speaker according to the hp jack and mute state */
8648static void alc262_hippo_automute(struct hda_codec *codec)
8649{
8650	struct alc_spec *spec = codec->spec;
8651	unsigned int mute;
8652	unsigned int present;
8653
8654	/* need to execute and sync at first */
8655	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8656	present = snd_hda_codec_read(codec, 0x15, 0,
8657				     AC_VERB_GET_PIN_SENSE, 0);
8658	spec->jack_present = (present & 0x80000000) != 0;
8659	if (spec->jack_present) {
8660		/* mute internal speaker */
8661		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8662					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8663	} else {
8664		/* unmute internal speaker if necessary */
8665		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8666		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8667					 HDA_AMP_MUTE, mute);
8668	}
8669}
8670
8671/* unsolicited event for HP jack sensing */
8672static void alc262_hippo_unsol_event(struct hda_codec *codec,
8673				       unsigned int res)
8674{
8675	if ((res >> 26) != ALC880_HP_EVENT)
8676		return;
8677	alc262_hippo_automute(codec);
8678}
8679
8680static void alc262_hippo1_automute(struct hda_codec *codec)
8681{
8682	unsigned int mute;
8683	unsigned int present;
8684
8685	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8686	present = snd_hda_codec_read(codec, 0x1b, 0,
8687				     AC_VERB_GET_PIN_SENSE, 0);
8688	present = (present & 0x80000000) != 0;
8689	if (present) {
8690		/* mute internal speaker */
8691		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8692					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8693	} else {
8694		/* unmute internal speaker if necessary */
8695		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8696		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8697					 HDA_AMP_MUTE, mute);
8698	}
8699}
8700
8701/* unsolicited event for HP jack sensing */
8702static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8703				       unsigned int res)
8704{
8705	if ((res >> 26) != ALC880_HP_EVENT)
8706		return;
8707	alc262_hippo1_automute(codec);
8708}
8709
8710/*
8711 * fujitsu model
8712 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
8713 *  0x1b = port replicator headphone out
8714 */
8715
8716#define ALC_HP_EVENT	0x37
8717
8718static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8719	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8720	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8721	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8722	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8723	{}
8724};
8725
8726static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
8727	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8728	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8729	{}
8730};
8731
8732static struct hda_input_mux alc262_fujitsu_capture_source = {
8733	.num_items = 3,
8734	.items = {
8735		{ "Mic", 0x0 },
8736		{ "Int Mic", 0x1 },
8737		{ "CD", 0x4 },
8738	},
8739};
8740
8741static struct hda_input_mux alc262_HP_capture_source = {
8742	.num_items = 5,
8743	.items = {
8744		{ "Mic", 0x0 },
8745		{ "Front Mic", 0x1 },
8746		{ "Line", 0x2 },
8747		{ "CD", 0x4 },
8748		{ "AUX IN", 0x6 },
8749	},
8750};
8751
8752static struct hda_input_mux alc262_HP_D7000_capture_source = {
8753	.num_items = 4,
8754	.items = {
8755		{ "Mic", 0x0 },
8756		{ "Front Mic", 0x2 },
8757		{ "Line", 0x1 },
8758		{ "CD", 0x4 },
8759	},
8760};
8761
8762/* mute/unmute internal speaker according to the hp jacks and mute state */
8763static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8764{
8765	struct alc_spec *spec = codec->spec;
8766	unsigned int mute;
8767
8768	if (force || !spec->sense_updated) {
8769		unsigned int present;
8770		/* need to execute and sync at first */
8771		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8772		/* check laptop HP jack */
8773		present = snd_hda_codec_read(codec, 0x14, 0,
8774					     AC_VERB_GET_PIN_SENSE, 0);
8775		/* need to execute and sync at first */
8776		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8777		/* check docking HP jack */
8778		present |= snd_hda_codec_read(codec, 0x1b, 0,
8779					      AC_VERB_GET_PIN_SENSE, 0);
8780		if (present & AC_PINSENSE_PRESENCE)
8781			spec->jack_present = 1;
8782		else
8783			spec->jack_present = 0;
8784		spec->sense_updated = 1;
8785	}
8786	/* unmute internal speaker only if both HPs are unplugged and
8787	 * master switch is on
8788	 */
8789	if (spec->jack_present)
8790		mute = HDA_AMP_MUTE;
8791	else
8792		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8793	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8794				 HDA_AMP_MUTE, mute);
8795}
8796
8797/* unsolicited event for HP jack sensing */
8798static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8799				       unsigned int res)
8800{
8801	if ((res >> 26) != ALC_HP_EVENT)
8802		return;
8803	alc262_fujitsu_automute(codec, 1);
8804}
8805
8806static void alc262_fujitsu_init_hook(struct hda_codec *codec)
8807{
8808	alc262_fujitsu_automute(codec, 1);
8809}
8810
8811/* bind volumes of both NID 0x0c and 0x0d */
8812static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8813	.ops = &snd_hda_bind_vol,
8814	.values = {
8815		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8816		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8817		0
8818	},
8819};
8820
8821/* mute/unmute internal speaker according to the hp jack and mute state */
8822static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
8823{
8824	struct alc_spec *spec = codec->spec;
8825	unsigned int mute;
8826
8827	if (force || !spec->sense_updated) {
8828		unsigned int present_int_hp;
8829		/* need to execute and sync at first */
8830		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8831		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
8832					AC_VERB_GET_PIN_SENSE, 0);
8833		spec->jack_present = (present_int_hp & 0x80000000) != 0;
8834		spec->sense_updated = 1;
8835	}
8836	if (spec->jack_present) {
8837		/* mute internal speaker */
8838		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8839					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8840		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8841					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8842	} else {
8843		/* unmute internal speaker if necessary */
8844		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8845		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8846					 HDA_AMP_MUTE, mute);
8847		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8848					 HDA_AMP_MUTE, mute);
8849	}
8850}
8851
8852/* unsolicited event for HP jack sensing */
8853static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
8854				       unsigned int res)
8855{
8856	if ((res >> 26) != ALC_HP_EVENT)
8857		return;
8858	alc262_lenovo_3000_automute(codec, 1);
8859}
8860
8861/* bind hp and internal speaker mute (with plug check) */
8862static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8863					 struct snd_ctl_elem_value *ucontrol)
8864{
8865	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8866	long *valp = ucontrol->value.integer.value;
8867	int change;
8868
8869	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8870						 HDA_AMP_MUTE,
8871						 valp ? 0 : HDA_AMP_MUTE);
8872	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8873						 HDA_AMP_MUTE,
8874						 valp ? 0 : HDA_AMP_MUTE);
8875
8876	if (change)
8877		alc262_fujitsu_automute(codec, 0);
8878	return change;
8879}
8880
8881static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8882	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8883	{
8884		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8885		.name = "Master Playback Switch",
8886		.info = snd_hda_mixer_amp_switch_info,
8887		.get = snd_hda_mixer_amp_switch_get,
8888		.put = alc262_fujitsu_master_sw_put,
8889		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8890	},
8891	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8892	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8893	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
8894	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
8895	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8896	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8897	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8898	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8899	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8900	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8901	{ } /* end */
8902};
8903
8904/* bind hp and internal speaker mute (with plug check) */
8905static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
8906					 struct snd_ctl_elem_value *ucontrol)
8907{
8908	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8909	long *valp = ucontrol->value.integer.value;
8910	int change;
8911
8912	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8913						 HDA_AMP_MUTE,
8914						 valp ? 0 : HDA_AMP_MUTE);
8915
8916	if (change)
8917		alc262_lenovo_3000_automute(codec, 0);
8918	return change;
8919}
8920
8921static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
8922	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8923	{
8924		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8925		.name = "Master Playback Switch",
8926		.info = snd_hda_mixer_amp_switch_info,
8927		.get = snd_hda_mixer_amp_switch_get,
8928		.put = alc262_lenovo_3000_master_sw_put,
8929		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
8930	},
8931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8932	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8933	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8934	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8935	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8936	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8937	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8938	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8939	{ } /* end */
8940};
8941
8942/* additional init verbs for Benq laptops */
8943static struct hda_verb alc262_EAPD_verbs[] = {
8944	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8945	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
8946	{}
8947};
8948
8949static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8950	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8951	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8952
8953	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8954	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
8955	{}
8956};
8957
8958/* Samsung Q1 Ultra Vista model setup */
8959static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8960	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8961	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
8962	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8963	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8964	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8965	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
8966	{ } /* end */
8967};
8968
8969static struct hda_verb alc262_ultra_verbs[] = {
8970	/* output mixer */
8971	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8972	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8973	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8974	/* speaker */
8975	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8976	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8977	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8979	/* HP */
8980	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8981	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8982	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8983	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8984	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8985	/* internal mic */
8986	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8987	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8988	/* ADC, choose mic */
8989	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8990	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8991	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8992	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8993	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8994	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8995	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8996	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8997	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8998	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
8999	{}
9000};
9001
9002/* mute/unmute internal speaker according to the hp jack and mute state */
9003static void alc262_ultra_automute(struct hda_codec *codec)
9004{
9005	struct alc_spec *spec = codec->spec;
9006	unsigned int mute;
9007
9008	mute = 0;
9009	/* auto-mute only when HP is used as HP */
9010	if (!spec->cur_mux[0]) {
9011		unsigned int present;
9012		/* need to execute and sync at first */
9013		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9014		present = snd_hda_codec_read(codec, 0x15, 0,
9015					     AC_VERB_GET_PIN_SENSE, 0);
9016		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9017		if (spec->jack_present)
9018			mute = HDA_AMP_MUTE;
9019	}
9020	/* mute/unmute internal speaker */
9021	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9022				 HDA_AMP_MUTE, mute);
9023	/* mute/unmute HP */
9024	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9025				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9026}
9027
9028/* unsolicited event for HP jack sensing */
9029static void alc262_ultra_unsol_event(struct hda_codec *codec,
9030				       unsigned int res)
9031{
9032	if ((res >> 26) != ALC880_HP_EVENT)
9033		return;
9034	alc262_ultra_automute(codec);
9035}
9036
9037static struct hda_input_mux alc262_ultra_capture_source = {
9038	.num_items = 2,
9039	.items = {
9040		{ "Mic", 0x1 },
9041		{ "Headphone", 0x7 },
9042	},
9043};
9044
9045static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9046				     struct snd_ctl_elem_value *ucontrol)
9047{
9048	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9049	struct alc_spec *spec = codec->spec;
9050	int ret;
9051
9052	ret = alc882_mux_enum_put(kcontrol, ucontrol);
9053	if (!ret)
9054		return 0;
9055	/* reprogram the HP pin as mic or HP according to the input source */
9056	snd_hda_codec_write_cache(codec, 0x15, 0,
9057				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9058				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9059	alc262_ultra_automute(codec); /* mute/unmute HP */
9060	return ret;
9061}
9062
9063static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9064	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9065	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9066	{
9067		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9068		.name = "Capture Source",
9069		.info = alc882_mux_enum_info,
9070		.get = alc882_mux_enum_get,
9071		.put = alc262_ultra_mux_enum_put,
9072	},
9073	{ } /* end */
9074};
9075
9076/* add playback controls from the parsed DAC table */
9077static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9078					     const struct auto_pin_cfg *cfg)
9079{
9080	hda_nid_t nid;
9081	int err;
9082
9083	spec->multiout.num_dacs = 1;	/* only use one dac */
9084	spec->multiout.dac_nids = spec->private_dac_nids;
9085	spec->multiout.dac_nids[0] = 2;
9086
9087	nid = cfg->line_out_pins[0];
9088	if (nid) {
9089		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9090				  "Front Playback Volume",
9091				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9092		if (err < 0)
9093			return err;
9094		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9095				  "Front Playback Switch",
9096				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9097		if (err < 0)
9098			return err;
9099	}
9100
9101	nid = cfg->speaker_pins[0];
9102	if (nid) {
9103		if (nid == 0x16) {
9104			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9105					  "Speaker Playback Volume",
9106					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9107							      HDA_OUTPUT));
9108			if (err < 0)
9109				return err;
9110			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9111					  "Speaker Playback Switch",
9112					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9113							      HDA_OUTPUT));
9114			if (err < 0)
9115				return err;
9116		} else {
9117			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9118					  "Speaker Playback Switch",
9119					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9120							      HDA_OUTPUT));
9121			if (err < 0)
9122				return err;
9123		}
9124	}
9125	nid = cfg->hp_pins[0];
9126	if (nid) {
9127		/* spec->multiout.hp_nid = 2; */
9128		if (nid == 0x16) {
9129			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9130					  "Headphone Playback Volume",
9131					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9132							      HDA_OUTPUT));
9133			if (err < 0)
9134				return err;
9135			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9136					  "Headphone Playback Switch",
9137					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9138							      HDA_OUTPUT));
9139			if (err < 0)
9140				return err;
9141		} else {
9142			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9143					  "Headphone Playback Switch",
9144					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9145							      HDA_OUTPUT));
9146			if (err < 0)
9147				return err;
9148		}
9149	}
9150	return 0;
9151}
9152
9153/* identical with ALC880 */
9154#define alc262_auto_create_analog_input_ctls \
9155	alc880_auto_create_analog_input_ctls
9156
9157/*
9158 * generic initialization of ADC, input mixers and output mixers
9159 */
9160static struct hda_verb alc262_volume_init_verbs[] = {
9161	/*
9162	 * Unmute ADC0-2 and set the default input to mic-in
9163	 */
9164	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9165	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9166	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9167	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9168	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9169	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9170
9171	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9172	 * mixer widget
9173	 * Note: PASD motherboards uses the Line In 2 as the input for
9174	 * front panel mic (mic 2)
9175	 */
9176	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9177	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9178	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9179	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9180	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9181	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9182
9183	/*
9184	 * Set up output mixers (0x0c - 0x0f)
9185	 */
9186	/* set vol=0 to output mixers */
9187	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9188	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9189	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9190
9191	/* set up input amps for analog loopback */
9192	/* Amp Indices: DAC = 0, mixer = 1 */
9193	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9194	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9195	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9196	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9197	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9198	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9199
9200	/* FIXME: use matrix-type input source selection */
9201	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9202	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9203	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9204	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9205	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9206	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9207	/* Input mixer2 */
9208	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9209	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9210	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9211	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9212	/* Input mixer3 */
9213	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9214	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9215	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9216	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9217
9218	{ }
9219};
9220
9221static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9222	/*
9223	 * Unmute ADC0-2 and set the default input to mic-in
9224	 */
9225	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9226	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9227	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9228	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9229	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9230	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9231
9232	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9233	 * mixer widget
9234	 * Note: PASD motherboards uses the Line In 2 as the input for
9235	 * front panel mic (mic 2)
9236	 */
9237	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9238	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9239	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9240	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9241	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9242	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9243	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9244        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9245
9246	/*
9247	 * Set up output mixers (0x0c - 0x0e)
9248	 */
9249	/* set vol=0 to output mixers */
9250	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9251	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9252	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9253
9254	/* set up input amps for analog loopback */
9255	/* Amp Indices: DAC = 0, mixer = 1 */
9256	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9257	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9258	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9259	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9260	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9261	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9262
9263	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9264	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9265	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9266
9267	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9268	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9269
9270	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9271	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9272
9273	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9274	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9275        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9276	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9277	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9278
9279	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9280	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9281        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9282	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9283	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9284	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9285
9286
9287	/* FIXME: use matrix-type input source selection */
9288	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9289	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9290	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9291	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9292	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9293	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9294	/* Input mixer2 */
9295	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9296	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9297	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9298	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9299	/* Input mixer3 */
9300	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9301	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9302	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9303	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9304
9305	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9306
9307	{ }
9308};
9309
9310static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9311	/*
9312	 * Unmute ADC0-2 and set the default input to mic-in
9313	 */
9314	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9315	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9316	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9317	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9318	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9319	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9320
9321	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9322	 * mixer widget
9323	 * Note: PASD motherboards uses the Line In 2 as the input for front
9324	 * panel mic (mic 2)
9325	 */
9326	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9327	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9328	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9329	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9330	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9331	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9332	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9333	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9334	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9335	/*
9336	 * Set up output mixers (0x0c - 0x0e)
9337	 */
9338	/* set vol=0 to output mixers */
9339	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9340	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9341	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9342
9343	/* set up input amps for analog loopback */
9344	/* Amp Indices: DAC = 0, mixer = 1 */
9345	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9346	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9347	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9348	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9349	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9350	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9351
9352
9353	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
9354	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
9355	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
9356	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
9357	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
9358	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
9359	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
9360
9361	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9362	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9363
9364	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9365	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9366
9367	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9368	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9369	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9370	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9371	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9372	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9373
9374	/* FIXME: use matrix-type input source selection */
9375	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9376	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9377	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9378	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9379	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9380	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9381	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9382        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
9383	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9384	/* Input mixer2 */
9385	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9386	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9387	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9388	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9389	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9390        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9391	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9392	/* Input mixer3 */
9393	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9394	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9395	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9396	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9397	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9398        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9399	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9400
9401	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9402
9403	{ }
9404};
9405
9406#ifdef CONFIG_SND_HDA_POWER_SAVE
9407#define alc262_loopbacks	alc880_loopbacks
9408#endif
9409
9410/* pcm configuration: identiacal with ALC880 */
9411#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
9412#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
9413#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
9414#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
9415
9416/*
9417 * BIOS auto configuration
9418 */
9419static int alc262_parse_auto_config(struct hda_codec *codec)
9420{
9421	struct alc_spec *spec = codec->spec;
9422	int err;
9423	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9424
9425	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9426					   alc262_ignore);
9427	if (err < 0)
9428		return err;
9429	if (!spec->autocfg.line_outs)
9430		return 0; /* can't find valid BIOS pin config */
9431	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9432	if (err < 0)
9433		return err;
9434	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9435	if (err < 0)
9436		return err;
9437
9438	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9439
9440	if (spec->autocfg.dig_out_pin)
9441		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9442	if (spec->autocfg.dig_in_pin)
9443		spec->dig_in_nid = ALC262_DIGIN_NID;
9444
9445	if (spec->kctl_alloc)
9446		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9447
9448	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
9449	spec->num_mux_defs = 1;
9450	spec->input_mux = &spec->private_imux;
9451
9452	err = alc_auto_add_mic_boost(codec);
9453	if (err < 0)
9454		return err;
9455
9456	return 1;
9457}
9458
9459#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
9460#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
9461#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
9462
9463
9464/* init callback for auto-configuration model -- overriding the default init */
9465static void alc262_auto_init(struct hda_codec *codec)
9466{
9467	struct alc_spec *spec = codec->spec;
9468	alc262_auto_init_multi_out(codec);
9469	alc262_auto_init_hp_out(codec);
9470	alc262_auto_init_analog_input(codec);
9471	if (spec->unsol_event)
9472		alc_sku_automute(codec);
9473}
9474
9475/*
9476 * configuration and preset
9477 */
9478static const char *alc262_models[ALC262_MODEL_LAST] = {
9479	[ALC262_BASIC]		= "basic",
9480	[ALC262_HIPPO]		= "hippo",
9481	[ALC262_HIPPO_1]	= "hippo_1",
9482	[ALC262_FUJITSU]	= "fujitsu",
9483	[ALC262_HP_BPC]		= "hp-bpc",
9484	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
9485	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
9486	[ALC262_HP_RP5700]	= "hp-rp5700",
9487	[ALC262_BENQ_ED8]	= "benq",
9488	[ALC262_BENQ_T31]	= "benq-t31",
9489	[ALC262_SONY_ASSAMD]	= "sony-assamd",
9490	[ALC262_ULTRA]		= "ultra",
9491	[ALC262_LENOVO_3000]	= "lenovo-3000",
9492	[ALC262_AUTO]		= "auto",
9493};
9494
9495static struct snd_pci_quirk alc262_cfg_tbl[] = {
9496	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9497	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9498	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9499	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9500	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
9501	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
9502	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
9503	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
9504	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
9505	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
9506	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
9507	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
9508	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
9509	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
9510	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
9511	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
9512	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
9513	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9514	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9515	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
9516	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9517		      ALC262_HP_TC_T5735),
9518	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
9519	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9520	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
9521	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9522	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9523	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9524	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9525	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9526	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
9527	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
9528	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
9529	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9530	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9531	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
9532	{}
9533};
9534
9535static struct alc_config_preset alc262_presets[] = {
9536	[ALC262_BASIC] = {
9537		.mixers = { alc262_base_mixer },
9538		.init_verbs = { alc262_init_verbs },
9539		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9540		.dac_nids = alc262_dac_nids,
9541		.hp_nid = 0x03,
9542		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9543		.channel_mode = alc262_modes,
9544		.input_mux = &alc262_capture_source,
9545	},
9546	[ALC262_HIPPO] = {
9547		.mixers = { alc262_base_mixer },
9548		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9549		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9550		.dac_nids = alc262_dac_nids,
9551		.hp_nid = 0x03,
9552		.dig_out_nid = ALC262_DIGOUT_NID,
9553		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9554		.channel_mode = alc262_modes,
9555		.input_mux = &alc262_capture_source,
9556		.unsol_event = alc262_hippo_unsol_event,
9557		.init_hook = alc262_hippo_automute,
9558	},
9559	[ALC262_HIPPO_1] = {
9560		.mixers = { alc262_hippo1_mixer },
9561		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9562		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9563		.dac_nids = alc262_dac_nids,
9564		.hp_nid = 0x02,
9565		.dig_out_nid = ALC262_DIGOUT_NID,
9566		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9567		.channel_mode = alc262_modes,
9568		.input_mux = &alc262_capture_source,
9569		.unsol_event = alc262_hippo1_unsol_event,
9570		.init_hook = alc262_hippo1_automute,
9571	},
9572	[ALC262_FUJITSU] = {
9573		.mixers = { alc262_fujitsu_mixer },
9574		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9575				alc262_fujitsu_unsol_verbs },
9576		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9577		.dac_nids = alc262_dac_nids,
9578		.hp_nid = 0x03,
9579		.dig_out_nid = ALC262_DIGOUT_NID,
9580		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9581		.channel_mode = alc262_modes,
9582		.input_mux = &alc262_fujitsu_capture_source,
9583		.unsol_event = alc262_fujitsu_unsol_event,
9584		.init_hook = alc262_fujitsu_init_hook,
9585	},
9586	[ALC262_HP_BPC] = {
9587		.mixers = { alc262_HP_BPC_mixer },
9588		.init_verbs = { alc262_HP_BPC_init_verbs },
9589		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9590		.dac_nids = alc262_dac_nids,
9591		.hp_nid = 0x03,
9592		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9593		.channel_mode = alc262_modes,
9594		.input_mux = &alc262_HP_capture_source,
9595		.unsol_event = alc262_hp_bpc_unsol_event,
9596		.init_hook = alc262_hp_bpc_automute,
9597	},
9598	[ALC262_HP_BPC_D7000_WF] = {
9599		.mixers = { alc262_HP_BPC_WildWest_mixer },
9600		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9601		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9602		.dac_nids = alc262_dac_nids,
9603		.hp_nid = 0x03,
9604		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9605		.channel_mode = alc262_modes,
9606		.input_mux = &alc262_HP_D7000_capture_source,
9607		.unsol_event = alc262_hp_wildwest_unsol_event,
9608		.init_hook = alc262_hp_wildwest_automute,
9609	},
9610	[ALC262_HP_BPC_D7000_WL] = {
9611		.mixers = { alc262_HP_BPC_WildWest_mixer,
9612			    alc262_HP_BPC_WildWest_option_mixer },
9613		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9614		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9615		.dac_nids = alc262_dac_nids,
9616		.hp_nid = 0x03,
9617		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9618		.channel_mode = alc262_modes,
9619		.input_mux = &alc262_HP_D7000_capture_source,
9620		.unsol_event = alc262_hp_wildwest_unsol_event,
9621		.init_hook = alc262_hp_wildwest_automute,
9622	},
9623	[ALC262_HP_TC_T5735] = {
9624		.mixers = { alc262_hp_t5735_mixer },
9625		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9626		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9627		.dac_nids = alc262_dac_nids,
9628		.hp_nid = 0x03,
9629		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9630		.channel_mode = alc262_modes,
9631		.input_mux = &alc262_capture_source,
9632		.unsol_event = alc262_hp_t5735_unsol_event,
9633		.init_hook = alc262_hp_t5735_init_hook,
9634	},
9635	[ALC262_HP_RP5700] = {
9636		.mixers = { alc262_hp_rp5700_mixer },
9637		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9638		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9639		.dac_nids = alc262_dac_nids,
9640		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9641		.channel_mode = alc262_modes,
9642		.input_mux = &alc262_hp_rp5700_capture_source,
9643        },
9644	[ALC262_BENQ_ED8] = {
9645		.mixers = { alc262_base_mixer },
9646		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9647		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9648		.dac_nids = alc262_dac_nids,
9649		.hp_nid = 0x03,
9650		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9651		.channel_mode = alc262_modes,
9652		.input_mux = &alc262_capture_source,
9653	},
9654	[ALC262_SONY_ASSAMD] = {
9655		.mixers = { alc262_sony_mixer },
9656		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9657		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9658		.dac_nids = alc262_dac_nids,
9659		.hp_nid = 0x02,
9660		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9661		.channel_mode = alc262_modes,
9662		.input_mux = &alc262_capture_source,
9663		.unsol_event = alc262_hippo_unsol_event,
9664		.init_hook = alc262_hippo_automute,
9665	},
9666	[ALC262_BENQ_T31] = {
9667		.mixers = { alc262_benq_t31_mixer },
9668		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9669		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9670		.dac_nids = alc262_dac_nids,
9671		.hp_nid = 0x03,
9672		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9673		.channel_mode = alc262_modes,
9674		.input_mux = &alc262_capture_source,
9675		.unsol_event = alc262_hippo_unsol_event,
9676		.init_hook = alc262_hippo_automute,
9677	},
9678	[ALC262_ULTRA] = {
9679		.mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
9680		.init_verbs = { alc262_ultra_verbs },
9681		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9682		.dac_nids = alc262_dac_nids,
9683		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9684		.channel_mode = alc262_modes,
9685		.input_mux = &alc262_ultra_capture_source,
9686		.adc_nids = alc262_adc_nids, /* ADC0 */
9687		.capsrc_nids = alc262_capsrc_nids,
9688		.num_adc_nids = 1, /* single ADC */
9689		.unsol_event = alc262_ultra_unsol_event,
9690		.init_hook = alc262_ultra_automute,
9691	},
9692	[ALC262_LENOVO_3000] = {
9693		.mixers = { alc262_lenovo_3000_mixer },
9694		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9695				alc262_lenovo_3000_unsol_verbs },
9696		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9697		.dac_nids = alc262_dac_nids,
9698		.hp_nid = 0x03,
9699		.dig_out_nid = ALC262_DIGOUT_NID,
9700		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9701		.channel_mode = alc262_modes,
9702		.input_mux = &alc262_fujitsu_capture_source,
9703		.unsol_event = alc262_lenovo_3000_unsol_event,
9704	},
9705};
9706
9707static int patch_alc262(struct hda_codec *codec)
9708{
9709	struct alc_spec *spec;
9710	int board_config;
9711	int err;
9712
9713	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9714	if (spec == NULL)
9715		return -ENOMEM;
9716
9717	codec->spec = spec;
9718#if 0
9719	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
9720	 * under-run
9721	 */
9722	{
9723	int tmp;
9724	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9725	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9726	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9727	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9728	}
9729#endif
9730
9731	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9732						  alc262_models,
9733						  alc262_cfg_tbl);
9734
9735	if (board_config < 0) {
9736		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9737		       "trying auto-probe from BIOS...\n");
9738		board_config = ALC262_AUTO;
9739	}
9740
9741	if (board_config == ALC262_AUTO) {
9742		/* automatic parse from the BIOS config */
9743		err = alc262_parse_auto_config(codec);
9744		if (err < 0) {
9745			alc_free(codec);
9746			return err;
9747		} else if (!err) {
9748			printk(KERN_INFO
9749			       "hda_codec: Cannot set up configuration "
9750			       "from BIOS.  Using base mode...\n");
9751			board_config = ALC262_BASIC;
9752		}
9753	}
9754
9755	if (board_config != ALC262_AUTO)
9756		setup_preset(spec, &alc262_presets[board_config]);
9757
9758	spec->stream_name_analog = "ALC262 Analog";
9759	spec->stream_analog_playback = &alc262_pcm_analog_playback;
9760	spec->stream_analog_capture = &alc262_pcm_analog_capture;
9761
9762	spec->stream_name_digital = "ALC262 Digital";
9763	spec->stream_digital_playback = &alc262_pcm_digital_playback;
9764	spec->stream_digital_capture = &alc262_pcm_digital_capture;
9765
9766	if (!spec->adc_nids && spec->input_mux) {
9767		/* check whether NID 0x07 is valid */
9768		unsigned int wcap = get_wcaps(codec, 0x07);
9769
9770		/* get type */
9771		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9772		if (wcap != AC_WID_AUD_IN) {
9773			spec->adc_nids = alc262_adc_nids_alt;
9774			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
9775			spec->capsrc_nids = alc262_capsrc_nids_alt;
9776			spec->mixers[spec->num_mixers] =
9777				alc262_capture_alt_mixer;
9778			spec->num_mixers++;
9779		} else {
9780			spec->adc_nids = alc262_adc_nids;
9781			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9782			spec->capsrc_nids = alc262_capsrc_nids;
9783			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9784			spec->num_mixers++;
9785		}
9786	}
9787
9788	spec->vmaster_nid = 0x0c;
9789
9790	codec->patch_ops = alc_patch_ops;
9791	if (board_config == ALC262_AUTO)
9792		spec->init_hook = alc262_auto_init;
9793#ifdef CONFIG_SND_HDA_POWER_SAVE
9794	if (!spec->loopback.amplist)
9795		spec->loopback.amplist = alc262_loopbacks;
9796#endif
9797
9798	return 0;
9799}
9800
9801/*
9802 *  ALC268 channel source setting (2 channel)
9803 */
9804#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
9805#define alc268_modes		alc260_modes
9806
9807static hda_nid_t alc268_dac_nids[2] = {
9808	/* front, hp */
9809	0x02, 0x03
9810};
9811
9812static hda_nid_t alc268_adc_nids[2] = {
9813	/* ADC0-1 */
9814	0x08, 0x07
9815};
9816
9817static hda_nid_t alc268_adc_nids_alt[1] = {
9818	/* ADC0 */
9819	0x08
9820};
9821
9822static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
9823
9824static struct snd_kcontrol_new alc268_base_mixer[] = {
9825	/* output mixer control */
9826	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9827	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9828	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9829	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9830	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9831	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9832	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9833	{ }
9834};
9835
9836/* bind Beep switches of both NID 0x0f and 0x10 */
9837static struct hda_bind_ctls alc268_bind_beep_sw = {
9838	.ops = &snd_hda_bind_sw,
9839	.values = {
9840		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
9841		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
9842		0
9843	},
9844};
9845
9846static struct snd_kcontrol_new alc268_beep_mixer[] = {
9847	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
9848	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
9849	{ }
9850};
9851
9852static struct hda_verb alc268_eapd_verbs[] = {
9853	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9854	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9855	{ }
9856};
9857
9858/* Toshiba specific */
9859#define alc268_toshiba_automute	alc262_hippo_automute
9860
9861static struct hda_verb alc268_toshiba_verbs[] = {
9862	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9863	{ } /* end */
9864};
9865
9866/* Acer specific */
9867/* bind volumes of both NID 0x02 and 0x03 */
9868static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9869	.ops = &snd_hda_bind_vol,
9870	.values = {
9871		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9872		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9873		0
9874	},
9875};
9876
9877/* mute/unmute internal speaker according to the hp jack and mute state */
9878static void alc268_acer_automute(struct hda_codec *codec, int force)
9879{
9880	struct alc_spec *spec = codec->spec;
9881	unsigned int mute;
9882
9883	if (force || !spec->sense_updated) {
9884		unsigned int present;
9885		present = snd_hda_codec_read(codec, 0x14, 0,
9886				    	 AC_VERB_GET_PIN_SENSE, 0);
9887		spec->jack_present = (present & 0x80000000) != 0;
9888		spec->sense_updated = 1;
9889	}
9890	if (spec->jack_present)
9891		mute = HDA_AMP_MUTE; /* mute internal speaker */
9892	else /* unmute internal speaker if necessary */
9893		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9894	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9895				 HDA_AMP_MUTE, mute);
9896}
9897
9898
9899/* bind hp and internal speaker mute (with plug check) */
9900static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9901				     struct snd_ctl_elem_value *ucontrol)
9902{
9903	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9904	long *valp = ucontrol->value.integer.value;
9905	int change;
9906
9907	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9908					  HDA_AMP_MUTE,
9909					  valp[0] ? 0 : HDA_AMP_MUTE);
9910	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9911					   HDA_AMP_MUTE,
9912					   valp[1] ? 0 : HDA_AMP_MUTE);
9913	if (change)
9914		alc268_acer_automute(codec, 0);
9915	return change;
9916}
9917
9918static struct snd_kcontrol_new alc268_acer_mixer[] = {
9919	/* output mixer control */
9920	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9921	{
9922		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9923		.name = "Master Playback Switch",
9924		.info = snd_hda_mixer_amp_switch_info,
9925		.get = snd_hda_mixer_amp_switch_get,
9926		.put = alc268_acer_master_sw_put,
9927		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9928	},
9929	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9930	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9931	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9932	{ }
9933};
9934
9935static struct hda_verb alc268_acer_verbs[] = {
9936	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
9937	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9938	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9939	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9940	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9941	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9942
9943	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9944	{ }
9945};
9946
9947/* unsolicited event for HP jack sensing */
9948static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9949				       unsigned int res)
9950{
9951	if ((res >> 26) != ALC880_HP_EVENT)
9952		return;
9953	alc268_toshiba_automute(codec);
9954}
9955
9956static void alc268_acer_unsol_event(struct hda_codec *codec,
9957				       unsigned int res)
9958{
9959	if ((res >> 26) != ALC880_HP_EVENT)
9960		return;
9961	alc268_acer_automute(codec, 1);
9962}
9963
9964static void alc268_acer_init_hook(struct hda_codec *codec)
9965{
9966	alc268_acer_automute(codec, 1);
9967}
9968
9969static struct snd_kcontrol_new alc268_dell_mixer[] = {
9970	/* output mixer control */
9971	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9972	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9973	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9974	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9975	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9976	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9977	{ }
9978};
9979
9980static struct hda_verb alc268_dell_verbs[] = {
9981	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9982	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9983	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9984	{ }
9985};
9986
9987/* mute/unmute internal speaker according to the hp jack and mute state */
9988static void alc268_dell_automute(struct hda_codec *codec)
9989{
9990	unsigned int present;
9991	unsigned int mute;
9992
9993	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9994	if (present & 0x80000000)
9995		mute = HDA_AMP_MUTE;
9996	else
9997		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9998	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9999				 HDA_AMP_MUTE, mute);
10000}
10001
10002static void alc268_dell_unsol_event(struct hda_codec *codec,
10003				    unsigned int res)
10004{
10005	if ((res >> 26) != ALC880_HP_EVENT)
10006		return;
10007	alc268_dell_automute(codec);
10008}
10009
10010#define alc268_dell_init_hook	alc268_dell_automute
10011
10012static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10013	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10014	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10015	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10016	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10017	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10018	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10019	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10020	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10021	{ }
10022};
10023
10024static struct hda_verb alc267_quanta_il1_verbs[] = {
10025	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10026	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10027	{ }
10028};
10029
10030static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10031{
10032	unsigned int present;
10033
10034	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10035		& AC_PINSENSE_PRESENCE;
10036	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10037			    present ? 0 : PIN_OUT);
10038}
10039
10040static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10041{
10042	unsigned int present;
10043
10044	present = snd_hda_codec_read(codec, 0x18, 0,
10045				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10046	snd_hda_codec_write(codec, 0x23, 0,
10047			    AC_VERB_SET_CONNECT_SEL,
10048			    present ? 0x00 : 0x01);
10049}
10050
10051static void alc267_quanta_il1_automute(struct hda_codec *codec)
10052{
10053	alc267_quanta_il1_hp_automute(codec);
10054	alc267_quanta_il1_mic_automute(codec);
10055}
10056
10057static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10058					   unsigned int res)
10059{
10060	switch (res >> 26) {
10061	case ALC880_HP_EVENT:
10062		alc267_quanta_il1_hp_automute(codec);
10063		break;
10064	case ALC880_MIC_EVENT:
10065		alc267_quanta_il1_mic_automute(codec);
10066		break;
10067	}
10068}
10069
10070/*
10071 * generic initialization of ADC, input mixers and output mixers
10072 */
10073static struct hda_verb alc268_base_init_verbs[] = {
10074	/* Unmute DAC0-1 and set vol = 0 */
10075	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10076	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10077	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10078	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10079	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10080	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10081
10082	/*
10083	 * Set up output mixers (0x0c - 0x0e)
10084	 */
10085	/* set vol=0 to output mixers */
10086	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10087	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10088	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10089        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10090
10091	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10092	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10093
10094	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10095	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10096	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10097	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10098	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10099	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10100	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10101	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10102
10103	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10104	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10105	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10106	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10107	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10108	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10109	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10110
10111	/* set PCBEEP vol = 0, mute connections */
10112	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10113	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10114	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10115
10116	/* Unmute Selector 23h,24h and set the default input to mic-in */
10117
10118	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10119	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10120	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10121	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10122
10123	{ }
10124};
10125
10126/*
10127 * generic initialization of ADC, input mixers and output mixers
10128 */
10129static struct hda_verb alc268_volume_init_verbs[] = {
10130	/* set output DAC */
10131	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10132	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10133	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10134	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10135
10136	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10137	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10138	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10139	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10140	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10141
10142	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10143	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10144	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10145	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10146	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10147
10148	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10149	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10150	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10151	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10152
10153	/* set PCBEEP vol = 0, mute connections */
10154	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10155	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10156	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10157
10158	{ }
10159};
10160
10161#define alc268_mux_enum_info alc_mux_enum_info
10162#define alc268_mux_enum_get alc_mux_enum_get
10163#define alc268_mux_enum_put alc_mux_enum_put
10164
10165static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10166	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10167	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10168	{
10169		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10170		/* The multiple "Capture Source" controls confuse alsamixer
10171		 * So call somewhat different..
10172		 */
10173		/* .name = "Capture Source", */
10174		.name = "Input Source",
10175		.count = 1,
10176		.info = alc268_mux_enum_info,
10177		.get = alc268_mux_enum_get,
10178		.put = alc268_mux_enum_put,
10179	},
10180	{ } /* end */
10181};
10182
10183static struct snd_kcontrol_new alc268_capture_mixer[] = {
10184	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10185	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10186	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
10187	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
10188	{
10189		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10190		/* The multiple "Capture Source" controls confuse alsamixer
10191		 * So call somewhat different..
10192		 */
10193		/* .name = "Capture Source", */
10194		.name = "Input Source",
10195		.count = 2,
10196		.info = alc268_mux_enum_info,
10197		.get = alc268_mux_enum_get,
10198		.put = alc268_mux_enum_put,
10199	},
10200	{ } /* end */
10201};
10202
10203static struct hda_input_mux alc268_capture_source = {
10204	.num_items = 4,
10205	.items = {
10206		{ "Mic", 0x0 },
10207		{ "Front Mic", 0x1 },
10208		{ "Line", 0x2 },
10209		{ "CD", 0x3 },
10210	},
10211};
10212
10213static struct hda_input_mux alc268_acer_capture_source = {
10214	.num_items = 3,
10215	.items = {
10216		{ "Mic", 0x0 },
10217		{ "Internal Mic", 0x6 },
10218		{ "Line", 0x2 },
10219	},
10220};
10221
10222#ifdef CONFIG_SND_DEBUG
10223static struct snd_kcontrol_new alc268_test_mixer[] = {
10224	/* Volume widgets */
10225	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10226	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10227	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10228	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
10229	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
10230	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
10231	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
10232	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
10233	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
10234	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
10235	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
10236	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
10237	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
10238	/* The below appears problematic on some hardwares */
10239	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
10240	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10241	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
10242	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
10243	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
10244
10245	/* Modes for retasking pin widgets */
10246	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
10247	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
10248	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
10249	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
10250
10251	/* Controls for GPIO pins, assuming they are configured as outputs */
10252	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
10253	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
10254	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
10255	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
10256
10257	/* Switches to allow the digital SPDIF output pin to be enabled.
10258	 * The ALC268 does not have an SPDIF input.
10259	 */
10260	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
10261
10262	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
10263	 * this output to turn on an external amplifier.
10264	 */
10265	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
10266	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
10267
10268	{ } /* end */
10269};
10270#endif
10271
10272/* create input playback/capture controls for the given pin */
10273static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
10274				    const char *ctlname, int idx)
10275{
10276	char name[32];
10277	int err;
10278
10279	sprintf(name, "%s Playback Volume", ctlname);
10280	if (nid == 0x14) {
10281		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10282				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
10283						      HDA_OUTPUT));
10284		if (err < 0)
10285			return err;
10286	} else if (nid == 0x15) {
10287		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10288				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
10289						      HDA_OUTPUT));
10290		if (err < 0)
10291			return err;
10292	} else
10293		return -1;
10294	sprintf(name, "%s Playback Switch", ctlname);
10295	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10296			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
10297	if (err < 0)
10298		return err;
10299	return 0;
10300}
10301
10302/* add playback controls from the parsed DAC table */
10303static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10304					     const struct auto_pin_cfg *cfg)
10305{
10306	hda_nid_t nid;
10307	int err;
10308
10309	spec->multiout.num_dacs = 2;	/* only use one dac */
10310	spec->multiout.dac_nids = spec->private_dac_nids;
10311	spec->multiout.dac_nids[0] = 2;
10312	spec->multiout.dac_nids[1] = 3;
10313
10314	nid = cfg->line_out_pins[0];
10315	if (nid)
10316		alc268_new_analog_output(spec, nid, "Front", 0);
10317
10318	nid = cfg->speaker_pins[0];
10319	if (nid == 0x1d) {
10320		err = add_control(spec, ALC_CTL_WIDGET_VOL,
10321				  "Speaker Playback Volume",
10322				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10323		if (err < 0)
10324			return err;
10325	}
10326	nid = cfg->hp_pins[0];
10327	if (nid)
10328		alc268_new_analog_output(spec, nid, "Headphone", 0);
10329
10330	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
10331	if (nid == 0x16) {
10332		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10333				  "Mono Playback Switch",
10334				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
10335		if (err < 0)
10336			return err;
10337	}
10338	return 0;
10339}
10340
10341/* create playback/capture controls for input pins */
10342static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10343						const struct auto_pin_cfg *cfg)
10344{
10345	struct hda_input_mux *imux = &spec->private_imux;
10346	int i, idx1;
10347
10348	for (i = 0; i < AUTO_PIN_LAST; i++) {
10349		switch(cfg->input_pins[i]) {
10350		case 0x18:
10351			idx1 = 0;	/* Mic 1 */
10352			break;
10353		case 0x19:
10354			idx1 = 1;	/* Mic 2 */
10355			break;
10356		case 0x1a:
10357			idx1 = 2;	/* Line In */
10358			break;
10359		case 0x1c:
10360			idx1 = 3;	/* CD */
10361			break;
10362		case 0x12:
10363		case 0x13:
10364			idx1 = 6;	/* digital mics */
10365			break;
10366		default:
10367			continue;
10368		}
10369		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10370		imux->items[imux->num_items].index = idx1;
10371		imux->num_items++;
10372	}
10373	return 0;
10374}
10375
10376static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10377{
10378	struct alc_spec *spec = codec->spec;
10379	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10380	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10381	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10382	unsigned int	dac_vol1, dac_vol2;
10383
10384	if (speaker_nid) {
10385		snd_hda_codec_write(codec, speaker_nid, 0,
10386				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10387		snd_hda_codec_write(codec, 0x0f, 0,
10388				    AC_VERB_SET_AMP_GAIN_MUTE,
10389				    AMP_IN_UNMUTE(1));
10390		snd_hda_codec_write(codec, 0x10, 0,
10391				    AC_VERB_SET_AMP_GAIN_MUTE,
10392				    AMP_IN_UNMUTE(1));
10393	} else {
10394		snd_hda_codec_write(codec, 0x0f, 0,
10395				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10396		snd_hda_codec_write(codec, 0x10, 0,
10397				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10398	}
10399
10400	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
10401	if (line_nid == 0x14)
10402		dac_vol2 = AMP_OUT_ZERO;
10403	else if (line_nid == 0x15)
10404		dac_vol1 = AMP_OUT_ZERO;
10405	if (hp_nid == 0x14)
10406		dac_vol2 = AMP_OUT_ZERO;
10407	else if (hp_nid == 0x15)
10408		dac_vol1 = AMP_OUT_ZERO;
10409	if (line_nid != 0x16 || hp_nid != 0x16 ||
10410	    spec->autocfg.line_out_pins[1] != 0x16 ||
10411	    spec->autocfg.line_out_pins[2] != 0x16)
10412		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10413
10414	snd_hda_codec_write(codec, 0x02, 0,
10415			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10416	snd_hda_codec_write(codec, 0x03, 0,
10417			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10418}
10419
10420/* pcm configuration: identiacal with ALC880 */
10421#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
10422#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
10423#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
10424#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
10425
10426/*
10427 * BIOS auto configuration
10428 */
10429static int alc268_parse_auto_config(struct hda_codec *codec)
10430{
10431	struct alc_spec *spec = codec->spec;
10432	int err;
10433	static hda_nid_t alc268_ignore[] = { 0 };
10434
10435	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10436					   alc268_ignore);
10437	if (err < 0)
10438		return err;
10439	if (!spec->autocfg.line_outs)
10440		return 0; /* can't find valid BIOS pin config */
10441
10442	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10443	if (err < 0)
10444		return err;
10445	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10446	if (err < 0)
10447		return err;
10448
10449	spec->multiout.max_channels = 2;
10450
10451	/* digital only support output */
10452	if (spec->autocfg.dig_out_pin)
10453		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10454
10455	if (spec->kctl_alloc)
10456		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10457
10458	if (spec->autocfg.speaker_pins[0] != 0x1d)
10459		spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
10460
10461	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10462	spec->num_mux_defs = 1;
10463	spec->input_mux = &spec->private_imux;
10464
10465	err = alc_auto_add_mic_boost(codec);
10466	if (err < 0)
10467		return err;
10468
10469	return 1;
10470}
10471
10472#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
10473#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
10474#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
10475
10476/* init callback for auto-configuration model -- overriding the default init */
10477static void alc268_auto_init(struct hda_codec *codec)
10478{
10479	struct alc_spec *spec = codec->spec;
10480	alc268_auto_init_multi_out(codec);
10481	alc268_auto_init_hp_out(codec);
10482	alc268_auto_init_mono_speaker_out(codec);
10483	alc268_auto_init_analog_input(codec);
10484	if (spec->unsol_event)
10485		alc_sku_automute(codec);
10486}
10487
10488/*
10489 * configuration and preset
10490 */
10491static const char *alc268_models[ALC268_MODEL_LAST] = {
10492	[ALC267_QUANTA_IL1]	= "quanta-il1",
10493	[ALC268_3ST]		= "3stack",
10494	[ALC268_TOSHIBA]	= "toshiba",
10495	[ALC268_ACER]		= "acer",
10496	[ALC268_DELL]		= "dell",
10497	[ALC268_ZEPTO]		= "zepto",
10498#ifdef CONFIG_SND_DEBUG
10499	[ALC268_TEST]		= "test",
10500#endif
10501	[ALC268_AUTO]		= "auto",
10502};
10503
10504static struct snd_pci_quirk alc268_cfg_tbl[] = {
10505	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
10506	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
10507	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
10508	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
10509	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
10510	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
10511	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
10512	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
10513	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
10514	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
10515	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
10516	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
10517	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
10518	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
10519	{}
10520};
10521
10522static struct alc_config_preset alc268_presets[] = {
10523	[ALC267_QUANTA_IL1] = {
10524		.mixers = { alc267_quanta_il1_mixer },
10525		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10526				alc267_quanta_il1_verbs },
10527		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10528		.dac_nids = alc268_dac_nids,
10529		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10530		.adc_nids = alc268_adc_nids_alt,
10531		.hp_nid = 0x03,
10532		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10533		.channel_mode = alc268_modes,
10534		.input_mux = &alc268_capture_source,
10535		.unsol_event = alc267_quanta_il1_unsol_event,
10536		.init_hook = alc267_quanta_il1_automute,
10537	},
10538	[ALC268_3ST] = {
10539		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10540			    alc268_beep_mixer },
10541		.init_verbs = { alc268_base_init_verbs },
10542		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10543		.dac_nids = alc268_dac_nids,
10544                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10545                .adc_nids = alc268_adc_nids_alt,
10546		.capsrc_nids = alc268_capsrc_nids,
10547		.hp_nid = 0x03,
10548		.dig_out_nid = ALC268_DIGOUT_NID,
10549		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10550		.channel_mode = alc268_modes,
10551		.input_mux = &alc268_capture_source,
10552	},
10553	[ALC268_TOSHIBA] = {
10554		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10555			    alc268_beep_mixer },
10556		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10557				alc268_toshiba_verbs },
10558		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10559		.dac_nids = alc268_dac_nids,
10560		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10561		.adc_nids = alc268_adc_nids_alt,
10562		.capsrc_nids = alc268_capsrc_nids,
10563		.hp_nid = 0x03,
10564		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10565		.channel_mode = alc268_modes,
10566		.input_mux = &alc268_capture_source,
10567		.unsol_event = alc268_toshiba_unsol_event,
10568		.init_hook = alc268_toshiba_automute,
10569	},
10570	[ALC268_ACER] = {
10571		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
10572			    alc268_beep_mixer },
10573		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10574				alc268_acer_verbs },
10575		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10576		.dac_nids = alc268_dac_nids,
10577		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10578		.adc_nids = alc268_adc_nids_alt,
10579		.capsrc_nids = alc268_capsrc_nids,
10580		.hp_nid = 0x02,
10581		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10582		.channel_mode = alc268_modes,
10583		.input_mux = &alc268_acer_capture_source,
10584		.unsol_event = alc268_acer_unsol_event,
10585		.init_hook = alc268_acer_init_hook,
10586	},
10587	[ALC268_DELL] = {
10588		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
10589		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10590				alc268_dell_verbs },
10591		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10592		.dac_nids = alc268_dac_nids,
10593		.hp_nid = 0x02,
10594		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10595		.channel_mode = alc268_modes,
10596		.unsol_event = alc268_dell_unsol_event,
10597		.init_hook = alc268_dell_init_hook,
10598		.input_mux = &alc268_capture_source,
10599	},
10600	[ALC268_ZEPTO] = {
10601		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10602			    alc268_beep_mixer },
10603		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10604				alc268_toshiba_verbs },
10605		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10606		.dac_nids = alc268_dac_nids,
10607		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10608		.adc_nids = alc268_adc_nids_alt,
10609		.capsrc_nids = alc268_capsrc_nids,
10610		.hp_nid = 0x03,
10611		.dig_out_nid = ALC268_DIGOUT_NID,
10612		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10613		.channel_mode = alc268_modes,
10614		.input_mux = &alc268_capture_source,
10615		.unsol_event = alc268_toshiba_unsol_event,
10616		.init_hook = alc268_toshiba_automute
10617	},
10618#ifdef CONFIG_SND_DEBUG
10619	[ALC268_TEST] = {
10620		.mixers = { alc268_test_mixer, alc268_capture_mixer },
10621		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10622				alc268_volume_init_verbs },
10623		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10624		.dac_nids = alc268_dac_nids,
10625		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10626		.adc_nids = alc268_adc_nids_alt,
10627		.capsrc_nids = alc268_capsrc_nids,
10628		.hp_nid = 0x03,
10629		.dig_out_nid = ALC268_DIGOUT_NID,
10630		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10631		.channel_mode = alc268_modes,
10632		.input_mux = &alc268_capture_source,
10633	},
10634#endif
10635};
10636
10637static int patch_alc268(struct hda_codec *codec)
10638{
10639	struct alc_spec *spec;
10640	int board_config;
10641	int err;
10642
10643	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10644	if (spec == NULL)
10645		return -ENOMEM;
10646
10647	codec->spec = spec;
10648
10649	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10650						  alc268_models,
10651						  alc268_cfg_tbl);
10652
10653	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10654		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10655		       "trying auto-probe from BIOS...\n");
10656		board_config = ALC268_AUTO;
10657	}
10658
10659	if (board_config == ALC268_AUTO) {
10660		/* automatic parse from the BIOS config */
10661		err = alc268_parse_auto_config(codec);
10662		if (err < 0) {
10663			alc_free(codec);
10664			return err;
10665		} else if (!err) {
10666			printk(KERN_INFO
10667			       "hda_codec: Cannot set up configuration "
10668			       "from BIOS.  Using base mode...\n");
10669			board_config = ALC268_3ST;
10670		}
10671	}
10672
10673	if (board_config != ALC268_AUTO)
10674		setup_preset(spec, &alc268_presets[board_config]);
10675
10676	spec->stream_name_analog = "ALC268 Analog";
10677	spec->stream_analog_playback = &alc268_pcm_analog_playback;
10678	spec->stream_analog_capture = &alc268_pcm_analog_capture;
10679	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
10680
10681	spec->stream_name_digital = "ALC268 Digital";
10682	spec->stream_digital_playback = &alc268_pcm_digital_playback;
10683
10684	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
10685		/* override the amp caps for beep generator */
10686		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
10687					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
10688					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
10689					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
10690					  (0 << AC_AMPCAP_MUTE_SHIFT));
10691
10692	if (!spec->adc_nids && spec->input_mux) {
10693		/* check whether NID 0x07 is valid */
10694		unsigned int wcap = get_wcaps(codec, 0x07);
10695		int i;
10696
10697		/* get type */
10698		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10699		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
10700			spec->adc_nids = alc268_adc_nids_alt;
10701			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10702			spec->mixers[spec->num_mixers] =
10703					alc268_capture_alt_mixer;
10704			spec->num_mixers++;
10705		} else {
10706			spec->adc_nids = alc268_adc_nids;
10707			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10708			spec->mixers[spec->num_mixers] =
10709				alc268_capture_mixer;
10710			spec->num_mixers++;
10711		}
10712		spec->capsrc_nids = alc268_capsrc_nids;
10713		/* set default input source */
10714		for (i = 0; i < spec->num_adc_nids; i++)
10715			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
10716				0, AC_VERB_SET_CONNECT_SEL,
10717				spec->input_mux->items[0].index);
10718	}
10719
10720	spec->vmaster_nid = 0x02;
10721
10722	codec->patch_ops = alc_patch_ops;
10723	if (board_config == ALC268_AUTO)
10724		spec->init_hook = alc268_auto_init;
10725
10726	return 0;
10727}
10728
10729/*
10730 *  ALC269 channel source setting (2 channel)
10731 */
10732#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
10733
10734#define alc269_dac_nids		alc260_dac_nids
10735
10736static hda_nid_t alc269_adc_nids[1] = {
10737	/* ADC1 */
10738	0x07,
10739};
10740
10741#define alc269_modes		alc260_modes
10742#define alc269_capture_source	alc880_lg_lw_capture_source
10743
10744static struct snd_kcontrol_new alc269_base_mixer[] = {
10745	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10746	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10747	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10748	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10749	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10750	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10751	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10752	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10753	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10754	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10755	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10756	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10757	{ } /* end */
10758};
10759
10760/* capture mixer elements */
10761static struct snd_kcontrol_new alc269_capture_mixer[] = {
10762	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10763	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10764	{
10765		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10766		/* The multiple "Capture Source" controls confuse alsamixer
10767		 * So call somewhat different..
10768		 */
10769		/* .name = "Capture Source", */
10770		.name = "Input Source",
10771		.count = 1,
10772		.info = alc_mux_enum_info,
10773		.get = alc_mux_enum_get,
10774		.put = alc_mux_enum_put,
10775	},
10776	{ } /* end */
10777};
10778
10779/*
10780 * generic initialization of ADC, input mixers and output mixers
10781 */
10782static struct hda_verb alc269_init_verbs[] = {
10783	/*
10784	 * Unmute ADC0 and set the default input to mic-in
10785	 */
10786	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10787
10788	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10789	 * analog-loopback mixer widget
10790	 * Note: PASD motherboards uses the Line In 2 as the input for
10791	 * front panel mic (mic 2)
10792	 */
10793	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10794	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10795	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10796	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10797	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10798	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10799
10800	/*
10801	 * Set up output mixers (0x0c - 0x0e)
10802	 */
10803	/* set vol=0 to output mixers */
10804	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10805	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10806
10807	/* set up input amps for analog loopback */
10808	/* Amp Indices: DAC = 0, mixer = 1 */
10809	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10810	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10811	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10812	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10813	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10814	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10815
10816	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10817	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10818	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10819	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10820	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10821	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10822	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10823
10824	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10825	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10826	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10827	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10828	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10829	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10830	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10831
10832	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10833	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10834
10835	/* FIXME: use matrix-type input source selection */
10836	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10837	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10838	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10839	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10840	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10841	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10842
10843	/* set EAPD */
10844	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10845	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10846	{ }
10847};
10848
10849/* add playback controls from the parsed DAC table */
10850static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10851					     const struct auto_pin_cfg *cfg)
10852{
10853	hda_nid_t nid;
10854	int err;
10855
10856	spec->multiout.num_dacs = 1;	/* only use one dac */
10857	spec->multiout.dac_nids = spec->private_dac_nids;
10858	spec->multiout.dac_nids[0] = 2;
10859
10860	nid = cfg->line_out_pins[0];
10861	if (nid) {
10862		err = add_control(spec, ALC_CTL_WIDGET_VOL,
10863				  "Front Playback Volume",
10864				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10865		if (err < 0)
10866			return err;
10867		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10868				  "Front Playback Switch",
10869				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10870		if (err < 0)
10871			return err;
10872	}
10873
10874	nid = cfg->speaker_pins[0];
10875	if (nid) {
10876		if (!cfg->line_out_pins[0]) {
10877			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10878					  "Speaker Playback Volume",
10879					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10880							      HDA_OUTPUT));
10881			if (err < 0)
10882				return err;
10883		}
10884		if (nid == 0x16) {
10885			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10886					  "Speaker Playback Switch",
10887					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10888							      HDA_OUTPUT));
10889			if (err < 0)
10890				return err;
10891		} else {
10892			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10893					  "Speaker Playback Switch",
10894					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10895							      HDA_OUTPUT));
10896			if (err < 0)
10897				return err;
10898		}
10899	}
10900	nid = cfg->hp_pins[0];
10901	if (nid) {
10902		/* spec->multiout.hp_nid = 2; */
10903		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10904			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10905					  "Headphone Playback Volume",
10906					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10907							      HDA_OUTPUT));
10908			if (err < 0)
10909				return err;
10910		}
10911		if (nid == 0x16) {
10912			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10913					  "Headphone Playback Switch",
10914					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10915							      HDA_OUTPUT));
10916			if (err < 0)
10917				return err;
10918		} else {
10919			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10920					  "Headphone Playback Switch",
10921					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10922							      HDA_OUTPUT));
10923			if (err < 0)
10924				return err;
10925		}
10926	}
10927	return 0;
10928}
10929
10930#define alc269_auto_create_analog_input_ctls \
10931	alc880_auto_create_analog_input_ctls
10932
10933#ifdef CONFIG_SND_HDA_POWER_SAVE
10934#define alc269_loopbacks	alc880_loopbacks
10935#endif
10936
10937/* pcm configuration: identiacal with ALC880 */
10938#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
10939#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
10940#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
10941#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
10942
10943/*
10944 * BIOS auto configuration
10945 */
10946static int alc269_parse_auto_config(struct hda_codec *codec)
10947{
10948	struct alc_spec *spec = codec->spec;
10949	int err;
10950	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10951
10952	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10953					   alc269_ignore);
10954	if (err < 0)
10955		return err;
10956
10957	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10958	if (err < 0)
10959		return err;
10960	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10961	if (err < 0)
10962		return err;
10963
10964	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10965
10966	if (spec->autocfg.dig_out_pin)
10967		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10968
10969	if (spec->kctl_alloc)
10970		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10971
10972	spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10973	spec->num_mux_defs = 1;
10974	spec->input_mux = &spec->private_imux;
10975
10976	err = alc_auto_add_mic_boost(codec);
10977	if (err < 0)
10978		return err;
10979
10980	return 1;
10981}
10982
10983#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
10984#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
10985#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
10986
10987
10988/* init callback for auto-configuration model -- overriding the default init */
10989static void alc269_auto_init(struct hda_codec *codec)
10990{
10991	struct alc_spec *spec = codec->spec;
10992	alc269_auto_init_multi_out(codec);
10993	alc269_auto_init_hp_out(codec);
10994	alc269_auto_init_analog_input(codec);
10995	if (spec->unsol_event)
10996		alc_sku_automute(codec);
10997}
10998
10999/*
11000 * configuration and preset
11001 */
11002static const char *alc269_models[ALC269_MODEL_LAST] = {
11003	[ALC269_BASIC]		= "basic",
11004};
11005
11006static struct snd_pci_quirk alc269_cfg_tbl[] = {
11007	{}
11008};
11009
11010static struct alc_config_preset alc269_presets[] = {
11011	[ALC269_BASIC] = {
11012		.mixers = { alc269_base_mixer },
11013		.init_verbs = { alc269_init_verbs },
11014		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
11015		.dac_nids = alc269_dac_nids,
11016		.hp_nid = 0x03,
11017		.num_channel_mode = ARRAY_SIZE(alc269_modes),
11018		.channel_mode = alc269_modes,
11019		.input_mux = &alc269_capture_source,
11020	},
11021};
11022
11023static int patch_alc269(struct hda_codec *codec)
11024{
11025	struct alc_spec *spec;
11026	int board_config;
11027	int err;
11028
11029	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11030	if (spec == NULL)
11031		return -ENOMEM;
11032
11033	codec->spec = spec;
11034
11035	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
11036						  alc269_models,
11037						  alc269_cfg_tbl);
11038
11039	if (board_config < 0) {
11040		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
11041		       "trying auto-probe from BIOS...\n");
11042		board_config = ALC269_AUTO;
11043	}
11044
11045	if (board_config == ALC269_AUTO) {
11046		/* automatic parse from the BIOS config */
11047		err = alc269_parse_auto_config(codec);
11048		if (err < 0) {
11049			alc_free(codec);
11050			return err;
11051		} else if (!err) {
11052			printk(KERN_INFO
11053			       "hda_codec: Cannot set up configuration "
11054			       "from BIOS.  Using base mode...\n");
11055			board_config = ALC269_BASIC;
11056		}
11057	}
11058
11059	if (board_config != ALC269_AUTO)
11060		setup_preset(spec, &alc269_presets[board_config]);
11061
11062	spec->stream_name_analog = "ALC269 Analog";
11063	spec->stream_analog_playback = &alc269_pcm_analog_playback;
11064	spec->stream_analog_capture = &alc269_pcm_analog_capture;
11065
11066	spec->stream_name_digital = "ALC269 Digital";
11067	spec->stream_digital_playback = &alc269_pcm_digital_playback;
11068	spec->stream_digital_capture = &alc269_pcm_digital_capture;
11069
11070	spec->adc_nids = alc269_adc_nids;
11071	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
11072	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
11073	spec->num_mixers++;
11074
11075	codec->patch_ops = alc_patch_ops;
11076	if (board_config == ALC269_AUTO)
11077		spec->init_hook = alc269_auto_init;
11078#ifdef CONFIG_SND_HDA_POWER_SAVE
11079	if (!spec->loopback.amplist)
11080		spec->loopback.amplist = alc269_loopbacks;
11081#endif
11082
11083	return 0;
11084}
11085
11086/*
11087 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
11088 */
11089
11090/*
11091 * set the path ways for 2 channel output
11092 * need to set the codec line out and mic 1 pin widgets to inputs
11093 */
11094static struct hda_verb alc861_threestack_ch2_init[] = {
11095	/* set pin widget 1Ah (line in) for input */
11096	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11097	/* set pin widget 18h (mic1/2) for input, for mic also enable
11098	 * the vref
11099	 */
11100	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11101
11102	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11103#if 0
11104	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11105	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11106#endif
11107	{ } /* end */
11108};
11109/*
11110 * 6ch mode
11111 * need to set the codec line out and mic 1 pin widgets to outputs
11112 */
11113static struct hda_verb alc861_threestack_ch6_init[] = {
11114	/* set pin widget 1Ah (line in) for output (Back Surround)*/
11115	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11116	/* set pin widget 18h (mic1) for output (CLFE)*/
11117	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11118
11119	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11120	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11121
11122	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11123#if 0
11124	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11125	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11126#endif
11127	{ } /* end */
11128};
11129
11130static struct hda_channel_mode alc861_threestack_modes[2] = {
11131	{ 2, alc861_threestack_ch2_init },
11132	{ 6, alc861_threestack_ch6_init },
11133};
11134/* Set mic1 as input and unmute the mixer */
11135static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
11136	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11137	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11138	{ } /* end */
11139};
11140/* Set mic1 as output and mute mixer */
11141static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
11142	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11143	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11144	{ } /* end */
11145};
11146
11147static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
11148	{ 2, alc861_uniwill_m31_ch2_init },
11149	{ 4, alc861_uniwill_m31_ch4_init },
11150};
11151
11152/* Set mic1 and line-in as input and unmute the mixer */
11153static struct hda_verb alc861_asus_ch2_init[] = {
11154	/* set pin widget 1Ah (line in) for input */
11155	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11156	/* set pin widget 18h (mic1/2) for input, for mic also enable
11157	 * the vref
11158	 */
11159	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11160
11161	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11162#if 0
11163	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11164	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11165#endif
11166	{ } /* end */
11167};
11168/* Set mic1 nad line-in as output and mute mixer */
11169static struct hda_verb alc861_asus_ch6_init[] = {
11170	/* set pin widget 1Ah (line in) for output (Back Surround)*/
11171	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11172	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11173	/* set pin widget 18h (mic1) for output (CLFE)*/
11174	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11175	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11176	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11177	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11178
11179	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11180#if 0
11181	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11182	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11183#endif
11184	{ } /* end */
11185};
11186
11187static struct hda_channel_mode alc861_asus_modes[2] = {
11188	{ 2, alc861_asus_ch2_init },
11189	{ 6, alc861_asus_ch6_init },
11190};
11191
11192/* patch-ALC861 */
11193
11194static struct snd_kcontrol_new alc861_base_mixer[] = {
11195        /* output mixer control */
11196	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11197	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11198	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11199	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11200	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11201
11202        /*Input mixer control */
11203	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11204	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11205	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11206	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11207	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11208	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11209	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11210	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11211	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11212	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11213
11214        /* Capture mixer control */
11215	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11216	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11217	{
11218		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11219		.name = "Capture Source",
11220		.count = 1,
11221		.info = alc_mux_enum_info,
11222		.get = alc_mux_enum_get,
11223		.put = alc_mux_enum_put,
11224	},
11225	{ } /* end */
11226};
11227
11228static struct snd_kcontrol_new alc861_3ST_mixer[] = {
11229        /* output mixer control */
11230	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11231	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11232	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11233	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11234	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11235
11236	/* Input mixer control */
11237	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11238	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11239	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11240	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11241	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11242	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11243	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11244	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11245	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11246	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11247
11248	/* Capture mixer control */
11249	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11250	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11251	{
11252		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11253		.name = "Capture Source",
11254		.count = 1,
11255		.info = alc_mux_enum_info,
11256		.get = alc_mux_enum_get,
11257		.put = alc_mux_enum_put,
11258	},
11259	{
11260		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11261		.name = "Channel Mode",
11262		.info = alc_ch_mode_info,
11263		.get = alc_ch_mode_get,
11264		.put = alc_ch_mode_put,
11265                .private_value = ARRAY_SIZE(alc861_threestack_modes),
11266	},
11267	{ } /* end */
11268};
11269
11270static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
11271        /* output mixer control */
11272	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11273	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11274	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11275
11276        /*Capture mixer control */
11277	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11278	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11279	{
11280		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11281		.name = "Capture Source",
11282		.count = 1,
11283		.info = alc_mux_enum_info,
11284		.get = alc_mux_enum_get,
11285		.put = alc_mux_enum_put,
11286	},
11287
11288	{ } /* end */
11289};
11290
11291static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
11292        /* output mixer control */
11293	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11294	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11295	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11296	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11297	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11298
11299	/* Input mixer control */
11300	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11301	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11302	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11303	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11304	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11305	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11306	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11307	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11308	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11309	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11310
11311	/* Capture mixer control */
11312	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11313	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11314	{
11315		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11316		.name = "Capture Source",
11317		.count = 1,
11318		.info = alc_mux_enum_info,
11319		.get = alc_mux_enum_get,
11320		.put = alc_mux_enum_put,
11321	},
11322	{
11323		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11324		.name = "Channel Mode",
11325		.info = alc_ch_mode_info,
11326		.get = alc_ch_mode_get,
11327		.put = alc_ch_mode_put,
11328                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
11329	},
11330	{ } /* end */
11331};
11332
11333static struct snd_kcontrol_new alc861_asus_mixer[] = {
11334        /* output mixer control */
11335	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11336	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11337	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11338	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11339	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11340
11341	/* Input mixer control */
11342	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11343	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11344	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11345	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11346	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11347	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11348	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11349	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11350	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11351	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
11352
11353	/* Capture mixer control */
11354	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11355	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11356	{
11357		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11358		.name = "Capture Source",
11359		.count = 1,
11360		.info = alc_mux_enum_info,
11361		.get = alc_mux_enum_get,
11362		.put = alc_mux_enum_put,
11363	},
11364	{
11365		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11366		.name = "Channel Mode",
11367		.info = alc_ch_mode_info,
11368		.get = alc_ch_mode_get,
11369		.put = alc_ch_mode_put,
11370                .private_value = ARRAY_SIZE(alc861_asus_modes),
11371	},
11372	{ }
11373};
11374
11375/* additional mixer */
11376static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
11377	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11378	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11379	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
11380	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
11381	{ }
11382};
11383
11384/*
11385 * generic initialization of ADC, input mixers and output mixers
11386 */
11387static struct hda_verb alc861_base_init_verbs[] = {
11388	/*
11389	 * Unmute ADC0 and set the default input to mic-in
11390	 */
11391	/* port-A for surround (rear panel) */
11392	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11393	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
11394	/* port-B for mic-in (rear panel) with vref */
11395	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11396	/* port-C for line-in (rear panel) */
11397	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11398	/* port-D for Front */
11399	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11400	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11401	/* port-E for HP out (front panel) */
11402	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11403	/* route front PCM to HP */
11404	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11405	/* port-F for mic-in (front panel) with vref */
11406	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11407	/* port-G for CLFE (rear panel) */
11408	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11409	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11410	/* port-H for side (rear panel) */
11411	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11412	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
11413	/* CD-in */
11414	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11415	/* route front mic to ADC1*/
11416	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11417	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11418
11419	/* Unmute DAC0~3 & spdif out*/
11420	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11421	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11422	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11423	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11424	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11425
11426	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11427	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11428        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11429	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11430        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11431
11432	/* Unmute Stereo Mixer 15 */
11433	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11434	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11435	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11436	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11437
11438	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11439	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11440	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11441	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11442	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11443	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11444	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11445	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11446	/* hp used DAC 3 (Front) */
11447	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11448        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11449
11450	{ }
11451};
11452
11453static struct hda_verb alc861_threestack_init_verbs[] = {
11454	/*
11455	 * Unmute ADC0 and set the default input to mic-in
11456	 */
11457	/* port-A for surround (rear panel) */
11458	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11459	/* port-B for mic-in (rear panel) with vref */
11460	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11461	/* port-C for line-in (rear panel) */
11462	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11463	/* port-D for Front */
11464	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11465	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11466	/* port-E for HP out (front panel) */
11467	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11468	/* route front PCM to HP */
11469	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11470	/* port-F for mic-in (front panel) with vref */
11471	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11472	/* port-G for CLFE (rear panel) */
11473	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11474	/* port-H for side (rear panel) */
11475	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11476	/* CD-in */
11477	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11478	/* route front mic to ADC1*/
11479	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11480	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11481	/* Unmute DAC0~3 & spdif out*/
11482	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11483	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11484	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11485	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11486	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11487
11488	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11489	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11490        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11491	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11492        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11493
11494	/* Unmute Stereo Mixer 15 */
11495	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11496	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11497	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11498	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11499
11500	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11501	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11502	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11503	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11504	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11505	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11506	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11507	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11508	/* hp used DAC 3 (Front) */
11509	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11510        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11511	{ }
11512};
11513
11514static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11515	/*
11516	 * Unmute ADC0 and set the default input to mic-in
11517	 */
11518	/* port-A for surround (rear panel) */
11519	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11520	/* port-B for mic-in (rear panel) with vref */
11521	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11522	/* port-C for line-in (rear panel) */
11523	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11524	/* port-D for Front */
11525	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11526	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11527	/* port-E for HP out (front panel) */
11528	/* this has to be set to VREF80 */
11529	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11530	/* route front PCM to HP */
11531	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11532	/* port-F for mic-in (front panel) with vref */
11533	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11534	/* port-G for CLFE (rear panel) */
11535	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11536	/* port-H for side (rear panel) */
11537	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11538	/* CD-in */
11539	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11540	/* route front mic to ADC1*/
11541	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11542	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11543	/* Unmute DAC0~3 & spdif out*/
11544	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11545	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11546	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11547	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11548	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11549
11550	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11551	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11552        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11553	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11554        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11555
11556	/* Unmute Stereo Mixer 15 */
11557	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11558	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11559	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11560	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11561
11562	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11563	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11564	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11565	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11566	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11567	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11568	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11569	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11570	/* hp used DAC 3 (Front) */
11571	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11572        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11573	{ }
11574};
11575
11576static struct hda_verb alc861_asus_init_verbs[] = {
11577	/*
11578	 * Unmute ADC0 and set the default input to mic-in
11579	 */
11580	/* port-A for surround (rear panel)
11581	 * according to codec#0 this is the HP jack
11582	 */
11583	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11584	/* route front PCM to HP */
11585	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11586	/* port-B for mic-in (rear panel) with vref */
11587	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11588	/* port-C for line-in (rear panel) */
11589	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11590	/* port-D for Front */
11591	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11592	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11593	/* port-E for HP out (front panel) */
11594	/* this has to be set to VREF80 */
11595	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11596	/* route front PCM to HP */
11597	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11598	/* port-F for mic-in (front panel) with vref */
11599	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11600	/* port-G for CLFE (rear panel) */
11601	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11602	/* port-H for side (rear panel) */
11603	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11604	/* CD-in */
11605	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11606	/* route front mic to ADC1*/
11607	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11608	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11609	/* Unmute DAC0~3 & spdif out*/
11610	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11611	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11612	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11613	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11614	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11615	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11616	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11617        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11618	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11619        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11620
11621	/* Unmute Stereo Mixer 15 */
11622	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11623	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11624	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11625	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11626
11627	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11628	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11629	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11630	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11631	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11632	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11633	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11634	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11635	/* hp used DAC 3 (Front) */
11636	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11637	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11638	{ }
11639};
11640
11641/* additional init verbs for ASUS laptops */
11642static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11643	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11644	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11645	{ }
11646};
11647
11648/*
11649 * generic initialization of ADC, input mixers and output mixers
11650 */
11651static struct hda_verb alc861_auto_init_verbs[] = {
11652	/*
11653	 * Unmute ADC0 and set the default input to mic-in
11654	 */
11655	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
11656	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11657
11658	/* Unmute DAC0~3 & spdif out*/
11659	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11660	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11661	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11662	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11663	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11664
11665	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11666	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11667	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11668	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11669	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11670
11671	/* Unmute Stereo Mixer 15 */
11672	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11673	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11674	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11675	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11676
11677	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11678	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11679	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11680	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11681	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11682	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11683	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11684	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11685
11686	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11687	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11688	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11689	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11690	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11691	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11692	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11693	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11694
11695	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
11696
11697	{ }
11698};
11699
11700static struct hda_verb alc861_toshiba_init_verbs[] = {
11701	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11702
11703	{ }
11704};
11705
11706/* toggle speaker-output according to the hp-jack state */
11707static void alc861_toshiba_automute(struct hda_codec *codec)
11708{
11709	unsigned int present;
11710
11711	present = snd_hda_codec_read(codec, 0x0f, 0,
11712				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11713	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11714				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11715	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11716				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
11717}
11718
11719static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11720				       unsigned int res)
11721{
11722	if ((res >> 26) == ALC880_HP_EVENT)
11723		alc861_toshiba_automute(codec);
11724}
11725
11726/* pcm configuration: identiacal with ALC880 */
11727#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
11728#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
11729#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
11730#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
11731
11732
11733#define ALC861_DIGOUT_NID	0x07
11734
11735static struct hda_channel_mode alc861_8ch_modes[1] = {
11736	{ 8, NULL }
11737};
11738
11739static hda_nid_t alc861_dac_nids[4] = {
11740	/* front, surround, clfe, side */
11741	0x03, 0x06, 0x05, 0x04
11742};
11743
11744static hda_nid_t alc660_dac_nids[3] = {
11745	/* front, clfe, surround */
11746	0x03, 0x05, 0x06
11747};
11748
11749static hda_nid_t alc861_adc_nids[1] = {
11750	/* ADC0-2 */
11751	0x08,
11752};
11753
11754static struct hda_input_mux alc861_capture_source = {
11755	.num_items = 5,
11756	.items = {
11757		{ "Mic", 0x0 },
11758		{ "Front Mic", 0x3 },
11759		{ "Line", 0x1 },
11760		{ "CD", 0x4 },
11761		{ "Mixer", 0x5 },
11762	},
11763};
11764
11765/* fill in the dac_nids table from the parsed pin configuration */
11766static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11767				     const struct auto_pin_cfg *cfg)
11768{
11769	int i;
11770	hda_nid_t nid;
11771
11772	spec->multiout.dac_nids = spec->private_dac_nids;
11773	for (i = 0; i < cfg->line_outs; i++) {
11774		nid = cfg->line_out_pins[i];
11775		if (nid) {
11776			if (i >= ARRAY_SIZE(alc861_dac_nids))
11777				continue;
11778			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11779		}
11780	}
11781	spec->multiout.num_dacs = cfg->line_outs;
11782	return 0;
11783}
11784
11785/* add playback controls from the parsed DAC table */
11786static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11787					     const struct auto_pin_cfg *cfg)
11788{
11789	char name[32];
11790	static const char *chname[4] = {
11791		"Front", "Surround", NULL /*CLFE*/, "Side"
11792	};
11793	hda_nid_t nid;
11794	int i, idx, err;
11795
11796	for (i = 0; i < cfg->line_outs; i++) {
11797		nid = spec->multiout.dac_nids[i];
11798		if (!nid)
11799			continue;
11800		if (nid == 0x05) {
11801			/* Center/LFE */
11802			err = add_control(spec, ALC_CTL_BIND_MUTE,
11803					  "Center Playback Switch",
11804					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11805							      HDA_OUTPUT));
11806			if (err < 0)
11807				return err;
11808			err = add_control(spec, ALC_CTL_BIND_MUTE,
11809					  "LFE Playback Switch",
11810					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11811							      HDA_OUTPUT));
11812			if (err < 0)
11813				return err;
11814		} else {
11815			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11816			     idx++)
11817				if (nid == alc861_dac_nids[idx])
11818					break;
11819			sprintf(name, "%s Playback Switch", chname[idx]);
11820			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11821					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11822							      HDA_OUTPUT));
11823			if (err < 0)
11824				return err;
11825		}
11826	}
11827	return 0;
11828}
11829
11830static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11831{
11832	int err;
11833	hda_nid_t nid;
11834
11835	if (!pin)
11836		return 0;
11837
11838	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11839		nid = 0x03;
11840		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11841				  "Headphone Playback Switch",
11842				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11843		if (err < 0)
11844			return err;
11845		spec->multiout.hp_nid = nid;
11846	}
11847	return 0;
11848}
11849
11850/* create playback/capture controls for input pins */
11851static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11852						const struct auto_pin_cfg *cfg)
11853{
11854	struct hda_input_mux *imux = &spec->private_imux;
11855	int i, err, idx, idx1;
11856
11857	for (i = 0; i < AUTO_PIN_LAST; i++) {
11858		switch (cfg->input_pins[i]) {
11859		case 0x0c:
11860			idx1 = 1;
11861			idx = 2;	/* Line In */
11862			break;
11863		case 0x0f:
11864			idx1 = 2;
11865			idx = 2;	/* Line In */
11866			break;
11867		case 0x0d:
11868			idx1 = 0;
11869			idx = 1;	/* Mic In */
11870			break;
11871		case 0x10:
11872			idx1 = 3;
11873			idx = 1;	/* Mic In */
11874			break;
11875		case 0x11:
11876			idx1 = 4;
11877			idx = 0;	/* CD */
11878			break;
11879		default:
11880			continue;
11881		}
11882
11883		err = new_analog_input(spec, cfg->input_pins[i],
11884				       auto_pin_cfg_labels[i], idx, 0x15);
11885		if (err < 0)
11886			return err;
11887
11888		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11889		imux->items[imux->num_items].index = idx1;
11890		imux->num_items++;
11891	}
11892	return 0;
11893}
11894
11895static struct snd_kcontrol_new alc861_capture_mixer[] = {
11896	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11897	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11898
11899	{
11900		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11901		/* The multiple "Capture Source" controls confuse alsamixer
11902		 * So call somewhat different..
11903		 */
11904		/* .name = "Capture Source", */
11905		.name = "Input Source",
11906		.count = 1,
11907		.info = alc_mux_enum_info,
11908		.get = alc_mux_enum_get,
11909		.put = alc_mux_enum_put,
11910	},
11911	{ } /* end */
11912};
11913
11914static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11915					      hda_nid_t nid,
11916					      int pin_type, int dac_idx)
11917{
11918	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11919			    pin_type);
11920	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11921			    AMP_OUT_UNMUTE);
11922}
11923
11924static void alc861_auto_init_multi_out(struct hda_codec *codec)
11925{
11926	struct alc_spec *spec = codec->spec;
11927	int i;
11928
11929	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
11930	for (i = 0; i < spec->autocfg.line_outs; i++) {
11931		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11932		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11933		if (nid)
11934			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
11935							  spec->multiout.dac_nids[i]);
11936	}
11937}
11938
11939static void alc861_auto_init_hp_out(struct hda_codec *codec)
11940{
11941	struct alc_spec *spec = codec->spec;
11942	hda_nid_t pin;
11943
11944	pin = spec->autocfg.hp_pins[0];
11945	if (pin) /* connect to front */
11946		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11947						  spec->multiout.dac_nids[0]);
11948	pin = spec->autocfg.speaker_pins[0];
11949	if (pin)
11950		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
11951}
11952
11953static void alc861_auto_init_analog_input(struct hda_codec *codec)
11954{
11955	struct alc_spec *spec = codec->spec;
11956	int i;
11957
11958	for (i = 0; i < AUTO_PIN_LAST; i++) {
11959		hda_nid_t nid = spec->autocfg.input_pins[i];
11960		if (nid >= 0x0c && nid <= 0x11) {
11961			snd_hda_codec_write(codec, nid, 0,
11962					    AC_VERB_SET_PIN_WIDGET_CONTROL,
11963					    i <= AUTO_PIN_FRONT_MIC ?
11964					    PIN_VREF80 : PIN_IN);
11965		}
11966	}
11967}
11968
11969/* parse the BIOS configuration and set up the alc_spec */
11970/* return 1 if successful, 0 if the proper config is not found,
11971 * or a negative error code
11972 */
11973static int alc861_parse_auto_config(struct hda_codec *codec)
11974{
11975	struct alc_spec *spec = codec->spec;
11976	int err;
11977	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11978
11979	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11980					   alc861_ignore);
11981	if (err < 0)
11982		return err;
11983	if (!spec->autocfg.line_outs)
11984		return 0; /* can't find valid BIOS pin config */
11985
11986	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11987	if (err < 0)
11988		return err;
11989	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11990	if (err < 0)
11991		return err;
11992	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11993	if (err < 0)
11994		return err;
11995	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11996	if (err < 0)
11997		return err;
11998
11999	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12000
12001	if (spec->autocfg.dig_out_pin)
12002		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
12003
12004	if (spec->kctl_alloc)
12005		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12006
12007	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
12008
12009	spec->num_mux_defs = 1;
12010	spec->input_mux = &spec->private_imux;
12011
12012	spec->adc_nids = alc861_adc_nids;
12013	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
12014	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
12015	spec->num_mixers++;
12016
12017	return 1;
12018}
12019
12020/* additional initialization for auto-configuration model */
12021static void alc861_auto_init(struct hda_codec *codec)
12022{
12023	struct alc_spec *spec = codec->spec;
12024	alc861_auto_init_multi_out(codec);
12025	alc861_auto_init_hp_out(codec);
12026	alc861_auto_init_analog_input(codec);
12027	if (spec->unsol_event)
12028		alc_sku_automute(codec);
12029}
12030
12031#ifdef CONFIG_SND_HDA_POWER_SAVE
12032static struct hda_amp_list alc861_loopbacks[] = {
12033	{ 0x15, HDA_INPUT, 0 },
12034	{ 0x15, HDA_INPUT, 1 },
12035	{ 0x15, HDA_INPUT, 2 },
12036	{ 0x15, HDA_INPUT, 3 },
12037	{ } /* end */
12038};
12039#endif
12040
12041
12042/*
12043 * configuration and preset
12044 */
12045static const char *alc861_models[ALC861_MODEL_LAST] = {
12046	[ALC861_3ST]		= "3stack",
12047	[ALC660_3ST]		= "3stack-660",
12048	[ALC861_3ST_DIG]	= "3stack-dig",
12049	[ALC861_6ST_DIG]	= "6stack-dig",
12050	[ALC861_UNIWILL_M31]	= "uniwill-m31",
12051	[ALC861_TOSHIBA]	= "toshiba",
12052	[ALC861_ASUS]		= "asus",
12053	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
12054	[ALC861_AUTO]		= "auto",
12055};
12056
12057static struct snd_pci_quirk alc861_cfg_tbl[] = {
12058	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
12059	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12060	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12061	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
12062	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
12063	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
12064	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
12065	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
12066	 *        Any other models that need this preset?
12067	 */
12068	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
12069	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
12070	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
12071	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
12072	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
12073	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
12074	/* FIXME: the below seems conflict */
12075	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
12076	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
12077	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
12078	{}
12079};
12080
12081static struct alc_config_preset alc861_presets[] = {
12082	[ALC861_3ST] = {
12083		.mixers = { alc861_3ST_mixer },
12084		.init_verbs = { alc861_threestack_init_verbs },
12085		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12086		.dac_nids = alc861_dac_nids,
12087		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12088		.channel_mode = alc861_threestack_modes,
12089		.need_dac_fix = 1,
12090		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12091		.adc_nids = alc861_adc_nids,
12092		.input_mux = &alc861_capture_source,
12093	},
12094	[ALC861_3ST_DIG] = {
12095		.mixers = { alc861_base_mixer },
12096		.init_verbs = { alc861_threestack_init_verbs },
12097		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12098		.dac_nids = alc861_dac_nids,
12099		.dig_out_nid = ALC861_DIGOUT_NID,
12100		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12101		.channel_mode = alc861_threestack_modes,
12102		.need_dac_fix = 1,
12103		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12104		.adc_nids = alc861_adc_nids,
12105		.input_mux = &alc861_capture_source,
12106	},
12107	[ALC861_6ST_DIG] = {
12108		.mixers = { alc861_base_mixer },
12109		.init_verbs = { alc861_base_init_verbs },
12110		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12111		.dac_nids = alc861_dac_nids,
12112		.dig_out_nid = ALC861_DIGOUT_NID,
12113		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
12114		.channel_mode = alc861_8ch_modes,
12115		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12116		.adc_nids = alc861_adc_nids,
12117		.input_mux = &alc861_capture_source,
12118	},
12119	[ALC660_3ST] = {
12120		.mixers = { alc861_3ST_mixer },
12121		.init_verbs = { alc861_threestack_init_verbs },
12122		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
12123		.dac_nids = alc660_dac_nids,
12124		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12125		.channel_mode = alc861_threestack_modes,
12126		.need_dac_fix = 1,
12127		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12128		.adc_nids = alc861_adc_nids,
12129		.input_mux = &alc861_capture_source,
12130	},
12131	[ALC861_UNIWILL_M31] = {
12132		.mixers = { alc861_uniwill_m31_mixer },
12133		.init_verbs = { alc861_uniwill_m31_init_verbs },
12134		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12135		.dac_nids = alc861_dac_nids,
12136		.dig_out_nid = ALC861_DIGOUT_NID,
12137		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
12138		.channel_mode = alc861_uniwill_m31_modes,
12139		.need_dac_fix = 1,
12140		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12141		.adc_nids = alc861_adc_nids,
12142		.input_mux = &alc861_capture_source,
12143	},
12144	[ALC861_TOSHIBA] = {
12145		.mixers = { alc861_toshiba_mixer },
12146		.init_verbs = { alc861_base_init_verbs,
12147				alc861_toshiba_init_verbs },
12148		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12149		.dac_nids = alc861_dac_nids,
12150		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12151		.channel_mode = alc883_3ST_2ch_modes,
12152		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12153		.adc_nids = alc861_adc_nids,
12154		.input_mux = &alc861_capture_source,
12155		.unsol_event = alc861_toshiba_unsol_event,
12156		.init_hook = alc861_toshiba_automute,
12157	},
12158	[ALC861_ASUS] = {
12159		.mixers = { alc861_asus_mixer },
12160		.init_verbs = { alc861_asus_init_verbs },
12161		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12162		.dac_nids = alc861_dac_nids,
12163		.dig_out_nid = ALC861_DIGOUT_NID,
12164		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
12165		.channel_mode = alc861_asus_modes,
12166		.need_dac_fix = 1,
12167		.hp_nid = 0x06,
12168		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12169		.adc_nids = alc861_adc_nids,
12170		.input_mux = &alc861_capture_source,
12171	},
12172	[ALC861_ASUS_LAPTOP] = {
12173		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
12174		.init_verbs = { alc861_asus_init_verbs,
12175				alc861_asus_laptop_init_verbs },
12176		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12177		.dac_nids = alc861_dac_nids,
12178		.dig_out_nid = ALC861_DIGOUT_NID,
12179		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12180		.channel_mode = alc883_3ST_2ch_modes,
12181		.need_dac_fix = 1,
12182		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12183		.adc_nids = alc861_adc_nids,
12184		.input_mux = &alc861_capture_source,
12185	},
12186};
12187
12188
12189static int patch_alc861(struct hda_codec *codec)
12190{
12191	struct alc_spec *spec;
12192	int board_config;
12193	int err;
12194
12195	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12196	if (spec == NULL)
12197		return -ENOMEM;
12198
12199	codec->spec = spec;
12200
12201        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
12202						  alc861_models,
12203						  alc861_cfg_tbl);
12204
12205	if (board_config < 0) {
12206		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
12207		       "trying auto-probe from BIOS...\n");
12208		board_config = ALC861_AUTO;
12209	}
12210
12211	if (board_config == ALC861_AUTO) {
12212		/* automatic parse from the BIOS config */
12213		err = alc861_parse_auto_config(codec);
12214		if (err < 0) {
12215			alc_free(codec);
12216			return err;
12217		} else if (!err) {
12218			printk(KERN_INFO
12219			       "hda_codec: Cannot set up configuration "
12220			       "from BIOS.  Using base mode...\n");
12221		   board_config = ALC861_3ST_DIG;
12222		}
12223	}
12224
12225	if (board_config != ALC861_AUTO)
12226		setup_preset(spec, &alc861_presets[board_config]);
12227
12228	spec->stream_name_analog = "ALC861 Analog";
12229	spec->stream_analog_playback = &alc861_pcm_analog_playback;
12230	spec->stream_analog_capture = &alc861_pcm_analog_capture;
12231
12232	spec->stream_name_digital = "ALC861 Digital";
12233	spec->stream_digital_playback = &alc861_pcm_digital_playback;
12234	spec->stream_digital_capture = &alc861_pcm_digital_capture;
12235
12236	spec->vmaster_nid = 0x03;
12237
12238	codec->patch_ops = alc_patch_ops;
12239	if (board_config == ALC861_AUTO)
12240		spec->init_hook = alc861_auto_init;
12241#ifdef CONFIG_SND_HDA_POWER_SAVE
12242	if (!spec->loopback.amplist)
12243		spec->loopback.amplist = alc861_loopbacks;
12244#endif
12245
12246	return 0;
12247}
12248
12249/*
12250 * ALC861-VD support
12251 *
12252 * Based on ALC882
12253 *
12254 * In addition, an independent DAC
12255 */
12256#define ALC861VD_DIGOUT_NID	0x06
12257
12258static hda_nid_t alc861vd_dac_nids[4] = {
12259	/* front, surr, clfe, side surr */
12260	0x02, 0x03, 0x04, 0x05
12261};
12262
12263/* dac_nids for ALC660vd are in a different order - according to
12264 * Realtek's driver.
12265 * This should probably tesult in a different mixer for 6stack models
12266 * of ALC660vd codecs, but for now there is only 3stack mixer
12267 * - and it is the same as in 861vd.
12268 * adc_nids in ALC660vd are (is) the same as in 861vd
12269 */
12270static hda_nid_t alc660vd_dac_nids[3] = {
12271	/* front, rear, clfe, rear_surr */
12272	0x02, 0x04, 0x03
12273};
12274
12275static hda_nid_t alc861vd_adc_nids[1] = {
12276	/* ADC0 */
12277	0x09,
12278};
12279
12280static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
12281
12282/* input MUX */
12283/* FIXME: should be a matrix-type input source selection */
12284static struct hda_input_mux alc861vd_capture_source = {
12285	.num_items = 4,
12286	.items = {
12287		{ "Mic", 0x0 },
12288		{ "Front Mic", 0x1 },
12289		{ "Line", 0x2 },
12290		{ "CD", 0x4 },
12291	},
12292};
12293
12294static struct hda_input_mux alc861vd_dallas_capture_source = {
12295	.num_items = 2,
12296	.items = {
12297		{ "Ext Mic", 0x0 },
12298		{ "Int Mic", 0x1 },
12299	},
12300};
12301
12302static struct hda_input_mux alc861vd_hp_capture_source = {
12303	.num_items = 2,
12304	.items = {
12305		{ "Front Mic", 0x0 },
12306		{ "ATAPI Mic", 0x1 },
12307	},
12308};
12309
12310#define alc861vd_mux_enum_info alc_mux_enum_info
12311#define alc861vd_mux_enum_get alc_mux_enum_get
12312/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
12313#define alc861vd_mux_enum_put alc882_mux_enum_put
12314
12315/*
12316 * 2ch mode
12317 */
12318static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
12319	{ 2, NULL }
12320};
12321
12322/*
12323 * 6ch mode
12324 */
12325static struct hda_verb alc861vd_6stack_ch6_init[] = {
12326	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12327	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12328	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12329	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12330	{ } /* end */
12331};
12332
12333/*
12334 * 8ch mode
12335 */
12336static struct hda_verb alc861vd_6stack_ch8_init[] = {
12337	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12338	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12339	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12340	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12341	{ } /* end */
12342};
12343
12344static struct hda_channel_mode alc861vd_6stack_modes[2] = {
12345	{ 6, alc861vd_6stack_ch6_init },
12346	{ 8, alc861vd_6stack_ch8_init },
12347};
12348
12349static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
12350	{
12351		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12352		.name = "Channel Mode",
12353		.info = alc_ch_mode_info,
12354		.get = alc_ch_mode_get,
12355		.put = alc_ch_mode_put,
12356	},
12357	{ } /* end */
12358};
12359
12360static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
12361	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12362	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12363
12364	{
12365		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12366		/* The multiple "Capture Source" controls confuse alsamixer
12367		 * So call somewhat different..
12368		 */
12369		/* .name = "Capture Source", */
12370		.name = "Input Source",
12371		.count = 1,
12372		.info = alc861vd_mux_enum_info,
12373		.get = alc861vd_mux_enum_get,
12374		.put = alc861vd_mux_enum_put,
12375	},
12376	{ } /* end */
12377};
12378
12379/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12380 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12381 */
12382static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
12383	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12384	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12385
12386	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12387	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
12388
12389	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
12390				HDA_OUTPUT),
12391	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
12392				HDA_OUTPUT),
12393	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12394	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
12395
12396	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
12397	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
12398
12399	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12400
12401	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12402	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12403	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12404
12405	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12406	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12407	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12408
12409	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12410	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12411
12412	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12413	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12414
12415	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12416	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12417
12418	{ } /* end */
12419};
12420
12421static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12422	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12423	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12424
12425	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12426
12427	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12428	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12429	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12430
12431	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12432	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12433	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12434
12435	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12436	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12437
12438	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12439	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12440
12441	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12442	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12443
12444	{ } /* end */
12445};
12446
12447static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12448	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12449	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12450	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12451
12452	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12453
12454	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12455	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12456	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12457
12458	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12459	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12460	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12461
12462	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12463	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12464
12465	{ } /* end */
12466};
12467
12468/* Pin assignment: Speaker=0x14, HP = 0x15,
12469 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
12470 */
12471static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12472	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12473	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
12474	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12475	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12476	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12477	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12478	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12479	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12480	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12481	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12482	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
12483	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
12484	{ } /* end */
12485};
12486
12487/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12488 *                 Front Mic=0x18, ATAPI Mic = 0x19,
12489 */
12490static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12491	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12492	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12493	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12494	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12495	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12496	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12497	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12498	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12499
12500	{ } /* end */
12501};
12502
12503/*
12504 * generic initialization of ADC, input mixers and output mixers
12505 */
12506static struct hda_verb alc861vd_volume_init_verbs[] = {
12507	/*
12508	 * Unmute ADC0 and set the default input to mic-in
12509	 */
12510	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12511	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12512
12513	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12514	 * the analog-loopback mixer widget
12515	 */
12516	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12517	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12518	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12519	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12520	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12521	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12522
12523	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
12524	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12525	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12526	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12527	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12528
12529	/*
12530	 * Set up output mixers (0x02 - 0x05)
12531	 */
12532	/* set vol=0 to output mixers */
12533	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12534	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12535	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12536	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12537
12538	/* set up input amps for analog loopback */
12539	/* Amp Indices: DAC = 0, mixer = 1 */
12540	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12541	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12542	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12543	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12544	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12545	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12546	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12547	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12548
12549	{ }
12550};
12551
12552/*
12553 * 3-stack pin configuration:
12554 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12555 */
12556static struct hda_verb alc861vd_3stack_init_verbs[] = {
12557	/*
12558	 * Set pin mode and muting
12559	 */
12560	/* set front pin widgets 0x14 for output */
12561	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12562	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12563	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12564
12565	/* Mic (rear) pin: input vref at 80% */
12566	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12567	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12568	/* Front Mic pin: input vref at 80% */
12569	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12570	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12571	/* Line In pin: input */
12572	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12573	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12574	/* Line-2 In: Headphone output (output 0 - 0x0c) */
12575	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12576	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12577	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12578	/* CD pin widget for input */
12579	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12580
12581	{ }
12582};
12583
12584/*
12585 * 6-stack pin configuration:
12586 */
12587static struct hda_verb alc861vd_6stack_init_verbs[] = {
12588	/*
12589	 * Set pin mode and muting
12590	 */
12591	/* set front pin widgets 0x14 for output */
12592	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12593	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12594	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12595
12596	/* Rear Pin: output 1 (0x0d) */
12597	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12598	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12599	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12600	/* CLFE Pin: output 2 (0x0e) */
12601	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12602	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12603	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12604	/* Side Pin: output 3 (0x0f) */
12605	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12606	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12607	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12608
12609	/* Mic (rear) pin: input vref at 80% */
12610	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12611	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12612	/* Front Mic pin: input vref at 80% */
12613	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12614	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12615	/* Line In pin: input */
12616	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12617	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12618	/* Line-2 In: Headphone output (output 0 - 0x0c) */
12619	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12620	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12621	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12622	/* CD pin widget for input */
12623	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12624
12625	{ }
12626};
12627
12628static struct hda_verb alc861vd_eapd_verbs[] = {
12629	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12630	{ }
12631};
12632
12633static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12634	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12635	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12636	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12637	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12638	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12639	{}
12640};
12641
12642/* toggle speaker-output according to the hp-jack state */
12643static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12644{
12645	unsigned int present;
12646	unsigned char bits;
12647
12648	present = snd_hda_codec_read(codec, 0x1b, 0,
12649				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12650	bits = present ? HDA_AMP_MUTE : 0;
12651	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12652				 HDA_AMP_MUTE, bits);
12653}
12654
12655static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12656{
12657	unsigned int present;
12658	unsigned char bits;
12659
12660	present = snd_hda_codec_read(codec, 0x18, 0,
12661				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12662	bits = present ? HDA_AMP_MUTE : 0;
12663	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12664				 HDA_AMP_MUTE, bits);
12665}
12666
12667static void alc861vd_lenovo_automute(struct hda_codec *codec)
12668{
12669	alc861vd_lenovo_hp_automute(codec);
12670	alc861vd_lenovo_mic_automute(codec);
12671}
12672
12673static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12674					unsigned int res)
12675{
12676	switch (res >> 26) {
12677	case ALC880_HP_EVENT:
12678		alc861vd_lenovo_hp_automute(codec);
12679		break;
12680	case ALC880_MIC_EVENT:
12681		alc861vd_lenovo_mic_automute(codec);
12682		break;
12683	}
12684}
12685
12686static struct hda_verb alc861vd_dallas_verbs[] = {
12687	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12688	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12689	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12690	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12691
12692	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12693	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12694	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12695	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12696	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12697	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12698	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12699	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12700
12701	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12702	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12703	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12704	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12705	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12706	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12707	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12708	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12709
12710	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12711	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12712	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12713	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12714	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12715	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12716	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12717	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12718
12719	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12720	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12721	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12722	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12723
12724	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12725	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12726	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12727
12728	{ } /* end */
12729};
12730
12731/* toggle speaker-output according to the hp-jack state */
12732static void alc861vd_dallas_automute(struct hda_codec *codec)
12733{
12734	unsigned int present;
12735
12736	present = snd_hda_codec_read(codec, 0x15, 0,
12737				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12738	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12739				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12740}
12741
12742static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12743{
12744	if ((res >> 26) == ALC880_HP_EVENT)
12745		alc861vd_dallas_automute(codec);
12746}
12747
12748#ifdef CONFIG_SND_HDA_POWER_SAVE
12749#define alc861vd_loopbacks	alc880_loopbacks
12750#endif
12751
12752/* pcm configuration: identiacal with ALC880 */
12753#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
12754#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
12755#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
12756#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
12757
12758/*
12759 * configuration and preset
12760 */
12761static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12762	[ALC660VD_3ST]		= "3stack-660",
12763	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
12764	[ALC861VD_3ST]		= "3stack",
12765	[ALC861VD_3ST_DIG]	= "3stack-digout",
12766	[ALC861VD_6ST_DIG]	= "6stack-digout",
12767	[ALC861VD_LENOVO]	= "lenovo",
12768	[ALC861VD_DALLAS]	= "dallas",
12769	[ALC861VD_HP]		= "hp",
12770	[ALC861VD_AUTO]		= "auto",
12771};
12772
12773static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
12774	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12775	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
12776	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
12777	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
12778	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
12779	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
12780	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
12781	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
12782	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
12783	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
12784	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
12785	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
12786	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12787	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
12788	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
12789	{}
12790};
12791
12792static struct alc_config_preset alc861vd_presets[] = {
12793	[ALC660VD_3ST] = {
12794		.mixers = { alc861vd_3st_mixer },
12795		.init_verbs = { alc861vd_volume_init_verbs,
12796				 alc861vd_3stack_init_verbs },
12797		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12798		.dac_nids = alc660vd_dac_nids,
12799		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12800		.channel_mode = alc861vd_3stack_2ch_modes,
12801		.input_mux = &alc861vd_capture_source,
12802	},
12803	[ALC660VD_3ST_DIG] = {
12804		.mixers = { alc861vd_3st_mixer },
12805		.init_verbs = { alc861vd_volume_init_verbs,
12806				 alc861vd_3stack_init_verbs },
12807		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12808		.dac_nids = alc660vd_dac_nids,
12809		.dig_out_nid = ALC861VD_DIGOUT_NID,
12810		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12811		.channel_mode = alc861vd_3stack_2ch_modes,
12812		.input_mux = &alc861vd_capture_source,
12813	},
12814	[ALC861VD_3ST] = {
12815		.mixers = { alc861vd_3st_mixer },
12816		.init_verbs = { alc861vd_volume_init_verbs,
12817				 alc861vd_3stack_init_verbs },
12818		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12819		.dac_nids = alc861vd_dac_nids,
12820		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12821		.channel_mode = alc861vd_3stack_2ch_modes,
12822		.input_mux = &alc861vd_capture_source,
12823	},
12824	[ALC861VD_3ST_DIG] = {
12825		.mixers = { alc861vd_3st_mixer },
12826		.init_verbs = { alc861vd_volume_init_verbs,
12827		 		 alc861vd_3stack_init_verbs },
12828		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12829		.dac_nids = alc861vd_dac_nids,
12830		.dig_out_nid = ALC861VD_DIGOUT_NID,
12831		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12832		.channel_mode = alc861vd_3stack_2ch_modes,
12833		.input_mux = &alc861vd_capture_source,
12834	},
12835	[ALC861VD_6ST_DIG] = {
12836		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12837		.init_verbs = { alc861vd_volume_init_verbs,
12838				alc861vd_6stack_init_verbs },
12839		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12840		.dac_nids = alc861vd_dac_nids,
12841		.dig_out_nid = ALC861VD_DIGOUT_NID,
12842		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12843		.channel_mode = alc861vd_6stack_modes,
12844		.input_mux = &alc861vd_capture_source,
12845	},
12846	[ALC861VD_LENOVO] = {
12847		.mixers = { alc861vd_lenovo_mixer },
12848		.init_verbs = { alc861vd_volume_init_verbs,
12849				alc861vd_3stack_init_verbs,
12850				alc861vd_eapd_verbs,
12851				alc861vd_lenovo_unsol_verbs },
12852		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12853		.dac_nids = alc660vd_dac_nids,
12854		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12855		.channel_mode = alc861vd_3stack_2ch_modes,
12856		.input_mux = &alc861vd_capture_source,
12857		.unsol_event = alc861vd_lenovo_unsol_event,
12858		.init_hook = alc861vd_lenovo_automute,
12859	},
12860	[ALC861VD_DALLAS] = {
12861		.mixers = { alc861vd_dallas_mixer },
12862		.init_verbs = { alc861vd_dallas_verbs },
12863		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12864		.dac_nids = alc861vd_dac_nids,
12865		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12866		.channel_mode = alc861vd_3stack_2ch_modes,
12867		.input_mux = &alc861vd_dallas_capture_source,
12868		.unsol_event = alc861vd_dallas_unsol_event,
12869		.init_hook = alc861vd_dallas_automute,
12870	},
12871	[ALC861VD_HP] = {
12872		.mixers = { alc861vd_hp_mixer },
12873		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12874		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12875		.dac_nids = alc861vd_dac_nids,
12876		.dig_out_nid = ALC861VD_DIGOUT_NID,
12877		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12878		.channel_mode = alc861vd_3stack_2ch_modes,
12879		.input_mux = &alc861vd_hp_capture_source,
12880		.unsol_event = alc861vd_dallas_unsol_event,
12881		.init_hook = alc861vd_dallas_automute,
12882	},
12883};
12884
12885/*
12886 * BIOS auto configuration
12887 */
12888static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12889				hda_nid_t nid, int pin_type, int dac_idx)
12890{
12891	alc_set_pin_output(codec, nid, pin_type);
12892}
12893
12894static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12895{
12896	struct alc_spec *spec = codec->spec;
12897	int i;
12898
12899	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
12900	for (i = 0; i <= HDA_SIDE; i++) {
12901		hda_nid_t nid = spec->autocfg.line_out_pins[i];
12902		int pin_type = get_pin_type(spec->autocfg.line_out_type);
12903		if (nid)
12904			alc861vd_auto_set_output_and_unmute(codec, nid,
12905							    pin_type, i);
12906	}
12907}
12908
12909
12910static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12911{
12912	struct alc_spec *spec = codec->spec;
12913	hda_nid_t pin;
12914
12915	pin = spec->autocfg.hp_pins[0];
12916	if (pin) /* connect to front and  use dac 0 */
12917		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12918	pin = spec->autocfg.speaker_pins[0];
12919	if (pin)
12920		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
12921}
12922
12923#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
12924#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
12925
12926static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12927{
12928	struct alc_spec *spec = codec->spec;
12929	int i;
12930
12931	for (i = 0; i < AUTO_PIN_LAST; i++) {
12932		hda_nid_t nid = spec->autocfg.input_pins[i];
12933		if (alc861vd_is_input_pin(nid)) {
12934			snd_hda_codec_write(codec, nid, 0,
12935					AC_VERB_SET_PIN_WIDGET_CONTROL,
12936					i <= AUTO_PIN_FRONT_MIC ?
12937							PIN_VREF80 : PIN_IN);
12938			if (nid != ALC861VD_PIN_CD_NID)
12939				snd_hda_codec_write(codec, nid, 0,
12940						AC_VERB_SET_AMP_GAIN_MUTE,
12941						AMP_OUT_MUTE);
12942		}
12943	}
12944}
12945
12946#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
12947#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
12948
12949/* add playback controls from the parsed DAC table */
12950/* Based on ALC880 version. But ALC861VD has separate,
12951 * different NIDs for mute/unmute switch and volume control */
12952static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12953					     const struct auto_pin_cfg *cfg)
12954{
12955	char name[32];
12956	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12957	hda_nid_t nid_v, nid_s;
12958	int i, err;
12959
12960	for (i = 0; i < cfg->line_outs; i++) {
12961		if (!spec->multiout.dac_nids[i])
12962			continue;
12963		nid_v = alc861vd_idx_to_mixer_vol(
12964				alc880_dac_to_idx(
12965					spec->multiout.dac_nids[i]));
12966		nid_s = alc861vd_idx_to_mixer_switch(
12967				alc880_dac_to_idx(
12968					spec->multiout.dac_nids[i]));
12969
12970		if (i == 2) {
12971			/* Center/LFE */
12972			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12973					  "Center Playback Volume",
12974					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12975							      HDA_OUTPUT));
12976			if (err < 0)
12977				return err;
12978			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12979					  "LFE Playback Volume",
12980					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12981							      HDA_OUTPUT));
12982			if (err < 0)
12983				return err;
12984			err = add_control(spec, ALC_CTL_BIND_MUTE,
12985					  "Center Playback Switch",
12986					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12987							      HDA_INPUT));
12988			if (err < 0)
12989				return err;
12990			err = add_control(spec, ALC_CTL_BIND_MUTE,
12991					  "LFE Playback Switch",
12992					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12993							      HDA_INPUT));
12994			if (err < 0)
12995				return err;
12996		} else {
12997			sprintf(name, "%s Playback Volume", chname[i]);
12998			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12999					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
13000							      HDA_OUTPUT));
13001			if (err < 0)
13002				return err;
13003			sprintf(name, "%s Playback Switch", chname[i]);
13004			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13005					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
13006							      HDA_INPUT));
13007			if (err < 0)
13008				return err;
13009		}
13010	}
13011	return 0;
13012}
13013
13014/* add playback controls for speaker and HP outputs */
13015/* Based on ALC880 version. But ALC861VD has separate,
13016 * different NIDs for mute/unmute switch and volume control */
13017static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
13018					hda_nid_t pin, const char *pfx)
13019{
13020	hda_nid_t nid_v, nid_s;
13021	int err;
13022	char name[32];
13023
13024	if (!pin)
13025		return 0;
13026
13027	if (alc880_is_fixed_pin(pin)) {
13028		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13029		/* specify the DAC as the extra output */
13030		if (!spec->multiout.hp_nid)
13031			spec->multiout.hp_nid = nid_v;
13032		else
13033			spec->multiout.extra_out_nid[0] = nid_v;
13034		/* control HP volume/switch on the output mixer amp */
13035		nid_v = alc861vd_idx_to_mixer_vol(
13036				alc880_fixed_pin_idx(pin));
13037		nid_s = alc861vd_idx_to_mixer_switch(
13038				alc880_fixed_pin_idx(pin));
13039
13040		sprintf(name, "%s Playback Volume", pfx);
13041		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13042				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
13043		if (err < 0)
13044			return err;
13045		sprintf(name, "%s Playback Switch", pfx);
13046		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13047				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
13048		if (err < 0)
13049			return err;
13050	} else if (alc880_is_multi_pin(pin)) {
13051		/* set manual connection */
13052		/* we have only a switch on HP-out PIN */
13053		sprintf(name, "%s Playback Switch", pfx);
13054		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13055				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13056		if (err < 0)
13057			return err;
13058	}
13059	return 0;
13060}
13061
13062/* parse the BIOS configuration and set up the alc_spec
13063 * return 1 if successful, 0 if the proper config is not found,
13064 * or a negative error code
13065 * Based on ALC880 version - had to change it to override
13066 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
13067static int alc861vd_parse_auto_config(struct hda_codec *codec)
13068{
13069	struct alc_spec *spec = codec->spec;
13070	int err;
13071	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
13072
13073	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13074					   alc861vd_ignore);
13075	if (err < 0)
13076		return err;
13077	if (!spec->autocfg.line_outs)
13078		return 0; /* can't find valid BIOS pin config */
13079
13080	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13081	if (err < 0)
13082		return err;
13083	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
13084	if (err < 0)
13085		return err;
13086	err = alc861vd_auto_create_extra_out(spec,
13087					     spec->autocfg.speaker_pins[0],
13088					     "Speaker");
13089	if (err < 0)
13090		return err;
13091	err = alc861vd_auto_create_extra_out(spec,
13092					     spec->autocfg.hp_pins[0],
13093					     "Headphone");
13094	if (err < 0)
13095		return err;
13096	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
13097	if (err < 0)
13098		return err;
13099
13100	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13101
13102	if (spec->autocfg.dig_out_pin)
13103		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
13104
13105	if (spec->kctl_alloc)
13106		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13107
13108	spec->init_verbs[spec->num_init_verbs++]
13109		= alc861vd_volume_init_verbs;
13110
13111	spec->num_mux_defs = 1;
13112	spec->input_mux = &spec->private_imux;
13113
13114	err = alc_auto_add_mic_boost(codec);
13115	if (err < 0)
13116		return err;
13117
13118	return 1;
13119}
13120
13121/* additional initialization for auto-configuration model */
13122static void alc861vd_auto_init(struct hda_codec *codec)
13123{
13124	struct alc_spec *spec = codec->spec;
13125	alc861vd_auto_init_multi_out(codec);
13126	alc861vd_auto_init_hp_out(codec);
13127	alc861vd_auto_init_analog_input(codec);
13128	if (spec->unsol_event)
13129		alc_sku_automute(codec);
13130}
13131
13132static int patch_alc861vd(struct hda_codec *codec)
13133{
13134	struct alc_spec *spec;
13135	int err, board_config;
13136
13137	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13138	if (spec == NULL)
13139		return -ENOMEM;
13140
13141	codec->spec = spec;
13142
13143	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
13144						  alc861vd_models,
13145						  alc861vd_cfg_tbl);
13146
13147	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
13148		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
13149			"ALC861VD, trying auto-probe from BIOS...\n");
13150		board_config = ALC861VD_AUTO;
13151	}
13152
13153	if (board_config == ALC861VD_AUTO) {
13154		/* automatic parse from the BIOS config */
13155		err = alc861vd_parse_auto_config(codec);
13156		if (err < 0) {
13157			alc_free(codec);
13158			return err;
13159		} else if (!err) {
13160			printk(KERN_INFO
13161			       "hda_codec: Cannot set up configuration "
13162			       "from BIOS.  Using base mode...\n");
13163			board_config = ALC861VD_3ST;
13164		}
13165	}
13166
13167	if (board_config != ALC861VD_AUTO)
13168		setup_preset(spec, &alc861vd_presets[board_config]);
13169
13170	spec->stream_name_analog = "ALC861VD Analog";
13171	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
13172	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
13173
13174	spec->stream_name_digital = "ALC861VD Digital";
13175	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
13176	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
13177
13178	spec->adc_nids = alc861vd_adc_nids;
13179	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
13180	spec->capsrc_nids = alc861vd_capsrc_nids;
13181
13182	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
13183	spec->num_mixers++;
13184
13185	spec->vmaster_nid = 0x02;
13186
13187	codec->patch_ops = alc_patch_ops;
13188
13189	if (board_config == ALC861VD_AUTO)
13190		spec->init_hook = alc861vd_auto_init;
13191#ifdef CONFIG_SND_HDA_POWER_SAVE
13192	if (!spec->loopback.amplist)
13193		spec->loopback.amplist = alc861vd_loopbacks;
13194#endif
13195
13196	return 0;
13197}
13198
13199/*
13200 * ALC662 support
13201 *
13202 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
13203 * configuration.  Each pin widget can choose any input DACs and a mixer.
13204 * Each ADC is connected from a mixer of all inputs.  This makes possible
13205 * 6-channel independent captures.
13206 *
13207 * In addition, an independent DAC for the multi-playback (not used in this
13208 * driver yet).
13209 */
13210#define ALC662_DIGOUT_NID	0x06
13211#define ALC662_DIGIN_NID	0x0a
13212
13213static hda_nid_t alc662_dac_nids[4] = {
13214	/* front, rear, clfe, rear_surr */
13215	0x02, 0x03, 0x04
13216};
13217
13218static hda_nid_t alc662_adc_nids[1] = {
13219	/* ADC1-2 */
13220	0x09,
13221};
13222
13223static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
13224
13225/* input MUX */
13226/* FIXME: should be a matrix-type input source selection */
13227static struct hda_input_mux alc662_capture_source = {
13228	.num_items = 4,
13229	.items = {
13230		{ "Mic", 0x0 },
13231		{ "Front Mic", 0x1 },
13232		{ "Line", 0x2 },
13233		{ "CD", 0x4 },
13234	},
13235};
13236
13237static struct hda_input_mux alc662_lenovo_101e_capture_source = {
13238	.num_items = 2,
13239	.items = {
13240		{ "Mic", 0x1 },
13241		{ "Line", 0x2 },
13242	},
13243};
13244
13245static struct hda_input_mux alc662_eeepc_capture_source = {
13246	.num_items = 2,
13247	.items = {
13248		{ "i-Mic", 0x1 },
13249		{ "e-Mic", 0x0 },
13250	},
13251};
13252
13253#define alc662_mux_enum_info alc_mux_enum_info
13254#define alc662_mux_enum_get alc_mux_enum_get
13255#define alc662_mux_enum_put alc882_mux_enum_put
13256
13257/*
13258 * 2ch mode
13259 */
13260static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
13261	{ 2, NULL }
13262};
13263
13264/*
13265 * 2ch mode
13266 */
13267static struct hda_verb alc662_3ST_ch2_init[] = {
13268	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
13269	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13270	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
13271	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13272	{ } /* end */
13273};
13274
13275/*
13276 * 6ch mode
13277 */
13278static struct hda_verb alc662_3ST_ch6_init[] = {
13279	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13280	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13281	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
13282	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13283	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13284	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
13285	{ } /* end */
13286};
13287
13288static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
13289	{ 2, alc662_3ST_ch2_init },
13290	{ 6, alc662_3ST_ch6_init },
13291};
13292
13293/*
13294 * 2ch mode
13295 */
13296static struct hda_verb alc662_sixstack_ch6_init[] = {
13297	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13298	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13299	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13300	{ } /* end */
13301};
13302
13303/*
13304 * 6ch mode
13305 */
13306static struct hda_verb alc662_sixstack_ch8_init[] = {
13307	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13308	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13309	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13310	{ } /* end */
13311};
13312
13313static struct hda_channel_mode alc662_5stack_modes[2] = {
13314	{ 2, alc662_sixstack_ch6_init },
13315	{ 6, alc662_sixstack_ch8_init },
13316};
13317
13318/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13319 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13320 */
13321
13322static struct snd_kcontrol_new alc662_base_mixer[] = {
13323	/* output mixer control */
13324	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13325	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13326	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13327	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13328	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13329	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13330	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13331	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13332	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13333
13334	/*Input mixer control */
13335	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
13336	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
13337	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
13338	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
13339	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
13340	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
13341	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
13342	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
13343	{ } /* end */
13344};
13345
13346static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
13347	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13348	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13349	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13350	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13351	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13352	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13353	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13354	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13355	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13356	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13357	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13358	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13359	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13360	{ } /* end */
13361};
13362
13363static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
13364	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13365	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13366	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13367	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13368	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13369	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13370	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13371	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13372	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13373	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13374	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13375	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13376	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13377	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13378	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13379	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13380	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13381	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13382	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13383	{ } /* end */
13384};
13385
13386static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13387	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13388	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13389	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13390	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
13391	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13392	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13393	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13394	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13395	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13396	{ } /* end */
13397};
13398
13399static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
13400	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13401
13402	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13403	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13404
13405	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13406	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13407	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13408
13409	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13410	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13411	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13412	{ } /* end */
13413};
13414
13415static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13416	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13417	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13418	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13419	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13420	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13421	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13422	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13423	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
13424	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13425	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13426	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13427	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13428	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13429	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13430	{ } /* end */
13431};
13432
13433static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13434	{
13435		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13436		.name = "Channel Mode",
13437		.info = alc_ch_mode_info,
13438		.get = alc_ch_mode_get,
13439		.put = alc_ch_mode_put,
13440	},
13441	{ } /* end */
13442};
13443
13444static struct hda_verb alc662_init_verbs[] = {
13445	/* ADC: mute amp left and right */
13446	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13447	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13448	/* Front mixer: unmute input/output amp left and right (volume = 0) */
13449
13450	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13451	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13452	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13453	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13454	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13455
13456	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13458	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13460	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13461	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13462
13463	/* Front Pin: output 0 (0x0c) */
13464	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13465	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13466
13467	/* Rear Pin: output 1 (0x0d) */
13468	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13469	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13470
13471	/* CLFE Pin: output 2 (0x0e) */
13472	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13473	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13474
13475	/* Mic (rear) pin: input vref at 80% */
13476	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13477	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13478	/* Front Mic pin: input vref at 80% */
13479	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13480	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13481	/* Line In pin: input */
13482	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13483	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13484	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13485	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13486	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13487	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13488	/* CD pin widget for input */
13489	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13490
13491	/* FIXME: use matrix-type input source selection */
13492	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13493	/* Input mixer */
13494	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13495	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13496	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13497	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13498
13499	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13500	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13501	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13502	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13503	{ }
13504};
13505
13506static struct hda_verb alc662_sue_init_verbs[] = {
13507	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13508	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
13509	{}
13510};
13511
13512static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13513	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13514	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13515	{}
13516};
13517
13518/* Set Unsolicited Event*/
13519static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13520	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13521	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13522	{}
13523};
13524
13525/*
13526 * generic initialization of ADC, input mixers and output mixers
13527 */
13528static struct hda_verb alc662_auto_init_verbs[] = {
13529	/*
13530	 * Unmute ADC and set the default input to mic-in
13531	 */
13532	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13533	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13534
13535	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13536	 * mixer widget
13537	 * Note: PASD motherboards uses the Line In 2 as the input for front
13538	 * panel mic (mic 2)
13539	 */
13540	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13541	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13542	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13543	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13544	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13545	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13546
13547	/*
13548	 * Set up output mixers (0x0c - 0x0f)
13549	 */
13550	/* set vol=0 to output mixers */
13551	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13552	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13553	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13554
13555	/* set up input amps for analog loopback */
13556	/* Amp Indices: DAC = 0, mixer = 1 */
13557	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13558	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13559	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13560	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13561	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13562	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13563
13564
13565	/* FIXME: use matrix-type input source selection */
13566	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13567	/* Input mixer */
13568	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13569	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13570	{ }
13571};
13572
13573/* capture mixer elements */
13574static struct snd_kcontrol_new alc662_capture_mixer[] = {
13575	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13576	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13577	{
13578		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13579		/* The multiple "Capture Source" controls confuse alsamixer
13580		 * So call somewhat different..
13581		 */
13582		/* .name = "Capture Source", */
13583		.name = "Input Source",
13584		.count = 1,
13585		.info = alc662_mux_enum_info,
13586		.get = alc662_mux_enum_get,
13587		.put = alc662_mux_enum_put,
13588	},
13589	{ } /* end */
13590};
13591
13592static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13593{
13594	unsigned int present;
13595	unsigned char bits;
13596
13597	present = snd_hda_codec_read(codec, 0x14, 0,
13598				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13599	bits = present ? HDA_AMP_MUTE : 0;
13600	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13601				 HDA_AMP_MUTE, bits);
13602}
13603
13604static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13605{
13606	unsigned int present;
13607	unsigned char bits;
13608
13609 	present = snd_hda_codec_read(codec, 0x1b, 0,
13610				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13611	bits = present ? HDA_AMP_MUTE : 0;
13612	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13613				 HDA_AMP_MUTE, bits);
13614	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13615				 HDA_AMP_MUTE, bits);
13616}
13617
13618static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13619					   unsigned int res)
13620{
13621	if ((res >> 26) == ALC880_HP_EVENT)
13622		alc662_lenovo_101e_all_automute(codec);
13623	if ((res >> 26) == ALC880_FRONT_EVENT)
13624		alc662_lenovo_101e_ispeaker_automute(codec);
13625}
13626
13627static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13628{
13629	unsigned int present;
13630
13631	present = snd_hda_codec_read(codec, 0x18, 0,
13632				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13633	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13634			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13635	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13636			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13637	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13638			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13639	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13640			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13641}
13642
13643/* unsolicited event for HP jack sensing */
13644static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13645				     unsigned int res)
13646{
13647	if ((res >> 26) == ALC880_HP_EVENT)
13648		alc262_hippo1_automute( codec );
13649
13650	if ((res >> 26) == ALC880_MIC_EVENT)
13651		alc662_eeepc_mic_automute(codec);
13652}
13653
13654static void alc662_eeepc_inithook(struct hda_codec *codec)
13655{
13656	alc262_hippo1_automute( codec );
13657	alc662_eeepc_mic_automute(codec);
13658}
13659
13660static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13661{
13662	unsigned int mute;
13663	unsigned int present;
13664
13665	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13666	present = snd_hda_codec_read(codec, 0x14, 0,
13667				     AC_VERB_GET_PIN_SENSE, 0);
13668	present = (present & 0x80000000) != 0;
13669	if (present) {
13670		/* mute internal speaker */
13671		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13672					 HDA_AMP_MUTE, HDA_AMP_MUTE);
13673	} else {
13674		/* unmute internal speaker if necessary */
13675		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13676		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13677					 HDA_AMP_MUTE, mute);
13678	}
13679}
13680
13681/* unsolicited event for HP jack sensing */
13682static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13683					  unsigned int res)
13684{
13685	if ((res >> 26) == ALC880_HP_EVENT)
13686		alc662_eeepc_ep20_automute(codec);
13687}
13688
13689static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13690{
13691	alc662_eeepc_ep20_automute(codec);
13692}
13693
13694#ifdef CONFIG_SND_HDA_POWER_SAVE
13695#define alc662_loopbacks	alc880_loopbacks
13696#endif
13697
13698
13699/* pcm configuration: identiacal with ALC880 */
13700#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
13701#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
13702#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
13703#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
13704
13705/*
13706 * configuration and preset
13707 */
13708static const char *alc662_models[ALC662_MODEL_LAST] = {
13709	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
13710	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
13711	[ALC662_3ST_6ch]	= "3stack-6ch",
13712	[ALC662_5ST_DIG]	= "6stack-dig",
13713	[ALC662_LENOVO_101E]	= "lenovo-101e",
13714	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
13715	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
13716	[ALC662_AUTO]		= "auto",
13717};
13718
13719static struct snd_pci_quirk alc662_cfg_tbl[] = {
13720	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
13721	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
13722	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
13723	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
13724	{}
13725};
13726
13727static struct alc_config_preset alc662_presets[] = {
13728	[ALC662_3ST_2ch_DIG] = {
13729		.mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
13730		.init_verbs = { alc662_init_verbs },
13731		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13732		.dac_nids = alc662_dac_nids,
13733		.dig_out_nid = ALC662_DIGOUT_NID,
13734		.dig_in_nid = ALC662_DIGIN_NID,
13735		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13736		.channel_mode = alc662_3ST_2ch_modes,
13737		.input_mux = &alc662_capture_source,
13738	},
13739	[ALC662_3ST_6ch_DIG] = {
13740		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13741			    alc662_capture_mixer },
13742		.init_verbs = { alc662_init_verbs },
13743		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13744		.dac_nids = alc662_dac_nids,
13745		.dig_out_nid = ALC662_DIGOUT_NID,
13746		.dig_in_nid = ALC662_DIGIN_NID,
13747		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13748		.channel_mode = alc662_3ST_6ch_modes,
13749		.need_dac_fix = 1,
13750		.input_mux = &alc662_capture_source,
13751	},
13752	[ALC662_3ST_6ch] = {
13753		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13754			    alc662_capture_mixer },
13755		.init_verbs = { alc662_init_verbs },
13756		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13757		.dac_nids = alc662_dac_nids,
13758		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13759		.channel_mode = alc662_3ST_6ch_modes,
13760		.need_dac_fix = 1,
13761		.input_mux = &alc662_capture_source,
13762	},
13763	[ALC662_5ST_DIG] = {
13764		.mixers = { alc662_base_mixer, alc662_chmode_mixer,
13765			    alc662_capture_mixer },
13766		.init_verbs = { alc662_init_verbs },
13767		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13768		.dac_nids = alc662_dac_nids,
13769		.dig_out_nid = ALC662_DIGOUT_NID,
13770		.dig_in_nid = ALC662_DIGIN_NID,
13771		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13772		.channel_mode = alc662_5stack_modes,
13773		.input_mux = &alc662_capture_source,
13774	},
13775	[ALC662_LENOVO_101E] = {
13776		.mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
13777		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13778		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13779		.dac_nids = alc662_dac_nids,
13780		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13781		.channel_mode = alc662_3ST_2ch_modes,
13782		.input_mux = &alc662_lenovo_101e_capture_source,
13783		.unsol_event = alc662_lenovo_101e_unsol_event,
13784		.init_hook = alc662_lenovo_101e_all_automute,
13785	},
13786	[ALC662_ASUS_EEEPC_P701] = {
13787		.mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13788		.init_verbs = { alc662_init_verbs,
13789				alc662_eeepc_sue_init_verbs },
13790		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13791		.dac_nids = alc662_dac_nids,
13792		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13793		.channel_mode = alc662_3ST_2ch_modes,
13794		.input_mux = &alc662_eeepc_capture_source,
13795		.unsol_event = alc662_eeepc_unsol_event,
13796		.init_hook = alc662_eeepc_inithook,
13797	},
13798	[ALC662_ASUS_EEEPC_EP20] = {
13799		.mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13800			    alc662_chmode_mixer },
13801		.init_verbs = { alc662_init_verbs,
13802				alc662_eeepc_ep20_sue_init_verbs },
13803		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13804		.dac_nids = alc662_dac_nids,
13805		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13806		.channel_mode = alc662_3ST_6ch_modes,
13807		.input_mux = &alc662_lenovo_101e_capture_source,
13808		.unsol_event = alc662_eeepc_ep20_unsol_event,
13809		.init_hook = alc662_eeepc_ep20_inithook,
13810	},
13811
13812};
13813
13814
13815/*
13816 * BIOS auto configuration
13817 */
13818
13819/* add playback controls from the parsed DAC table */
13820static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13821					     const struct auto_pin_cfg *cfg)
13822{
13823	char name[32];
13824	static const char *chname[4] = {
13825		"Front", "Surround", NULL /*CLFE*/, "Side"
13826	};
13827	hda_nid_t nid;
13828	int i, err;
13829
13830	for (i = 0; i < cfg->line_outs; i++) {
13831		if (!spec->multiout.dac_nids[i])
13832			continue;
13833		nid = alc880_idx_to_dac(i);
13834		if (i == 2) {
13835			/* Center/LFE */
13836			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13837					  "Center Playback Volume",
13838					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13839							      HDA_OUTPUT));
13840			if (err < 0)
13841				return err;
13842			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13843					  "LFE Playback Volume",
13844					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13845							      HDA_OUTPUT));
13846			if (err < 0)
13847				return err;
13848			err = add_control(spec, ALC_CTL_BIND_MUTE,
13849					  "Center Playback Switch",
13850					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13851							      HDA_INPUT));
13852			if (err < 0)
13853				return err;
13854			err = add_control(spec, ALC_CTL_BIND_MUTE,
13855					  "LFE Playback Switch",
13856					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13857							      HDA_INPUT));
13858			if (err < 0)
13859				return err;
13860		} else {
13861			sprintf(name, "%s Playback Volume", chname[i]);
13862			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13863					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13864							      HDA_OUTPUT));
13865			if (err < 0)
13866				return err;
13867			sprintf(name, "%s Playback Switch", chname[i]);
13868			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13869					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13870							      HDA_INPUT));
13871			if (err < 0)
13872				return err;
13873		}
13874	}
13875	return 0;
13876}
13877
13878/* add playback controls for speaker and HP outputs */
13879static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13880					const char *pfx)
13881{
13882	hda_nid_t nid;
13883	int err;
13884	char name[32];
13885
13886	if (!pin)
13887		return 0;
13888
13889	if (alc880_is_fixed_pin(pin)) {
13890		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13891                /* printk("DAC nid=%x\n",nid); */
13892		/* specify the DAC as the extra output */
13893		if (!spec->multiout.hp_nid)
13894			spec->multiout.hp_nid = nid;
13895		else
13896			spec->multiout.extra_out_nid[0] = nid;
13897		/* control HP volume/switch on the output mixer amp */
13898		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13899		sprintf(name, "%s Playback Volume", pfx);
13900		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13901				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13902		if (err < 0)
13903			return err;
13904		sprintf(name, "%s Playback Switch", pfx);
13905		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13906				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13907		if (err < 0)
13908			return err;
13909	} else if (alc880_is_multi_pin(pin)) {
13910		/* set manual connection */
13911		/* we have only a switch on HP-out PIN */
13912		sprintf(name, "%s Playback Switch", pfx);
13913		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13914				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13915		if (err < 0)
13916			return err;
13917	}
13918	return 0;
13919}
13920
13921/* create playback/capture controls for input pins */
13922static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13923						const struct auto_pin_cfg *cfg)
13924{
13925	struct hda_input_mux *imux = &spec->private_imux;
13926	int i, err, idx;
13927
13928	for (i = 0; i < AUTO_PIN_LAST; i++) {
13929		if (alc880_is_input_pin(cfg->input_pins[i])) {
13930			idx = alc880_input_pin_idx(cfg->input_pins[i]);
13931			err = new_analog_input(spec, cfg->input_pins[i],
13932					       auto_pin_cfg_labels[i],
13933					       idx, 0x0b);
13934			if (err < 0)
13935				return err;
13936			imux->items[imux->num_items].label =
13937				auto_pin_cfg_labels[i];
13938			imux->items[imux->num_items].index =
13939				alc880_input_pin_idx(cfg->input_pins[i]);
13940			imux->num_items++;
13941		}
13942	}
13943	return 0;
13944}
13945
13946static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13947					      hda_nid_t nid, int pin_type,
13948					      int dac_idx)
13949{
13950	alc_set_pin_output(codec, nid, pin_type);
13951	/* need the manual connection? */
13952	if (alc880_is_multi_pin(nid)) {
13953		struct alc_spec *spec = codec->spec;
13954		int idx = alc880_multi_pin_idx(nid);
13955		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13956				    AC_VERB_SET_CONNECT_SEL,
13957				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13958	}
13959}
13960
13961static void alc662_auto_init_multi_out(struct hda_codec *codec)
13962{
13963	struct alc_spec *spec = codec->spec;
13964	int i;
13965
13966	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13967	for (i = 0; i <= HDA_SIDE; i++) {
13968		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13969		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13970		if (nid)
13971			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
13972							  i);
13973	}
13974}
13975
13976static void alc662_auto_init_hp_out(struct hda_codec *codec)
13977{
13978	struct alc_spec *spec = codec->spec;
13979	hda_nid_t pin;
13980
13981	pin = spec->autocfg.hp_pins[0];
13982	if (pin) /* connect to front */
13983		/* use dac 0 */
13984		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13985	pin = spec->autocfg.speaker_pins[0];
13986	if (pin)
13987		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13988}
13989
13990#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
13991#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
13992
13993static void alc662_auto_init_analog_input(struct hda_codec *codec)
13994{
13995	struct alc_spec *spec = codec->spec;
13996	int i;
13997
13998	for (i = 0; i < AUTO_PIN_LAST; i++) {
13999		hda_nid_t nid = spec->autocfg.input_pins[i];
14000		if (alc662_is_input_pin(nid)) {
14001			snd_hda_codec_write(codec, nid, 0,
14002					    AC_VERB_SET_PIN_WIDGET_CONTROL,
14003					    (i <= AUTO_PIN_FRONT_MIC ?
14004					     PIN_VREF80 : PIN_IN));
14005			if (nid != ALC662_PIN_CD_NID)
14006				snd_hda_codec_write(codec, nid, 0,
14007						    AC_VERB_SET_AMP_GAIN_MUTE,
14008						    AMP_OUT_MUTE);
14009		}
14010	}
14011}
14012
14013static int alc662_parse_auto_config(struct hda_codec *codec)
14014{
14015	struct alc_spec *spec = codec->spec;
14016	int err;
14017	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
14018
14019	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14020					   alc662_ignore);
14021	if (err < 0)
14022		return err;
14023	if (!spec->autocfg.line_outs)
14024		return 0; /* can't find valid BIOS pin config */
14025
14026	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14027	if (err < 0)
14028		return err;
14029	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
14030	if (err < 0)
14031		return err;
14032	err = alc662_auto_create_extra_out(spec,
14033					   spec->autocfg.speaker_pins[0],
14034					   "Speaker");
14035	if (err < 0)
14036		return err;
14037	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
14038					   "Headphone");
14039	if (err < 0)
14040		return err;
14041	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
14042	if (err < 0)
14043		return err;
14044
14045	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14046
14047	if (spec->autocfg.dig_out_pin)
14048		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
14049
14050	if (spec->kctl_alloc)
14051		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14052
14053	spec->num_mux_defs = 1;
14054	spec->input_mux = &spec->private_imux;
14055
14056	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
14057	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
14058	spec->num_mixers++;
14059	return 1;
14060}
14061
14062/* additional initialization for auto-configuration model */
14063static void alc662_auto_init(struct hda_codec *codec)
14064{
14065	struct alc_spec *spec = codec->spec;
14066	alc662_auto_init_multi_out(codec);
14067	alc662_auto_init_hp_out(codec);
14068	alc662_auto_init_analog_input(codec);
14069	if (spec->unsol_event)
14070		alc_sku_automute(codec);
14071}
14072
14073static int patch_alc662(struct hda_codec *codec)
14074{
14075	struct alc_spec *spec;
14076	int err, board_config;
14077
14078	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14079	if (!spec)
14080		return -ENOMEM;
14081
14082	codec->spec = spec;
14083
14084	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
14085						  alc662_models,
14086			  	                  alc662_cfg_tbl);
14087	if (board_config < 0) {
14088		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
14089		       "trying auto-probe from BIOS...\n");
14090		board_config = ALC662_AUTO;
14091	}
14092
14093	if (board_config == ALC662_AUTO) {
14094		/* automatic parse from the BIOS config */
14095		err = alc662_parse_auto_config(codec);
14096		if (err < 0) {
14097			alc_free(codec);
14098			return err;
14099		} else if (!err) {
14100			printk(KERN_INFO
14101			       "hda_codec: Cannot set up configuration "
14102			       "from BIOS.  Using base mode...\n");
14103			board_config = ALC662_3ST_2ch_DIG;
14104		}
14105	}
14106
14107	if (board_config != ALC662_AUTO)
14108		setup_preset(spec, &alc662_presets[board_config]);
14109
14110	spec->stream_name_analog = "ALC662 Analog";
14111	spec->stream_analog_playback = &alc662_pcm_analog_playback;
14112	spec->stream_analog_capture = &alc662_pcm_analog_capture;
14113
14114	spec->stream_name_digital = "ALC662 Digital";
14115	spec->stream_digital_playback = &alc662_pcm_digital_playback;
14116	spec->stream_digital_capture = &alc662_pcm_digital_capture;
14117
14118	spec->adc_nids = alc662_adc_nids;
14119	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
14120	spec->capsrc_nids = alc662_capsrc_nids;
14121
14122	spec->vmaster_nid = 0x02;
14123
14124	codec->patch_ops = alc_patch_ops;
14125	if (board_config == ALC662_AUTO)
14126		spec->init_hook = alc662_auto_init;
14127#ifdef CONFIG_SND_HDA_POWER_SAVE
14128	if (!spec->loopback.amplist)
14129		spec->loopback.amplist = alc662_loopbacks;
14130#endif
14131
14132	return 0;
14133}
14134
14135/*
14136 * patch entries
14137 */
14138struct hda_codec_preset snd_hda_preset_realtek[] = {
14139	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
14140	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
14141	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
14142	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
14143	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
14144	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
14145	  .patch = patch_alc861 },
14146	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
14147	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
14148	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
14149	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
14150	  .patch = patch_alc883 },
14151	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
14152	  .patch = patch_alc662 },
14153	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
14154	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
14155	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
14156	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
14157	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
14158	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
14159	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
14160	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
14161	{} /* terminator */
14162};
14163