patch_realtek.c revision 24fb9173815045ab3f85a670d7df8af5af6ff3be
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_ASUS_EEEPC_P703,
126	ALC269_ASUS_EEEPC_P901,
127	ALC269_AUTO,
128	ALC269_MODEL_LAST /* last tag */
129};
130
131/* ALC861 models */
132enum {
133	ALC861_3ST,
134	ALC660_3ST,
135	ALC861_3ST_DIG,
136	ALC861_6ST_DIG,
137	ALC861_UNIWILL_M31,
138	ALC861_TOSHIBA,
139	ALC861_ASUS,
140	ALC861_ASUS_LAPTOP,
141	ALC861_AUTO,
142	ALC861_MODEL_LAST,
143};
144
145/* ALC861-VD models */
146enum {
147	ALC660VD_3ST,
148	ALC660VD_3ST_DIG,
149	ALC861VD_3ST,
150	ALC861VD_3ST_DIG,
151	ALC861VD_6ST_DIG,
152	ALC861VD_LENOVO,
153	ALC861VD_DALLAS,
154	ALC861VD_HP,
155	ALC861VD_AUTO,
156	ALC861VD_MODEL_LAST,
157};
158
159/* ALC662 models */
160enum {
161	ALC662_3ST_2ch_DIG,
162	ALC662_3ST_6ch_DIG,
163	ALC662_3ST_6ch,
164	ALC662_5ST_DIG,
165	ALC662_LENOVO_101E,
166	ALC662_ASUS_EEEPC_P701,
167	ALC662_ASUS_EEEPC_EP20,
168	ALC663_ASUS_M51VA,
169	ALC663_ASUS_G71V,
170	ALC663_ASUS_H13,
171	ALC663_ASUS_G50V,
172	ALC662_AUTO,
173	ALC662_MODEL_LAST,
174};
175
176/* ALC882 models */
177enum {
178	ALC882_3ST_DIG,
179	ALC882_6ST_DIG,
180	ALC882_ARIMA,
181	ALC882_W2JC,
182	ALC882_TARGA,
183	ALC882_ASUS_A7J,
184	ALC882_ASUS_A7M,
185	ALC885_MACPRO,
186	ALC885_MBP3,
187	ALC885_IMAC24,
188	ALC882_AUTO,
189	ALC882_MODEL_LAST,
190};
191
192/* ALC883 models */
193enum {
194	ALC883_3ST_2ch_DIG,
195	ALC883_3ST_6ch_DIG,
196	ALC883_3ST_6ch,
197	ALC883_6ST_DIG,
198	ALC883_TARGA_DIG,
199	ALC883_TARGA_2ch_DIG,
200	ALC883_ACER,
201	ALC883_ACER_ASPIRE,
202	ALC883_MEDION,
203	ALC883_MEDION_MD2,
204	ALC883_LAPTOP_EAPD,
205	ALC883_LENOVO_101E_2ch,
206	ALC883_LENOVO_NB0763,
207	ALC888_LENOVO_MS7195_DIG,
208	ALC883_HAIER_W66,
209	ALC888_3ST_HP,
210	ALC888_6ST_DELL,
211	ALC883_MITAC,
212	ALC883_CLEVO_M720,
213	ALC883_FUJITSU_PI2515,
214	ALC883_3ST_6ch_INTEL,
215	ALC883_AUTO,
216	ALC883_MODEL_LAST,
217};
218
219/* for GPIO Poll */
220#define GPIO_MASK	0x03
221
222struct alc_spec {
223	/* codec parameterization */
224	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
225	unsigned int num_mixers;
226
227	const struct hda_verb *init_verbs[5];	/* initialization verbs
228						 * don't forget NULL
229						 * termination!
230						 */
231	unsigned int num_init_verbs;
232
233	char *stream_name_analog;	/* analog PCM stream */
234	struct hda_pcm_stream *stream_analog_playback;
235	struct hda_pcm_stream *stream_analog_capture;
236	struct hda_pcm_stream *stream_analog_alt_playback;
237	struct hda_pcm_stream *stream_analog_alt_capture;
238
239	char *stream_name_digital;	/* digital PCM stream */
240	struct hda_pcm_stream *stream_digital_playback;
241	struct hda_pcm_stream *stream_digital_capture;
242
243	/* playback */
244	struct hda_multi_out multiout;	/* playback set-up
245					 * max_channels, dacs must be set
246					 * dig_out_nid and hp_nid are optional
247					 */
248	hda_nid_t alt_dac_nid;
249
250	/* capture */
251	unsigned int num_adc_nids;
252	hda_nid_t *adc_nids;
253	hda_nid_t *capsrc_nids;
254	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
255
256	/* capture source */
257	unsigned int num_mux_defs;
258	const struct hda_input_mux *input_mux;
259	unsigned int cur_mux[3];
260
261	/* channel model */
262	const struct hda_channel_mode *channel_mode;
263	int num_channel_mode;
264	int need_dac_fix;
265
266	/* PCM information */
267	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
268
269	/* dynamic controls, init_verbs and input_mux */
270	struct auto_pin_cfg autocfg;
271	unsigned int num_kctl_alloc, num_kctl_used;
272	struct snd_kcontrol_new *kctl_alloc;
273	struct hda_input_mux private_imux;
274	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
275
276	/* hooks */
277	void (*init_hook)(struct hda_codec *codec);
278	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
279
280	/* for pin sensing */
281	unsigned int sense_updated: 1;
282	unsigned int jack_present: 1;
283	unsigned int master_sw: 1;
284
285	/* for virtual master */
286	hda_nid_t vmaster_nid;
287#ifdef CONFIG_SND_HDA_POWER_SAVE
288	struct hda_loopback_check loopback;
289#endif
290
291	/* for PLL fix */
292	hda_nid_t pll_nid;
293	unsigned int pll_coef_idx, pll_coef_bit;
294};
295
296/*
297 * configuration template - to be copied to the spec instance
298 */
299struct alc_config_preset {
300	struct snd_kcontrol_new *mixers[5]; /* should be identical size
301					     * with spec
302					     */
303	const struct hda_verb *init_verbs[5];
304	unsigned int num_dacs;
305	hda_nid_t *dac_nids;
306	hda_nid_t dig_out_nid;		/* optional */
307	hda_nid_t hp_nid;		/* optional */
308	unsigned int num_adc_nids;
309	hda_nid_t *adc_nids;
310	hda_nid_t *capsrc_nids;
311	hda_nid_t dig_in_nid;
312	unsigned int num_channel_mode;
313	const struct hda_channel_mode *channel_mode;
314	int need_dac_fix;
315	unsigned int num_mux_defs;
316	const struct hda_input_mux *input_mux;
317	void (*unsol_event)(struct hda_codec *, unsigned int);
318	void (*init_hook)(struct hda_codec *);
319#ifdef CONFIG_SND_HDA_POWER_SAVE
320	struct hda_amp_list *loopbacks;
321#endif
322};
323
324
325/*
326 * input MUX handling
327 */
328static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
329			     struct snd_ctl_elem_info *uinfo)
330{
331	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
332	struct alc_spec *spec = codec->spec;
333	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
334	if (mux_idx >= spec->num_mux_defs)
335		mux_idx = 0;
336	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
337}
338
339static int alc_mux_enum_get(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
346	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
347	return 0;
348}
349
350static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
351			    struct snd_ctl_elem_value *ucontrol)
352{
353	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
354	struct alc_spec *spec = codec->spec;
355	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
356	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
357	hda_nid_t nid = spec->capsrc_nids ?
358		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
359	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
360				     nid, &spec->cur_mux[adc_idx]);
361}
362
363
364/*
365 * channel mode setting
366 */
367static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
368			    struct snd_ctl_elem_info *uinfo)
369{
370	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
371	struct alc_spec *spec = codec->spec;
372	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
373				    spec->num_channel_mode);
374}
375
376static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
377			   struct snd_ctl_elem_value *ucontrol)
378{
379	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
380	struct alc_spec *spec = codec->spec;
381	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
382				   spec->num_channel_mode,
383				   spec->multiout.max_channels);
384}
385
386static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
387			   struct snd_ctl_elem_value *ucontrol)
388{
389	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
390	struct alc_spec *spec = codec->spec;
391	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
392				      spec->num_channel_mode,
393				      &spec->multiout.max_channels);
394	if (err >= 0 && spec->need_dac_fix)
395		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
396	return err;
397}
398
399/*
400 * Control the mode of pin widget settings via the mixer.  "pc" is used
401 * instead of "%" to avoid consequences of accidently treating the % as
402 * being part of a format specifier.  Maximum allowed length of a value is
403 * 63 characters plus NULL terminator.
404 *
405 * Note: some retasking pin complexes seem to ignore requests for input
406 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
407 * are requested.  Therefore order this list so that this behaviour will not
408 * cause problems when mixer clients move through the enum sequentially.
409 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
410 * March 2006.
411 */
412static char *alc_pin_mode_names[] = {
413	"Mic 50pc bias", "Mic 80pc bias",
414	"Line in", "Line out", "Headphone out",
415};
416static unsigned char alc_pin_mode_values[] = {
417	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
418};
419/* The control can present all 5 options, or it can limit the options based
420 * in the pin being assumed to be exclusively an input or an output pin.  In
421 * addition, "input" pins may or may not process the mic bias option
422 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
423 * accept requests for bias as of chip versions up to March 2006) and/or
424 * wiring in the computer.
425 */
426#define ALC_PIN_DIR_IN              0x00
427#define ALC_PIN_DIR_OUT             0x01
428#define ALC_PIN_DIR_INOUT           0x02
429#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
430#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
431
432/* Info about the pin modes supported by the different pin direction modes.
433 * For each direction the minimum and maximum values are given.
434 */
435static signed char alc_pin_mode_dir_info[5][2] = {
436	{ 0, 2 },    /* ALC_PIN_DIR_IN */
437	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
438	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
439	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
440	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
441};
442#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
443#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
444#define alc_pin_mode_n_items(_dir) \
445	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
446
447static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
448			     struct snd_ctl_elem_info *uinfo)
449{
450	unsigned int item_num = uinfo->value.enumerated.item;
451	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
452
453	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
454	uinfo->count = 1;
455	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
456
457	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
458		item_num = alc_pin_mode_min(dir);
459	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
460	return 0;
461}
462
463static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
464			    struct snd_ctl_elem_value *ucontrol)
465{
466	unsigned int i;
467	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
468	hda_nid_t nid = kcontrol->private_value & 0xffff;
469	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
470	long *valp = ucontrol->value.integer.value;
471	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
472						 AC_VERB_GET_PIN_WIDGET_CONTROL,
473						 0x00);
474
475	/* Find enumerated value for current pinctl setting */
476	i = alc_pin_mode_min(dir);
477	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
478		i++;
479	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
480	return 0;
481}
482
483static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
484			    struct snd_ctl_elem_value *ucontrol)
485{
486	signed int change;
487	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
488	hda_nid_t nid = kcontrol->private_value & 0xffff;
489	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
490	long val = *ucontrol->value.integer.value;
491	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
492						 AC_VERB_GET_PIN_WIDGET_CONTROL,
493						 0x00);
494
495	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
496		val = alc_pin_mode_min(dir);
497
498	change = pinctl != alc_pin_mode_values[val];
499	if (change) {
500		/* Set pin mode to that requested */
501		snd_hda_codec_write_cache(codec, nid, 0,
502					  AC_VERB_SET_PIN_WIDGET_CONTROL,
503					  alc_pin_mode_values[val]);
504
505		/* Also enable the retasking pin's input/output as required
506		 * for the requested pin mode.  Enum values of 2 or less are
507		 * input modes.
508		 *
509		 * Dynamically switching the input/output buffers probably
510		 * reduces noise slightly (particularly on input) so we'll
511		 * do it.  However, having both input and output buffers
512		 * enabled simultaneously doesn't seem to be problematic if
513		 * this turns out to be necessary in the future.
514		 */
515		if (val <= 2) {
516			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
517						 HDA_AMP_MUTE, HDA_AMP_MUTE);
518			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
519						 HDA_AMP_MUTE, 0);
520		} else {
521			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
522						 HDA_AMP_MUTE, HDA_AMP_MUTE);
523			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
524						 HDA_AMP_MUTE, 0);
525		}
526	}
527	return change;
528}
529
530#define ALC_PIN_MODE(xname, nid, dir) \
531	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
532	  .info = alc_pin_mode_info, \
533	  .get = alc_pin_mode_get, \
534	  .put = alc_pin_mode_put, \
535	  .private_value = nid | (dir<<16) }
536
537/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
538 * together using a mask with more than one bit set.  This control is
539 * currently used only by the ALC260 test model.  At this stage they are not
540 * needed for any "production" models.
541 */
542#ifdef CONFIG_SND_DEBUG
543#define alc_gpio_data_info	snd_ctl_boolean_mono_info
544
545static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
546			     struct snd_ctl_elem_value *ucontrol)
547{
548	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
549	hda_nid_t nid = kcontrol->private_value & 0xffff;
550	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
551	long *valp = ucontrol->value.integer.value;
552	unsigned int val = snd_hda_codec_read(codec, nid, 0,
553					      AC_VERB_GET_GPIO_DATA, 0x00);
554
555	*valp = (val & mask) != 0;
556	return 0;
557}
558static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
559			     struct snd_ctl_elem_value *ucontrol)
560{
561	signed int change;
562	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
563	hda_nid_t nid = kcontrol->private_value & 0xffff;
564	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
565	long val = *ucontrol->value.integer.value;
566	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
567						    AC_VERB_GET_GPIO_DATA,
568						    0x00);
569
570	/* Set/unset the masked GPIO bit(s) as needed */
571	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
572	if (val == 0)
573		gpio_data &= ~mask;
574	else
575		gpio_data |= mask;
576	snd_hda_codec_write_cache(codec, nid, 0,
577				  AC_VERB_SET_GPIO_DATA, gpio_data);
578
579	return change;
580}
581#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
582	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
583	  .info = alc_gpio_data_info, \
584	  .get = alc_gpio_data_get, \
585	  .put = alc_gpio_data_put, \
586	  .private_value = nid | (mask<<16) }
587#endif   /* CONFIG_SND_DEBUG */
588
589/* A switch control to allow the enabling of the digital IO pins on the
590 * ALC260.  This is incredibly simplistic; the intention of this control is
591 * to provide something in the test model allowing digital outputs to be
592 * identified if present.  If models are found which can utilise these
593 * outputs a more complete mixer control can be devised for those models if
594 * necessary.
595 */
596#ifdef CONFIG_SND_DEBUG
597#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
598
599static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
600			      struct snd_ctl_elem_value *ucontrol)
601{
602	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
603	hda_nid_t nid = kcontrol->private_value & 0xffff;
604	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
605	long *valp = ucontrol->value.integer.value;
606	unsigned int val = snd_hda_codec_read(codec, nid, 0,
607					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
608
609	*valp = (val & mask) != 0;
610	return 0;
611}
612static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
613			      struct snd_ctl_elem_value *ucontrol)
614{
615	signed int change;
616	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
617	hda_nid_t nid = kcontrol->private_value & 0xffff;
618	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
619	long val = *ucontrol->value.integer.value;
620	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
621						    AC_VERB_GET_DIGI_CONVERT_1,
622						    0x00);
623
624	/* Set/unset the masked control bit(s) as needed */
625	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
626	if (val==0)
627		ctrl_data &= ~mask;
628	else
629		ctrl_data |= mask;
630	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
631				  ctrl_data);
632
633	return change;
634}
635#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
636	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
637	  .info = alc_spdif_ctrl_info, \
638	  .get = alc_spdif_ctrl_get, \
639	  .put = alc_spdif_ctrl_put, \
640	  .private_value = nid | (mask<<16) }
641#endif   /* CONFIG_SND_DEBUG */
642
643/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
644 * Again, this is only used in the ALC26x test models to help identify when
645 * the EAPD line must be asserted for features to work.
646 */
647#ifdef CONFIG_SND_DEBUG
648#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
649
650static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
651			      struct snd_ctl_elem_value *ucontrol)
652{
653	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
654	hda_nid_t nid = kcontrol->private_value & 0xffff;
655	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
656	long *valp = ucontrol->value.integer.value;
657	unsigned int val = snd_hda_codec_read(codec, nid, 0,
658					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
659
660	*valp = (val & mask) != 0;
661	return 0;
662}
663
664static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
665			      struct snd_ctl_elem_value *ucontrol)
666{
667	int change;
668	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
669	hda_nid_t nid = kcontrol->private_value & 0xffff;
670	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
671	long val = *ucontrol->value.integer.value;
672	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
673						    AC_VERB_GET_EAPD_BTLENABLE,
674						    0x00);
675
676	/* Set/unset the masked control bit(s) as needed */
677	change = (!val ? 0 : mask) != (ctrl_data & mask);
678	if (!val)
679		ctrl_data &= ~mask;
680	else
681		ctrl_data |= mask;
682	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
683				  ctrl_data);
684
685	return change;
686}
687
688#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
689	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
690	  .info = alc_eapd_ctrl_info, \
691	  .get = alc_eapd_ctrl_get, \
692	  .put = alc_eapd_ctrl_put, \
693	  .private_value = nid | (mask<<16) }
694#endif   /* CONFIG_SND_DEBUG */
695
696/*
697 * set up from the preset table
698 */
699static void setup_preset(struct alc_spec *spec,
700			 const struct alc_config_preset *preset)
701{
702	int i;
703
704	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
705		spec->mixers[spec->num_mixers++] = preset->mixers[i];
706	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
707	     i++)
708		spec->init_verbs[spec->num_init_verbs++] =
709			preset->init_verbs[i];
710
711	spec->channel_mode = preset->channel_mode;
712	spec->num_channel_mode = preset->num_channel_mode;
713	spec->need_dac_fix = preset->need_dac_fix;
714
715	spec->multiout.max_channels = spec->channel_mode[0].channels;
716
717	spec->multiout.num_dacs = preset->num_dacs;
718	spec->multiout.dac_nids = preset->dac_nids;
719	spec->multiout.dig_out_nid = preset->dig_out_nid;
720	spec->multiout.hp_nid = preset->hp_nid;
721
722	spec->num_mux_defs = preset->num_mux_defs;
723	if (!spec->num_mux_defs)
724		spec->num_mux_defs = 1;
725	spec->input_mux = preset->input_mux;
726
727	spec->num_adc_nids = preset->num_adc_nids;
728	spec->adc_nids = preset->adc_nids;
729	spec->capsrc_nids = preset->capsrc_nids;
730	spec->dig_in_nid = preset->dig_in_nid;
731
732	spec->unsol_event = preset->unsol_event;
733	spec->init_hook = preset->init_hook;
734#ifdef CONFIG_SND_HDA_POWER_SAVE
735	spec->loopback.amplist = preset->loopbacks;
736#endif
737}
738
739/* Enable GPIO mask and set output */
740static struct hda_verb alc_gpio1_init_verbs[] = {
741	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
742	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
743	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
744	{ }
745};
746
747static struct hda_verb alc_gpio2_init_verbs[] = {
748	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
749	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
750	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
751	{ }
752};
753
754static struct hda_verb alc_gpio3_init_verbs[] = {
755	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
756	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
757	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
758	{ }
759};
760
761/*
762 * Fix hardware PLL issue
763 * On some codecs, the analog PLL gating control must be off while
764 * the default value is 1.
765 */
766static void alc_fix_pll(struct hda_codec *codec)
767{
768	struct alc_spec *spec = codec->spec;
769	unsigned int val;
770
771	if (!spec->pll_nid)
772		return;
773	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
774			    spec->pll_coef_idx);
775	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
776				 AC_VERB_GET_PROC_COEF, 0);
777	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
778			    spec->pll_coef_idx);
779	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
780			    val & ~(1 << spec->pll_coef_bit));
781}
782
783static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
784			     unsigned int coef_idx, unsigned int coef_bit)
785{
786	struct alc_spec *spec = codec->spec;
787	spec->pll_nid = nid;
788	spec->pll_coef_idx = coef_idx;
789	spec->pll_coef_bit = coef_bit;
790	alc_fix_pll(codec);
791}
792
793static void alc_sku_automute(struct hda_codec *codec)
794{
795	struct alc_spec *spec = codec->spec;
796	unsigned int present;
797	unsigned int hp_nid = spec->autocfg.hp_pins[0];
798	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
799
800	/* need to execute and sync at first */
801	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
802	present = snd_hda_codec_read(codec, hp_nid, 0,
803				     AC_VERB_GET_PIN_SENSE, 0);
804	spec->jack_present = (present & 0x80000000) != 0;
805	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
806			    spec->jack_present ? 0 : PIN_OUT);
807}
808
809/* unsolicited event for HP jack sensing */
810static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
811{
812	if (codec->vendor_id == 0x10ec0880)
813		res >>= 28;
814	else
815		res >>= 26;
816	if (res != ALC880_HP_EVENT)
817		return;
818
819	alc_sku_automute(codec);
820}
821
822/* additional initialization for ALC888 variants */
823static void alc888_coef_init(struct hda_codec *codec)
824{
825	unsigned int tmp;
826
827	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
828	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
829	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
830	if ((tmp & 0xf0) == 2)
831		/* alc888S-VC */
832		snd_hda_codec_read(codec, 0x20, 0,
833				   AC_VERB_SET_PROC_COEF, 0x830);
834	 else
835		 /* alc888-VB */
836		 snd_hda_codec_read(codec, 0x20, 0,
837				    AC_VERB_SET_PROC_COEF, 0x3030);
838}
839
840/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
841 *	31 ~ 16 :	Manufacture ID
842 *	15 ~ 8	:	SKU ID
843 *	7  ~ 0	:	Assembly ID
844 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
845 */
846static void alc_subsystem_id(struct hda_codec *codec,
847			     unsigned int porta, unsigned int porte,
848			     unsigned int portd)
849{
850	unsigned int ass, tmp, i;
851	unsigned nid;
852	struct alc_spec *spec = codec->spec;
853
854	ass = codec->subsystem_id & 0xffff;
855	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
856		goto do_sku;
857
858	/*
859	 * 31~30	: port conetcivity
860	 * 29~21	: reserve
861	 * 20		: PCBEEP input
862	 * 19~16	: Check sum (15:1)
863	 * 15~1		: Custom
864	 * 0		: override
865	*/
866	nid = 0x1d;
867	if (codec->vendor_id == 0x10ec0260)
868		nid = 0x17;
869	ass = snd_hda_codec_read(codec, nid, 0,
870				 AC_VERB_GET_CONFIG_DEFAULT, 0);
871	if (!(ass & 1) && !(ass & 0x100000))
872		return;
873	if ((ass >> 30) != 1)	/* no physical connection */
874		return;
875
876	/* check sum */
877	tmp = 0;
878	for (i = 1; i < 16; i++) {
879		if ((ass >> i) & 1)
880			tmp++;
881	}
882	if (((ass >> 16) & 0xf) != tmp)
883		return;
884do_sku:
885	/*
886	 * 0 : override
887	 * 1 :	Swap Jack
888	 * 2 : 0 --> Desktop, 1 --> Laptop
889	 * 3~5 : External Amplifier control
890	 * 7~6 : Reserved
891	*/
892	tmp = (ass & 0x38) >> 3;	/* external Amp control */
893	switch (tmp) {
894	case 1:
895		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
896		break;
897	case 3:
898		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
899		break;
900	case 7:
901		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
902		break;
903	case 5:	/* set EAPD output high */
904		switch (codec->vendor_id) {
905		case 0x10ec0260:
906			snd_hda_codec_write(codec, 0x0f, 0,
907					    AC_VERB_SET_EAPD_BTLENABLE, 2);
908			snd_hda_codec_write(codec, 0x10, 0,
909					    AC_VERB_SET_EAPD_BTLENABLE, 2);
910			break;
911		case 0x10ec0262:
912		case 0x10ec0267:
913		case 0x10ec0268:
914		case 0x10ec0269:
915		case 0x10ec0660:
916		case 0x10ec0662:
917		case 0x10ec0663:
918		case 0x10ec0862:
919		case 0x10ec0889:
920			snd_hda_codec_write(codec, 0x14, 0,
921					    AC_VERB_SET_EAPD_BTLENABLE, 2);
922			snd_hda_codec_write(codec, 0x15, 0,
923					    AC_VERB_SET_EAPD_BTLENABLE, 2);
924			break;
925		}
926		switch (codec->vendor_id) {
927		case 0x10ec0260:
928			snd_hda_codec_write(codec, 0x1a, 0,
929					    AC_VERB_SET_COEF_INDEX, 7);
930			tmp = snd_hda_codec_read(codec, 0x1a, 0,
931						 AC_VERB_GET_PROC_COEF, 0);
932			snd_hda_codec_write(codec, 0x1a, 0,
933					    AC_VERB_SET_COEF_INDEX, 7);
934			snd_hda_codec_write(codec, 0x1a, 0,
935					    AC_VERB_SET_PROC_COEF,
936					    tmp | 0x2010);
937			break;
938		case 0x10ec0262:
939		case 0x10ec0880:
940		case 0x10ec0882:
941		case 0x10ec0883:
942		case 0x10ec0885:
943		case 0x10ec0889:
944			snd_hda_codec_write(codec, 0x20, 0,
945					    AC_VERB_SET_COEF_INDEX, 7);
946			tmp = snd_hda_codec_read(codec, 0x20, 0,
947						 AC_VERB_GET_PROC_COEF, 0);
948			snd_hda_codec_write(codec, 0x20, 0,
949					    AC_VERB_SET_COEF_INDEX, 7);
950			snd_hda_codec_write(codec, 0x20, 0,
951					    AC_VERB_SET_PROC_COEF,
952					    tmp | 0x2010);
953			break;
954		case 0x10ec0888:
955			/*alc888_coef_init(codec);*/ /* called in alc_init() */
956			break;
957		case 0x10ec0267:
958		case 0x10ec0268:
959			snd_hda_codec_write(codec, 0x20, 0,
960					    AC_VERB_SET_COEF_INDEX, 7);
961			tmp = snd_hda_codec_read(codec, 0x20, 0,
962						 AC_VERB_GET_PROC_COEF, 0);
963			snd_hda_codec_write(codec, 0x20, 0,
964					    AC_VERB_SET_COEF_INDEX, 7);
965			snd_hda_codec_write(codec, 0x20, 0,
966					    AC_VERB_SET_PROC_COEF,
967					    tmp | 0x3000);
968			break;
969		}
970	default:
971		break;
972	}
973
974	/* is laptop or Desktop and enable the function "Mute internal speaker
975	 * when the external headphone out jack is plugged"
976	 */
977	if (!(ass & 0x8000))
978		return;
979	/*
980	 * 10~8 : Jack location
981	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
982	 * 14~13: Resvered
983	 * 15   : 1 --> enable the function "Mute internal speaker
984	 *	        when the external headphone out jack is plugged"
985	 */
986	if (!spec->autocfg.speaker_pins[0]) {
987		if (spec->autocfg.line_out_pins[0])
988			spec->autocfg.speaker_pins[0] =
989				spec->autocfg.line_out_pins[0];
990		else
991			return;
992	}
993
994	if (!spec->autocfg.hp_pins[0]) {
995		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
996		if (tmp == 0)
997			spec->autocfg.hp_pins[0] = porta;
998		else if (tmp == 1)
999			spec->autocfg.hp_pins[0] = porte;
1000		else if (tmp == 2)
1001			spec->autocfg.hp_pins[0] = portd;
1002		else
1003			return;
1004	}
1005
1006	snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1007			    AC_VERB_SET_UNSOLICITED_ENABLE,
1008			    AC_USRSP_EN | ALC880_HP_EVENT);
1009	spec->unsol_event = alc_sku_unsol_event;
1010}
1011
1012/*
1013 * Fix-up pin default configurations
1014 */
1015
1016struct alc_pincfg {
1017	hda_nid_t nid;
1018	u32 val;
1019};
1020
1021static void alc_fix_pincfg(struct hda_codec *codec,
1022			   const struct snd_pci_quirk *quirk,
1023			   const struct alc_pincfg **pinfix)
1024{
1025	const struct alc_pincfg *cfg;
1026
1027	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1028	if (!quirk)
1029		return;
1030
1031	cfg = pinfix[quirk->value];
1032	for (; cfg->nid; cfg++) {
1033		int i;
1034		u32 val = cfg->val;
1035		for (i = 0; i < 4; i++) {
1036			snd_hda_codec_write(codec, cfg->nid, 0,
1037				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1038				    val & 0xff);
1039			val >>= 8;
1040		}
1041	}
1042}
1043
1044/*
1045 * ALC880 3-stack model
1046 *
1047 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1048 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1049 *                 F-Mic = 0x1b, HP = 0x19
1050 */
1051
1052static hda_nid_t alc880_dac_nids[4] = {
1053	/* front, rear, clfe, rear_surr */
1054	0x02, 0x05, 0x04, 0x03
1055};
1056
1057static hda_nid_t alc880_adc_nids[3] = {
1058	/* ADC0-2 */
1059	0x07, 0x08, 0x09,
1060};
1061
1062/* The datasheet says the node 0x07 is connected from inputs,
1063 * but it shows zero connection in the real implementation on some devices.
1064 * Note: this is a 915GAV bug, fixed on 915GLV
1065 */
1066static hda_nid_t alc880_adc_nids_alt[2] = {
1067	/* ADC1-2 */
1068	0x08, 0x09,
1069};
1070
1071#define ALC880_DIGOUT_NID	0x06
1072#define ALC880_DIGIN_NID	0x0a
1073
1074static struct hda_input_mux alc880_capture_source = {
1075	.num_items = 4,
1076	.items = {
1077		{ "Mic", 0x0 },
1078		{ "Front Mic", 0x3 },
1079		{ "Line", 0x2 },
1080		{ "CD", 0x4 },
1081	},
1082};
1083
1084/* channel source setting (2/6 channel selection for 3-stack) */
1085/* 2ch mode */
1086static struct hda_verb alc880_threestack_ch2_init[] = {
1087	/* set line-in to input, mute it */
1088	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1089	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1090	/* set mic-in to input vref 80%, mute it */
1091	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1092	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1093	{ } /* end */
1094};
1095
1096/* 6ch mode */
1097static struct hda_verb alc880_threestack_ch6_init[] = {
1098	/* set line-in to output, unmute it */
1099	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1100	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1101	/* set mic-in to output, unmute it */
1102	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1103	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1104	{ } /* end */
1105};
1106
1107static struct hda_channel_mode alc880_threestack_modes[2] = {
1108	{ 2, alc880_threestack_ch2_init },
1109	{ 6, alc880_threestack_ch6_init },
1110};
1111
1112static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1113	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1114	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1115	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1116	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1117	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1118	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1119	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1120	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1121	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1122	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1123	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1124	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1125	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1126	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1127	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1128	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1129	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1130	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1131	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1132	{
1133		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1134		.name = "Channel Mode",
1135		.info = alc_ch_mode_info,
1136		.get = alc_ch_mode_get,
1137		.put = alc_ch_mode_put,
1138	},
1139	{ } /* end */
1140};
1141
1142/* capture mixer elements */
1143static struct snd_kcontrol_new alc880_capture_mixer[] = {
1144	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1145	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1146	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1147	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1148	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1149	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1150	{
1151		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1152		/* The multiple "Capture Source" controls confuse alsamixer
1153		 * So call somewhat different..
1154		 */
1155		/* .name = "Capture Source", */
1156		.name = "Input Source",
1157		.count = 3,
1158		.info = alc_mux_enum_info,
1159		.get = alc_mux_enum_get,
1160		.put = alc_mux_enum_put,
1161	},
1162	{ } /* end */
1163};
1164
1165/* capture mixer elements (in case NID 0x07 not available) */
1166static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1167	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1168	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1169	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1170	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1171	{
1172		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1173		/* The multiple "Capture Source" controls confuse alsamixer
1174		 * So call somewhat different..
1175		 */
1176		/* .name = "Capture Source", */
1177		.name = "Input Source",
1178		.count = 2,
1179		.info = alc_mux_enum_info,
1180		.get = alc_mux_enum_get,
1181		.put = alc_mux_enum_put,
1182	},
1183	{ } /* end */
1184};
1185
1186
1187
1188/*
1189 * ALC880 5-stack model
1190 *
1191 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1192 *      Side = 0x02 (0xd)
1193 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1194 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1195 */
1196
1197/* additional mixers to alc880_three_stack_mixer */
1198static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1199	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1200	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1201	{ } /* end */
1202};
1203
1204/* channel source setting (6/8 channel selection for 5-stack) */
1205/* 6ch mode */
1206static struct hda_verb alc880_fivestack_ch6_init[] = {
1207	/* set line-in to input, mute it */
1208	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1209	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1210	{ } /* end */
1211};
1212
1213/* 8ch mode */
1214static struct hda_verb alc880_fivestack_ch8_init[] = {
1215	/* set line-in to output, unmute it */
1216	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1217	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1218	{ } /* end */
1219};
1220
1221static struct hda_channel_mode alc880_fivestack_modes[2] = {
1222	{ 6, alc880_fivestack_ch6_init },
1223	{ 8, alc880_fivestack_ch8_init },
1224};
1225
1226
1227/*
1228 * ALC880 6-stack model
1229 *
1230 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1231 *      Side = 0x05 (0x0f)
1232 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1233 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1234 */
1235
1236static hda_nid_t alc880_6st_dac_nids[4] = {
1237	/* front, rear, clfe, rear_surr */
1238	0x02, 0x03, 0x04, 0x05
1239};
1240
1241static struct hda_input_mux alc880_6stack_capture_source = {
1242	.num_items = 4,
1243	.items = {
1244		{ "Mic", 0x0 },
1245		{ "Front Mic", 0x1 },
1246		{ "Line", 0x2 },
1247		{ "CD", 0x4 },
1248	},
1249};
1250
1251/* fixed 8-channels */
1252static struct hda_channel_mode alc880_sixstack_modes[1] = {
1253	{ 8, NULL },
1254};
1255
1256static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1257	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1258	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1259	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1260	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1261	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1262	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1263	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1264	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1265	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1266	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1267	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1268	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1269	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1270	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1271	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1272	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1273	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1274	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1275	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1276	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1277	{
1278		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1279		.name = "Channel Mode",
1280		.info = alc_ch_mode_info,
1281		.get = alc_ch_mode_get,
1282		.put = alc_ch_mode_put,
1283	},
1284	{ } /* end */
1285};
1286
1287
1288/*
1289 * ALC880 W810 model
1290 *
1291 * W810 has rear IO for:
1292 * Front (DAC 02)
1293 * Surround (DAC 03)
1294 * Center/LFE (DAC 04)
1295 * Digital out (06)
1296 *
1297 * The system also has a pair of internal speakers, and a headphone jack.
1298 * These are both connected to Line2 on the codec, hence to DAC 02.
1299 *
1300 * There is a variable resistor to control the speaker or headphone
1301 * volume. This is a hardware-only device without a software API.
1302 *
1303 * Plugging headphones in will disable the internal speakers. This is
1304 * implemented in hardware, not via the driver using jack sense. In
1305 * a similar fashion, plugging into the rear socket marked "front" will
1306 * disable both the speakers and headphones.
1307 *
1308 * For input, there's a microphone jack, and an "audio in" jack.
1309 * These may not do anything useful with this driver yet, because I
1310 * haven't setup any initialization verbs for these yet...
1311 */
1312
1313static hda_nid_t alc880_w810_dac_nids[3] = {
1314	/* front, rear/surround, clfe */
1315	0x02, 0x03, 0x04
1316};
1317
1318/* fixed 6 channels */
1319static struct hda_channel_mode alc880_w810_modes[1] = {
1320	{ 6, NULL }
1321};
1322
1323/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1324static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1325	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1326	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1327	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1328	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1329	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1330	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1331	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1332	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1333	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1334	{ } /* end */
1335};
1336
1337
1338/*
1339 * Z710V model
1340 *
1341 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1342 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1343 *                 Line = 0x1a
1344 */
1345
1346static hda_nid_t alc880_z71v_dac_nids[1] = {
1347	0x02
1348};
1349#define ALC880_Z71V_HP_DAC	0x03
1350
1351/* fixed 2 channels */
1352static struct hda_channel_mode alc880_2_jack_modes[1] = {
1353	{ 2, NULL }
1354};
1355
1356static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1357	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1358	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1359	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1360	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1361	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1362	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1363	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1364	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1365	{ } /* end */
1366};
1367
1368
1369/*
1370 * ALC880 F1734 model
1371 *
1372 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1373 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1374 */
1375
1376static hda_nid_t alc880_f1734_dac_nids[1] = {
1377	0x03
1378};
1379#define ALC880_F1734_HP_DAC	0x02
1380
1381static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1382	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1383	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1384	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1385	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1386	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1387	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1388	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1389	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1390	{ } /* end */
1391};
1392
1393static struct hda_input_mux alc880_f1734_capture_source = {
1394	.num_items = 2,
1395	.items = {
1396		{ "Mic", 0x1 },
1397		{ "CD", 0x4 },
1398	},
1399};
1400
1401
1402/*
1403 * ALC880 ASUS model
1404 *
1405 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1406 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1407 *  Mic = 0x18, Line = 0x1a
1408 */
1409
1410#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1411#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1412
1413static struct snd_kcontrol_new alc880_asus_mixer[] = {
1414	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1415	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1416	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1417	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1418	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1419	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1420	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1421	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1422	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1423	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1424	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1425	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1426	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1427	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1428	{
1429		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1430		.name = "Channel Mode",
1431		.info = alc_ch_mode_info,
1432		.get = alc_ch_mode_get,
1433		.put = alc_ch_mode_put,
1434	},
1435	{ } /* end */
1436};
1437
1438/*
1439 * ALC880 ASUS W1V model
1440 *
1441 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1442 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1443 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1444 */
1445
1446/* additional mixers to alc880_asus_mixer */
1447static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1448	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1449	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1450	{ } /* end */
1451};
1452
1453/* additional mixers to alc880_asus_mixer */
1454static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1455	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1456	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1457	{ } /* end */
1458};
1459
1460/* TCL S700 */
1461static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1462	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1463	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1464	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1465	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1466	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1467	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1468	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1469	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1470	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1471	{
1472		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1473		/* The multiple "Capture Source" controls confuse alsamixer
1474		 * So call somewhat different..
1475		 */
1476		/* .name = "Capture Source", */
1477		.name = "Input Source",
1478		.count = 1,
1479		.info = alc_mux_enum_info,
1480		.get = alc_mux_enum_get,
1481		.put = alc_mux_enum_put,
1482	},
1483	{ } /* end */
1484};
1485
1486/* Uniwill */
1487static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1488	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1489	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1490	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1491	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1492	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1493	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1494	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1495	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1496	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1497	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1498	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1499	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1500	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1501	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1502	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1503	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1504	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1505	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1506	{
1507		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1508		.name = "Channel Mode",
1509		.info = alc_ch_mode_info,
1510		.get = alc_ch_mode_get,
1511		.put = alc_ch_mode_put,
1512	},
1513	{ } /* end */
1514};
1515
1516static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1517	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1518	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1519	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1520	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1521	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1522	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1523	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1524	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1525	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1526	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1527	{ } /* end */
1528};
1529
1530static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1531	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1532	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1533	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1534	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1535	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1536	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1537	{ } /* end */
1538};
1539
1540/*
1541 * virtual master controls
1542 */
1543
1544/*
1545 * slave controls for virtual master
1546 */
1547static const char *alc_slave_vols[] = {
1548	"Front Playback Volume",
1549	"Surround Playback Volume",
1550	"Center Playback Volume",
1551	"LFE Playback Volume",
1552	"Side Playback Volume",
1553	"Headphone Playback Volume",
1554	"Speaker Playback Volume",
1555	"Mono Playback Volume",
1556	"Line-Out Playback Volume",
1557	NULL,
1558};
1559
1560static const char *alc_slave_sws[] = {
1561	"Front Playback Switch",
1562	"Surround Playback Switch",
1563	"Center Playback Switch",
1564	"LFE Playback Switch",
1565	"Side Playback Switch",
1566	"Headphone Playback Switch",
1567	"Speaker Playback Switch",
1568	"Mono Playback Switch",
1569	"IEC958 Playback Switch",
1570	NULL,
1571};
1572
1573/*
1574 * build control elements
1575 */
1576static int alc_build_controls(struct hda_codec *codec)
1577{
1578	struct alc_spec *spec = codec->spec;
1579	int err;
1580	int i;
1581
1582	for (i = 0; i < spec->num_mixers; i++) {
1583		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1584		if (err < 0)
1585			return err;
1586	}
1587
1588	if (spec->multiout.dig_out_nid) {
1589		err = snd_hda_create_spdif_out_ctls(codec,
1590						    spec->multiout.dig_out_nid);
1591		if (err < 0)
1592			return err;
1593		err = snd_hda_create_spdif_share_sw(codec,
1594						    &spec->multiout);
1595		if (err < 0)
1596			return err;
1597		spec->multiout.share_spdif = 1;
1598	}
1599	if (spec->dig_in_nid) {
1600		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1601		if (err < 0)
1602			return err;
1603	}
1604
1605	/* if we have no master control, let's create it */
1606	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1607		unsigned int vmaster_tlv[4];
1608		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1609					HDA_OUTPUT, vmaster_tlv);
1610		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1611					  vmaster_tlv, alc_slave_vols);
1612		if (err < 0)
1613			return err;
1614	}
1615	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1616		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1617					  NULL, alc_slave_sws);
1618		if (err < 0)
1619			return err;
1620	}
1621
1622	return 0;
1623}
1624
1625
1626/*
1627 * initialize the codec volumes, etc
1628 */
1629
1630/*
1631 * generic initialization of ADC, input mixers and output mixers
1632 */
1633static struct hda_verb alc880_volume_init_verbs[] = {
1634	/*
1635	 * Unmute ADC0-2 and set the default input to mic-in
1636	 */
1637	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1638	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1639	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1640	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1641	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1642	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1643
1644	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1645	 * mixer widget
1646	 * Note: PASD motherboards uses the Line In 2 as the input for front
1647	 * panel mic (mic 2)
1648	 */
1649	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1650	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1651	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1652	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1653	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1654	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1655	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1656	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1657
1658	/*
1659	 * Set up output mixers (0x0c - 0x0f)
1660	 */
1661	/* set vol=0 to output mixers */
1662	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1663	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1664	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1665	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1666	/* set up input amps for analog loopback */
1667	/* Amp Indices: DAC = 0, mixer = 1 */
1668	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1669	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1670	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1671	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1672	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1673	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1674	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1675	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1676
1677	{ }
1678};
1679
1680/*
1681 * 3-stack pin configuration:
1682 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1683 */
1684static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1685	/*
1686	 * preset connection lists of input pins
1687	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1688	 */
1689	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1690	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1691	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1692
1693	/*
1694	 * Set pin mode and muting
1695	 */
1696	/* set front pin widgets 0x14 for output */
1697	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1698	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1699	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1700	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1701	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1702	/* Mic2 (as headphone out) for HP output */
1703	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1704	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1705	/* Line In pin widget for input */
1706	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1707	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1708	/* Line2 (as front mic) pin widget for input and vref at 80% */
1709	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1710	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1711	/* CD pin widget for input */
1712	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1713
1714	{ }
1715};
1716
1717/*
1718 * 5-stack pin configuration:
1719 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1720 * line-in/side = 0x1a, f-mic = 0x1b
1721 */
1722static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1723	/*
1724	 * preset connection lists of input pins
1725	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1726	 */
1727	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1728	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1729
1730	/*
1731	 * Set pin mode and muting
1732	 */
1733	/* set pin widgets 0x14-0x17 for output */
1734	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1736	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1737	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1738	/* unmute pins for output (no gain on this amp) */
1739	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1740	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1741	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1742	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1743
1744	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1745	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1746	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1747	/* Mic2 (as headphone out) for HP output */
1748	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1749	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1750	/* Line In pin widget for input */
1751	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1752	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1753	/* Line2 (as front mic) pin widget for input and vref at 80% */
1754	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1755	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1756	/* CD pin widget for input */
1757	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1758
1759	{ }
1760};
1761
1762/*
1763 * W810 pin configuration:
1764 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1765 */
1766static struct hda_verb alc880_pin_w810_init_verbs[] = {
1767	/* hphone/speaker input selector: front DAC */
1768	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1769
1770	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1771	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1772	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1773	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1774	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1775	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1776
1777	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1778	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1779
1780	{ }
1781};
1782
1783/*
1784 * Z71V pin configuration:
1785 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1786 */
1787static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1788	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1789	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1790	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1791	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1792
1793	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1794	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1795	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1796	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1797
1798	{ }
1799};
1800
1801/*
1802 * 6-stack pin configuration:
1803 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1804 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1805 */
1806static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1807	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1808
1809	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1810	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1811	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1812	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1813	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1814	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1815	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1816	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1817
1818	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1819	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1820	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1821	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1822	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1823	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1824	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1825	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1826	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1827
1828	{ }
1829};
1830
1831/*
1832 * Uniwill pin configuration:
1833 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1834 * line = 0x1a
1835 */
1836static struct hda_verb alc880_uniwill_init_verbs[] = {
1837	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1838
1839	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1840	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1841	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1842	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1843	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1844	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1845	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1846	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1848	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1849	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1850	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1851	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1852	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1853
1854	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1855	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1856	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1857	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1858	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1859	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1860	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1861	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1862	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1863
1864	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1865	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1866
1867	{ }
1868};
1869
1870/*
1871* Uniwill P53
1872* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1873 */
1874static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1875	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1876
1877	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1878	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1879	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1880	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1881	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1882	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1883	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1884	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1885	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1886	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1887	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1888	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1889
1890	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1891	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1892	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1893	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1894	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1895	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1896
1897	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1898	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1899
1900	{ }
1901};
1902
1903static struct hda_verb alc880_beep_init_verbs[] = {
1904	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1905	{ }
1906};
1907
1908/* toggle speaker-output according to the hp-jack state */
1909static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1910{
1911 	unsigned int present;
1912	unsigned char bits;
1913
1914 	present = snd_hda_codec_read(codec, 0x14, 0,
1915				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1916	bits = present ? HDA_AMP_MUTE : 0;
1917	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1918				 HDA_AMP_MUTE, bits);
1919	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1920				 HDA_AMP_MUTE, bits);
1921}
1922
1923/* auto-toggle front mic */
1924static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1925{
1926 	unsigned int present;
1927	unsigned char bits;
1928
1929	present = snd_hda_codec_read(codec, 0x18, 0,
1930				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1931	bits = present ? HDA_AMP_MUTE : 0;
1932	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1933}
1934
1935static void alc880_uniwill_automute(struct hda_codec *codec)
1936{
1937	alc880_uniwill_hp_automute(codec);
1938	alc880_uniwill_mic_automute(codec);
1939}
1940
1941static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1942				       unsigned int res)
1943{
1944	/* Looks like the unsol event is incompatible with the standard
1945	 * definition.  4bit tag is placed at 28 bit!
1946	 */
1947	switch (res >> 28) {
1948	case ALC880_HP_EVENT:
1949		alc880_uniwill_hp_automute(codec);
1950		break;
1951	case ALC880_MIC_EVENT:
1952		alc880_uniwill_mic_automute(codec);
1953		break;
1954	}
1955}
1956
1957static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1958{
1959 	unsigned int present;
1960	unsigned char bits;
1961
1962 	present = snd_hda_codec_read(codec, 0x14, 0,
1963				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1964	bits = present ? HDA_AMP_MUTE : 0;
1965	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1966}
1967
1968static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1969{
1970	unsigned int present;
1971
1972	present = snd_hda_codec_read(codec, 0x21, 0,
1973				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1974	present &= HDA_AMP_VOLMASK;
1975	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1976				 HDA_AMP_VOLMASK, present);
1977	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1978				 HDA_AMP_VOLMASK, present);
1979}
1980
1981static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1982					   unsigned int res)
1983{
1984	/* Looks like the unsol event is incompatible with the standard
1985	 * definition.  4bit tag is placed at 28 bit!
1986	 */
1987	if ((res >> 28) == ALC880_HP_EVENT)
1988		alc880_uniwill_p53_hp_automute(codec);
1989	if ((res >> 28) == ALC880_DCVOL_EVENT)
1990		alc880_uniwill_p53_dcvol_automute(codec);
1991}
1992
1993/*
1994 * F1734 pin configuration:
1995 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1996 */
1997static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1998	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
1999	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2000	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2001	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2002	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2003
2004	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2005	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2006	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2007	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008
2009	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2010	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2011	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2012	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2013	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2014	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2015	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2016	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2017	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2018
2019	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2020	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2021
2022	{ }
2023};
2024
2025/*
2026 * ASUS pin configuration:
2027 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2028 */
2029static struct hda_verb alc880_pin_asus_init_verbs[] = {
2030	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2031	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2032	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2033	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2034
2035	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2036	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2037	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2038	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2039	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2040	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2041	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2042	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2043
2044	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2045	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2046	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2047	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2048	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2049	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2050	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2051	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2052	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2053
2054	{ }
2055};
2056
2057/* Enable GPIO mask and set output */
2058#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2059#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2060
2061/* Clevo m520g init */
2062static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2063	/* headphone output */
2064	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2065	/* line-out */
2066	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2067	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2068	/* Line-in */
2069	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2070	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2071	/* CD */
2072	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2073	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2074	/* Mic1 (rear panel) */
2075	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2076	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077	/* Mic2 (front panel) */
2078	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2079	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2080	/* headphone */
2081	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2082	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2083        /* change to EAPD mode */
2084	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2085	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2086
2087	{ }
2088};
2089
2090static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2091	/* change to EAPD mode */
2092	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2093	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2094
2095	/* Headphone output */
2096	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2097	/* Front output*/
2098	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2099	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2100
2101	/* Line In pin widget for input */
2102	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2103	/* CD pin widget for input */
2104	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2105	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2106	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2107
2108	/* change to EAPD mode */
2109	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2110	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2111
2112	{ }
2113};
2114
2115/*
2116 * LG m1 express dual
2117 *
2118 * Pin assignment:
2119 *   Rear Line-In/Out (blue): 0x14
2120 *   Build-in Mic-In: 0x15
2121 *   Speaker-out: 0x17
2122 *   HP-Out (green): 0x1b
2123 *   Mic-In/Out (red): 0x19
2124 *   SPDIF-Out: 0x1e
2125 */
2126
2127/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2128static hda_nid_t alc880_lg_dac_nids[3] = {
2129	0x05, 0x02, 0x03
2130};
2131
2132/* seems analog CD is not working */
2133static struct hda_input_mux alc880_lg_capture_source = {
2134	.num_items = 3,
2135	.items = {
2136		{ "Mic", 0x1 },
2137		{ "Line", 0x5 },
2138		{ "Internal Mic", 0x6 },
2139	},
2140};
2141
2142/* 2,4,6 channel modes */
2143static struct hda_verb alc880_lg_ch2_init[] = {
2144	/* set line-in and mic-in to input */
2145	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2146	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2147	{ }
2148};
2149
2150static struct hda_verb alc880_lg_ch4_init[] = {
2151	/* set line-in to out and mic-in to input */
2152	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2153	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2154	{ }
2155};
2156
2157static struct hda_verb alc880_lg_ch6_init[] = {
2158	/* set line-in and mic-in to output */
2159	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2160	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2161	{ }
2162};
2163
2164static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2165	{ 2, alc880_lg_ch2_init },
2166	{ 4, alc880_lg_ch4_init },
2167	{ 6, alc880_lg_ch6_init },
2168};
2169
2170static struct snd_kcontrol_new alc880_lg_mixer[] = {
2171	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2172	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2173	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2174	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2175	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2176	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2177	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2178	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2179	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2180	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2181	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2182	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2183	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2184	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2185	{
2186		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2187		.name = "Channel Mode",
2188		.info = alc_ch_mode_info,
2189		.get = alc_ch_mode_get,
2190		.put = alc_ch_mode_put,
2191	},
2192	{ } /* end */
2193};
2194
2195static struct hda_verb alc880_lg_init_verbs[] = {
2196	/* set capture source to mic-in */
2197	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2198	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2199	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2200	/* mute all amp mixer inputs */
2201	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2202	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2203	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2204	/* line-in to input */
2205	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2206	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2207	/* built-in mic */
2208	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2209	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2210	/* speaker-out */
2211	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2212	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2213	/* mic-in to input */
2214	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2215	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2216	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2217	/* HP-out */
2218	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2219	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2220	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221	/* jack sense */
2222	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2223	{ }
2224};
2225
2226/* toggle speaker-output according to the hp-jack state */
2227static void alc880_lg_automute(struct hda_codec *codec)
2228{
2229	unsigned int present;
2230	unsigned char bits;
2231
2232	present = snd_hda_codec_read(codec, 0x1b, 0,
2233				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2234	bits = present ? HDA_AMP_MUTE : 0;
2235	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2236				 HDA_AMP_MUTE, bits);
2237}
2238
2239static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2240{
2241	/* Looks like the unsol event is incompatible with the standard
2242	 * definition.  4bit tag is placed at 28 bit!
2243	 */
2244	if ((res >> 28) == 0x01)
2245		alc880_lg_automute(codec);
2246}
2247
2248/*
2249 * LG LW20
2250 *
2251 * Pin assignment:
2252 *   Speaker-out: 0x14
2253 *   Mic-In: 0x18
2254 *   Built-in Mic-In: 0x19
2255 *   Line-In: 0x1b
2256 *   HP-Out: 0x1a
2257 *   SPDIF-Out: 0x1e
2258 */
2259
2260static struct hda_input_mux alc880_lg_lw_capture_source = {
2261	.num_items = 3,
2262	.items = {
2263		{ "Mic", 0x0 },
2264		{ "Internal Mic", 0x1 },
2265		{ "Line In", 0x2 },
2266	},
2267};
2268
2269#define alc880_lg_lw_modes alc880_threestack_modes
2270
2271static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2272	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2273	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2274	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2275	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2276	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2277	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2278	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2279	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2280	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2281	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2282	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2283	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2284	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2285	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2286	{
2287		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2288		.name = "Channel Mode",
2289		.info = alc_ch_mode_info,
2290		.get = alc_ch_mode_get,
2291		.put = alc_ch_mode_put,
2292	},
2293	{ } /* end */
2294};
2295
2296static struct hda_verb alc880_lg_lw_init_verbs[] = {
2297	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2298	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2299	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2300
2301	/* set capture source to mic-in */
2302	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2303	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2304	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2305	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2306	/* speaker-out */
2307	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2308	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2309	/* HP-out */
2310	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2311	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2312	/* mic-in to input */
2313	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2314	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2315	/* built-in mic */
2316	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2317	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2318	/* jack sense */
2319	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2320	{ }
2321};
2322
2323/* toggle speaker-output according to the hp-jack state */
2324static void alc880_lg_lw_automute(struct hda_codec *codec)
2325{
2326	unsigned int present;
2327	unsigned char bits;
2328
2329	present = snd_hda_codec_read(codec, 0x1b, 0,
2330				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2331	bits = present ? HDA_AMP_MUTE : 0;
2332	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2333				 HDA_AMP_MUTE, bits);
2334}
2335
2336static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2337{
2338	/* Looks like the unsol event is incompatible with the standard
2339	 * definition.  4bit tag is placed at 28 bit!
2340	 */
2341	if ((res >> 28) == 0x01)
2342		alc880_lg_lw_automute(codec);
2343}
2344
2345static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2346	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2347	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2348	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2349	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2350	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2351	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2352	{ } /* end */
2353};
2354
2355static struct hda_input_mux alc880_medion_rim_capture_source = {
2356	.num_items = 2,
2357	.items = {
2358		{ "Mic", 0x0 },
2359		{ "Internal Mic", 0x1 },
2360	},
2361};
2362
2363static struct hda_verb alc880_medion_rim_init_verbs[] = {
2364	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2365
2366	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2367	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2368
2369	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2370	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2371	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2372	/* Mic2 (as headphone out) for HP output */
2373	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2374	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2375	/* Internal Speaker */
2376	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2377	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2378
2379	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2380	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2381
2382	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2383	{ }
2384};
2385
2386/* toggle speaker-output according to the hp-jack state */
2387static void alc880_medion_rim_automute(struct hda_codec *codec)
2388{
2389	unsigned int present;
2390	unsigned char bits;
2391
2392	present = snd_hda_codec_read(codec, 0x14, 0,
2393				     AC_VERB_GET_PIN_SENSE, 0)
2394		& AC_PINSENSE_PRESENCE;
2395	bits = present ? HDA_AMP_MUTE : 0;
2396	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2397				 HDA_AMP_MUTE, bits);
2398	if (present)
2399		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2400	else
2401		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2402}
2403
2404static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2405					  unsigned int res)
2406{
2407	/* Looks like the unsol event is incompatible with the standard
2408	 * definition.  4bit tag is placed at 28 bit!
2409	 */
2410	if ((res >> 28) == ALC880_HP_EVENT)
2411		alc880_medion_rim_automute(codec);
2412}
2413
2414#ifdef CONFIG_SND_HDA_POWER_SAVE
2415static struct hda_amp_list alc880_loopbacks[] = {
2416	{ 0x0b, HDA_INPUT, 0 },
2417	{ 0x0b, HDA_INPUT, 1 },
2418	{ 0x0b, HDA_INPUT, 2 },
2419	{ 0x0b, HDA_INPUT, 3 },
2420	{ 0x0b, HDA_INPUT, 4 },
2421	{ } /* end */
2422};
2423
2424static struct hda_amp_list alc880_lg_loopbacks[] = {
2425	{ 0x0b, HDA_INPUT, 1 },
2426	{ 0x0b, HDA_INPUT, 6 },
2427	{ 0x0b, HDA_INPUT, 7 },
2428	{ } /* end */
2429};
2430#endif
2431
2432/*
2433 * Common callbacks
2434 */
2435
2436static int alc_init(struct hda_codec *codec)
2437{
2438	struct alc_spec *spec = codec->spec;
2439	unsigned int i;
2440
2441	alc_fix_pll(codec);
2442	if (codec->vendor_id == 0x10ec0888)
2443		alc888_coef_init(codec);
2444
2445	for (i = 0; i < spec->num_init_verbs; i++)
2446		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2447
2448	if (spec->init_hook)
2449		spec->init_hook(codec);
2450
2451	return 0;
2452}
2453
2454static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2455{
2456	struct alc_spec *spec = codec->spec;
2457
2458	if (spec->unsol_event)
2459		spec->unsol_event(codec, res);
2460}
2461
2462#ifdef CONFIG_SND_HDA_POWER_SAVE
2463static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2464{
2465	struct alc_spec *spec = codec->spec;
2466	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2467}
2468#endif
2469
2470/*
2471 * Analog playback callbacks
2472 */
2473static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2474				    struct hda_codec *codec,
2475				    struct snd_pcm_substream *substream)
2476{
2477	struct alc_spec *spec = codec->spec;
2478	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2479					     hinfo);
2480}
2481
2482static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2483				       struct hda_codec *codec,
2484				       unsigned int stream_tag,
2485				       unsigned int format,
2486				       struct snd_pcm_substream *substream)
2487{
2488	struct alc_spec *spec = codec->spec;
2489	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2490						stream_tag, format, substream);
2491}
2492
2493static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2494				       struct hda_codec *codec,
2495				       struct snd_pcm_substream *substream)
2496{
2497	struct alc_spec *spec = codec->spec;
2498	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2499}
2500
2501/*
2502 * Digital out
2503 */
2504static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2505					struct hda_codec *codec,
2506					struct snd_pcm_substream *substream)
2507{
2508	struct alc_spec *spec = codec->spec;
2509	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2510}
2511
2512static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2513					   struct hda_codec *codec,
2514					   unsigned int stream_tag,
2515					   unsigned int format,
2516					   struct snd_pcm_substream *substream)
2517{
2518	struct alc_spec *spec = codec->spec;
2519	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2520					     stream_tag, format, substream);
2521}
2522
2523static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2524					 struct hda_codec *codec,
2525					 struct snd_pcm_substream *substream)
2526{
2527	struct alc_spec *spec = codec->spec;
2528	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2529}
2530
2531/*
2532 * Analog capture
2533 */
2534static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2535				      struct hda_codec *codec,
2536				      unsigned int stream_tag,
2537				      unsigned int format,
2538				      struct snd_pcm_substream *substream)
2539{
2540	struct alc_spec *spec = codec->spec;
2541
2542	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2543				   stream_tag, 0, format);
2544	return 0;
2545}
2546
2547static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2548				      struct hda_codec *codec,
2549				      struct snd_pcm_substream *substream)
2550{
2551	struct alc_spec *spec = codec->spec;
2552
2553	snd_hda_codec_cleanup_stream(codec,
2554				     spec->adc_nids[substream->number + 1]);
2555	return 0;
2556}
2557
2558
2559/*
2560 */
2561static struct hda_pcm_stream alc880_pcm_analog_playback = {
2562	.substreams = 1,
2563	.channels_min = 2,
2564	.channels_max = 8,
2565	/* NID is set in alc_build_pcms */
2566	.ops = {
2567		.open = alc880_playback_pcm_open,
2568		.prepare = alc880_playback_pcm_prepare,
2569		.cleanup = alc880_playback_pcm_cleanup
2570	},
2571};
2572
2573static struct hda_pcm_stream alc880_pcm_analog_capture = {
2574	.substreams = 1,
2575	.channels_min = 2,
2576	.channels_max = 2,
2577	/* NID is set in alc_build_pcms */
2578};
2579
2580static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2581	.substreams = 1,
2582	.channels_min = 2,
2583	.channels_max = 2,
2584	/* NID is set in alc_build_pcms */
2585};
2586
2587static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2588	.substreams = 2, /* can be overridden */
2589	.channels_min = 2,
2590	.channels_max = 2,
2591	/* NID is set in alc_build_pcms */
2592	.ops = {
2593		.prepare = alc880_alt_capture_pcm_prepare,
2594		.cleanup = alc880_alt_capture_pcm_cleanup
2595	},
2596};
2597
2598static struct hda_pcm_stream alc880_pcm_digital_playback = {
2599	.substreams = 1,
2600	.channels_min = 2,
2601	.channels_max = 2,
2602	/* NID is set in alc_build_pcms */
2603	.ops = {
2604		.open = alc880_dig_playback_pcm_open,
2605		.close = alc880_dig_playback_pcm_close,
2606		.prepare = alc880_dig_playback_pcm_prepare
2607	},
2608};
2609
2610static struct hda_pcm_stream alc880_pcm_digital_capture = {
2611	.substreams = 1,
2612	.channels_min = 2,
2613	.channels_max = 2,
2614	/* NID is set in alc_build_pcms */
2615};
2616
2617/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2618static struct hda_pcm_stream alc_pcm_null_stream = {
2619	.substreams = 0,
2620	.channels_min = 0,
2621	.channels_max = 0,
2622};
2623
2624static int alc_build_pcms(struct hda_codec *codec)
2625{
2626	struct alc_spec *spec = codec->spec;
2627	struct hda_pcm *info = spec->pcm_rec;
2628	int i;
2629
2630	codec->num_pcms = 1;
2631	codec->pcm_info = info;
2632
2633	info->name = spec->stream_name_analog;
2634	if (spec->stream_analog_playback) {
2635		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2636		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2637		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2638	}
2639	if (spec->stream_analog_capture) {
2640		snd_assert(spec->adc_nids, return -EINVAL);
2641		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2642		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2643	}
2644
2645	if (spec->channel_mode) {
2646		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2647		for (i = 0; i < spec->num_channel_mode; i++) {
2648			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2649				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2650			}
2651		}
2652	}
2653
2654	/* SPDIF for stream index #1 */
2655	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2656		codec->num_pcms = 2;
2657		info = spec->pcm_rec + 1;
2658		info->name = spec->stream_name_digital;
2659		info->pcm_type = HDA_PCM_TYPE_SPDIF;
2660		if (spec->multiout.dig_out_nid &&
2661		    spec->stream_digital_playback) {
2662			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2663			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2664		}
2665		if (spec->dig_in_nid &&
2666		    spec->stream_digital_capture) {
2667			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2668			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2669		}
2670	}
2671
2672	/* If the use of more than one ADC is requested for the current
2673	 * model, configure a second analog capture-only PCM.
2674	 */
2675	/* Additional Analaog capture for index #2 */
2676	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2677	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2678		codec->num_pcms = 3;
2679		info = spec->pcm_rec + 2;
2680		info->name = spec->stream_name_analog;
2681		if (spec->alt_dac_nid) {
2682			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2683				*spec->stream_analog_alt_playback;
2684			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2685				spec->alt_dac_nid;
2686		} else {
2687			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2688				alc_pcm_null_stream;
2689			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2690		}
2691		if (spec->num_adc_nids > 1) {
2692			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2693				*spec->stream_analog_alt_capture;
2694			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2695				spec->adc_nids[1];
2696			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2697				spec->num_adc_nids - 1;
2698		} else {
2699			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2700				alc_pcm_null_stream;
2701			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2702		}
2703	}
2704
2705	return 0;
2706}
2707
2708static void alc_free(struct hda_codec *codec)
2709{
2710	struct alc_spec *spec = codec->spec;
2711	unsigned int i;
2712
2713	if (!spec)
2714		return;
2715
2716	if (spec->kctl_alloc) {
2717		for (i = 0; i < spec->num_kctl_used; i++)
2718			kfree(spec->kctl_alloc[i].name);
2719		kfree(spec->kctl_alloc);
2720	}
2721	kfree(spec);
2722	codec->spec = NULL; /* to be sure */
2723}
2724
2725/*
2726 */
2727static struct hda_codec_ops alc_patch_ops = {
2728	.build_controls = alc_build_controls,
2729	.build_pcms = alc_build_pcms,
2730	.init = alc_init,
2731	.free = alc_free,
2732	.unsol_event = alc_unsol_event,
2733#ifdef CONFIG_SND_HDA_POWER_SAVE
2734	.check_power_status = alc_check_power_status,
2735#endif
2736};
2737
2738
2739/*
2740 * Test configuration for debugging
2741 *
2742 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2743 * enum controls.
2744 */
2745#ifdef CONFIG_SND_DEBUG
2746static hda_nid_t alc880_test_dac_nids[4] = {
2747	0x02, 0x03, 0x04, 0x05
2748};
2749
2750static struct hda_input_mux alc880_test_capture_source = {
2751	.num_items = 7,
2752	.items = {
2753		{ "In-1", 0x0 },
2754		{ "In-2", 0x1 },
2755		{ "In-3", 0x2 },
2756		{ "In-4", 0x3 },
2757		{ "CD", 0x4 },
2758		{ "Front", 0x5 },
2759		{ "Surround", 0x6 },
2760	},
2761};
2762
2763static struct hda_channel_mode alc880_test_modes[4] = {
2764	{ 2, NULL },
2765	{ 4, NULL },
2766	{ 6, NULL },
2767	{ 8, NULL },
2768};
2769
2770static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2771				 struct snd_ctl_elem_info *uinfo)
2772{
2773	static char *texts[] = {
2774		"N/A", "Line Out", "HP Out",
2775		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2776	};
2777	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2778	uinfo->count = 1;
2779	uinfo->value.enumerated.items = 8;
2780	if (uinfo->value.enumerated.item >= 8)
2781		uinfo->value.enumerated.item = 7;
2782	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2783	return 0;
2784}
2785
2786static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2787				struct snd_ctl_elem_value *ucontrol)
2788{
2789	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2790	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2791	unsigned int pin_ctl, item = 0;
2792
2793	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2794				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2795	if (pin_ctl & AC_PINCTL_OUT_EN) {
2796		if (pin_ctl & AC_PINCTL_HP_EN)
2797			item = 2;
2798		else
2799			item = 1;
2800	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2801		switch (pin_ctl & AC_PINCTL_VREFEN) {
2802		case AC_PINCTL_VREF_HIZ: item = 3; break;
2803		case AC_PINCTL_VREF_50:  item = 4; break;
2804		case AC_PINCTL_VREF_GRD: item = 5; break;
2805		case AC_PINCTL_VREF_80:  item = 6; break;
2806		case AC_PINCTL_VREF_100: item = 7; break;
2807		}
2808	}
2809	ucontrol->value.enumerated.item[0] = item;
2810	return 0;
2811}
2812
2813static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2814				struct snd_ctl_elem_value *ucontrol)
2815{
2816	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2817	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2818	static unsigned int ctls[] = {
2819		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2820		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2821		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2822		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2823		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2824		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2825	};
2826	unsigned int old_ctl, new_ctl;
2827
2828	old_ctl = snd_hda_codec_read(codec, nid, 0,
2829				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2830	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2831	if (old_ctl != new_ctl) {
2832		int val;
2833		snd_hda_codec_write_cache(codec, nid, 0,
2834					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2835					  new_ctl);
2836		val = ucontrol->value.enumerated.item[0] >= 3 ?
2837			HDA_AMP_MUTE : 0;
2838		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2839					 HDA_AMP_MUTE, val);
2840		return 1;
2841	}
2842	return 0;
2843}
2844
2845static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2846				 struct snd_ctl_elem_info *uinfo)
2847{
2848	static char *texts[] = {
2849		"Front", "Surround", "CLFE", "Side"
2850	};
2851	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2852	uinfo->count = 1;
2853	uinfo->value.enumerated.items = 4;
2854	if (uinfo->value.enumerated.item >= 4)
2855		uinfo->value.enumerated.item = 3;
2856	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2857	return 0;
2858}
2859
2860static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2861				struct snd_ctl_elem_value *ucontrol)
2862{
2863	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2864	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2865	unsigned int sel;
2866
2867	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2868	ucontrol->value.enumerated.item[0] = sel & 3;
2869	return 0;
2870}
2871
2872static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2873				struct snd_ctl_elem_value *ucontrol)
2874{
2875	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2876	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2877	unsigned int sel;
2878
2879	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2880	if (ucontrol->value.enumerated.item[0] != sel) {
2881		sel = ucontrol->value.enumerated.item[0] & 3;
2882		snd_hda_codec_write_cache(codec, nid, 0,
2883					  AC_VERB_SET_CONNECT_SEL, sel);
2884		return 1;
2885	}
2886	return 0;
2887}
2888
2889#define PIN_CTL_TEST(xname,nid) {			\
2890		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2891			.name = xname,		       \
2892			.info = alc_test_pin_ctl_info, \
2893			.get = alc_test_pin_ctl_get,   \
2894			.put = alc_test_pin_ctl_put,   \
2895			.private_value = nid	       \
2896			}
2897
2898#define PIN_SRC_TEST(xname,nid) {			\
2899		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2900			.name = xname,		       \
2901			.info = alc_test_pin_src_info, \
2902			.get = alc_test_pin_src_get,   \
2903			.put = alc_test_pin_src_put,   \
2904			.private_value = nid	       \
2905			}
2906
2907static struct snd_kcontrol_new alc880_test_mixer[] = {
2908	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2909	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2910	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2911	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2912	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2913	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2914	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2915	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2916	PIN_CTL_TEST("Front Pin Mode", 0x14),
2917	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2918	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2919	PIN_CTL_TEST("Side Pin Mode", 0x17),
2920	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2921	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2922	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2923	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2924	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2925	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2926	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2927	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2928	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2929	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2930	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2931	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2932	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2933	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2934	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2935	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2936	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2937	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2938	{
2939		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2940		.name = "Channel Mode",
2941		.info = alc_ch_mode_info,
2942		.get = alc_ch_mode_get,
2943		.put = alc_ch_mode_put,
2944	},
2945	{ } /* end */
2946};
2947
2948static struct hda_verb alc880_test_init_verbs[] = {
2949	/* Unmute inputs of 0x0c - 0x0f */
2950	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2951	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2952	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2953	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2954	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2955	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2956	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2957	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2958	/* Vol output for 0x0c-0x0f */
2959	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2960	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2961	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2962	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2963	/* Set output pins 0x14-0x17 */
2964	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2965	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2966	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2967	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2968	/* Unmute output pins 0x14-0x17 */
2969	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2970	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2971	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2972	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2973	/* Set input pins 0x18-0x1c */
2974	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2975	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2976	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2977	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2978	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2979	/* Mute input pins 0x18-0x1b */
2980	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2981	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2982	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2983	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2984	/* ADC set up */
2985	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2986	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2987	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2988	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2989	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2990	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2991	/* Analog input/passthru */
2992	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2993	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2994	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2995	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2996	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2997	{ }
2998};
2999#endif
3000
3001/*
3002 */
3003
3004static const char *alc880_models[ALC880_MODEL_LAST] = {
3005	[ALC880_3ST]		= "3stack",
3006	[ALC880_TCL_S700]	= "tcl",
3007	[ALC880_3ST_DIG]	= "3stack-digout",
3008	[ALC880_CLEVO]		= "clevo",
3009	[ALC880_5ST]		= "5stack",
3010	[ALC880_5ST_DIG]	= "5stack-digout",
3011	[ALC880_W810]		= "w810",
3012	[ALC880_Z71V]		= "z71v",
3013	[ALC880_6ST]		= "6stack",
3014	[ALC880_6ST_DIG]	= "6stack-digout",
3015	[ALC880_ASUS]		= "asus",
3016	[ALC880_ASUS_W1V]	= "asus-w1v",
3017	[ALC880_ASUS_DIG]	= "asus-dig",
3018	[ALC880_ASUS_DIG2]	= "asus-dig2",
3019	[ALC880_UNIWILL_DIG]	= "uniwill",
3020	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3021	[ALC880_FUJITSU]	= "fujitsu",
3022	[ALC880_F1734]		= "F1734",
3023	[ALC880_LG]		= "lg",
3024	[ALC880_LG_LW]		= "lg-lw",
3025	[ALC880_MEDION_RIM]	= "medion",
3026#ifdef CONFIG_SND_DEBUG
3027	[ALC880_TEST]		= "test",
3028#endif
3029	[ALC880_AUTO]		= "auto",
3030};
3031
3032static struct snd_pci_quirk alc880_cfg_tbl[] = {
3033	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3034	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3035	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3036	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3037	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3038	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3039	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3040	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3041	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3042	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3043	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3044	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3045	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3046	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3047	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3048	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3049	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3050	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3051	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3052	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3053	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3054	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3055	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3056	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3057	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3058	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3059	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3060	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3061	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3062	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3063	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3064	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3065	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3066	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3067	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3068	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3069	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3070	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3071	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3072	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3073	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3074	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3075	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3076	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3077	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3078	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3079	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3080	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3081	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3082	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3083	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3084	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3085	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3086	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3087	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3088	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3089	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3090	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3091	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3092	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3093	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3094	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3095	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3096	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3097	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3098	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3099	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3100	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3101	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3102	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3103	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3104	{}
3105};
3106
3107/*
3108 * ALC880 codec presets
3109 */
3110static struct alc_config_preset alc880_presets[] = {
3111	[ALC880_3ST] = {
3112		.mixers = { alc880_three_stack_mixer },
3113		.init_verbs = { alc880_volume_init_verbs,
3114				alc880_pin_3stack_init_verbs },
3115		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3116		.dac_nids = alc880_dac_nids,
3117		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3118		.channel_mode = alc880_threestack_modes,
3119		.need_dac_fix = 1,
3120		.input_mux = &alc880_capture_source,
3121	},
3122	[ALC880_3ST_DIG] = {
3123		.mixers = { alc880_three_stack_mixer },
3124		.init_verbs = { alc880_volume_init_verbs,
3125				alc880_pin_3stack_init_verbs },
3126		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3127		.dac_nids = alc880_dac_nids,
3128		.dig_out_nid = ALC880_DIGOUT_NID,
3129		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3130		.channel_mode = alc880_threestack_modes,
3131		.need_dac_fix = 1,
3132		.input_mux = &alc880_capture_source,
3133	},
3134	[ALC880_TCL_S700] = {
3135		.mixers = { alc880_tcl_s700_mixer },
3136		.init_verbs = { alc880_volume_init_verbs,
3137				alc880_pin_tcl_S700_init_verbs,
3138				alc880_gpio2_init_verbs },
3139		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3140		.dac_nids = alc880_dac_nids,
3141		.hp_nid = 0x03,
3142		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3143		.channel_mode = alc880_2_jack_modes,
3144		.input_mux = &alc880_capture_source,
3145	},
3146	[ALC880_5ST] = {
3147		.mixers = { alc880_three_stack_mixer,
3148			    alc880_five_stack_mixer},
3149		.init_verbs = { alc880_volume_init_verbs,
3150				alc880_pin_5stack_init_verbs },
3151		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3152		.dac_nids = alc880_dac_nids,
3153		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3154		.channel_mode = alc880_fivestack_modes,
3155		.input_mux = &alc880_capture_source,
3156	},
3157	[ALC880_5ST_DIG] = {
3158		.mixers = { alc880_three_stack_mixer,
3159			    alc880_five_stack_mixer },
3160		.init_verbs = { alc880_volume_init_verbs,
3161				alc880_pin_5stack_init_verbs },
3162		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3163		.dac_nids = alc880_dac_nids,
3164		.dig_out_nid = ALC880_DIGOUT_NID,
3165		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3166		.channel_mode = alc880_fivestack_modes,
3167		.input_mux = &alc880_capture_source,
3168	},
3169	[ALC880_6ST] = {
3170		.mixers = { alc880_six_stack_mixer },
3171		.init_verbs = { alc880_volume_init_verbs,
3172				alc880_pin_6stack_init_verbs },
3173		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3174		.dac_nids = alc880_6st_dac_nids,
3175		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3176		.channel_mode = alc880_sixstack_modes,
3177		.input_mux = &alc880_6stack_capture_source,
3178	},
3179	[ALC880_6ST_DIG] = {
3180		.mixers = { alc880_six_stack_mixer },
3181		.init_verbs = { alc880_volume_init_verbs,
3182				alc880_pin_6stack_init_verbs },
3183		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3184		.dac_nids = alc880_6st_dac_nids,
3185		.dig_out_nid = ALC880_DIGOUT_NID,
3186		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3187		.channel_mode = alc880_sixstack_modes,
3188		.input_mux = &alc880_6stack_capture_source,
3189	},
3190	[ALC880_W810] = {
3191		.mixers = { alc880_w810_base_mixer },
3192		.init_verbs = { alc880_volume_init_verbs,
3193				alc880_pin_w810_init_verbs,
3194				alc880_gpio2_init_verbs },
3195		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3196		.dac_nids = alc880_w810_dac_nids,
3197		.dig_out_nid = ALC880_DIGOUT_NID,
3198		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3199		.channel_mode = alc880_w810_modes,
3200		.input_mux = &alc880_capture_source,
3201	},
3202	[ALC880_Z71V] = {
3203		.mixers = { alc880_z71v_mixer },
3204		.init_verbs = { alc880_volume_init_verbs,
3205				alc880_pin_z71v_init_verbs },
3206		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3207		.dac_nids = alc880_z71v_dac_nids,
3208		.dig_out_nid = ALC880_DIGOUT_NID,
3209		.hp_nid = 0x03,
3210		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3211		.channel_mode = alc880_2_jack_modes,
3212		.input_mux = &alc880_capture_source,
3213	},
3214	[ALC880_F1734] = {
3215		.mixers = { alc880_f1734_mixer },
3216		.init_verbs = { alc880_volume_init_verbs,
3217				alc880_pin_f1734_init_verbs },
3218		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3219		.dac_nids = alc880_f1734_dac_nids,
3220		.hp_nid = 0x02,
3221		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3222		.channel_mode = alc880_2_jack_modes,
3223		.input_mux = &alc880_f1734_capture_source,
3224		.unsol_event = alc880_uniwill_p53_unsol_event,
3225		.init_hook = alc880_uniwill_p53_hp_automute,
3226	},
3227	[ALC880_ASUS] = {
3228		.mixers = { alc880_asus_mixer },
3229		.init_verbs = { alc880_volume_init_verbs,
3230				alc880_pin_asus_init_verbs,
3231				alc880_gpio1_init_verbs },
3232		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3233		.dac_nids = alc880_asus_dac_nids,
3234		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3235		.channel_mode = alc880_asus_modes,
3236		.need_dac_fix = 1,
3237		.input_mux = &alc880_capture_source,
3238	},
3239	[ALC880_ASUS_DIG] = {
3240		.mixers = { alc880_asus_mixer },
3241		.init_verbs = { alc880_volume_init_verbs,
3242				alc880_pin_asus_init_verbs,
3243				alc880_gpio1_init_verbs },
3244		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3245		.dac_nids = alc880_asus_dac_nids,
3246		.dig_out_nid = ALC880_DIGOUT_NID,
3247		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3248		.channel_mode = alc880_asus_modes,
3249		.need_dac_fix = 1,
3250		.input_mux = &alc880_capture_source,
3251	},
3252	[ALC880_ASUS_DIG2] = {
3253		.mixers = { alc880_asus_mixer },
3254		.init_verbs = { alc880_volume_init_verbs,
3255				alc880_pin_asus_init_verbs,
3256				alc880_gpio2_init_verbs }, /* use GPIO2 */
3257		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3258		.dac_nids = alc880_asus_dac_nids,
3259		.dig_out_nid = ALC880_DIGOUT_NID,
3260		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3261		.channel_mode = alc880_asus_modes,
3262		.need_dac_fix = 1,
3263		.input_mux = &alc880_capture_source,
3264	},
3265	[ALC880_ASUS_W1V] = {
3266		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3267		.init_verbs = { alc880_volume_init_verbs,
3268				alc880_pin_asus_init_verbs,
3269				alc880_gpio1_init_verbs },
3270		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3271		.dac_nids = alc880_asus_dac_nids,
3272		.dig_out_nid = ALC880_DIGOUT_NID,
3273		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3274		.channel_mode = alc880_asus_modes,
3275		.need_dac_fix = 1,
3276		.input_mux = &alc880_capture_source,
3277	},
3278	[ALC880_UNIWILL_DIG] = {
3279		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3280		.init_verbs = { alc880_volume_init_verbs,
3281				alc880_pin_asus_init_verbs },
3282		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3283		.dac_nids = alc880_asus_dac_nids,
3284		.dig_out_nid = ALC880_DIGOUT_NID,
3285		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3286		.channel_mode = alc880_asus_modes,
3287		.need_dac_fix = 1,
3288		.input_mux = &alc880_capture_source,
3289	},
3290	[ALC880_UNIWILL] = {
3291		.mixers = { alc880_uniwill_mixer },
3292		.init_verbs = { alc880_volume_init_verbs,
3293				alc880_uniwill_init_verbs },
3294		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3295		.dac_nids = alc880_asus_dac_nids,
3296		.dig_out_nid = ALC880_DIGOUT_NID,
3297		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3298		.channel_mode = alc880_threestack_modes,
3299		.need_dac_fix = 1,
3300		.input_mux = &alc880_capture_source,
3301		.unsol_event = alc880_uniwill_unsol_event,
3302		.init_hook = alc880_uniwill_automute,
3303	},
3304	[ALC880_UNIWILL_P53] = {
3305		.mixers = { alc880_uniwill_p53_mixer },
3306		.init_verbs = { alc880_volume_init_verbs,
3307				alc880_uniwill_p53_init_verbs },
3308		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3309		.dac_nids = alc880_asus_dac_nids,
3310		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3311		.channel_mode = alc880_threestack_modes,
3312		.input_mux = &alc880_capture_source,
3313		.unsol_event = alc880_uniwill_p53_unsol_event,
3314		.init_hook = alc880_uniwill_p53_hp_automute,
3315	},
3316	[ALC880_FUJITSU] = {
3317		.mixers = { alc880_fujitsu_mixer,
3318			    alc880_pcbeep_mixer, },
3319		.init_verbs = { alc880_volume_init_verbs,
3320				alc880_uniwill_p53_init_verbs,
3321	       			alc880_beep_init_verbs },
3322		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3323		.dac_nids = alc880_dac_nids,
3324		.dig_out_nid = ALC880_DIGOUT_NID,
3325		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3326		.channel_mode = alc880_2_jack_modes,
3327		.input_mux = &alc880_capture_source,
3328		.unsol_event = alc880_uniwill_p53_unsol_event,
3329		.init_hook = alc880_uniwill_p53_hp_automute,
3330	},
3331	[ALC880_CLEVO] = {
3332		.mixers = { alc880_three_stack_mixer },
3333		.init_verbs = { alc880_volume_init_verbs,
3334				alc880_pin_clevo_init_verbs },
3335		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3336		.dac_nids = alc880_dac_nids,
3337		.hp_nid = 0x03,
3338		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3339		.channel_mode = alc880_threestack_modes,
3340		.need_dac_fix = 1,
3341		.input_mux = &alc880_capture_source,
3342	},
3343	[ALC880_LG] = {
3344		.mixers = { alc880_lg_mixer },
3345		.init_verbs = { alc880_volume_init_verbs,
3346				alc880_lg_init_verbs },
3347		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3348		.dac_nids = alc880_lg_dac_nids,
3349		.dig_out_nid = ALC880_DIGOUT_NID,
3350		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3351		.channel_mode = alc880_lg_ch_modes,
3352		.need_dac_fix = 1,
3353		.input_mux = &alc880_lg_capture_source,
3354		.unsol_event = alc880_lg_unsol_event,
3355		.init_hook = alc880_lg_automute,
3356#ifdef CONFIG_SND_HDA_POWER_SAVE
3357		.loopbacks = alc880_lg_loopbacks,
3358#endif
3359	},
3360	[ALC880_LG_LW] = {
3361		.mixers = { alc880_lg_lw_mixer },
3362		.init_verbs = { alc880_volume_init_verbs,
3363				alc880_lg_lw_init_verbs },
3364		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3365		.dac_nids = alc880_dac_nids,
3366		.dig_out_nid = ALC880_DIGOUT_NID,
3367		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3368		.channel_mode = alc880_lg_lw_modes,
3369		.input_mux = &alc880_lg_lw_capture_source,
3370		.unsol_event = alc880_lg_lw_unsol_event,
3371		.init_hook = alc880_lg_lw_automute,
3372	},
3373	[ALC880_MEDION_RIM] = {
3374		.mixers = { alc880_medion_rim_mixer },
3375		.init_verbs = { alc880_volume_init_verbs,
3376				alc880_medion_rim_init_verbs,
3377				alc_gpio2_init_verbs },
3378		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3379		.dac_nids = alc880_dac_nids,
3380		.dig_out_nid = ALC880_DIGOUT_NID,
3381		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3382		.channel_mode = alc880_2_jack_modes,
3383		.input_mux = &alc880_medion_rim_capture_source,
3384		.unsol_event = alc880_medion_rim_unsol_event,
3385		.init_hook = alc880_medion_rim_automute,
3386	},
3387#ifdef CONFIG_SND_DEBUG
3388	[ALC880_TEST] = {
3389		.mixers = { alc880_test_mixer },
3390		.init_verbs = { alc880_test_init_verbs },
3391		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3392		.dac_nids = alc880_test_dac_nids,
3393		.dig_out_nid = ALC880_DIGOUT_NID,
3394		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3395		.channel_mode = alc880_test_modes,
3396		.input_mux = &alc880_test_capture_source,
3397	},
3398#endif
3399};
3400
3401/*
3402 * Automatic parse of I/O pins from the BIOS configuration
3403 */
3404
3405#define NUM_CONTROL_ALLOC	32
3406#define NUM_VERB_ALLOC		32
3407
3408enum {
3409	ALC_CTL_WIDGET_VOL,
3410	ALC_CTL_WIDGET_MUTE,
3411	ALC_CTL_BIND_MUTE,
3412};
3413static struct snd_kcontrol_new alc880_control_templates[] = {
3414	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3415	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3416	HDA_BIND_MUTE(NULL, 0, 0, 0),
3417};
3418
3419/* add dynamic controls */
3420static int add_control(struct alc_spec *spec, int type, const char *name,
3421		       unsigned long val)
3422{
3423	struct snd_kcontrol_new *knew;
3424
3425	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3426		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3427
3428		/* array + terminator */
3429		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3430		if (!knew)
3431			return -ENOMEM;
3432		if (spec->kctl_alloc) {
3433			memcpy(knew, spec->kctl_alloc,
3434			       sizeof(*knew) * spec->num_kctl_alloc);
3435			kfree(spec->kctl_alloc);
3436		}
3437		spec->kctl_alloc = knew;
3438		spec->num_kctl_alloc = num;
3439	}
3440
3441	knew = &spec->kctl_alloc[spec->num_kctl_used];
3442	*knew = alc880_control_templates[type];
3443	knew->name = kstrdup(name, GFP_KERNEL);
3444	if (!knew->name)
3445		return -ENOMEM;
3446	knew->private_value = val;
3447	spec->num_kctl_used++;
3448	return 0;
3449}
3450
3451#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3452#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3453#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3454#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3455#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3456#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3457#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3458#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3459#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3460#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3461#define ALC880_PIN_CD_NID		0x1c
3462
3463/* fill in the dac_nids table from the parsed pin configuration */
3464static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3465				     const struct auto_pin_cfg *cfg)
3466{
3467	hda_nid_t nid;
3468	int assigned[4];
3469	int i, j;
3470
3471	memset(assigned, 0, sizeof(assigned));
3472	spec->multiout.dac_nids = spec->private_dac_nids;
3473
3474	/* check the pins hardwired to audio widget */
3475	for (i = 0; i < cfg->line_outs; i++) {
3476		nid = cfg->line_out_pins[i];
3477		if (alc880_is_fixed_pin(nid)) {
3478			int idx = alc880_fixed_pin_idx(nid);
3479			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3480			assigned[idx] = 1;
3481		}
3482	}
3483	/* left pins can be connect to any audio widget */
3484	for (i = 0; i < cfg->line_outs; i++) {
3485		nid = cfg->line_out_pins[i];
3486		if (alc880_is_fixed_pin(nid))
3487			continue;
3488		/* search for an empty channel */
3489		for (j = 0; j < cfg->line_outs; j++) {
3490			if (!assigned[j]) {
3491				spec->multiout.dac_nids[i] =
3492					alc880_idx_to_dac(j);
3493				assigned[j] = 1;
3494				break;
3495			}
3496		}
3497	}
3498	spec->multiout.num_dacs = cfg->line_outs;
3499	return 0;
3500}
3501
3502/* add playback controls from the parsed DAC table */
3503static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3504					     const struct auto_pin_cfg *cfg)
3505{
3506	char name[32];
3507	static const char *chname[4] = {
3508		"Front", "Surround", NULL /*CLFE*/, "Side"
3509	};
3510	hda_nid_t nid;
3511	int i, err;
3512
3513	for (i = 0; i < cfg->line_outs; i++) {
3514		if (!spec->multiout.dac_nids[i])
3515			continue;
3516		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3517		if (i == 2) {
3518			/* Center/LFE */
3519			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3520					  "Center Playback Volume",
3521					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3522							      HDA_OUTPUT));
3523			if (err < 0)
3524				return err;
3525			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3526					  "LFE Playback Volume",
3527					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3528							      HDA_OUTPUT));
3529			if (err < 0)
3530				return err;
3531			err = add_control(spec, ALC_CTL_BIND_MUTE,
3532					  "Center Playback Switch",
3533					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3534							      HDA_INPUT));
3535			if (err < 0)
3536				return err;
3537			err = add_control(spec, ALC_CTL_BIND_MUTE,
3538					  "LFE Playback Switch",
3539					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3540							      HDA_INPUT));
3541			if (err < 0)
3542				return err;
3543		} else {
3544			sprintf(name, "%s Playback Volume", chname[i]);
3545			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3546					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3547							      HDA_OUTPUT));
3548			if (err < 0)
3549				return err;
3550			sprintf(name, "%s Playback Switch", chname[i]);
3551			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3552					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3553							      HDA_INPUT));
3554			if (err < 0)
3555				return err;
3556		}
3557	}
3558	return 0;
3559}
3560
3561/* add playback controls for speaker and HP outputs */
3562static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3563					const char *pfx)
3564{
3565	hda_nid_t nid;
3566	int err;
3567	char name[32];
3568
3569	if (!pin)
3570		return 0;
3571
3572	if (alc880_is_fixed_pin(pin)) {
3573		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3574		/* specify the DAC as the extra output */
3575		if (!spec->multiout.hp_nid)
3576			spec->multiout.hp_nid = nid;
3577		else
3578			spec->multiout.extra_out_nid[0] = nid;
3579		/* control HP volume/switch on the output mixer amp */
3580		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3581		sprintf(name, "%s Playback Volume", pfx);
3582		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3583				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3584		if (err < 0)
3585			return err;
3586		sprintf(name, "%s Playback Switch", pfx);
3587		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3588				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3589		if (err < 0)
3590			return err;
3591	} else if (alc880_is_multi_pin(pin)) {
3592		/* set manual connection */
3593		/* we have only a switch on HP-out PIN */
3594		sprintf(name, "%s Playback Switch", pfx);
3595		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3596				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3597		if (err < 0)
3598			return err;
3599	}
3600	return 0;
3601}
3602
3603/* create input playback/capture controls for the given pin */
3604static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3605			    const char *ctlname,
3606			    int idx, hda_nid_t mix_nid)
3607{
3608	char name[32];
3609	int err;
3610
3611	sprintf(name, "%s Playback Volume", ctlname);
3612	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3613			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3614	if (err < 0)
3615		return err;
3616	sprintf(name, "%s Playback Switch", ctlname);
3617	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3618			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3619	if (err < 0)
3620		return err;
3621	return 0;
3622}
3623
3624/* create playback/capture controls for input pins */
3625static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3626						const struct auto_pin_cfg *cfg)
3627{
3628	struct hda_input_mux *imux = &spec->private_imux;
3629	int i, err, idx;
3630
3631	for (i = 0; i < AUTO_PIN_LAST; i++) {
3632		if (alc880_is_input_pin(cfg->input_pins[i])) {
3633			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3634			err = new_analog_input(spec, cfg->input_pins[i],
3635					       auto_pin_cfg_labels[i],
3636					       idx, 0x0b);
3637			if (err < 0)
3638				return err;
3639			imux->items[imux->num_items].label =
3640				auto_pin_cfg_labels[i];
3641			imux->items[imux->num_items].index =
3642				alc880_input_pin_idx(cfg->input_pins[i]);
3643			imux->num_items++;
3644		}
3645	}
3646	return 0;
3647}
3648
3649static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3650			       unsigned int pin_type)
3651{
3652	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3653			    pin_type);
3654	/* unmute pin */
3655	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3656			    AMP_OUT_UNMUTE);
3657}
3658
3659static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3660					      hda_nid_t nid, int pin_type,
3661					      int dac_idx)
3662{
3663	alc_set_pin_output(codec, nid, pin_type);
3664	/* need the manual connection? */
3665	if (alc880_is_multi_pin(nid)) {
3666		struct alc_spec *spec = codec->spec;
3667		int idx = alc880_multi_pin_idx(nid);
3668		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3669				    AC_VERB_SET_CONNECT_SEL,
3670				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3671	}
3672}
3673
3674static int get_pin_type(int line_out_type)
3675{
3676	if (line_out_type == AUTO_PIN_HP_OUT)
3677		return PIN_HP;
3678	else
3679		return PIN_OUT;
3680}
3681
3682static void alc880_auto_init_multi_out(struct hda_codec *codec)
3683{
3684	struct alc_spec *spec = codec->spec;
3685	int i;
3686
3687	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3688	for (i = 0; i < spec->autocfg.line_outs; i++) {
3689		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3690		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3691		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3692	}
3693}
3694
3695static void alc880_auto_init_extra_out(struct hda_codec *codec)
3696{
3697	struct alc_spec *spec = codec->spec;
3698	hda_nid_t pin;
3699
3700	pin = spec->autocfg.speaker_pins[0];
3701	if (pin) /* connect to front */
3702		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3703	pin = spec->autocfg.hp_pins[0];
3704	if (pin) /* connect to front */
3705		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3706}
3707
3708static void alc880_auto_init_analog_input(struct hda_codec *codec)
3709{
3710	struct alc_spec *spec = codec->spec;
3711	int i;
3712
3713	for (i = 0; i < AUTO_PIN_LAST; i++) {
3714		hda_nid_t nid = spec->autocfg.input_pins[i];
3715		if (alc880_is_input_pin(nid)) {
3716			snd_hda_codec_write(codec, nid, 0,
3717					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3718					    i <= AUTO_PIN_FRONT_MIC ?
3719					    PIN_VREF80 : PIN_IN);
3720			if (nid != ALC880_PIN_CD_NID)
3721				snd_hda_codec_write(codec, nid, 0,
3722						    AC_VERB_SET_AMP_GAIN_MUTE,
3723						    AMP_OUT_MUTE);
3724		}
3725	}
3726}
3727
3728/* parse the BIOS configuration and set up the alc_spec */
3729/* return 1 if successful, 0 if the proper config is not found,
3730 * or a negative error code
3731 */
3732static int alc880_parse_auto_config(struct hda_codec *codec)
3733{
3734	struct alc_spec *spec = codec->spec;
3735	int err;
3736	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3737
3738	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3739					   alc880_ignore);
3740	if (err < 0)
3741		return err;
3742	if (!spec->autocfg.line_outs)
3743		return 0; /* can't find valid BIOS pin config */
3744
3745	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3746	if (err < 0)
3747		return err;
3748	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3749	if (err < 0)
3750		return err;
3751	err = alc880_auto_create_extra_out(spec,
3752					   spec->autocfg.speaker_pins[0],
3753					   "Speaker");
3754	if (err < 0)
3755		return err;
3756	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3757					   "Headphone");
3758	if (err < 0)
3759		return err;
3760	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3761	if (err < 0)
3762		return err;
3763
3764	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3765
3766	if (spec->autocfg.dig_out_pin)
3767		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3768	if (spec->autocfg.dig_in_pin)
3769		spec->dig_in_nid = ALC880_DIGIN_NID;
3770
3771	if (spec->kctl_alloc)
3772		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3773
3774	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3775
3776	spec->num_mux_defs = 1;
3777	spec->input_mux = &spec->private_imux;
3778
3779	return 1;
3780}
3781
3782/* additional initialization for auto-configuration model */
3783static void alc880_auto_init(struct hda_codec *codec)
3784{
3785	struct alc_spec *spec = codec->spec;
3786	alc880_auto_init_multi_out(codec);
3787	alc880_auto_init_extra_out(codec);
3788	alc880_auto_init_analog_input(codec);
3789	if (spec->unsol_event)
3790		alc_sku_automute(codec);
3791}
3792
3793/*
3794 * OK, here we have finally the patch for ALC880
3795 */
3796
3797static int patch_alc880(struct hda_codec *codec)
3798{
3799	struct alc_spec *spec;
3800	int board_config;
3801	int err;
3802
3803	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3804	if (spec == NULL)
3805		return -ENOMEM;
3806
3807	codec->spec = spec;
3808
3809	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3810						  alc880_models,
3811						  alc880_cfg_tbl);
3812	if (board_config < 0) {
3813		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3814		       "trying auto-probe from BIOS...\n");
3815		board_config = ALC880_AUTO;
3816	}
3817
3818	if (board_config == ALC880_AUTO) {
3819		/* automatic parse from the BIOS config */
3820		err = alc880_parse_auto_config(codec);
3821		if (err < 0) {
3822			alc_free(codec);
3823			return err;
3824		} else if (!err) {
3825			printk(KERN_INFO
3826			       "hda_codec: Cannot set up configuration "
3827			       "from BIOS.  Using 3-stack mode...\n");
3828			board_config = ALC880_3ST;
3829		}
3830	}
3831
3832	if (board_config != ALC880_AUTO)
3833		setup_preset(spec, &alc880_presets[board_config]);
3834
3835	spec->stream_name_analog = "ALC880 Analog";
3836	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3837	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3838	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3839
3840	spec->stream_name_digital = "ALC880 Digital";
3841	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3842	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3843
3844	if (!spec->adc_nids && spec->input_mux) {
3845		/* check whether NID 0x07 is valid */
3846		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3847		/* get type */
3848		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3849		if (wcap != AC_WID_AUD_IN) {
3850			spec->adc_nids = alc880_adc_nids_alt;
3851			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3852			spec->mixers[spec->num_mixers] =
3853				alc880_capture_alt_mixer;
3854			spec->num_mixers++;
3855		} else {
3856			spec->adc_nids = alc880_adc_nids;
3857			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3858			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3859			spec->num_mixers++;
3860		}
3861	}
3862
3863	spec->vmaster_nid = 0x0c;
3864
3865	codec->patch_ops = alc_patch_ops;
3866	if (board_config == ALC880_AUTO)
3867		spec->init_hook = alc880_auto_init;
3868#ifdef CONFIG_SND_HDA_POWER_SAVE
3869	if (!spec->loopback.amplist)
3870		spec->loopback.amplist = alc880_loopbacks;
3871#endif
3872
3873	return 0;
3874}
3875
3876
3877/*
3878 * ALC260 support
3879 */
3880
3881static hda_nid_t alc260_dac_nids[1] = {
3882	/* front */
3883	0x02,
3884};
3885
3886static hda_nid_t alc260_adc_nids[1] = {
3887	/* ADC0 */
3888	0x04,
3889};
3890
3891static hda_nid_t alc260_adc_nids_alt[1] = {
3892	/* ADC1 */
3893	0x05,
3894};
3895
3896static hda_nid_t alc260_hp_adc_nids[2] = {
3897	/* ADC1, 0 */
3898	0x05, 0x04
3899};
3900
3901/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3902 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3903 */
3904static hda_nid_t alc260_dual_adc_nids[2] = {
3905	/* ADC0, ADC1 */
3906	0x04, 0x05
3907};
3908
3909#define ALC260_DIGOUT_NID	0x03
3910#define ALC260_DIGIN_NID	0x06
3911
3912static struct hda_input_mux alc260_capture_source = {
3913	.num_items = 4,
3914	.items = {
3915		{ "Mic", 0x0 },
3916		{ "Front Mic", 0x1 },
3917		{ "Line", 0x2 },
3918		{ "CD", 0x4 },
3919	},
3920};
3921
3922/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3923 * headphone jack and the internal CD lines since these are the only pins at
3924 * which audio can appear.  For flexibility, also allow the option of
3925 * recording the mixer output on the second ADC (ADC0 doesn't have a
3926 * connection to the mixer output).
3927 */
3928static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3929	{
3930		.num_items = 3,
3931		.items = {
3932			{ "Mic/Line", 0x0 },
3933			{ "CD", 0x4 },
3934			{ "Headphone", 0x2 },
3935		},
3936	},
3937	{
3938		.num_items = 4,
3939		.items = {
3940			{ "Mic/Line", 0x0 },
3941			{ "CD", 0x4 },
3942			{ "Headphone", 0x2 },
3943			{ "Mixer", 0x5 },
3944		},
3945	},
3946
3947};
3948
3949/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3950 * the Fujitsu S702x, but jacks are marked differently.
3951 */
3952static struct hda_input_mux alc260_acer_capture_sources[2] = {
3953	{
3954		.num_items = 4,
3955		.items = {
3956			{ "Mic", 0x0 },
3957			{ "Line", 0x2 },
3958			{ "CD", 0x4 },
3959			{ "Headphone", 0x5 },
3960		},
3961	},
3962	{
3963		.num_items = 5,
3964		.items = {
3965			{ "Mic", 0x0 },
3966			{ "Line", 0x2 },
3967			{ "CD", 0x4 },
3968			{ "Headphone", 0x6 },
3969			{ "Mixer", 0x5 },
3970		},
3971	},
3972};
3973/*
3974 * This is just place-holder, so there's something for alc_build_pcms to look
3975 * at when it calculates the maximum number of channels. ALC260 has no mixer
3976 * element which allows changing the channel mode, so the verb list is
3977 * never used.
3978 */
3979static struct hda_channel_mode alc260_modes[1] = {
3980	{ 2, NULL },
3981};
3982
3983
3984/* Mixer combinations
3985 *
3986 * basic: base_output + input + pc_beep + capture
3987 * HP: base_output + input + capture_alt
3988 * HP_3013: hp_3013 + input + capture
3989 * fujitsu: fujitsu + capture
3990 * acer: acer + capture
3991 */
3992
3993static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3994	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3995	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3996	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3997	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3998	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3999	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4000	{ } /* end */
4001};
4002
4003static struct snd_kcontrol_new alc260_input_mixer[] = {
4004	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4005	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4006	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4007	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4008	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4009	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4010	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4011	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4012	{ } /* end */
4013};
4014
4015static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4016	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4017	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4018	{ } /* end */
4019};
4020
4021/* update HP, line and mono out pins according to the master switch */
4022static void alc260_hp_master_update(struct hda_codec *codec,
4023				    hda_nid_t hp, hda_nid_t line,
4024				    hda_nid_t mono)
4025{
4026	struct alc_spec *spec = codec->spec;
4027	unsigned int val = spec->master_sw ? PIN_HP : 0;
4028	/* change HP and line-out pins */
4029	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4030			    val);
4031	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4032			    val);
4033	/* mono (speaker) depending on the HP jack sense */
4034	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4035	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4036			    val);
4037}
4038
4039static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4040				   struct snd_ctl_elem_value *ucontrol)
4041{
4042	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4043	struct alc_spec *spec = codec->spec;
4044	*ucontrol->value.integer.value = spec->master_sw;
4045	return 0;
4046}
4047
4048static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4049				   struct snd_ctl_elem_value *ucontrol)
4050{
4051	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4052	struct alc_spec *spec = codec->spec;
4053	int val = !!*ucontrol->value.integer.value;
4054	hda_nid_t hp, line, mono;
4055
4056	if (val == spec->master_sw)
4057		return 0;
4058	spec->master_sw = val;
4059	hp = (kcontrol->private_value >> 16) & 0xff;
4060	line = (kcontrol->private_value >> 8) & 0xff;
4061	mono = kcontrol->private_value & 0xff;
4062	alc260_hp_master_update(codec, hp, line, mono);
4063	return 1;
4064}
4065
4066static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4067	{
4068		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4069		.name = "Master Playback Switch",
4070		.info = snd_ctl_boolean_mono_info,
4071		.get = alc260_hp_master_sw_get,
4072		.put = alc260_hp_master_sw_put,
4073		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4074	},
4075	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4076	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4077	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4078	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4079	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4080			      HDA_OUTPUT),
4081	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4082	{ } /* end */
4083};
4084
4085static struct hda_verb alc260_hp_unsol_verbs[] = {
4086	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4087	{},
4088};
4089
4090static void alc260_hp_automute(struct hda_codec *codec)
4091{
4092	struct alc_spec *spec = codec->spec;
4093	unsigned int present;
4094
4095	present = snd_hda_codec_read(codec, 0x10, 0,
4096				     AC_VERB_GET_PIN_SENSE, 0);
4097	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4098	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4099}
4100
4101static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4102{
4103	if ((res >> 26) == ALC880_HP_EVENT)
4104		alc260_hp_automute(codec);
4105}
4106
4107static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4108	{
4109		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4110		.name = "Master Playback Switch",
4111		.info = snd_ctl_boolean_mono_info,
4112		.get = alc260_hp_master_sw_get,
4113		.put = alc260_hp_master_sw_put,
4114		.private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4115	},
4116	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4117	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4118	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4119	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4120	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4121	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4122	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4123	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4124	{ } /* end */
4125};
4126
4127static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4128	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4129	{},
4130};
4131
4132static void alc260_hp_3013_automute(struct hda_codec *codec)
4133{
4134	struct alc_spec *spec = codec->spec;
4135	unsigned int present;
4136
4137	present = snd_hda_codec_read(codec, 0x15, 0,
4138				     AC_VERB_GET_PIN_SENSE, 0);
4139	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4140	alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4141}
4142
4143static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4144				       unsigned int res)
4145{
4146	if ((res >> 26) == ALC880_HP_EVENT)
4147		alc260_hp_3013_automute(codec);
4148}
4149
4150/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4151 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4152 */
4153static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4154	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4155	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4156	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4157	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4158	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4159	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4160	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4161	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4162	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4163	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4164	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4165	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4166	{ } /* end */
4167};
4168
4169/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4170 * versions of the ALC260 don't act on requests to enable mic bias from NID
4171 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4172 * datasheet doesn't mention this restriction.  At this stage it's not clear
4173 * whether this behaviour is intentional or is a hardware bug in chip
4174 * revisions available in early 2006.  Therefore for now allow the
4175 * "Headphone Jack Mode" control to span all choices, but if it turns out
4176 * that the lack of mic bias for this NID is intentional we could change the
4177 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4178 *
4179 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4180 * don't appear to make the mic bias available from the "line" jack, even
4181 * though the NID used for this jack (0x14) can supply it.  The theory is
4182 * that perhaps Acer have included blocking capacitors between the ALC260
4183 * and the output jack.  If this turns out to be the case for all such
4184 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4185 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4186 *
4187 * The C20x Tablet series have a mono internal speaker which is controlled
4188 * via the chip's Mono sum widget and pin complex, so include the necessary
4189 * controls for such models.  On models without a "mono speaker" the control
4190 * won't do anything.
4191 */
4192static struct snd_kcontrol_new alc260_acer_mixer[] = {
4193	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4194	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4195	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4196	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4197			      HDA_OUTPUT),
4198	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4199			   HDA_INPUT),
4200	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4201	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4202	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4203	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4204	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4205	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4206	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4207	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4208	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4209	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4210	{ } /* end */
4211};
4212
4213/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4214 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4215 */
4216static struct snd_kcontrol_new alc260_will_mixer[] = {
4217	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4218	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4219	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4220	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4221	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4222	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4223	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4224	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4225	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4226	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4227	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4228	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4229	{ } /* end */
4230};
4231
4232/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4233 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4234 */
4235static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4236	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4237	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4238	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4239	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4240	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4241	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4242	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4243	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4244	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4245	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4246	{ } /* end */
4247};
4248
4249/* capture mixer elements */
4250static struct snd_kcontrol_new alc260_capture_mixer[] = {
4251	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4252	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4253	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4254	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4255	{
4256		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4257		/* The multiple "Capture Source" controls confuse alsamixer
4258		 * So call somewhat different..
4259		 */
4260		/* .name = "Capture Source", */
4261		.name = "Input Source",
4262		.count = 2,
4263		.info = alc_mux_enum_info,
4264		.get = alc_mux_enum_get,
4265		.put = alc_mux_enum_put,
4266	},
4267	{ } /* end */
4268};
4269
4270static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4271	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4272	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4273	{
4274		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4275		/* The multiple "Capture Source" controls confuse alsamixer
4276		 * So call somewhat different..
4277		 */
4278		/* .name = "Capture Source", */
4279		.name = "Input Source",
4280		.count = 1,
4281		.info = alc_mux_enum_info,
4282		.get = alc_mux_enum_get,
4283		.put = alc_mux_enum_put,
4284	},
4285	{ } /* end */
4286};
4287
4288/*
4289 * initialization verbs
4290 */
4291static struct hda_verb alc260_init_verbs[] = {
4292	/* Line In pin widget for input */
4293	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4294	/* CD pin widget for input */
4295	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4296	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4297	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4298	/* Mic2 (front panel) pin widget for input and vref at 80% */
4299	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4300	/* LINE-2 is used for line-out in rear */
4301	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4302	/* select line-out */
4303	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4304	/* LINE-OUT pin */
4305	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4306	/* enable HP */
4307	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4308	/* enable Mono */
4309	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4310	/* mute capture amp left and right */
4311	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4312	/* set connection select to line in (default select for this ADC) */
4313	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4314	/* mute capture amp left and right */
4315	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4316	/* set connection select to line in (default select for this ADC) */
4317	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4318	/* set vol=0 Line-Out mixer amp left and right */
4319	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4320	/* unmute pin widget amp left and right (no gain on this amp) */
4321	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4322	/* set vol=0 HP mixer amp left and right */
4323	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4324	/* unmute pin widget amp left and right (no gain on this amp) */
4325	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4326	/* set vol=0 Mono mixer amp left and right */
4327	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4328	/* unmute pin widget amp left and right (no gain on this amp) */
4329	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4330	/* unmute LINE-2 out pin */
4331	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4332	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4333	 * Line In 2 = 0x03
4334	 */
4335	/* mute analog inputs */
4336	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4337	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4338	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4339	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4340	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4341	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4342	/* mute Front out path */
4343	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4344	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4345	/* mute Headphone out path */
4346	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4347	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4348	/* mute Mono out path */
4349	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4350	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4351	{ }
4352};
4353
4354#if 0 /* should be identical with alc260_init_verbs? */
4355static struct hda_verb alc260_hp_init_verbs[] = {
4356	/* Headphone and output */
4357	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4358	/* mono output */
4359	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4360	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4361	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4362	/* Mic2 (front panel) pin widget for input and vref at 80% */
4363	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4364	/* Line In pin widget for input */
4365	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4366	/* Line-2 pin widget for output */
4367	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4368	/* CD pin widget for input */
4369	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4370	/* unmute amp left and right */
4371	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4372	/* set connection select to line in (default select for this ADC) */
4373	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4374	/* unmute Line-Out mixer amp left and right (volume = 0) */
4375	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4376	/* mute pin widget amp left and right (no gain on this amp) */
4377	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4378	/* unmute HP mixer amp left and right (volume = 0) */
4379	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4380	/* mute pin widget amp left and right (no gain on this amp) */
4381	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4382	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4383	 * Line In 2 = 0x03
4384	 */
4385	/* mute analog inputs */
4386	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4387	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4388	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4389	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4390	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4391	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4392	/* Unmute Front out path */
4393	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4394	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4395	/* Unmute Headphone out path */
4396	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4397	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4398	/* Unmute Mono out path */
4399	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4400	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4401	{ }
4402};
4403#endif
4404
4405static struct hda_verb alc260_hp_3013_init_verbs[] = {
4406	/* Line out and output */
4407	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4408	/* mono output */
4409	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4410	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4411	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4412	/* Mic2 (front panel) pin widget for input and vref at 80% */
4413	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4414	/* Line In pin widget for input */
4415	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4416	/* Headphone pin widget for output */
4417	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4418	/* CD pin widget for input */
4419	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4420	/* unmute amp left and right */
4421	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4422	/* set connection select to line in (default select for this ADC) */
4423	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4424	/* unmute Line-Out mixer amp left and right (volume = 0) */
4425	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4426	/* mute pin widget amp left and right (no gain on this amp) */
4427	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4428	/* unmute HP mixer amp left and right (volume = 0) */
4429	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4430	/* mute pin widget amp left and right (no gain on this amp) */
4431	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4432	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4433	 * Line In 2 = 0x03
4434	 */
4435	/* mute analog inputs */
4436	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4437	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4438	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4439	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4440	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4441	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4442	/* Unmute Front out path */
4443	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4444	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4445	/* Unmute Headphone out path */
4446	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4447	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4448	/* Unmute Mono out path */
4449	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4450	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4451	{ }
4452};
4453
4454/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4455 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4456 * audio = 0x16, internal speaker = 0x10.
4457 */
4458static struct hda_verb alc260_fujitsu_init_verbs[] = {
4459	/* Disable all GPIOs */
4460	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4461	/* Internal speaker is connected to headphone pin */
4462	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4463	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4464	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4465	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4466	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4467	/* Ensure all other unused pins are disabled and muted. */
4468	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4469	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4470	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4471	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4472	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4473	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4474	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4475	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4476
4477	/* Disable digital (SPDIF) pins */
4478	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4479	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4480
4481	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4482	 * when acting as an output.
4483	 */
4484	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4485
4486	/* Start with output sum widgets muted and their output gains at min */
4487	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4488	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4489	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4490	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4491	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4492	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4493	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4494	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4495	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4496
4497	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4498	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4499	/* Unmute Line1 pin widget output buffer since it starts as an output.
4500	 * If the pin mode is changed by the user the pin mode control will
4501	 * take care of enabling the pin's input/output buffers as needed.
4502	 * Therefore there's no need to enable the input buffer at this
4503	 * stage.
4504	 */
4505	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4506	/* Unmute input buffer of pin widget used for Line-in (no equiv
4507	 * mixer ctrl)
4508	 */
4509	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4510
4511	/* Mute capture amp left and right */
4512	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4513	/* Set ADC connection select to match default mixer setting - line
4514	 * in (on mic1 pin)
4515	 */
4516	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4517
4518	/* Do the same for the second ADC: mute capture input amp and
4519	 * set ADC connection to line in (on mic1 pin)
4520	 */
4521	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4522	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4523
4524	/* Mute all inputs to mixer widget (even unconnected ones) */
4525	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4526	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4527	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4528	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4529	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4530	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4531	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4532	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4533
4534	{ }
4535};
4536
4537/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4538 * similar laptops (adapted from Fujitsu init verbs).
4539 */
4540static struct hda_verb alc260_acer_init_verbs[] = {
4541	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4542	 * the headphone jack.  Turn this on and rely on the standard mute
4543	 * methods whenever the user wants to turn these outputs off.
4544	 */
4545	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4546	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4547	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4548	/* Internal speaker/Headphone jack is connected to Line-out pin */
4549	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4550	/* Internal microphone/Mic jack is connected to Mic1 pin */
4551	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4552	/* Line In jack is connected to Line1 pin */
4553	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4554	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4555	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4556	/* Ensure all other unused pins are disabled and muted. */
4557	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4558	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4559	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4560	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4561	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4562	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4563	/* Disable digital (SPDIF) pins */
4564	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4565	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4566
4567	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4568	 * bus when acting as outputs.
4569	 */
4570	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4571	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4572
4573	/* Start with output sum widgets muted and their output gains at min */
4574	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4575	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4576	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4577	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4578	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4579	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4580	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4581	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4582	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4583
4584	/* Unmute Line-out pin widget amp left and right
4585	 * (no equiv mixer ctrl)
4586	 */
4587	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4588	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4589	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4590	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4591	 * inputs. If the pin mode is changed by the user the pin mode control
4592	 * will take care of enabling the pin's input/output buffers as needed.
4593	 * Therefore there's no need to enable the input buffer at this
4594	 * stage.
4595	 */
4596	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4597	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4598
4599	/* Mute capture amp left and right */
4600	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4601	/* Set ADC connection select to match default mixer setting - mic
4602	 * (on mic1 pin)
4603	 */
4604	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4605
4606	/* Do similar with the second ADC: mute capture input amp and
4607	 * set ADC connection to mic to match ALSA's default state.
4608	 */
4609	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4610	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4611
4612	/* Mute all inputs to mixer widget (even unconnected ones) */
4613	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4614	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4615	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4616	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4617	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4618	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4619	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4620	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4621
4622	{ }
4623};
4624
4625static struct hda_verb alc260_will_verbs[] = {
4626	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4627	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4628	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4629	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4630	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4631	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4632	{}
4633};
4634
4635static struct hda_verb alc260_replacer_672v_verbs[] = {
4636	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4637	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4638	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4639
4640	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4641	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4642	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4643
4644	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4645	{}
4646};
4647
4648/* toggle speaker-output according to the hp-jack state */
4649static void alc260_replacer_672v_automute(struct hda_codec *codec)
4650{
4651        unsigned int present;
4652
4653	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4654        present = snd_hda_codec_read(codec, 0x0f, 0,
4655                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4656	if (present) {
4657		snd_hda_codec_write_cache(codec, 0x01, 0,
4658					  AC_VERB_SET_GPIO_DATA, 1);
4659		snd_hda_codec_write_cache(codec, 0x0f, 0,
4660					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4661					  PIN_HP);
4662	} else {
4663		snd_hda_codec_write_cache(codec, 0x01, 0,
4664					  AC_VERB_SET_GPIO_DATA, 0);
4665		snd_hda_codec_write_cache(codec, 0x0f, 0,
4666					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4667					  PIN_OUT);
4668	}
4669}
4670
4671static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4672                                       unsigned int res)
4673{
4674        if ((res >> 26) == ALC880_HP_EVENT)
4675                alc260_replacer_672v_automute(codec);
4676}
4677
4678/* Test configuration for debugging, modelled after the ALC880 test
4679 * configuration.
4680 */
4681#ifdef CONFIG_SND_DEBUG
4682static hda_nid_t alc260_test_dac_nids[1] = {
4683	0x02,
4684};
4685static hda_nid_t alc260_test_adc_nids[2] = {
4686	0x04, 0x05,
4687};
4688/* For testing the ALC260, each input MUX needs its own definition since
4689 * the signal assignments are different.  This assumes that the first ADC
4690 * is NID 0x04.
4691 */
4692static struct hda_input_mux alc260_test_capture_sources[2] = {
4693	{
4694		.num_items = 7,
4695		.items = {
4696			{ "MIC1 pin", 0x0 },
4697			{ "MIC2 pin", 0x1 },
4698			{ "LINE1 pin", 0x2 },
4699			{ "LINE2 pin", 0x3 },
4700			{ "CD pin", 0x4 },
4701			{ "LINE-OUT pin", 0x5 },
4702			{ "HP-OUT pin", 0x6 },
4703		},
4704        },
4705	{
4706		.num_items = 8,
4707		.items = {
4708			{ "MIC1 pin", 0x0 },
4709			{ "MIC2 pin", 0x1 },
4710			{ "LINE1 pin", 0x2 },
4711			{ "LINE2 pin", 0x3 },
4712			{ "CD pin", 0x4 },
4713			{ "Mixer", 0x5 },
4714			{ "LINE-OUT pin", 0x6 },
4715			{ "HP-OUT pin", 0x7 },
4716		},
4717        },
4718};
4719static struct snd_kcontrol_new alc260_test_mixer[] = {
4720	/* Output driver widgets */
4721	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4722	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4723	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4724	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4725	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4726	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4727
4728	/* Modes for retasking pin widgets
4729	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4730         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4731         * mention this restriction.  At this stage it's not clear whether
4732         * this behaviour is intentional or is a hardware bug in chip
4733         * revisions available at least up until early 2006.  Therefore for
4734         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4735         * choices, but if it turns out that the lack of mic bias for these
4736         * NIDs is intentional we could change their modes from
4737         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4738	 */
4739	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4740	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4741	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4742	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4743	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4744	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4745
4746	/* Loopback mixer controls */
4747	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4748	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4749	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4750	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4751	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4752	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4753	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4754	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4755	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4756	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4757	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4758	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4759	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4760	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4761	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4762	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4763
4764	/* Controls for GPIO pins, assuming they are configured as outputs */
4765	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4766	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4767	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4768	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4769
4770	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4771	 * is ambigious as to which NID is which; testing on laptops which
4772	 * make this output available should provide clarification.
4773	 */
4774	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4775	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4776
4777	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
4778	 * this output to turn on an external amplifier.
4779	 */
4780	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4781	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4782
4783	{ } /* end */
4784};
4785static struct hda_verb alc260_test_init_verbs[] = {
4786	/* Enable all GPIOs as outputs with an initial value of 0 */
4787	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4788	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4789	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4790
4791	/* Enable retasking pins as output, initially without power amp */
4792	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4793	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4794	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4795	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4796	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4797	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4798
4799	/* Disable digital (SPDIF) pins initially, but users can enable
4800	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4801	 * payload also sets the generation to 0, output to be in "consumer"
4802	 * PCM format, copyright asserted, no pre-emphasis and no validity
4803	 * control.
4804	 */
4805	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4806	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4807
4808	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4809	 * OUT1 sum bus when acting as an output.
4810	 */
4811	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4812	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4813	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4814	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4815
4816	/* Start with output sum widgets muted and their output gains at min */
4817	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4818	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4819	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4820	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4821	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4822	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4823	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4824	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4825	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4826
4827	/* Unmute retasking pin widget output buffers since the default
4828	 * state appears to be output.  As the pin mode is changed by the
4829	 * user the pin mode control will take care of enabling the pin's
4830	 * input/output buffers as needed.
4831	 */
4832	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4833	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4834	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4835	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4836	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4837	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4838	/* Also unmute the mono-out pin widget */
4839	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4840
4841	/* Mute capture amp left and right */
4842	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4843	/* Set ADC connection select to match default mixer setting (mic1
4844	 * pin)
4845	 */
4846	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4847
4848	/* Do the same for the second ADC: mute capture input amp and
4849	 * set ADC connection to mic1 pin
4850	 */
4851	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4852	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4853
4854	/* Mute all inputs to mixer widget (even unconnected ones) */
4855	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4856	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4857	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4858	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4859	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4860	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4861	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4862	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4863
4864	{ }
4865};
4866#endif
4867
4868#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
4869#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
4870
4871#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4872#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4873
4874/*
4875 * for BIOS auto-configuration
4876 */
4877
4878static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4879					const char *pfx)
4880{
4881	hda_nid_t nid_vol;
4882	unsigned long vol_val, sw_val;
4883	char name[32];
4884	int err;
4885
4886	if (nid >= 0x0f && nid < 0x11) {
4887		nid_vol = nid - 0x7;
4888		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4889		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4890	} else if (nid == 0x11) {
4891		nid_vol = nid - 0x7;
4892		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4893		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4894	} else if (nid >= 0x12 && nid <= 0x15) {
4895		nid_vol = 0x08;
4896		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4897		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4898	} else
4899		return 0; /* N/A */
4900
4901	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4902	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4903	if (err < 0)
4904		return err;
4905	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4906	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4907	if (err < 0)
4908		return err;
4909	return 1;
4910}
4911
4912/* add playback controls from the parsed DAC table */
4913static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4914					     const struct auto_pin_cfg *cfg)
4915{
4916	hda_nid_t nid;
4917	int err;
4918
4919	spec->multiout.num_dacs = 1;
4920	spec->multiout.dac_nids = spec->private_dac_nids;
4921	spec->multiout.dac_nids[0] = 0x02;
4922
4923	nid = cfg->line_out_pins[0];
4924	if (nid) {
4925		err = alc260_add_playback_controls(spec, nid, "Front");
4926		if (err < 0)
4927			return err;
4928	}
4929
4930	nid = cfg->speaker_pins[0];
4931	if (nid) {
4932		err = alc260_add_playback_controls(spec, nid, "Speaker");
4933		if (err < 0)
4934			return err;
4935	}
4936
4937	nid = cfg->hp_pins[0];
4938	if (nid) {
4939		err = alc260_add_playback_controls(spec, nid, "Headphone");
4940		if (err < 0)
4941			return err;
4942	}
4943	return 0;
4944}
4945
4946/* create playback/capture controls for input pins */
4947static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4948						const struct auto_pin_cfg *cfg)
4949{
4950	struct hda_input_mux *imux = &spec->private_imux;
4951	int i, err, idx;
4952
4953	for (i = 0; i < AUTO_PIN_LAST; i++) {
4954		if (cfg->input_pins[i] >= 0x12) {
4955			idx = cfg->input_pins[i] - 0x12;
4956			err = new_analog_input(spec, cfg->input_pins[i],
4957					       auto_pin_cfg_labels[i], idx,
4958					       0x07);
4959			if (err < 0)
4960				return err;
4961			imux->items[imux->num_items].label =
4962				auto_pin_cfg_labels[i];
4963			imux->items[imux->num_items].index = idx;
4964			imux->num_items++;
4965		}
4966		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4967			idx = cfg->input_pins[i] - 0x09;
4968			err = new_analog_input(spec, cfg->input_pins[i],
4969					       auto_pin_cfg_labels[i], idx,
4970					       0x07);
4971			if (err < 0)
4972				return err;
4973			imux->items[imux->num_items].label =
4974				auto_pin_cfg_labels[i];
4975			imux->items[imux->num_items].index = idx;
4976			imux->num_items++;
4977		}
4978	}
4979	return 0;
4980}
4981
4982static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4983					      hda_nid_t nid, int pin_type,
4984					      int sel_idx)
4985{
4986	alc_set_pin_output(codec, nid, pin_type);
4987	/* need the manual connection? */
4988	if (nid >= 0x12) {
4989		int idx = nid - 0x12;
4990		snd_hda_codec_write(codec, idx + 0x0b, 0,
4991				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4992	}
4993}
4994
4995static void alc260_auto_init_multi_out(struct hda_codec *codec)
4996{
4997	struct alc_spec *spec = codec->spec;
4998	hda_nid_t nid;
4999
5000	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5001	nid = spec->autocfg.line_out_pins[0];
5002	if (nid) {
5003		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5004		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5005	}
5006
5007	nid = spec->autocfg.speaker_pins[0];
5008	if (nid)
5009		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5010
5011	nid = spec->autocfg.hp_pins[0];
5012	if (nid)
5013		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5014}
5015
5016#define ALC260_PIN_CD_NID		0x16
5017static void alc260_auto_init_analog_input(struct hda_codec *codec)
5018{
5019	struct alc_spec *spec = codec->spec;
5020	int i;
5021
5022	for (i = 0; i < AUTO_PIN_LAST; i++) {
5023		hda_nid_t nid = spec->autocfg.input_pins[i];
5024		if (nid >= 0x12) {
5025			snd_hda_codec_write(codec, nid, 0,
5026					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5027					    i <= AUTO_PIN_FRONT_MIC ?
5028					    PIN_VREF80 : PIN_IN);
5029			if (nid != ALC260_PIN_CD_NID)
5030				snd_hda_codec_write(codec, nid, 0,
5031						    AC_VERB_SET_AMP_GAIN_MUTE,
5032						    AMP_OUT_MUTE);
5033		}
5034	}
5035}
5036
5037/*
5038 * generic initialization of ADC, input mixers and output mixers
5039 */
5040static struct hda_verb alc260_volume_init_verbs[] = {
5041	/*
5042	 * Unmute ADC0-1 and set the default input to mic-in
5043	 */
5044	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5045	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5046	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5047	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5048
5049	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5050	 * mixer widget
5051	 * Note: PASD motherboards uses the Line In 2 as the input for
5052	 * front panel mic (mic 2)
5053	 */
5054	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5055	/* mute analog inputs */
5056	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5057	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5058	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5059	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5060	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5061
5062	/*
5063	 * Set up output mixers (0x08 - 0x0a)
5064	 */
5065	/* set vol=0 to output mixers */
5066	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5067	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5068	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5069	/* set up input amps for analog loopback */
5070	/* Amp Indices: DAC = 0, mixer = 1 */
5071	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5072	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5073	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5074	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5075	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5076	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5077
5078	{ }
5079};
5080
5081static int alc260_parse_auto_config(struct hda_codec *codec)
5082{
5083	struct alc_spec *spec = codec->spec;
5084	unsigned int wcap;
5085	int err;
5086	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5087
5088	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5089					   alc260_ignore);
5090	if (err < 0)
5091		return err;
5092	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5093	if (err < 0)
5094		return err;
5095	if (!spec->kctl_alloc)
5096		return 0; /* can't find valid BIOS pin config */
5097	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5098	if (err < 0)
5099		return err;
5100
5101	spec->multiout.max_channels = 2;
5102
5103	if (spec->autocfg.dig_out_pin)
5104		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5105	if (spec->kctl_alloc)
5106		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5107
5108	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5109
5110	spec->num_mux_defs = 1;
5111	spec->input_mux = &spec->private_imux;
5112
5113	/* check whether NID 0x04 is valid */
5114	wcap = get_wcaps(codec, 0x04);
5115	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5116	if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5117		spec->adc_nids = alc260_adc_nids_alt;
5118		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5119		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5120	} else {
5121		spec->adc_nids = alc260_adc_nids;
5122		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5123		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5124	}
5125	spec->num_mixers++;
5126
5127	return 1;
5128}
5129
5130/* additional initialization for auto-configuration model */
5131static void alc260_auto_init(struct hda_codec *codec)
5132{
5133	struct alc_spec *spec = codec->spec;
5134	alc260_auto_init_multi_out(codec);
5135	alc260_auto_init_analog_input(codec);
5136	if (spec->unsol_event)
5137		alc_sku_automute(codec);
5138}
5139
5140#ifdef CONFIG_SND_HDA_POWER_SAVE
5141static struct hda_amp_list alc260_loopbacks[] = {
5142	{ 0x07, HDA_INPUT, 0 },
5143	{ 0x07, HDA_INPUT, 1 },
5144	{ 0x07, HDA_INPUT, 2 },
5145	{ 0x07, HDA_INPUT, 3 },
5146	{ 0x07, HDA_INPUT, 4 },
5147	{ } /* end */
5148};
5149#endif
5150
5151/*
5152 * ALC260 configurations
5153 */
5154static const char *alc260_models[ALC260_MODEL_LAST] = {
5155	[ALC260_BASIC]		= "basic",
5156	[ALC260_HP]		= "hp",
5157	[ALC260_HP_3013]	= "hp-3013",
5158	[ALC260_FUJITSU_S702X]	= "fujitsu",
5159	[ALC260_ACER]		= "acer",
5160	[ALC260_WILL]		= "will",
5161	[ALC260_REPLACER_672V]	= "replacer",
5162#ifdef CONFIG_SND_DEBUG
5163	[ALC260_TEST]		= "test",
5164#endif
5165	[ALC260_AUTO]		= "auto",
5166};
5167
5168static struct snd_pci_quirk alc260_cfg_tbl[] = {
5169	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5170	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5171	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5172	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5173	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5174	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5175	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5176	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5177	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5178	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5179	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5180	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5181	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5182	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5183	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5184	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5185	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5186	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5187	{}
5188};
5189
5190static struct alc_config_preset alc260_presets[] = {
5191	[ALC260_BASIC] = {
5192		.mixers = { alc260_base_output_mixer,
5193			    alc260_input_mixer,
5194			    alc260_pc_beep_mixer,
5195			    alc260_capture_mixer },
5196		.init_verbs = { alc260_init_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		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5202		.channel_mode = alc260_modes,
5203		.input_mux = &alc260_capture_source,
5204	},
5205	[ALC260_HP] = {
5206		.mixers = { alc260_hp_output_mixer,
5207			    alc260_input_mixer,
5208			    alc260_capture_alt_mixer },
5209		.init_verbs = { alc260_init_verbs,
5210				alc260_hp_unsol_verbs },
5211		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5212		.dac_nids = alc260_dac_nids,
5213		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5214		.adc_nids = alc260_hp_adc_nids,
5215		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5216		.channel_mode = alc260_modes,
5217		.input_mux = &alc260_capture_source,
5218		.unsol_event = alc260_hp_unsol_event,
5219		.init_hook = alc260_hp_automute,
5220	},
5221	[ALC260_HP_3013] = {
5222		.mixers = { alc260_hp_3013_mixer,
5223			    alc260_input_mixer,
5224			    alc260_capture_alt_mixer },
5225		.init_verbs = { alc260_hp_3013_init_verbs,
5226				alc260_hp_3013_unsol_verbs },
5227		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5228		.dac_nids = alc260_dac_nids,
5229		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5230		.adc_nids = alc260_hp_adc_nids,
5231		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5232		.channel_mode = alc260_modes,
5233		.input_mux = &alc260_capture_source,
5234		.unsol_event = alc260_hp_3013_unsol_event,
5235		.init_hook = alc260_hp_3013_automute,
5236	},
5237	[ALC260_FUJITSU_S702X] = {
5238		.mixers = { alc260_fujitsu_mixer,
5239			    alc260_capture_mixer },
5240		.init_verbs = { alc260_fujitsu_init_verbs },
5241		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5242		.dac_nids = alc260_dac_nids,
5243		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5244		.adc_nids = alc260_dual_adc_nids,
5245		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5246		.channel_mode = alc260_modes,
5247		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5248		.input_mux = alc260_fujitsu_capture_sources,
5249	},
5250	[ALC260_ACER] = {
5251		.mixers = { alc260_acer_mixer,
5252			    alc260_capture_mixer },
5253		.init_verbs = { alc260_acer_init_verbs },
5254		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5255		.dac_nids = alc260_dac_nids,
5256		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5257		.adc_nids = alc260_dual_adc_nids,
5258		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5259		.channel_mode = alc260_modes,
5260		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5261		.input_mux = alc260_acer_capture_sources,
5262	},
5263	[ALC260_WILL] = {
5264		.mixers = { alc260_will_mixer,
5265			    alc260_capture_mixer },
5266		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5267		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5268		.dac_nids = alc260_dac_nids,
5269		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5270		.adc_nids = alc260_adc_nids,
5271		.dig_out_nid = ALC260_DIGOUT_NID,
5272		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5273		.channel_mode = alc260_modes,
5274		.input_mux = &alc260_capture_source,
5275	},
5276	[ALC260_REPLACER_672V] = {
5277		.mixers = { alc260_replacer_672v_mixer,
5278			    alc260_capture_mixer },
5279		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5280		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5281		.dac_nids = alc260_dac_nids,
5282		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5283		.adc_nids = alc260_adc_nids,
5284		.dig_out_nid = ALC260_DIGOUT_NID,
5285		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5286		.channel_mode = alc260_modes,
5287		.input_mux = &alc260_capture_source,
5288		.unsol_event = alc260_replacer_672v_unsol_event,
5289		.init_hook = alc260_replacer_672v_automute,
5290	},
5291#ifdef CONFIG_SND_DEBUG
5292	[ALC260_TEST] = {
5293		.mixers = { alc260_test_mixer,
5294			    alc260_capture_mixer },
5295		.init_verbs = { alc260_test_init_verbs },
5296		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5297		.dac_nids = alc260_test_dac_nids,
5298		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5299		.adc_nids = alc260_test_adc_nids,
5300		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5301		.channel_mode = alc260_modes,
5302		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5303		.input_mux = alc260_test_capture_sources,
5304	},
5305#endif
5306};
5307
5308static int patch_alc260(struct hda_codec *codec)
5309{
5310	struct alc_spec *spec;
5311	int err, board_config;
5312
5313	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5314	if (spec == NULL)
5315		return -ENOMEM;
5316
5317	codec->spec = spec;
5318
5319	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5320						  alc260_models,
5321						  alc260_cfg_tbl);
5322	if (board_config < 0) {
5323		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5324			   "trying auto-probe from BIOS...\n");
5325		board_config = ALC260_AUTO;
5326	}
5327
5328	if (board_config == ALC260_AUTO) {
5329		/* automatic parse from the BIOS config */
5330		err = alc260_parse_auto_config(codec);
5331		if (err < 0) {
5332			alc_free(codec);
5333			return err;
5334		} else if (!err) {
5335			printk(KERN_INFO
5336			       "hda_codec: Cannot set up configuration "
5337			       "from BIOS.  Using base mode...\n");
5338			board_config = ALC260_BASIC;
5339		}
5340	}
5341
5342	if (board_config != ALC260_AUTO)
5343		setup_preset(spec, &alc260_presets[board_config]);
5344
5345	spec->stream_name_analog = "ALC260 Analog";
5346	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5347	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5348
5349	spec->stream_name_digital = "ALC260 Digital";
5350	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5351	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5352
5353	spec->vmaster_nid = 0x08;
5354
5355	codec->patch_ops = alc_patch_ops;
5356	if (board_config == ALC260_AUTO)
5357		spec->init_hook = alc260_auto_init;
5358#ifdef CONFIG_SND_HDA_POWER_SAVE
5359	if (!spec->loopback.amplist)
5360		spec->loopback.amplist = alc260_loopbacks;
5361#endif
5362
5363	return 0;
5364}
5365
5366
5367/*
5368 * ALC882 support
5369 *
5370 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5371 * configuration.  Each pin widget can choose any input DACs and a mixer.
5372 * Each ADC is connected from a mixer of all inputs.  This makes possible
5373 * 6-channel independent captures.
5374 *
5375 * In addition, an independent DAC for the multi-playback (not used in this
5376 * driver yet).
5377 */
5378#define ALC882_DIGOUT_NID	0x06
5379#define ALC882_DIGIN_NID	0x0a
5380
5381static struct hda_channel_mode alc882_ch_modes[1] = {
5382	{ 8, NULL }
5383};
5384
5385static hda_nid_t alc882_dac_nids[4] = {
5386	/* front, rear, clfe, rear_surr */
5387	0x02, 0x03, 0x04, 0x05
5388};
5389
5390/* identical with ALC880 */
5391#define alc882_adc_nids		alc880_adc_nids
5392#define alc882_adc_nids_alt	alc880_adc_nids_alt
5393
5394static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5395static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5396
5397/* input MUX */
5398/* FIXME: should be a matrix-type input source selection */
5399
5400static struct hda_input_mux alc882_capture_source = {
5401	.num_items = 4,
5402	.items = {
5403		{ "Mic", 0x0 },
5404		{ "Front Mic", 0x1 },
5405		{ "Line", 0x2 },
5406		{ "CD", 0x4 },
5407	},
5408};
5409#define alc882_mux_enum_info alc_mux_enum_info
5410#define alc882_mux_enum_get alc_mux_enum_get
5411
5412static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5413			       struct snd_ctl_elem_value *ucontrol)
5414{
5415	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5416	struct alc_spec *spec = codec->spec;
5417	const struct hda_input_mux *imux = spec->input_mux;
5418	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5419	hda_nid_t nid = spec->capsrc_nids ?
5420		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5421	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5422	unsigned int i, idx;
5423
5424	idx = ucontrol->value.enumerated.item[0];
5425	if (idx >= imux->num_items)
5426		idx = imux->num_items - 1;
5427	if (*cur_val == idx)
5428		return 0;
5429	for (i = 0; i < imux->num_items; i++) {
5430		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5431		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5432					 imux->items[i].index,
5433					 HDA_AMP_MUTE, v);
5434	}
5435	*cur_val = idx;
5436	return 1;
5437}
5438
5439/*
5440 * 2ch mode
5441 */
5442static struct hda_verb alc882_3ST_ch2_init[] = {
5443	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5444	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5445	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5446	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5447	{ } /* end */
5448};
5449
5450/*
5451 * 6ch mode
5452 */
5453static struct hda_verb alc882_3ST_ch6_init[] = {
5454	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5455	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5456	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5457	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5458	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5459	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5460	{ } /* end */
5461};
5462
5463static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5464	{ 2, alc882_3ST_ch2_init },
5465	{ 6, alc882_3ST_ch6_init },
5466};
5467
5468/*
5469 * 6ch mode
5470 */
5471static struct hda_verb alc882_sixstack_ch6_init[] = {
5472	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5473	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5474	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5475	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5476	{ } /* end */
5477};
5478
5479/*
5480 * 8ch mode
5481 */
5482static struct hda_verb alc882_sixstack_ch8_init[] = {
5483	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5484	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5485	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5486	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5487	{ } /* end */
5488};
5489
5490static struct hda_channel_mode alc882_sixstack_modes[2] = {
5491	{ 6, alc882_sixstack_ch6_init },
5492	{ 8, alc882_sixstack_ch8_init },
5493};
5494
5495/*
5496 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5497 */
5498
5499/*
5500 * 2ch mode
5501 */
5502static struct hda_verb alc885_mbp_ch2_init[] = {
5503	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5504	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5505	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5506	{ } /* end */
5507};
5508
5509/*
5510 * 6ch mode
5511 */
5512static struct hda_verb alc885_mbp_ch6_init[] = {
5513	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5514	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5515	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5516	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5517	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5518	{ } /* end */
5519};
5520
5521static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5522	{ 2, alc885_mbp_ch2_init },
5523	{ 6, alc885_mbp_ch6_init },
5524};
5525
5526
5527/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5528 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5529 */
5530static struct snd_kcontrol_new alc882_base_mixer[] = {
5531	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5532	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5533	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5534	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5535	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5536	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5537	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5538	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5539	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5540	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5541	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5542	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5543	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5544	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5545	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5546	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5547	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5548	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5549	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5550	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5551	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5552	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5553	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5554	{ } /* end */
5555};
5556
5557static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5558	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5559	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5560	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5561	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5562	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5563	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5564	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5565	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5566	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5567	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5568	{ } /* end */
5569};
5570static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5571	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5572	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5573	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5574	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5575	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5576	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5577	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5578	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5579	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5580	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5581	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5582	{ } /* end */
5583};
5584
5585static struct snd_kcontrol_new alc882_targa_mixer[] = {
5586	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5587	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5588	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5589	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5590	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5591	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5592	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5593	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5594	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5595	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5596	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5597	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5598	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5599	{ } /* end */
5600};
5601
5602/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5603 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5604 */
5605static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5606	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5607	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5608	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5609	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5610	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5611	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5612	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5613	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5614	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5615	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5616	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5617	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5618	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5619	{ } /* end */
5620};
5621
5622static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5623	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5624	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5625	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5626	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5627	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5628	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5629	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5630	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5631	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5632	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5633	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5634	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5635	{ } /* end */
5636};
5637
5638static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5639	{
5640		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5641		.name = "Channel Mode",
5642		.info = alc_ch_mode_info,
5643		.get = alc_ch_mode_get,
5644		.put = alc_ch_mode_put,
5645	},
5646	{ } /* end */
5647};
5648
5649static struct hda_verb alc882_init_verbs[] = {
5650	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5651	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5652	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5653	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5654	/* Rear mixer */
5655	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5656	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5657	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5658	/* CLFE mixer */
5659	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5660	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5661	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5662	/* Side mixer */
5663	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5664	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5665	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5666
5667	/* Front Pin: output 0 (0x0c) */
5668	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5669	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5670	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5671	/* Rear Pin: output 1 (0x0d) */
5672	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5673	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5674	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5675	/* CLFE Pin: output 2 (0x0e) */
5676	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5677	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5678	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5679	/* Side Pin: output 3 (0x0f) */
5680	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5681	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5682	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5683	/* Mic (rear) pin: input vref at 80% */
5684	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5685	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5686	/* Front Mic pin: input vref at 80% */
5687	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5688	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5689	/* Line In pin: input */
5690	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5691	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5692	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5693	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5694	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5695	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5696	/* CD pin widget for input */
5697	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
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
5729static struct hda_verb alc882_eapd_verbs[] = {
5730	/* change to EAPD mode */
5731	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5732	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5733	{ }
5734};
5735
5736/* Mac Pro test */
5737static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5738	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5739	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5740	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5741	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5742	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5743	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5744	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5745	{ } /* end */
5746};
5747
5748static struct hda_verb alc882_macpro_init_verbs[] = {
5749	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5750	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5751	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5752	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5753	/* Front Pin: output 0 (0x0c) */
5754	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5755	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5756	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5757	/* Front Mic pin: input vref at 80% */
5758	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5759	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5760	/* Speaker:  output */
5761	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5762	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5763	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5764	/* Headphone output (output 0 - 0x0c) */
5765	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5766	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5767	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5768
5769	/* FIXME: use matrix-type input source selection */
5770	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5771	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5772	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5773	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5774	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5775	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5776	/* Input mixer2 */
5777	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5778	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5779	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5780	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5781	/* Input mixer3 */
5782	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5783	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5784	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5785	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5786	/* ADC1: mute amp left and right */
5787	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5788	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5789	/* ADC2: mute amp left and right */
5790	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5791	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5792	/* ADC3: mute amp left and right */
5793	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5794	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5795
5796	{ }
5797};
5798
5799/* Macbook Pro rev3 */
5800static struct hda_verb alc885_mbp3_init_verbs[] = {
5801	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5802	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5803	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5804	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5805	/* Rear mixer */
5806	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5807	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5808	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5809	/* Front Pin: output 0 (0x0c) */
5810	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5811	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5812	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5813	/* HP Pin: output 0 (0x0d) */
5814	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5815	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5816	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5817	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5818	/* Mic (rear) pin: input vref at 80% */
5819	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5820	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5821	/* Front Mic pin: input vref at 80% */
5822	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5823	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5824	/* Line In pin: use output 1 when in LineOut mode */
5825	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5826	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5827	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5828
5829	/* FIXME: use matrix-type input source selection */
5830	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5831	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5832	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5833	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5834	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5835	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5836	/* Input mixer2 */
5837	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5838	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5839	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5840	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5841	/* Input mixer3 */
5842	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5843	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5844	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5845	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5846	/* ADC1: mute amp left and right */
5847	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5848	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5849	/* ADC2: mute amp left and right */
5850	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5851	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5852	/* ADC3: mute amp left and right */
5853	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5854	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5855
5856	{ }
5857};
5858
5859/* iMac 24 mixer. */
5860static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5861	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5862	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5863	{ } /* end */
5864};
5865
5866/* iMac 24 init verbs. */
5867static struct hda_verb alc885_imac24_init_verbs[] = {
5868	/* Internal speakers: output 0 (0x0c) */
5869	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5870	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5871	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5872	/* Internal speakers: output 0 (0x0c) */
5873	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5874	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5875	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5876	/* Headphone: output 0 (0x0c) */
5877	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5878	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5879	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5880	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5881	/* Front Mic: input vref at 80% */
5882	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5883	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5884	{ }
5885};
5886
5887/* Toggle speaker-output according to the hp-jack state */
5888static void alc885_imac24_automute(struct hda_codec *codec)
5889{
5890 	unsigned int present;
5891
5892 	present = snd_hda_codec_read(codec, 0x14, 0,
5893				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5894	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5895				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5896	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5897				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5898}
5899
5900/* Processes unsolicited events. */
5901static void alc885_imac24_unsol_event(struct hda_codec *codec,
5902				      unsigned int res)
5903{
5904	/* Headphone insertion or removal. */
5905	if ((res >> 26) == ALC880_HP_EVENT)
5906		alc885_imac24_automute(codec);
5907}
5908
5909static void alc885_mbp3_automute(struct hda_codec *codec)
5910{
5911 	unsigned int present;
5912
5913 	present = snd_hda_codec_read(codec, 0x15, 0,
5914				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5915	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5916				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5917	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5918				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5919
5920}
5921static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5922				    unsigned int res)
5923{
5924	/* Headphone insertion or removal. */
5925	if ((res >> 26) == ALC880_HP_EVENT)
5926		alc885_mbp3_automute(codec);
5927}
5928
5929
5930static struct hda_verb alc882_targa_verbs[] = {
5931	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5932	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5933
5934	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5935	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5936
5937	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5938	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5939	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5940
5941	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5942	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5943	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5944	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5945	{ } /* end */
5946};
5947
5948/* toggle speaker-output according to the hp-jack state */
5949static void alc882_targa_automute(struct hda_codec *codec)
5950{
5951 	unsigned int present;
5952
5953 	present = snd_hda_codec_read(codec, 0x14, 0,
5954				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5955	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5956				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5957	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5958				  present ? 1 : 3);
5959}
5960
5961static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5962{
5963	/* Looks like the unsol event is incompatible with the standard
5964	 * definition.  4bit tag is placed at 26 bit!
5965	 */
5966	if (((res >> 26) == ALC880_HP_EVENT)) {
5967		alc882_targa_automute(codec);
5968	}
5969}
5970
5971static struct hda_verb alc882_asus_a7j_verbs[] = {
5972	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5973	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5974
5975	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5976	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5977	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5978
5979	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5980	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5981	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5982
5983	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5984	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5985	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5986	{ } /* end */
5987};
5988
5989static struct hda_verb alc882_asus_a7m_verbs[] = {
5990	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5991	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5992
5993	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5994	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5995	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5996
5997	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5998	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5999	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6000
6001	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6002	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6003	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6004 	{ } /* end */
6005};
6006
6007static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6008{
6009	unsigned int gpiostate, gpiomask, gpiodir;
6010
6011	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6012				       AC_VERB_GET_GPIO_DATA, 0);
6013
6014	if (!muted)
6015		gpiostate |= (1 << pin);
6016	else
6017		gpiostate &= ~(1 << pin);
6018
6019	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6020				      AC_VERB_GET_GPIO_MASK, 0);
6021	gpiomask |= (1 << pin);
6022
6023	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6024				     AC_VERB_GET_GPIO_DIRECTION, 0);
6025	gpiodir |= (1 << pin);
6026
6027
6028	snd_hda_codec_write(codec, codec->afg, 0,
6029			    AC_VERB_SET_GPIO_MASK, gpiomask);
6030	snd_hda_codec_write(codec, codec->afg, 0,
6031			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6032
6033	msleep(1);
6034
6035	snd_hda_codec_write(codec, codec->afg, 0,
6036			    AC_VERB_SET_GPIO_DATA, gpiostate);
6037}
6038
6039/* set up GPIO at initialization */
6040static void alc885_macpro_init_hook(struct hda_codec *codec)
6041{
6042	alc882_gpio_mute(codec, 0, 0);
6043	alc882_gpio_mute(codec, 1, 0);
6044}
6045
6046/* set up GPIO and update auto-muting at initialization */
6047static void alc885_imac24_init_hook(struct hda_codec *codec)
6048{
6049	alc885_macpro_init_hook(codec);
6050	alc885_imac24_automute(codec);
6051}
6052
6053/*
6054 * generic initialization of ADC, input mixers and output mixers
6055 */
6056static struct hda_verb alc882_auto_init_verbs[] = {
6057	/*
6058	 * Unmute ADC0-2 and set the default input to mic-in
6059	 */
6060	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6061	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6062	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6063	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6064	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6065	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6066
6067	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6068	 * mixer widget
6069	 * Note: PASD motherboards uses the Line In 2 as the input for
6070	 * front panel mic (mic 2)
6071	 */
6072	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6073	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6074	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6075	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6076	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6077	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6078
6079	/*
6080	 * Set up output mixers (0x0c - 0x0f)
6081	 */
6082	/* set vol=0 to output mixers */
6083	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6084	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6085	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6086	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6087	/* set up input amps for analog loopback */
6088	/* Amp Indices: DAC = 0, mixer = 1 */
6089	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6090	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6091	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6092	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6093	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6094	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6095	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6096	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6097	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6098	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6099
6100	/* FIXME: use matrix-type input source selection */
6101	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6102	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6103	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6104	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6105	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6106	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6107	/* Input mixer2 */
6108	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6109	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6110	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6111	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6112	/* Input mixer3 */
6113	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6114	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6115	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6116	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6117
6118	{ }
6119};
6120
6121/* capture mixer elements */
6122static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6123	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6124	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6125	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6126	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6127	{
6128		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6129		/* The multiple "Capture Source" controls confuse alsamixer
6130		 * So call somewhat different..
6131		 */
6132		/* .name = "Capture Source", */
6133		.name = "Input Source",
6134		.count = 2,
6135		.info = alc882_mux_enum_info,
6136		.get = alc882_mux_enum_get,
6137		.put = alc882_mux_enum_put,
6138	},
6139	{ } /* end */
6140};
6141
6142static struct snd_kcontrol_new alc882_capture_mixer[] = {
6143	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6144	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6145	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6146	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6147	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6148	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6149	{
6150		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6151		/* The multiple "Capture Source" controls confuse alsamixer
6152		 * So call somewhat different..
6153		 */
6154		/* .name = "Capture Source", */
6155		.name = "Input Source",
6156		.count = 3,
6157		.info = alc882_mux_enum_info,
6158		.get = alc882_mux_enum_get,
6159		.put = alc882_mux_enum_put,
6160	},
6161	{ } /* end */
6162};
6163
6164#ifdef CONFIG_SND_HDA_POWER_SAVE
6165#define alc882_loopbacks	alc880_loopbacks
6166#endif
6167
6168/* pcm configuration: identiacal with ALC880 */
6169#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6170#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6171#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6172#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6173
6174/*
6175 * configuration and preset
6176 */
6177static const char *alc882_models[ALC882_MODEL_LAST] = {
6178	[ALC882_3ST_DIG]	= "3stack-dig",
6179	[ALC882_6ST_DIG]	= "6stack-dig",
6180	[ALC882_ARIMA]		= "arima",
6181	[ALC882_W2JC]		= "w2jc",
6182	[ALC882_TARGA]		= "targa",
6183	[ALC882_ASUS_A7J]	= "asus-a7j",
6184	[ALC882_ASUS_A7M]	= "asus-a7m",
6185	[ALC885_MACPRO]		= "macpro",
6186	[ALC885_MBP3]		= "mbp3",
6187	[ALC885_IMAC24]		= "imac24",
6188	[ALC882_AUTO]		= "auto",
6189};
6190
6191static struct snd_pci_quirk alc882_cfg_tbl[] = {
6192	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6193	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6194	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6195	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6196	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6197	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6198	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6199	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6200	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6201	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6202	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6203	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6204	{}
6205};
6206
6207static struct alc_config_preset alc882_presets[] = {
6208	[ALC882_3ST_DIG] = {
6209		.mixers = { alc882_base_mixer },
6210		.init_verbs = { alc882_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		.need_dac_fix = 1,
6218		.input_mux = &alc882_capture_source,
6219	},
6220	[ALC882_6ST_DIG] = {
6221		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6222		.init_verbs = { alc882_init_verbs },
6223		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6224		.dac_nids = alc882_dac_nids,
6225		.dig_out_nid = ALC882_DIGOUT_NID,
6226		.dig_in_nid = ALC882_DIGIN_NID,
6227		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6228		.channel_mode = alc882_sixstack_modes,
6229		.input_mux = &alc882_capture_source,
6230	},
6231	[ALC882_ARIMA] = {
6232		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6233		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6234		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6235		.dac_nids = alc882_dac_nids,
6236		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6237		.channel_mode = alc882_sixstack_modes,
6238		.input_mux = &alc882_capture_source,
6239	},
6240	[ALC882_W2JC] = {
6241		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6242		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6243				alc880_gpio1_init_verbs },
6244		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6245		.dac_nids = alc882_dac_nids,
6246		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6247		.channel_mode = alc880_threestack_modes,
6248		.need_dac_fix = 1,
6249		.input_mux = &alc882_capture_source,
6250		.dig_out_nid = ALC882_DIGOUT_NID,
6251	},
6252	[ALC885_MBP3] = {
6253		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6254		.init_verbs = { alc885_mbp3_init_verbs,
6255				alc880_gpio1_init_verbs },
6256		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6257		.dac_nids = alc882_dac_nids,
6258		.channel_mode = alc885_mbp_6ch_modes,
6259		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6260		.input_mux = &alc882_capture_source,
6261		.dig_out_nid = ALC882_DIGOUT_NID,
6262		.dig_in_nid = ALC882_DIGIN_NID,
6263		.unsol_event = alc885_mbp3_unsol_event,
6264		.init_hook = alc885_mbp3_automute,
6265	},
6266	[ALC885_MACPRO] = {
6267		.mixers = { alc882_macpro_mixer },
6268		.init_verbs = { alc882_macpro_init_verbs },
6269		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6270		.dac_nids = alc882_dac_nids,
6271		.dig_out_nid = ALC882_DIGOUT_NID,
6272		.dig_in_nid = ALC882_DIGIN_NID,
6273		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6274		.channel_mode = alc882_ch_modes,
6275		.input_mux = &alc882_capture_source,
6276		.init_hook = alc885_macpro_init_hook,
6277	},
6278	[ALC885_IMAC24] = {
6279		.mixers = { alc885_imac24_mixer },
6280		.init_verbs = { alc885_imac24_init_verbs },
6281		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6282		.dac_nids = alc882_dac_nids,
6283		.dig_out_nid = ALC882_DIGOUT_NID,
6284		.dig_in_nid = ALC882_DIGIN_NID,
6285		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6286		.channel_mode = alc882_ch_modes,
6287		.input_mux = &alc882_capture_source,
6288		.unsol_event = alc885_imac24_unsol_event,
6289		.init_hook = alc885_imac24_init_hook,
6290	},
6291	[ALC882_TARGA] = {
6292		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6293			    alc882_capture_mixer },
6294		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6295		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6296		.dac_nids = alc882_dac_nids,
6297		.dig_out_nid = ALC882_DIGOUT_NID,
6298		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6299		.adc_nids = alc882_adc_nids,
6300		.capsrc_nids = alc882_capsrc_nids,
6301		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6302		.channel_mode = alc882_3ST_6ch_modes,
6303		.need_dac_fix = 1,
6304		.input_mux = &alc882_capture_source,
6305		.unsol_event = alc882_targa_unsol_event,
6306		.init_hook = alc882_targa_automute,
6307	},
6308	[ALC882_ASUS_A7J] = {
6309		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6310			    alc882_capture_mixer },
6311		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6312		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6313		.dac_nids = alc882_dac_nids,
6314		.dig_out_nid = ALC882_DIGOUT_NID,
6315		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6316		.adc_nids = alc882_adc_nids,
6317		.capsrc_nids = alc882_capsrc_nids,
6318		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6319		.channel_mode = alc882_3ST_6ch_modes,
6320		.need_dac_fix = 1,
6321		.input_mux = &alc882_capture_source,
6322	},
6323	[ALC882_ASUS_A7M] = {
6324		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6325		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6326				alc880_gpio1_init_verbs,
6327				alc882_asus_a7m_verbs },
6328		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6329		.dac_nids = alc882_dac_nids,
6330		.dig_out_nid = ALC882_DIGOUT_NID,
6331		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6332		.channel_mode = alc880_threestack_modes,
6333		.need_dac_fix = 1,
6334		.input_mux = &alc882_capture_source,
6335	},
6336};
6337
6338
6339/*
6340 * Pin config fixes
6341 */
6342enum {
6343	PINFIX_ABIT_AW9D_MAX
6344};
6345
6346static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6347	{ 0x15, 0x01080104 }, /* side */
6348	{ 0x16, 0x01011012 }, /* rear */
6349	{ 0x17, 0x01016011 }, /* clfe */
6350	{ }
6351};
6352
6353static const struct alc_pincfg *alc882_pin_fixes[] = {
6354	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6355};
6356
6357static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6358	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6359	{}
6360};
6361
6362/*
6363 * BIOS auto configuration
6364 */
6365static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6366					      hda_nid_t nid, int pin_type,
6367					      int dac_idx)
6368{
6369	/* set as output */
6370	struct alc_spec *spec = codec->spec;
6371	int idx;
6372
6373	alc_set_pin_output(codec, nid, pin_type);
6374	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6375		idx = 4;
6376	else
6377		idx = spec->multiout.dac_nids[dac_idx] - 2;
6378	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6379
6380}
6381
6382static void alc882_auto_init_multi_out(struct hda_codec *codec)
6383{
6384	struct alc_spec *spec = codec->spec;
6385	int i;
6386
6387	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6388	for (i = 0; i <= HDA_SIDE; i++) {
6389		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6390		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6391		if (nid)
6392			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6393							  i);
6394	}
6395}
6396
6397static void alc882_auto_init_hp_out(struct hda_codec *codec)
6398{
6399	struct alc_spec *spec = codec->spec;
6400	hda_nid_t pin;
6401
6402	pin = spec->autocfg.hp_pins[0];
6403	if (pin) /* connect to front */
6404		/* use dac 0 */
6405		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6406	pin = spec->autocfg.speaker_pins[0];
6407	if (pin)
6408		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6409}
6410
6411#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6412#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6413
6414static void alc882_auto_init_analog_input(struct hda_codec *codec)
6415{
6416	struct alc_spec *spec = codec->spec;
6417	int i;
6418
6419	for (i = 0; i < AUTO_PIN_LAST; i++) {
6420		hda_nid_t nid = spec->autocfg.input_pins[i];
6421		unsigned int vref;
6422		if (!nid)
6423			continue;
6424		vref = PIN_IN;
6425		if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6426			unsigned int pincap;
6427			pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6428			if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6429			    AC_PINCAP_VREF_80)
6430				vref = PIN_VREF80;
6431		}
6432		snd_hda_codec_write(codec, nid, 0,
6433				    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6434		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6435			snd_hda_codec_write(codec, nid, 0,
6436					    AC_VERB_SET_AMP_GAIN_MUTE,
6437					    AMP_OUT_MUTE);
6438	}
6439}
6440
6441static void alc882_auto_init_input_src(struct hda_codec *codec)
6442{
6443	struct alc_spec *spec = codec->spec;
6444	const struct hda_input_mux *imux = spec->input_mux;
6445	int c;
6446
6447	for (c = 0; c < spec->num_adc_nids; c++) {
6448		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6449		hda_nid_t nid = spec->capsrc_nids[c];
6450		int conns, mute, idx, item;
6451
6452		conns = snd_hda_get_connections(codec, nid, conn_list,
6453						ARRAY_SIZE(conn_list));
6454		if (conns < 0)
6455			continue;
6456		for (idx = 0; idx < conns; idx++) {
6457			/* if the current connection is the selected one,
6458			 * unmute it as default - otherwise mute it
6459			 */
6460			mute = AMP_IN_MUTE(idx);
6461			for (item = 0; item < imux->num_items; item++) {
6462				if (imux->items[item].index == idx) {
6463					if (spec->cur_mux[c] == item)
6464						mute = AMP_IN_UNMUTE(idx);
6465					break;
6466				}
6467			}
6468			snd_hda_codec_write(codec, nid, 0,
6469					    AC_VERB_SET_AMP_GAIN_MUTE, mute);
6470		}
6471	}
6472}
6473
6474/* add mic boosts if needed */
6475static int alc_auto_add_mic_boost(struct hda_codec *codec)
6476{
6477	struct alc_spec *spec = codec->spec;
6478	int err;
6479	hda_nid_t nid;
6480
6481	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6482	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6483		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6484				  "Mic Boost",
6485				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6486		if (err < 0)
6487			return err;
6488	}
6489	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6490	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6491		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6492				  "Front Mic Boost",
6493				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6494		if (err < 0)
6495			return err;
6496	}
6497	return 0;
6498}
6499
6500/* almost identical with ALC880 parser... */
6501static int alc882_parse_auto_config(struct hda_codec *codec)
6502{
6503	struct alc_spec *spec = codec->spec;
6504	int err = alc880_parse_auto_config(codec);
6505
6506	if (err < 0)
6507		return err;
6508	else if (!err)
6509		return 0; /* no config found */
6510
6511	err = alc_auto_add_mic_boost(codec);
6512	if (err < 0)
6513		return err;
6514
6515	/* hack - override the init verbs */
6516	spec->init_verbs[0] = alc882_auto_init_verbs;
6517
6518	return 1; /* config found */
6519}
6520
6521/* additional initialization for auto-configuration model */
6522static void alc882_auto_init(struct hda_codec *codec)
6523{
6524	struct alc_spec *spec = codec->spec;
6525	alc882_auto_init_multi_out(codec);
6526	alc882_auto_init_hp_out(codec);
6527	alc882_auto_init_analog_input(codec);
6528	alc882_auto_init_input_src(codec);
6529	if (spec->unsol_event)
6530		alc_sku_automute(codec);
6531}
6532
6533static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6534
6535static int patch_alc882(struct hda_codec *codec)
6536{
6537	struct alc_spec *spec;
6538	int err, board_config;
6539
6540	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6541	if (spec == NULL)
6542		return -ENOMEM;
6543
6544	codec->spec = spec;
6545
6546	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6547						  alc882_models,
6548						  alc882_cfg_tbl);
6549
6550	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6551		/* Pick up systems that don't supply PCI SSID */
6552		switch (codec->subsystem_id) {
6553		case 0x106b0c00: /* Mac Pro */
6554			board_config = ALC885_MACPRO;
6555			break;
6556		case 0x106b1000: /* iMac 24 */
6557			board_config = ALC885_IMAC24;
6558			break;
6559		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6560		case 0x106b2c00: /* Macbook Pro rev3 */
6561		case 0x106b3600: /* Macbook 3.1 */
6562			board_config = ALC885_MBP3;
6563			break;
6564		default:
6565			/* ALC889A is handled better as ALC888-compatible */
6566			if (codec->revision_id == 0x100103) {
6567				alc_free(codec);
6568				return patch_alc883(codec);
6569			}
6570			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6571		       			 "trying auto-probe from BIOS...\n");
6572			board_config = ALC882_AUTO;
6573		}
6574	}
6575
6576	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6577
6578	if (board_config == ALC882_AUTO) {
6579		/* automatic parse from the BIOS config */
6580		err = alc882_parse_auto_config(codec);
6581		if (err < 0) {
6582			alc_free(codec);
6583			return err;
6584		} else if (!err) {
6585			printk(KERN_INFO
6586			       "hda_codec: Cannot set up configuration "
6587			       "from BIOS.  Using base mode...\n");
6588			board_config = ALC882_3ST_DIG;
6589		}
6590	}
6591
6592	if (board_config != ALC882_AUTO)
6593		setup_preset(spec, &alc882_presets[board_config]);
6594
6595	if (codec->vendor_id == 0x10ec0885) {
6596		spec->stream_name_analog = "ALC885 Analog";
6597		spec->stream_name_digital = "ALC885 Digital";
6598	} else {
6599		spec->stream_name_analog = "ALC882 Analog";
6600		spec->stream_name_digital = "ALC882 Digital";
6601	}
6602
6603	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6604	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6605	/* FIXME: setup DAC5 */
6606	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6607	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6608
6609	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6610	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6611
6612	if (!spec->adc_nids && spec->input_mux) {
6613		/* check whether NID 0x07 is valid */
6614		unsigned int wcap = get_wcaps(codec, 0x07);
6615		/* get type */
6616		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6617		if (wcap != AC_WID_AUD_IN) {
6618			spec->adc_nids = alc882_adc_nids_alt;
6619			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6620			spec->capsrc_nids = alc882_capsrc_nids_alt;
6621			spec->mixers[spec->num_mixers] =
6622				alc882_capture_alt_mixer;
6623			spec->num_mixers++;
6624		} else {
6625			spec->adc_nids = alc882_adc_nids;
6626			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6627			spec->capsrc_nids = alc882_capsrc_nids;
6628			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6629			spec->num_mixers++;
6630		}
6631	}
6632
6633	spec->vmaster_nid = 0x0c;
6634
6635	codec->patch_ops = alc_patch_ops;
6636	if (board_config == ALC882_AUTO)
6637		spec->init_hook = alc882_auto_init;
6638#ifdef CONFIG_SND_HDA_POWER_SAVE
6639	if (!spec->loopback.amplist)
6640		spec->loopback.amplist = alc882_loopbacks;
6641#endif
6642
6643	return 0;
6644}
6645
6646/*
6647 * ALC883 support
6648 *
6649 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6650 * configuration.  Each pin widget can choose any input DACs and a mixer.
6651 * Each ADC is connected from a mixer of all inputs.  This makes possible
6652 * 6-channel independent captures.
6653 *
6654 * In addition, an independent DAC for the multi-playback (not used in this
6655 * driver yet).
6656 */
6657#define ALC883_DIGOUT_NID	0x06
6658#define ALC883_DIGIN_NID	0x0a
6659
6660static hda_nid_t alc883_dac_nids[4] = {
6661	/* front, rear, clfe, rear_surr */
6662	0x02, 0x03, 0x04, 0x05
6663};
6664
6665static hda_nid_t alc883_adc_nids[2] = {
6666	/* ADC1-2 */
6667	0x08, 0x09,
6668};
6669
6670static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6671
6672/* input MUX */
6673/* FIXME: should be a matrix-type input source selection */
6674
6675static struct hda_input_mux alc883_capture_source = {
6676	.num_items = 4,
6677	.items = {
6678		{ "Mic", 0x0 },
6679		{ "Front Mic", 0x1 },
6680		{ "Line", 0x2 },
6681		{ "CD", 0x4 },
6682	},
6683};
6684
6685static struct hda_input_mux alc883_3stack_6ch_intel = {
6686	.num_items = 4,
6687	.items = {
6688		{ "Mic", 0x1 },
6689		{ "Front Mic", 0x0 },
6690		{ "Line", 0x2 },
6691		{ "CD", 0x4 },
6692	},
6693};
6694
6695static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6696	.num_items = 2,
6697	.items = {
6698		{ "Mic", 0x1 },
6699		{ "Line", 0x2 },
6700	},
6701};
6702
6703static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6704	.num_items = 4,
6705	.items = {
6706		{ "Mic", 0x0 },
6707		{ "iMic", 0x1 },
6708		{ "Line", 0x2 },
6709		{ "CD", 0x4 },
6710	},
6711};
6712
6713static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6714	.num_items = 2,
6715	.items = {
6716		{ "Mic", 0x0 },
6717		{ "Int Mic", 0x1 },
6718	},
6719};
6720
6721#define alc883_mux_enum_info alc_mux_enum_info
6722#define alc883_mux_enum_get alc_mux_enum_get
6723/* ALC883 has the ALC882-type input selection */
6724#define alc883_mux_enum_put alc882_mux_enum_put
6725
6726/*
6727 * 2ch mode
6728 */
6729static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6730	{ 2, NULL }
6731};
6732
6733/*
6734 * 2ch mode
6735 */
6736static struct hda_verb alc883_3ST_ch2_init[] = {
6737	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6738	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6739	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6740	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6741	{ } /* end */
6742};
6743
6744/*
6745 * 4ch mode
6746 */
6747static struct hda_verb alc883_3ST_ch4_init[] = {
6748	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6749	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6750	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6751	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6752	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6753	{ } /* end */
6754};
6755
6756/*
6757 * 6ch mode
6758 */
6759static struct hda_verb alc883_3ST_ch6_init[] = {
6760	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6761	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6762	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6763	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6764	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6765	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6766	{ } /* end */
6767};
6768
6769static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6770	{ 2, alc883_3ST_ch2_init },
6771	{ 4, alc883_3ST_ch4_init },
6772	{ 6, alc883_3ST_ch6_init },
6773};
6774
6775/*
6776 * 2ch mode
6777 */
6778static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6779	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6780	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6781	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6782	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6783	{ } /* end */
6784};
6785
6786/*
6787 * 4ch mode
6788 */
6789static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6790	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6791	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6792	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6793	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6794	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6795	{ } /* end */
6796};
6797
6798/*
6799 * 6ch mode
6800 */
6801static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6802	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6803	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6804	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6805	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6806	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6807	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6808	{ } /* end */
6809};
6810
6811static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6812	{ 2, alc883_3ST_ch2_intel_init },
6813	{ 4, alc883_3ST_ch4_intel_init },
6814	{ 6, alc883_3ST_ch6_intel_init },
6815};
6816
6817/*
6818 * 6ch mode
6819 */
6820static struct hda_verb alc883_sixstack_ch6_init[] = {
6821	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6822	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6823	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6824	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6825	{ } /* end */
6826};
6827
6828/*
6829 * 8ch mode
6830 */
6831static struct hda_verb alc883_sixstack_ch8_init[] = {
6832	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6833	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6834	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6835	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6836	{ } /* end */
6837};
6838
6839static struct hda_channel_mode alc883_sixstack_modes[2] = {
6840	{ 6, alc883_sixstack_ch6_init },
6841	{ 8, alc883_sixstack_ch8_init },
6842};
6843
6844static struct hda_verb alc883_medion_eapd_verbs[] = {
6845        /* eanable EAPD on medion laptop */
6846	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6847	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6848	{ }
6849};
6850
6851/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6852 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6853 */
6854
6855static struct snd_kcontrol_new alc883_base_mixer[] = {
6856	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6857	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6858	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6859	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6860	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6861	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6862	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6863	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6864	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6865	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6866	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6867	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6868	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6869	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6870	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6871	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6872	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6873	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6874	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6875	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6876	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6877	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6878	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6879	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6880	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6881	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6882	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6883	{
6884		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6885		/* .name = "Capture Source", */
6886		.name = "Input Source",
6887		.count = 2,
6888		.info = alc883_mux_enum_info,
6889		.get = alc883_mux_enum_get,
6890		.put = alc883_mux_enum_put,
6891	},
6892	{ } /* end */
6893};
6894
6895static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6896	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6897	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6898	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6899	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6900	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6901	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6902	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6903	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6904	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6905	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6906	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6907	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6908	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6909	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6910	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6911	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6912	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6913	{
6914		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6915		/* .name = "Capture Source", */
6916		.name = "Input Source",
6917		.count = 2,
6918		.info = alc883_mux_enum_info,
6919		.get = alc883_mux_enum_get,
6920		.put = alc883_mux_enum_put,
6921	},
6922	{ } /* end */
6923};
6924
6925static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
6926	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6927	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6928	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6929	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6930	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6931	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6932	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6933	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6934	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6935	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6936	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6937	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6938	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6939	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6940	{
6941		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6942		/* .name = "Capture Source", */
6943		.name = "Input Source",
6944		.count = 2,
6945		.info = alc883_mux_enum_info,
6946		.get = alc883_mux_enum_get,
6947		.put = alc883_mux_enum_put,
6948	},
6949	{ } /* end */
6950};
6951
6952static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
6953	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6954	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6955	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6956	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6957	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6958	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6959	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6960	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6961	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6962	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6963	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6964	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6965	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6966	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6967	{
6968		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6969		/* .name = "Capture Source", */
6970		.name = "Input Source",
6971		.count = 2,
6972		.info = alc883_mux_enum_info,
6973		.get = alc883_mux_enum_get,
6974		.put = alc883_mux_enum_put,
6975	},
6976	{ } /* end */
6977};
6978
6979static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6980	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6981	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6982	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6983	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6984	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6985	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6986	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6987	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6988	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6989	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6990	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6991	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6992	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6993	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6994	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6995	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6996	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6997	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6998	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6999	{
7000		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7001		/* .name = "Capture Source", */
7002		.name = "Input Source",
7003		.count = 2,
7004		.info = alc883_mux_enum_info,
7005		.get = alc883_mux_enum_get,
7006		.put = alc883_mux_enum_put,
7007	},
7008	{ } /* end */
7009};
7010
7011static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7012	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7013	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7014	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7015	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7016	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7017	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7018	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7019	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7020	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7021	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7022	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7023	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7024	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7025	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7026	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7027	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7028	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7029	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7030	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7031	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7032	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7033	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7034	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7035	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7036	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7037	{
7038		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7039		/* .name = "Capture Source", */
7040		.name = "Input Source",
7041		.count = 2,
7042		.info = alc883_mux_enum_info,
7043		.get = alc883_mux_enum_get,
7044		.put = alc883_mux_enum_put,
7045	},
7046	{ } /* end */
7047};
7048
7049static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7050	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7051	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7052	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7053	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7054	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7055			      HDA_OUTPUT),
7056	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7057	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7058	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7059	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7060	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7061	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7062	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7063	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7064	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7065	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7066	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7067	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7068	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7069	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7070	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7071	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7072	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7073	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7074	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7075	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7076	{
7077		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7078		/* .name = "Capture Source", */
7079		.name = "Input Source",
7080		.count = 2,
7081		.info = alc883_mux_enum_info,
7082		.get = alc883_mux_enum_get,
7083		.put = alc883_mux_enum_put,
7084	},
7085	{ } /* end */
7086};
7087
7088static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7089	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7090	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7091	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7092	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7093	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7094	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7095	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7096	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7097	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7098	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7099	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7100	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7101	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7102	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7103	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7104	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7105	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7106	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7107	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7108	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7109	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7110	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7111	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7112
7113	{
7114		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7115		/* .name = "Capture Source", */
7116		.name = "Input Source",
7117		.count = 1,
7118		.info = alc883_mux_enum_info,
7119		.get = alc883_mux_enum_get,
7120		.put = alc883_mux_enum_put,
7121	},
7122	{ } /* end */
7123};
7124
7125static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7126	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7127	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7128	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7129	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7130	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7131	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7132	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7133	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7134	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7135	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7136	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7137	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7138	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7139	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7140	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7141	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7142	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7143	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7144	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7145	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7146	{
7147		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7148		/* .name = "Capture Source", */
7149		.name = "Input Source",
7150		.count = 2,
7151		.info = alc883_mux_enum_info,
7152		.get = alc883_mux_enum_get,
7153		.put = alc883_mux_enum_put,
7154	},
7155	{ } /* end */
7156};
7157
7158static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7159	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7160	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7161	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7162	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7163	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7164	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7165	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7166	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7167	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7168	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7169	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7170	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7171	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7172	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7173	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7174	{
7175		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7176		/* .name = "Capture Source", */
7177		.name = "Input Source",
7178		.count = 2,
7179		.info = alc883_mux_enum_info,
7180		.get = alc883_mux_enum_get,
7181		.put = alc883_mux_enum_put,
7182	},
7183	{ } /* end */
7184};
7185
7186static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7187	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7188	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7189	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7190	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7191	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7192	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7193	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7194	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7195	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7196	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7197	{
7198		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7199		/* .name = "Capture Source", */
7200		.name = "Input Source",
7201		.count = 1,
7202		.info = alc883_mux_enum_info,
7203		.get = alc883_mux_enum_get,
7204		.put = alc883_mux_enum_put,
7205	},
7206	{ } /* end */
7207};
7208
7209static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7210	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7211	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7212	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7213	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7214	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7215	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7216	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7217	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7218	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7219	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7220	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7221	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7222	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7223	{
7224		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7225		/* .name = "Capture Source", */
7226		.name = "Input Source",
7227		.count = 2,
7228		.info = alc883_mux_enum_info,
7229		.get = alc883_mux_enum_get,
7230		.put = alc883_mux_enum_put,
7231	},
7232	{ } /* end */
7233};
7234
7235static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7236	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7237	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7238	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7239	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7240	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7241	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7242	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7243	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7244	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7245	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7246	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7247	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7248	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7249	{
7250		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7251		/* .name = "Capture Source", */
7252		.name = "Input Source",
7253		.count = 2,
7254		.info = alc883_mux_enum_info,
7255		.get = alc883_mux_enum_get,
7256		.put = alc883_mux_enum_put,
7257	},
7258	{ } /* end */
7259};
7260
7261static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7262	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7263	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7264	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7265	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7266	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7267	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7268	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7269	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7270	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7271	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7272	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7273	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7274	{
7275		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7276		/* .name = "Capture Source", */
7277		.name = "Input Source",
7278		.count = 2,
7279		.info = alc883_mux_enum_info,
7280		.get = alc883_mux_enum_get,
7281		.put = alc883_mux_enum_put,
7282	},
7283	{ } /* end */
7284};
7285
7286static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7287	{
7288		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7289		.name = "Channel Mode",
7290		.info = alc_ch_mode_info,
7291		.get = alc_ch_mode_get,
7292		.put = alc_ch_mode_put,
7293	},
7294	{ } /* end */
7295};
7296
7297static struct hda_verb alc883_init_verbs[] = {
7298	/* ADC1: mute amp left and right */
7299	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7300	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7301	/* ADC2: mute amp left and right */
7302	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7303	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7304	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7305	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7307	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7308	/* Rear mixer */
7309	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7310	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7311	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7312	/* CLFE mixer */
7313	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7314	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7315	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7316	/* Side mixer */
7317	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7318	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7319	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7320
7321	/* mute analog input loopbacks */
7322	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7323	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7324	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7325	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7326	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7327
7328	/* Front Pin: output 0 (0x0c) */
7329	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7330	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7331	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7332	/* Rear Pin: output 1 (0x0d) */
7333	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7334	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7335	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7336	/* CLFE Pin: output 2 (0x0e) */
7337	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7338	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7339	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7340	/* Side Pin: output 3 (0x0f) */
7341	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7342	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7343	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7344	/* Mic (rear) pin: input vref at 80% */
7345	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7346	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7347	/* Front Mic pin: input vref at 80% */
7348	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7349	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7350	/* Line In pin: input */
7351	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7352	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7353	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7354	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7355	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7356	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7357	/* CD pin widget for input */
7358	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7359
7360	/* FIXME: use matrix-type input source selection */
7361	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7362	/* Input mixer2 */
7363	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7364	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7365	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7366	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7367	/* Input mixer3 */
7368	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7369	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7370	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7371	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7372	{ }
7373};
7374
7375/* toggle speaker-output according to the hp-jack state */
7376static void alc883_mitac_hp_automute(struct hda_codec *codec)
7377{
7378	unsigned int present;
7379
7380	present = snd_hda_codec_read(codec, 0x15, 0,
7381				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7382	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7383				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7384	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7385				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7386}
7387
7388/* auto-toggle front mic */
7389/*
7390static void alc883_mitac_mic_automute(struct hda_codec *codec)
7391{
7392	unsigned int present;
7393	unsigned char bits;
7394
7395	present = snd_hda_codec_read(codec, 0x18, 0,
7396				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7397	bits = present ? HDA_AMP_MUTE : 0;
7398	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7399}
7400*/
7401
7402static void alc883_mitac_automute(struct hda_codec *codec)
7403{
7404	alc883_mitac_hp_automute(codec);
7405	/* alc883_mitac_mic_automute(codec); */
7406}
7407
7408static void alc883_mitac_unsol_event(struct hda_codec *codec,
7409					   unsigned int res)
7410{
7411	switch (res >> 26) {
7412	case ALC880_HP_EVENT:
7413		alc883_mitac_hp_automute(codec);
7414		break;
7415	case ALC880_MIC_EVENT:
7416		/* alc883_mitac_mic_automute(codec); */
7417		break;
7418	}
7419}
7420
7421static struct hda_verb alc883_mitac_verbs[] = {
7422	/* HP */
7423	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7424	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7425	/* Subwoofer */
7426	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7427	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7428
7429	/* enable unsolicited event */
7430	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7431	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7432
7433	{ } /* end */
7434};
7435
7436static struct hda_verb alc883_clevo_m720_verbs[] = {
7437	/* HP */
7438	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7439	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7440	/* Int speaker */
7441	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7442	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7443
7444	/* enable unsolicited event */
7445	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7446	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7447
7448	{ } /* end */
7449};
7450
7451static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7452	/* HP */
7453	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7454	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7455	/* Subwoofer */
7456	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7457	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7458
7459	/* enable unsolicited event */
7460	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7461
7462	{ } /* end */
7463};
7464
7465static struct hda_verb alc883_tagra_verbs[] = {
7466	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7467	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7468
7469	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7470	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7471
7472	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7473	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7474	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7475
7476	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7477	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7478	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7479	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7480
7481	{ } /* end */
7482};
7483
7484static struct hda_verb alc883_lenovo_101e_verbs[] = {
7485	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7486	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7487        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7488	{ } /* end */
7489};
7490
7491static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7492        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7493	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7494        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7495        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7496	{ } /* end */
7497};
7498
7499static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7500	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7501	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7502	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7503	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7504	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7505	{ } /* end */
7506};
7507
7508static struct hda_verb alc883_haier_w66_verbs[] = {
7509	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7510	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7511
7512	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7513
7514	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7515	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7516	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7517	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7518	{ } /* end */
7519};
7520
7521static struct hda_verb alc888_3st_hp_verbs[] = {
7522	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7523	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7524	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7525	{ }
7526};
7527
7528static struct hda_verb alc888_6st_dell_verbs[] = {
7529	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7530	{ }
7531};
7532
7533static struct hda_verb alc888_3st_hp_2ch_init[] = {
7534	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7535	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7536	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7537	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7538	{ }
7539};
7540
7541static struct hda_verb alc888_3st_hp_6ch_init[] = {
7542	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7543	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7544	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7545	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7546	{ }
7547};
7548
7549static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7550	{ 2, alc888_3st_hp_2ch_init },
7551	{ 6, alc888_3st_hp_6ch_init },
7552};
7553
7554/* toggle front-jack and RCA according to the hp-jack state */
7555static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7556{
7557 	unsigned int present;
7558
7559 	present = snd_hda_codec_read(codec, 0x1b, 0,
7560				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7561	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7562				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7563	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7564				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7565}
7566
7567/* toggle RCA according to the front-jack state */
7568static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7569{
7570 	unsigned int present;
7571
7572 	present = snd_hda_codec_read(codec, 0x14, 0,
7573				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7574	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7575				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7576}
7577
7578static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7579					     unsigned int res)
7580{
7581	if ((res >> 26) == ALC880_HP_EVENT)
7582		alc888_lenovo_ms7195_front_automute(codec);
7583	if ((res >> 26) == ALC880_FRONT_EVENT)
7584		alc888_lenovo_ms7195_rca_automute(codec);
7585}
7586
7587static struct hda_verb alc883_medion_md2_verbs[] = {
7588	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7589	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7590
7591	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7592
7593	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7594	{ } /* end */
7595};
7596
7597/* toggle speaker-output according to the hp-jack state */
7598static void alc883_medion_md2_automute(struct hda_codec *codec)
7599{
7600 	unsigned int present;
7601
7602 	present = snd_hda_codec_read(codec, 0x14, 0,
7603				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7604	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7605				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7606}
7607
7608static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7609					  unsigned int res)
7610{
7611	if ((res >> 26) == ALC880_HP_EVENT)
7612		alc883_medion_md2_automute(codec);
7613}
7614
7615/* toggle speaker-output according to the hp-jack state */
7616static void alc883_tagra_automute(struct hda_codec *codec)
7617{
7618 	unsigned int present;
7619	unsigned char bits;
7620
7621 	present = snd_hda_codec_read(codec, 0x14, 0,
7622				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7623	bits = present ? HDA_AMP_MUTE : 0;
7624	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7625				 HDA_AMP_MUTE, bits);
7626	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7627				  present ? 1 : 3);
7628}
7629
7630static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7631{
7632	if ((res >> 26) == ALC880_HP_EVENT)
7633		alc883_tagra_automute(codec);
7634}
7635
7636/* toggle speaker-output according to the hp-jack state */
7637static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7638{
7639	unsigned int present;
7640	unsigned char bits;
7641
7642	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7643		& AC_PINSENSE_PRESENCE;
7644	bits = present ? HDA_AMP_MUTE : 0;
7645	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7646				 HDA_AMP_MUTE, bits);
7647}
7648
7649static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7650{
7651	unsigned int present;
7652
7653	present = snd_hda_codec_read(codec, 0x18, 0,
7654				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7655	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7656				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7657}
7658
7659static void alc883_clevo_m720_automute(struct hda_codec *codec)
7660{
7661	alc883_clevo_m720_hp_automute(codec);
7662	alc883_clevo_m720_mic_automute(codec);
7663}
7664
7665static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7666					   unsigned int res)
7667{
7668	switch (res >> 26) {
7669	case ALC880_HP_EVENT:
7670		alc883_clevo_m720_hp_automute(codec);
7671		break;
7672	case ALC880_MIC_EVENT:
7673		alc883_clevo_m720_mic_automute(codec);
7674		break;
7675	}
7676}
7677
7678/* toggle speaker-output according to the hp-jack state */
7679static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7680{
7681 	unsigned int present;
7682	unsigned char bits;
7683
7684 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7685		& AC_PINSENSE_PRESENCE;
7686	bits = present ? HDA_AMP_MUTE : 0;
7687	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7688				 HDA_AMP_MUTE, bits);
7689}
7690
7691static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7692						  unsigned int res)
7693{
7694	if ((res >> 26) == ALC880_HP_EVENT)
7695		alc883_2ch_fujitsu_pi2515_automute(codec);
7696}
7697
7698static void alc883_haier_w66_automute(struct hda_codec *codec)
7699{
7700	unsigned int present;
7701	unsigned char bits;
7702
7703	present = snd_hda_codec_read(codec, 0x1b, 0,
7704				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7705	bits = present ? 0x80 : 0;
7706	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7707				 0x80, bits);
7708}
7709
7710static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7711					 unsigned int res)
7712{
7713	if ((res >> 26) == ALC880_HP_EVENT)
7714		alc883_haier_w66_automute(codec);
7715}
7716
7717static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7718{
7719 	unsigned int present;
7720	unsigned char bits;
7721
7722 	present = snd_hda_codec_read(codec, 0x14, 0,
7723				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7724	bits = present ? HDA_AMP_MUTE : 0;
7725	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7726				 HDA_AMP_MUTE, bits);
7727}
7728
7729static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7730{
7731 	unsigned int present;
7732	unsigned char bits;
7733
7734 	present = snd_hda_codec_read(codec, 0x1b, 0,
7735				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7736	bits = present ? HDA_AMP_MUTE : 0;
7737	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7738				 HDA_AMP_MUTE, bits);
7739	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7740				 HDA_AMP_MUTE, bits);
7741}
7742
7743static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7744					   unsigned int res)
7745{
7746	if ((res >> 26) == ALC880_HP_EVENT)
7747		alc883_lenovo_101e_all_automute(codec);
7748	if ((res >> 26) == ALC880_FRONT_EVENT)
7749		alc883_lenovo_101e_ispeaker_automute(codec);
7750}
7751
7752/* toggle speaker-output according to the hp-jack state */
7753static void alc883_acer_aspire_automute(struct hda_codec *codec)
7754{
7755 	unsigned int present;
7756
7757 	present = snd_hda_codec_read(codec, 0x14, 0,
7758				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7759	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7760				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7761	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7762				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7763}
7764
7765static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7766					   unsigned int res)
7767{
7768	if ((res >> 26) == ALC880_HP_EVENT)
7769		alc883_acer_aspire_automute(codec);
7770}
7771
7772static struct hda_verb alc883_acer_eapd_verbs[] = {
7773	/* HP Pin: output 0 (0x0c) */
7774	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7775	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7776	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7777	/* Front Pin: output 0 (0x0c) */
7778	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7779	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7780	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7781	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7782        /* eanable EAPD on medion laptop */
7783	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7784	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7785	/* enable unsolicited event */
7786	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7787	{ }
7788};
7789
7790static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7791{
7792 	unsigned int present;
7793
7794 	present = snd_hda_codec_read(codec, 0x1b, 0,
7795				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7796	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7797				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7798	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7799				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7800	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7801				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7802	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7803				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7804}
7805
7806static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7807					     unsigned int res)
7808{
7809	switch (res >> 26) {
7810	case ALC880_HP_EVENT:
7811		printk("hp_event\n");
7812		alc888_6st_dell_front_automute(codec);
7813		break;
7814	}
7815}
7816
7817/*
7818 * generic initialization of ADC, input mixers and output mixers
7819 */
7820static struct hda_verb alc883_auto_init_verbs[] = {
7821	/*
7822	 * Unmute ADC0-2 and set the default input to mic-in
7823	 */
7824	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7825	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7826	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7827	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7828
7829	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7830	 * mixer widget
7831	 * Note: PASD motherboards uses the Line In 2 as the input for
7832	 * front panel mic (mic 2)
7833	 */
7834	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7835	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7836	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7837	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7838	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7839	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7840
7841	/*
7842	 * Set up output mixers (0x0c - 0x0f)
7843	 */
7844	/* set vol=0 to output mixers */
7845	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7846	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7847	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7848	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7849	/* set up input amps for analog loopback */
7850	/* Amp Indices: DAC = 0, mixer = 1 */
7851	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7852	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7853	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7854	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7855	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7856	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7857	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7858	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7859	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7860	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7861
7862	/* FIXME: use matrix-type input source selection */
7863	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7864	/* Input mixer1 */
7865	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7866	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7867	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7868	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7869	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7870	/* Input mixer2 */
7871	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7872	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7873	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7874	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7875	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7876
7877	{ }
7878};
7879
7880/* capture mixer elements */
7881static struct snd_kcontrol_new alc883_capture_mixer[] = {
7882	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7883	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7884	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7885	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7886	{
7887		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7888		/* The multiple "Capture Source" controls confuse alsamixer
7889		 * So call somewhat different..
7890		 */
7891		/* .name = "Capture Source", */
7892		.name = "Input Source",
7893		.count = 2,
7894		.info = alc882_mux_enum_info,
7895		.get = alc882_mux_enum_get,
7896		.put = alc882_mux_enum_put,
7897	},
7898	{ } /* end */
7899};
7900
7901#ifdef CONFIG_SND_HDA_POWER_SAVE
7902#define alc883_loopbacks	alc880_loopbacks
7903#endif
7904
7905/* pcm configuration: identiacal with ALC880 */
7906#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
7907#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
7908#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
7909#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
7910#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
7911
7912/*
7913 * configuration and preset
7914 */
7915static const char *alc883_models[ALC883_MODEL_LAST] = {
7916	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
7917	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
7918	[ALC883_3ST_6ch]	= "3stack-6ch",
7919	[ALC883_6ST_DIG]	= "6stack-dig",
7920	[ALC883_TARGA_DIG]	= "targa-dig",
7921	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
7922	[ALC883_ACER]		= "acer",
7923	[ALC883_ACER_ASPIRE]	= "acer-aspire",
7924	[ALC883_MEDION]		= "medion",
7925	[ALC883_MEDION_MD2]	= "medion-md2",
7926	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
7927	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7928	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
7929	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7930	[ALC883_HAIER_W66] 	= "haier-w66",
7931	[ALC888_3ST_HP]		= "3stack-hp",
7932	[ALC888_6ST_DELL]	= "6stack-dell",
7933	[ALC883_MITAC]		= "mitac",
7934	[ALC883_CLEVO_M720]	= "clevo-m720",
7935	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
7936	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
7937	[ALC883_AUTO]		= "auto",
7938};
7939
7940static struct snd_pci_quirk alc883_cfg_tbl[] = {
7941	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7942	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7943	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7944	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7945	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
7946	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7947	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
7948	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7949	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7950	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7951	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
7952	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7953	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
7954	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7955	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7956	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7957	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7958	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7959	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7960	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7961	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7962	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
7963	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7964	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
7965	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7966	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7967	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7968	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7969	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7970	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7971	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7972	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7973	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7974	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7975	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7976	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7977	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
7978	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7979	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7980	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7981	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7982	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
7983	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
7984	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7985	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7986	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7987	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
7988	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7989	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7990	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7991	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7992	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7993	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7994	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7995	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
7996	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
7997	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7998	{}
7999};
8000
8001static struct alc_config_preset alc883_presets[] = {
8002	[ALC883_3ST_2ch_DIG] = {
8003		.mixers = { alc883_3ST_2ch_mixer },
8004		.init_verbs = { alc883_init_verbs },
8005		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8006		.dac_nids = alc883_dac_nids,
8007		.dig_out_nid = ALC883_DIGOUT_NID,
8008		.dig_in_nid = ALC883_DIGIN_NID,
8009		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8010		.channel_mode = alc883_3ST_2ch_modes,
8011		.input_mux = &alc883_capture_source,
8012	},
8013	[ALC883_3ST_6ch_DIG] = {
8014		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8015		.init_verbs = { alc883_init_verbs },
8016		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8017		.dac_nids = alc883_dac_nids,
8018		.dig_out_nid = ALC883_DIGOUT_NID,
8019		.dig_in_nid = ALC883_DIGIN_NID,
8020		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8021		.channel_mode = alc883_3ST_6ch_modes,
8022		.need_dac_fix = 1,
8023		.input_mux = &alc883_capture_source,
8024	},
8025	[ALC883_3ST_6ch] = {
8026		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8027		.init_verbs = { alc883_init_verbs },
8028		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8029		.dac_nids = alc883_dac_nids,
8030		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8031		.channel_mode = alc883_3ST_6ch_modes,
8032		.need_dac_fix = 1,
8033		.input_mux = &alc883_capture_source,
8034	},
8035	[ALC883_3ST_6ch_INTEL] = {
8036		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8037		.init_verbs = { alc883_init_verbs },
8038		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8039		.dac_nids = alc883_dac_nids,
8040		.dig_out_nid = ALC883_DIGOUT_NID,
8041		.dig_in_nid = ALC883_DIGIN_NID,
8042		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8043		.channel_mode = alc883_3ST_6ch_intel_modes,
8044		.need_dac_fix = 1,
8045		.input_mux = &alc883_3stack_6ch_intel,
8046	},
8047	[ALC883_6ST_DIG] = {
8048		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8049		.init_verbs = { alc883_init_verbs },
8050		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8051		.dac_nids = alc883_dac_nids,
8052		.dig_out_nid = ALC883_DIGOUT_NID,
8053		.dig_in_nid = ALC883_DIGIN_NID,
8054		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8055		.channel_mode = alc883_sixstack_modes,
8056		.input_mux = &alc883_capture_source,
8057	},
8058	[ALC883_TARGA_DIG] = {
8059		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8060		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8061		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8062		.dac_nids = alc883_dac_nids,
8063		.dig_out_nid = ALC883_DIGOUT_NID,
8064		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8065		.channel_mode = alc883_3ST_6ch_modes,
8066		.need_dac_fix = 1,
8067		.input_mux = &alc883_capture_source,
8068		.unsol_event = alc883_tagra_unsol_event,
8069		.init_hook = alc883_tagra_automute,
8070	},
8071	[ALC883_TARGA_2ch_DIG] = {
8072		.mixers = { alc883_tagra_2ch_mixer},
8073		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8074		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8075		.dac_nids = alc883_dac_nids,
8076		.dig_out_nid = ALC883_DIGOUT_NID,
8077		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8078		.channel_mode = alc883_3ST_2ch_modes,
8079		.input_mux = &alc883_capture_source,
8080		.unsol_event = alc883_tagra_unsol_event,
8081		.init_hook = alc883_tagra_automute,
8082	},
8083	[ALC883_ACER] = {
8084		.mixers = { alc883_base_mixer },
8085		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8086		 * and the headphone jack.  Turn this on and rely on the
8087		 * standard mute methods whenever the user wants to turn
8088		 * these outputs off.
8089		 */
8090		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8091		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8092		.dac_nids = alc883_dac_nids,
8093		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8094		.channel_mode = alc883_3ST_2ch_modes,
8095		.input_mux = &alc883_capture_source,
8096	},
8097	[ALC883_ACER_ASPIRE] = {
8098		.mixers = { alc883_acer_aspire_mixer },
8099		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8100		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8101		.dac_nids = alc883_dac_nids,
8102		.dig_out_nid = ALC883_DIGOUT_NID,
8103		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8104		.channel_mode = alc883_3ST_2ch_modes,
8105		.input_mux = &alc883_capture_source,
8106		.unsol_event = alc883_acer_aspire_unsol_event,
8107		.init_hook = alc883_acer_aspire_automute,
8108	},
8109	[ALC883_MEDION] = {
8110		.mixers = { alc883_fivestack_mixer,
8111			    alc883_chmode_mixer },
8112		.init_verbs = { alc883_init_verbs,
8113				alc883_medion_eapd_verbs },
8114		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8115		.dac_nids = alc883_dac_nids,
8116		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8117		.channel_mode = alc883_sixstack_modes,
8118		.input_mux = &alc883_capture_source,
8119	},
8120	[ALC883_MEDION_MD2] = {
8121		.mixers = { alc883_medion_md2_mixer},
8122		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8123		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8124		.dac_nids = alc883_dac_nids,
8125		.dig_out_nid = ALC883_DIGOUT_NID,
8126		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8127		.channel_mode = alc883_3ST_2ch_modes,
8128		.input_mux = &alc883_capture_source,
8129		.unsol_event = alc883_medion_md2_unsol_event,
8130		.init_hook = alc883_medion_md2_automute,
8131	},
8132	[ALC883_LAPTOP_EAPD] = {
8133		.mixers = { alc883_base_mixer },
8134		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8135		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8136		.dac_nids = alc883_dac_nids,
8137		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8138		.channel_mode = alc883_3ST_2ch_modes,
8139		.input_mux = &alc883_capture_source,
8140	},
8141	[ALC883_CLEVO_M720] = {
8142		.mixers = { alc883_clevo_m720_mixer },
8143		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8144		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8145		.dac_nids = alc883_dac_nids,
8146		.dig_out_nid = ALC883_DIGOUT_NID,
8147		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8148		.channel_mode = alc883_3ST_2ch_modes,
8149		.input_mux = &alc883_capture_source,
8150		.unsol_event = alc883_clevo_m720_unsol_event,
8151		.init_hook = alc883_clevo_m720_automute,
8152	},
8153	[ALC883_LENOVO_101E_2ch] = {
8154		.mixers = { alc883_lenovo_101e_2ch_mixer},
8155		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8156		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8157		.dac_nids = alc883_dac_nids,
8158		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8159		.channel_mode = alc883_3ST_2ch_modes,
8160		.input_mux = &alc883_lenovo_101e_capture_source,
8161		.unsol_event = alc883_lenovo_101e_unsol_event,
8162		.init_hook = alc883_lenovo_101e_all_automute,
8163	},
8164	[ALC883_LENOVO_NB0763] = {
8165		.mixers = { alc883_lenovo_nb0763_mixer },
8166		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8167		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8168		.dac_nids = alc883_dac_nids,
8169		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8170		.channel_mode = alc883_3ST_2ch_modes,
8171		.need_dac_fix = 1,
8172		.input_mux = &alc883_lenovo_nb0763_capture_source,
8173		.unsol_event = alc883_medion_md2_unsol_event,
8174		.init_hook = alc883_medion_md2_automute,
8175	},
8176	[ALC888_LENOVO_MS7195_DIG] = {
8177		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8178		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8179		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8180		.dac_nids = alc883_dac_nids,
8181		.dig_out_nid = ALC883_DIGOUT_NID,
8182		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8183		.channel_mode = alc883_3ST_6ch_modes,
8184		.need_dac_fix = 1,
8185		.input_mux = &alc883_capture_source,
8186		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8187		.init_hook = alc888_lenovo_ms7195_front_automute,
8188	},
8189	[ALC883_HAIER_W66] = {
8190		.mixers = { alc883_tagra_2ch_mixer},
8191		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8192		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8193		.dac_nids = alc883_dac_nids,
8194		.dig_out_nid = ALC883_DIGOUT_NID,
8195		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8196		.channel_mode = alc883_3ST_2ch_modes,
8197		.input_mux = &alc883_capture_source,
8198		.unsol_event = alc883_haier_w66_unsol_event,
8199		.init_hook = alc883_haier_w66_automute,
8200	},
8201	[ALC888_3ST_HP] = {
8202		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8203		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8204		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8205		.dac_nids = alc883_dac_nids,
8206		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8207		.channel_mode = alc888_3st_hp_modes,
8208		.need_dac_fix = 1,
8209		.input_mux = &alc883_capture_source,
8210	},
8211	[ALC888_6ST_DELL] = {
8212		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8213		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8214		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8215		.dac_nids = alc883_dac_nids,
8216		.dig_out_nid = ALC883_DIGOUT_NID,
8217		.dig_in_nid = ALC883_DIGIN_NID,
8218		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8219		.channel_mode = alc883_sixstack_modes,
8220		.input_mux = &alc883_capture_source,
8221		.unsol_event = alc888_6st_dell_unsol_event,
8222		.init_hook = alc888_6st_dell_front_automute,
8223	},
8224	[ALC883_MITAC] = {
8225		.mixers = { alc883_mitac_mixer },
8226		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8227		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8228		.dac_nids = alc883_dac_nids,
8229		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8230		.channel_mode = alc883_3ST_2ch_modes,
8231		.input_mux = &alc883_capture_source,
8232		.unsol_event = alc883_mitac_unsol_event,
8233		.init_hook = alc883_mitac_automute,
8234	},
8235	[ALC883_FUJITSU_PI2515] = {
8236		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8237		.init_verbs = { alc883_init_verbs,
8238				alc883_2ch_fujitsu_pi2515_verbs},
8239		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8240		.dac_nids = alc883_dac_nids,
8241		.dig_out_nid = ALC883_DIGOUT_NID,
8242		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8243		.channel_mode = alc883_3ST_2ch_modes,
8244		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8245		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8246		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
8247	},
8248};
8249
8250
8251/*
8252 * BIOS auto configuration
8253 */
8254static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8255					      hda_nid_t nid, int pin_type,
8256					      int dac_idx)
8257{
8258	/* set as output */
8259	struct alc_spec *spec = codec->spec;
8260	int idx;
8261
8262	alc_set_pin_output(codec, nid, pin_type);
8263	if (spec->multiout.dac_nids[dac_idx] == 0x25)
8264		idx = 4;
8265	else
8266		idx = spec->multiout.dac_nids[dac_idx] - 2;
8267	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8268
8269}
8270
8271static void alc883_auto_init_multi_out(struct hda_codec *codec)
8272{
8273	struct alc_spec *spec = codec->spec;
8274	int i;
8275
8276	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8277	for (i = 0; i <= HDA_SIDE; i++) {
8278		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8279		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8280		if (nid)
8281			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8282							  i);
8283	}
8284}
8285
8286static void alc883_auto_init_hp_out(struct hda_codec *codec)
8287{
8288	struct alc_spec *spec = codec->spec;
8289	hda_nid_t pin;
8290
8291	pin = spec->autocfg.hp_pins[0];
8292	if (pin) /* connect to front */
8293		/* use dac 0 */
8294		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8295	pin = spec->autocfg.speaker_pins[0];
8296	if (pin)
8297		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8298}
8299
8300#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
8301#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
8302
8303static void alc883_auto_init_analog_input(struct hda_codec *codec)
8304{
8305	struct alc_spec *spec = codec->spec;
8306	int i;
8307
8308	for (i = 0; i < AUTO_PIN_LAST; i++) {
8309		hda_nid_t nid = spec->autocfg.input_pins[i];
8310		if (alc883_is_input_pin(nid)) {
8311			snd_hda_codec_write(codec, nid, 0,
8312					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8313					    (i <= AUTO_PIN_FRONT_MIC ?
8314					     PIN_VREF80 : PIN_IN));
8315			if (nid != ALC883_PIN_CD_NID)
8316				snd_hda_codec_write(codec, nid, 0,
8317						    AC_VERB_SET_AMP_GAIN_MUTE,
8318						    AMP_OUT_MUTE);
8319		}
8320	}
8321}
8322
8323#define alc883_auto_init_input_src	alc882_auto_init_input_src
8324
8325/* almost identical with ALC880 parser... */
8326static int alc883_parse_auto_config(struct hda_codec *codec)
8327{
8328	struct alc_spec *spec = codec->spec;
8329	int err = alc880_parse_auto_config(codec);
8330
8331	if (err < 0)
8332		return err;
8333	else if (!err)
8334		return 0; /* no config found */
8335
8336	err = alc_auto_add_mic_boost(codec);
8337	if (err < 0)
8338		return err;
8339
8340	/* hack - override the init verbs */
8341	spec->init_verbs[0] = alc883_auto_init_verbs;
8342	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8343	spec->num_mixers++;
8344
8345	return 1; /* config found */
8346}
8347
8348/* additional initialization for auto-configuration model */
8349static void alc883_auto_init(struct hda_codec *codec)
8350{
8351	struct alc_spec *spec = codec->spec;
8352	alc883_auto_init_multi_out(codec);
8353	alc883_auto_init_hp_out(codec);
8354	alc883_auto_init_analog_input(codec);
8355	alc883_auto_init_input_src(codec);
8356	if (spec->unsol_event)
8357		alc_sku_automute(codec);
8358}
8359
8360static int patch_alc883(struct hda_codec *codec)
8361{
8362	struct alc_spec *spec;
8363	int err, board_config;
8364
8365	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8366	if (spec == NULL)
8367		return -ENOMEM;
8368
8369	codec->spec = spec;
8370
8371	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8372
8373	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8374						  alc883_models,
8375						  alc883_cfg_tbl);
8376	if (board_config < 0) {
8377		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8378		       "trying auto-probe from BIOS...\n");
8379		board_config = ALC883_AUTO;
8380	}
8381
8382	if (board_config == ALC883_AUTO) {
8383		/* automatic parse from the BIOS config */
8384		err = alc883_parse_auto_config(codec);
8385		if (err < 0) {
8386			alc_free(codec);
8387			return err;
8388		} else if (!err) {
8389			printk(KERN_INFO
8390			       "hda_codec: Cannot set up configuration "
8391			       "from BIOS.  Using base mode...\n");
8392			board_config = ALC883_3ST_2ch_DIG;
8393		}
8394	}
8395
8396	if (board_config != ALC883_AUTO)
8397		setup_preset(spec, &alc883_presets[board_config]);
8398
8399	switch (codec->vendor_id) {
8400	case 0x10ec0888:
8401		spec->stream_name_analog = "ALC888 Analog";
8402		spec->stream_name_digital = "ALC888 Digital";
8403		break;
8404	case 0x10ec0889:
8405		spec->stream_name_analog = "ALC889 Analog";
8406		spec->stream_name_digital = "ALC889 Digital";
8407		break;
8408	default:
8409		spec->stream_name_analog = "ALC883 Analog";
8410		spec->stream_name_digital = "ALC883 Digital";
8411		break;
8412	}
8413
8414	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8415	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8416	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8417
8418	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8419	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8420
8421	spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8422	spec->adc_nids = alc883_adc_nids;
8423	spec->capsrc_nids = alc883_capsrc_nids;
8424
8425	spec->vmaster_nid = 0x0c;
8426
8427	codec->patch_ops = alc_patch_ops;
8428	if (board_config == ALC883_AUTO)
8429		spec->init_hook = alc883_auto_init;
8430
8431#ifdef CONFIG_SND_HDA_POWER_SAVE
8432	if (!spec->loopback.amplist)
8433		spec->loopback.amplist = alc883_loopbacks;
8434#endif
8435
8436	return 0;
8437}
8438
8439/*
8440 * ALC262 support
8441 */
8442
8443#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8444#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8445
8446#define alc262_dac_nids		alc260_dac_nids
8447#define alc262_adc_nids		alc882_adc_nids
8448#define alc262_adc_nids_alt	alc882_adc_nids_alt
8449#define alc262_capsrc_nids	alc882_capsrc_nids
8450#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8451
8452#define alc262_modes		alc260_modes
8453#define alc262_capture_source	alc882_capture_source
8454
8455static struct snd_kcontrol_new alc262_base_mixer[] = {
8456	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8457	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8458	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8459	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8460	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8461	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8462	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8463	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8464	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8465	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8466	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8467	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8468	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8469	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8470	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8471	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8472	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8473	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8474	{ } /* end */
8475};
8476
8477static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8478	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8479	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8480	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8481	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8482	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8483	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8484	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8485	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8486	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8487	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8488	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8489	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8490	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8491	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8492	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8493	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8494	{ } /* end */
8495};
8496
8497/* update HP, line and mono-out pins according to the master switch */
8498static void alc262_hp_master_update(struct hda_codec *codec)
8499{
8500	struct alc_spec *spec = codec->spec;
8501	int val = spec->master_sw;
8502
8503	/* HP & line-out */
8504	snd_hda_codec_write_cache(codec, 0x1b, 0,
8505				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8506				  val ? PIN_HP : 0);
8507	snd_hda_codec_write_cache(codec, 0x15, 0,
8508				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8509				  val ? PIN_HP : 0);
8510	/* mono (speaker) depending on the HP jack sense */
8511	val = val && !spec->jack_present;
8512	snd_hda_codec_write_cache(codec, 0x16, 0,
8513				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8514				  val ? PIN_OUT : 0);
8515}
8516
8517static void alc262_hp_bpc_automute(struct hda_codec *codec)
8518{
8519	struct alc_spec *spec = codec->spec;
8520	unsigned int presence;
8521	presence = snd_hda_codec_read(codec, 0x1b, 0,
8522				      AC_VERB_GET_PIN_SENSE, 0);
8523	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8524	alc262_hp_master_update(codec);
8525}
8526
8527static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8528{
8529	if ((res >> 26) != ALC880_HP_EVENT)
8530		return;
8531	alc262_hp_bpc_automute(codec);
8532}
8533
8534static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8535{
8536	struct alc_spec *spec = codec->spec;
8537	unsigned int presence;
8538	presence = snd_hda_codec_read(codec, 0x15, 0,
8539				      AC_VERB_GET_PIN_SENSE, 0);
8540	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8541	alc262_hp_master_update(codec);
8542}
8543
8544static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8545					   unsigned int res)
8546{
8547	if ((res >> 26) != ALC880_HP_EVENT)
8548		return;
8549	alc262_hp_wildwest_automute(codec);
8550}
8551
8552static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8553				   struct snd_ctl_elem_value *ucontrol)
8554{
8555	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8556	struct alc_spec *spec = codec->spec;
8557	*ucontrol->value.integer.value = spec->master_sw;
8558	return 0;
8559}
8560
8561static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8562				   struct snd_ctl_elem_value *ucontrol)
8563{
8564	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8565	struct alc_spec *spec = codec->spec;
8566	int val = !!*ucontrol->value.integer.value;
8567
8568	if (val == spec->master_sw)
8569		return 0;
8570	spec->master_sw = val;
8571	alc262_hp_master_update(codec);
8572	return 1;
8573}
8574
8575static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8576	{
8577		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8578		.name = "Master Playback Switch",
8579		.info = snd_ctl_boolean_mono_info,
8580		.get = alc262_hp_master_sw_get,
8581		.put = alc262_hp_master_sw_put,
8582	},
8583	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8584	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8585	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8586	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8587			      HDA_OUTPUT),
8588	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8589			    HDA_OUTPUT),
8590	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8591	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8592	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8593	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8594	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8595	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8596	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8597	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8598	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8599	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8600	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8601	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8602	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8603	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8604	{ } /* end */
8605};
8606
8607static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8608	{
8609		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8610		.name = "Master Playback Switch",
8611		.info = snd_ctl_boolean_mono_info,
8612		.get = alc262_hp_master_sw_get,
8613		.put = alc262_hp_master_sw_put,
8614	},
8615	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8616	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8617	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8618	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8619	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8620			      HDA_OUTPUT),
8621	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8622			    HDA_OUTPUT),
8623	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8624	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8625	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8626	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8627	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8628	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8629	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8630	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8631	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8632	{ } /* end */
8633};
8634
8635static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8636	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8637	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8638	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8639	{ } /* end */
8640};
8641
8642/* mute/unmute internal speaker according to the hp jack and mute state */
8643static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8644{
8645	struct alc_spec *spec = codec->spec;
8646
8647	if (force || !spec->sense_updated) {
8648		unsigned int present;
8649		present = snd_hda_codec_read(codec, 0x15, 0,
8650					     AC_VERB_GET_PIN_SENSE, 0);
8651		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8652		spec->sense_updated = 1;
8653	}
8654	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8655				 spec->jack_present ? HDA_AMP_MUTE : 0);
8656}
8657
8658static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8659					unsigned int res)
8660{
8661	if ((res >> 26) != ALC880_HP_EVENT)
8662		return;
8663	alc262_hp_t5735_automute(codec, 1);
8664}
8665
8666static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8667{
8668	alc262_hp_t5735_automute(codec, 1);
8669}
8670
8671static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8672	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8673	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8674	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8675	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8676	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8677	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8678	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8679	{ } /* end */
8680};
8681
8682static struct hda_verb alc262_hp_t5735_verbs[] = {
8683	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8684	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8685
8686	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8687	{ }
8688};
8689
8690static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8691	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8692	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8693	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8694	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8695	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8696	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8697	{ } /* end */
8698};
8699
8700static struct hda_verb alc262_hp_rp5700_verbs[] = {
8701	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8702	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8703	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8704	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8705	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8706	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8707	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8708	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8709	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8710	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8711	{}
8712};
8713
8714static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8715	.num_items = 1,
8716	.items = {
8717		{ "Line", 0x1 },
8718	},
8719};
8720
8721/* bind hp and internal speaker mute (with plug check) */
8722static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8723				     struct snd_ctl_elem_value *ucontrol)
8724{
8725	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8726	long *valp = ucontrol->value.integer.value;
8727	int change;
8728
8729	/* change hp mute */
8730	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8731					  HDA_AMP_MUTE,
8732					  valp[0] ? 0 : HDA_AMP_MUTE);
8733	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8734					   HDA_AMP_MUTE,
8735					   valp[1] ? 0 : HDA_AMP_MUTE);
8736	if (change) {
8737		/* change speaker according to HP jack state */
8738		struct alc_spec *spec = codec->spec;
8739		unsigned int mute;
8740		if (spec->jack_present)
8741			mute = HDA_AMP_MUTE;
8742		else
8743			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8744						      HDA_OUTPUT, 0);
8745		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8746					 HDA_AMP_MUTE, mute);
8747	}
8748	return change;
8749}
8750
8751static struct snd_kcontrol_new alc262_sony_mixer[] = {
8752	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8753	{
8754		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8755		.name = "Master Playback Switch",
8756		.info = snd_hda_mixer_amp_switch_info,
8757		.get = snd_hda_mixer_amp_switch_get,
8758		.put = alc262_sony_master_sw_put,
8759		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8760	},
8761	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8762	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8763	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8764	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8765	{ } /* end */
8766};
8767
8768static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8769	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8770	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8771	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8772	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8773	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8774	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8775	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8776	{ } /* end */
8777};
8778
8779#define alc262_capture_mixer		alc882_capture_mixer
8780#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
8781
8782/*
8783 * generic initialization of ADC, input mixers and output mixers
8784 */
8785static struct hda_verb alc262_init_verbs[] = {
8786	/*
8787	 * Unmute ADC0-2 and set the default input to mic-in
8788	 */
8789	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8790	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8791	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8792	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8793	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8794	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8795
8796	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8797	 * mixer widget
8798	 * Note: PASD motherboards uses the Line In 2 as the input for
8799	 * front panel mic (mic 2)
8800	 */
8801	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8802	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8803	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8804	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8805	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8806	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8807
8808	/*
8809	 * Set up output mixers (0x0c - 0x0e)
8810	 */
8811	/* set vol=0 to output mixers */
8812	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8813	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8814	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8815	/* set up input amps for analog loopback */
8816	/* Amp Indices: DAC = 0, mixer = 1 */
8817	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8818	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8819	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8820	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8821	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8822	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8823
8824	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8825	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8826	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8827	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8828	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8829	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8830
8831	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8832	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8833	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8834	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8835	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8836
8837	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8838	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8839
8840	/* FIXME: use matrix-type input source selection */
8841	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8842	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8843	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8844	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8845	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8846	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8847	/* Input mixer2 */
8848	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8849	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8850	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8851	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8852	/* Input mixer3 */
8853	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8854	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8855	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8856	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8857
8858	{ }
8859};
8860
8861static struct hda_verb alc262_hippo_unsol_verbs[] = {
8862	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8863	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8864	{}
8865};
8866
8867static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8868	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8869	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8870	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8871
8872	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8873	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8874	{}
8875};
8876
8877static struct hda_verb alc262_sony_unsol_verbs[] = {
8878	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8879	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8880	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
8881
8882	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8883	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8884	{}
8885};
8886
8887/* mute/unmute internal speaker according to the hp jack and mute state */
8888static void alc262_hippo_automute(struct hda_codec *codec)
8889{
8890	struct alc_spec *spec = codec->spec;
8891	unsigned int mute;
8892	unsigned int present;
8893
8894	/* need to execute and sync at first */
8895	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8896	present = snd_hda_codec_read(codec, 0x15, 0,
8897				     AC_VERB_GET_PIN_SENSE, 0);
8898	spec->jack_present = (present & 0x80000000) != 0;
8899	if (spec->jack_present) {
8900		/* mute internal speaker */
8901		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8902					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8903	} else {
8904		/* unmute internal speaker if necessary */
8905		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8906		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8907					 HDA_AMP_MUTE, mute);
8908	}
8909}
8910
8911/* unsolicited event for HP jack sensing */
8912static void alc262_hippo_unsol_event(struct hda_codec *codec,
8913				       unsigned int res)
8914{
8915	if ((res >> 26) != ALC880_HP_EVENT)
8916		return;
8917	alc262_hippo_automute(codec);
8918}
8919
8920static void alc262_hippo1_automute(struct hda_codec *codec)
8921{
8922	unsigned int mute;
8923	unsigned int present;
8924
8925	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8926	present = snd_hda_codec_read(codec, 0x1b, 0,
8927				     AC_VERB_GET_PIN_SENSE, 0);
8928	present = (present & 0x80000000) != 0;
8929	if (present) {
8930		/* mute internal speaker */
8931		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8932					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8933	} else {
8934		/* unmute internal speaker if necessary */
8935		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8936		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8937					 HDA_AMP_MUTE, mute);
8938	}
8939}
8940
8941/* unsolicited event for HP jack sensing */
8942static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8943				       unsigned int res)
8944{
8945	if ((res >> 26) != ALC880_HP_EVENT)
8946		return;
8947	alc262_hippo1_automute(codec);
8948}
8949
8950/*
8951 * fujitsu model
8952 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
8953 *  0x1b = port replicator headphone out
8954 */
8955
8956#define ALC_HP_EVENT	0x37
8957
8958static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8959	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8960	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8961	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8962	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8963	{}
8964};
8965
8966static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
8967	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8968	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8969	{}
8970};
8971
8972static struct hda_input_mux alc262_fujitsu_capture_source = {
8973	.num_items = 3,
8974	.items = {
8975		{ "Mic", 0x0 },
8976		{ "Int Mic", 0x1 },
8977		{ "CD", 0x4 },
8978	},
8979};
8980
8981static struct hda_input_mux alc262_HP_capture_source = {
8982	.num_items = 5,
8983	.items = {
8984		{ "Mic", 0x0 },
8985		{ "Front Mic", 0x1 },
8986		{ "Line", 0x2 },
8987		{ "CD", 0x4 },
8988		{ "AUX IN", 0x6 },
8989	},
8990};
8991
8992static struct hda_input_mux alc262_HP_D7000_capture_source = {
8993	.num_items = 4,
8994	.items = {
8995		{ "Mic", 0x0 },
8996		{ "Front Mic", 0x2 },
8997		{ "Line", 0x1 },
8998		{ "CD", 0x4 },
8999	},
9000};
9001
9002/* mute/unmute internal speaker according to the hp jacks and mute state */
9003static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9004{
9005	struct alc_spec *spec = codec->spec;
9006	unsigned int mute;
9007
9008	if (force || !spec->sense_updated) {
9009		unsigned int present;
9010		/* need to execute and sync at first */
9011		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9012		/* check laptop HP jack */
9013		present = snd_hda_codec_read(codec, 0x14, 0,
9014					     AC_VERB_GET_PIN_SENSE, 0);
9015		/* need to execute and sync at first */
9016		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9017		/* check docking HP jack */
9018		present |= snd_hda_codec_read(codec, 0x1b, 0,
9019					      AC_VERB_GET_PIN_SENSE, 0);
9020		if (present & AC_PINSENSE_PRESENCE)
9021			spec->jack_present = 1;
9022		else
9023			spec->jack_present = 0;
9024		spec->sense_updated = 1;
9025	}
9026	/* unmute internal speaker only if both HPs are unplugged and
9027	 * master switch is on
9028	 */
9029	if (spec->jack_present)
9030		mute = HDA_AMP_MUTE;
9031	else
9032		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9033	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9034				 HDA_AMP_MUTE, mute);
9035}
9036
9037/* unsolicited event for HP jack sensing */
9038static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9039				       unsigned int res)
9040{
9041	if ((res >> 26) != ALC_HP_EVENT)
9042		return;
9043	alc262_fujitsu_automute(codec, 1);
9044}
9045
9046static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9047{
9048	alc262_fujitsu_automute(codec, 1);
9049}
9050
9051/* bind volumes of both NID 0x0c and 0x0d */
9052static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9053	.ops = &snd_hda_bind_vol,
9054	.values = {
9055		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9056		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9057		0
9058	},
9059};
9060
9061/* mute/unmute internal speaker according to the hp jack and mute state */
9062static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9063{
9064	struct alc_spec *spec = codec->spec;
9065	unsigned int mute;
9066
9067	if (force || !spec->sense_updated) {
9068		unsigned int present_int_hp;
9069		/* need to execute and sync at first */
9070		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9071		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9072					AC_VERB_GET_PIN_SENSE, 0);
9073		spec->jack_present = (present_int_hp & 0x80000000) != 0;
9074		spec->sense_updated = 1;
9075	}
9076	if (spec->jack_present) {
9077		/* mute internal speaker */
9078		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9079					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9080		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9081					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9082	} else {
9083		/* unmute internal speaker if necessary */
9084		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9085		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9086					 HDA_AMP_MUTE, mute);
9087		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9088					 HDA_AMP_MUTE, mute);
9089	}
9090}
9091
9092/* unsolicited event for HP jack sensing */
9093static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9094				       unsigned int res)
9095{
9096	if ((res >> 26) != ALC_HP_EVENT)
9097		return;
9098	alc262_lenovo_3000_automute(codec, 1);
9099}
9100
9101/* bind hp and internal speaker mute (with plug check) */
9102static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9103					 struct snd_ctl_elem_value *ucontrol)
9104{
9105	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9106	long *valp = ucontrol->value.integer.value;
9107	int change;
9108
9109	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9110						 HDA_AMP_MUTE,
9111						 valp ? 0 : HDA_AMP_MUTE);
9112	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9113						 HDA_AMP_MUTE,
9114						 valp ? 0 : HDA_AMP_MUTE);
9115
9116	if (change)
9117		alc262_fujitsu_automute(codec, 0);
9118	return change;
9119}
9120
9121static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9122	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9123	{
9124		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9125		.name = "Master Playback Switch",
9126		.info = snd_hda_mixer_amp_switch_info,
9127		.get = snd_hda_mixer_amp_switch_get,
9128		.put = alc262_fujitsu_master_sw_put,
9129		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9130	},
9131	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9132	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9133	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9134	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9135	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9136	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9137	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9138	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9139	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9140	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9141	{ } /* end */
9142};
9143
9144/* bind hp and internal speaker mute (with plug check) */
9145static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9146					 struct snd_ctl_elem_value *ucontrol)
9147{
9148	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9149	long *valp = ucontrol->value.integer.value;
9150	int change;
9151
9152	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9153						 HDA_AMP_MUTE,
9154						 valp ? 0 : HDA_AMP_MUTE);
9155
9156	if (change)
9157		alc262_lenovo_3000_automute(codec, 0);
9158	return change;
9159}
9160
9161static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9162	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9163	{
9164		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9165		.name = "Master Playback Switch",
9166		.info = snd_hda_mixer_amp_switch_info,
9167		.get = snd_hda_mixer_amp_switch_get,
9168		.put = alc262_lenovo_3000_master_sw_put,
9169		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9170	},
9171	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9172	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9173	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9174	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9175	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9176	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9177	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9178	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9179	{ } /* end */
9180};
9181
9182/* additional init verbs for Benq laptops */
9183static struct hda_verb alc262_EAPD_verbs[] = {
9184	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9185	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
9186	{}
9187};
9188
9189static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9190	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9191	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9192
9193	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9194	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
9195	{}
9196};
9197
9198/* Samsung Q1 Ultra Vista model setup */
9199static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9200	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9201	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9202	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9203	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9204	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9205	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9206	{ } /* end */
9207};
9208
9209static struct hda_verb alc262_ultra_verbs[] = {
9210	/* output mixer */
9211	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9212	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9213	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9214	/* speaker */
9215	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9216	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9217	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9218	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9219	/* HP */
9220	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9221	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9222	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9223	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9224	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9225	/* internal mic */
9226	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9227	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9228	/* ADC, choose mic */
9229	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9230	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9231	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9232	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9233	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9234	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9235	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9236	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9237	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9238	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9239	{}
9240};
9241
9242/* mute/unmute internal speaker according to the hp jack and mute state */
9243static void alc262_ultra_automute(struct hda_codec *codec)
9244{
9245	struct alc_spec *spec = codec->spec;
9246	unsigned int mute;
9247
9248	mute = 0;
9249	/* auto-mute only when HP is used as HP */
9250	if (!spec->cur_mux[0]) {
9251		unsigned int present;
9252		/* need to execute and sync at first */
9253		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9254		present = snd_hda_codec_read(codec, 0x15, 0,
9255					     AC_VERB_GET_PIN_SENSE, 0);
9256		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9257		if (spec->jack_present)
9258			mute = HDA_AMP_MUTE;
9259	}
9260	/* mute/unmute internal speaker */
9261	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9262				 HDA_AMP_MUTE, mute);
9263	/* mute/unmute HP */
9264	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9265				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9266}
9267
9268/* unsolicited event for HP jack sensing */
9269static void alc262_ultra_unsol_event(struct hda_codec *codec,
9270				       unsigned int res)
9271{
9272	if ((res >> 26) != ALC880_HP_EVENT)
9273		return;
9274	alc262_ultra_automute(codec);
9275}
9276
9277static struct hda_input_mux alc262_ultra_capture_source = {
9278	.num_items = 2,
9279	.items = {
9280		{ "Mic", 0x1 },
9281		{ "Headphone", 0x7 },
9282	},
9283};
9284
9285static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9286				     struct snd_ctl_elem_value *ucontrol)
9287{
9288	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9289	struct alc_spec *spec = codec->spec;
9290	int ret;
9291
9292	ret = alc882_mux_enum_put(kcontrol, ucontrol);
9293	if (!ret)
9294		return 0;
9295	/* reprogram the HP pin as mic or HP according to the input source */
9296	snd_hda_codec_write_cache(codec, 0x15, 0,
9297				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9298				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9299	alc262_ultra_automute(codec); /* mute/unmute HP */
9300	return ret;
9301}
9302
9303static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9304	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9305	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9306	{
9307		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9308		.name = "Capture Source",
9309		.info = alc882_mux_enum_info,
9310		.get = alc882_mux_enum_get,
9311		.put = alc262_ultra_mux_enum_put,
9312	},
9313	{ } /* end */
9314};
9315
9316/* add playback controls from the parsed DAC table */
9317static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9318					     const struct auto_pin_cfg *cfg)
9319{
9320	hda_nid_t nid;
9321	int err;
9322
9323	spec->multiout.num_dacs = 1;	/* only use one dac */
9324	spec->multiout.dac_nids = spec->private_dac_nids;
9325	spec->multiout.dac_nids[0] = 2;
9326
9327	nid = cfg->line_out_pins[0];
9328	if (nid) {
9329		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9330				  "Front Playback Volume",
9331				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9332		if (err < 0)
9333			return err;
9334		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9335				  "Front Playback Switch",
9336				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9337		if (err < 0)
9338			return err;
9339	}
9340
9341	nid = cfg->speaker_pins[0];
9342	if (nid) {
9343		if (nid == 0x16) {
9344			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9345					  "Speaker Playback Volume",
9346					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9347							      HDA_OUTPUT));
9348			if (err < 0)
9349				return err;
9350			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9351					  "Speaker Playback Switch",
9352					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9353							      HDA_OUTPUT));
9354			if (err < 0)
9355				return err;
9356		} else {
9357			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9358					  "Speaker Playback Switch",
9359					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9360							      HDA_OUTPUT));
9361			if (err < 0)
9362				return err;
9363		}
9364	}
9365	nid = cfg->hp_pins[0];
9366	if (nid) {
9367		/* spec->multiout.hp_nid = 2; */
9368		if (nid == 0x16) {
9369			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9370					  "Headphone Playback Volume",
9371					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9372							      HDA_OUTPUT));
9373			if (err < 0)
9374				return err;
9375			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9376					  "Headphone Playback Switch",
9377					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9378							      HDA_OUTPUT));
9379			if (err < 0)
9380				return err;
9381		} else {
9382			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9383					  "Headphone Playback Switch",
9384					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9385							      HDA_OUTPUT));
9386			if (err < 0)
9387				return err;
9388		}
9389	}
9390	return 0;
9391}
9392
9393/* identical with ALC880 */
9394#define alc262_auto_create_analog_input_ctls \
9395	alc880_auto_create_analog_input_ctls
9396
9397/*
9398 * generic initialization of ADC, input mixers and output mixers
9399 */
9400static struct hda_verb alc262_volume_init_verbs[] = {
9401	/*
9402	 * Unmute ADC0-2 and set the default input to mic-in
9403	 */
9404	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9405	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9406	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9407	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9408	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9409	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9410
9411	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9412	 * mixer widget
9413	 * Note: PASD motherboards uses the Line In 2 as the input for
9414	 * front panel mic (mic 2)
9415	 */
9416	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9417	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9418	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9419	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9420	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9421	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9422
9423	/*
9424	 * Set up output mixers (0x0c - 0x0f)
9425	 */
9426	/* set vol=0 to output mixers */
9427	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9428	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9429	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9430
9431	/* set up input amps for analog loopback */
9432	/* Amp Indices: DAC = 0, mixer = 1 */
9433	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9434	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9435	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9436	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9437	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9438	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9439
9440	/* FIXME: use matrix-type input source selection */
9441	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9442	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9443	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9444	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9445	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9446	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9447	/* Input mixer2 */
9448	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9449	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9450	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9451	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9452	/* Input mixer3 */
9453	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9454	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9455	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9456	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9457
9458	{ }
9459};
9460
9461static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9462	/*
9463	 * Unmute ADC0-2 and set the default input to mic-in
9464	 */
9465	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9466	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9467	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9468	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9469	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9470	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9471
9472	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9473	 * mixer widget
9474	 * Note: PASD motherboards uses the Line In 2 as the input for
9475	 * front panel mic (mic 2)
9476	 */
9477	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9478	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9479	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9480	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9481	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9482	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9483	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9484        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9485
9486	/*
9487	 * Set up output mixers (0x0c - 0x0e)
9488	 */
9489	/* set vol=0 to output mixers */
9490	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9491	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9492	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9493
9494	/* set up input amps for analog loopback */
9495	/* Amp Indices: DAC = 0, mixer = 1 */
9496	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9497	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9498	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9499	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9500	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9501	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9502
9503	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9504	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9505	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9506
9507	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9508	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9509
9510	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9511	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9512
9513	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9514	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9515        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9516	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9517	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9518
9519	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9520	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9521        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9522	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9523	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9524	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9525
9526
9527	/* FIXME: use matrix-type input source selection */
9528	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9529	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9530	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9531	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9532	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9533	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9534	/* Input mixer2 */
9535	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9536	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9537	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9538	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9539	/* Input mixer3 */
9540	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9541	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9542	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9543	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9544
9545	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9546
9547	{ }
9548};
9549
9550static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9551	/*
9552	 * Unmute ADC0-2 and set the default input to mic-in
9553	 */
9554	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9555	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9556	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9557	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9558	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9559	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9560
9561	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9562	 * mixer widget
9563	 * Note: PASD motherboards uses the Line In 2 as the input for front
9564	 * panel mic (mic 2)
9565	 */
9566	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9567	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9568	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9569	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9570	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9571	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9572	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9573	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9574	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9575	/*
9576	 * Set up output mixers (0x0c - 0x0e)
9577	 */
9578	/* set vol=0 to output mixers */
9579	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9580	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9581	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9582
9583	/* set up input amps for analog loopback */
9584	/* Amp Indices: DAC = 0, mixer = 1 */
9585	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9586	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9587	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9588	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9589	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9590	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9591
9592
9593	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
9594	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
9595	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
9596	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
9597	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
9598	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
9599	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
9600
9601	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9602	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9603
9604	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9605	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9606
9607	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9608	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9609	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9610	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9611	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9612	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9613
9614	/* FIXME: use matrix-type input source selection */
9615	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9616	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9617	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9618	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9619	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9620	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9621	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9622        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
9623	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9624	/* Input mixer2 */
9625	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9626	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9627	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9628	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9629	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9630        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9631	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9632	/* Input mixer3 */
9633	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9634	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9635	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9636	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9637	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9638        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9639	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9640
9641	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9642
9643	{ }
9644};
9645
9646#ifdef CONFIG_SND_HDA_POWER_SAVE
9647#define alc262_loopbacks	alc880_loopbacks
9648#endif
9649
9650/* pcm configuration: identiacal with ALC880 */
9651#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
9652#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
9653#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
9654#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
9655
9656/*
9657 * BIOS auto configuration
9658 */
9659static int alc262_parse_auto_config(struct hda_codec *codec)
9660{
9661	struct alc_spec *spec = codec->spec;
9662	int err;
9663	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9664
9665	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9666					   alc262_ignore);
9667	if (err < 0)
9668		return err;
9669	if (!spec->autocfg.line_outs)
9670		return 0; /* can't find valid BIOS pin config */
9671	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9672	if (err < 0)
9673		return err;
9674	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9675	if (err < 0)
9676		return err;
9677
9678	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9679
9680	if (spec->autocfg.dig_out_pin)
9681		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9682	if (spec->autocfg.dig_in_pin)
9683		spec->dig_in_nid = ALC262_DIGIN_NID;
9684
9685	if (spec->kctl_alloc)
9686		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9687
9688	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
9689	spec->num_mux_defs = 1;
9690	spec->input_mux = &spec->private_imux;
9691
9692	err = alc_auto_add_mic_boost(codec);
9693	if (err < 0)
9694		return err;
9695
9696	return 1;
9697}
9698
9699#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
9700#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
9701#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
9702#define alc262_auto_init_input_src	alc882_auto_init_input_src
9703
9704
9705/* init callback for auto-configuration model -- overriding the default init */
9706static void alc262_auto_init(struct hda_codec *codec)
9707{
9708	struct alc_spec *spec = codec->spec;
9709	alc262_auto_init_multi_out(codec);
9710	alc262_auto_init_hp_out(codec);
9711	alc262_auto_init_analog_input(codec);
9712	alc262_auto_init_input_src(codec);
9713	if (spec->unsol_event)
9714		alc_sku_automute(codec);
9715}
9716
9717/*
9718 * configuration and preset
9719 */
9720static const char *alc262_models[ALC262_MODEL_LAST] = {
9721	[ALC262_BASIC]		= "basic",
9722	[ALC262_HIPPO]		= "hippo",
9723	[ALC262_HIPPO_1]	= "hippo_1",
9724	[ALC262_FUJITSU]	= "fujitsu",
9725	[ALC262_HP_BPC]		= "hp-bpc",
9726	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
9727	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
9728	[ALC262_HP_RP5700]	= "hp-rp5700",
9729	[ALC262_BENQ_ED8]	= "benq",
9730	[ALC262_BENQ_T31]	= "benq-t31",
9731	[ALC262_SONY_ASSAMD]	= "sony-assamd",
9732	[ALC262_ULTRA]		= "ultra",
9733	[ALC262_LENOVO_3000]	= "lenovo-3000",
9734	[ALC262_AUTO]		= "auto",
9735};
9736
9737static struct snd_pci_quirk alc262_cfg_tbl[] = {
9738	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9739	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9740	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9741	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9742	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
9743	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
9744	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
9745	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
9746	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
9747	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
9748	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
9749	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
9750	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
9751	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
9752	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
9753	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
9754	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
9755	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9756	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9757	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
9758	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9759		      ALC262_HP_TC_T5735),
9760	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
9761	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9762	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
9763	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9764	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9765	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9766	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9767		      ALC262_SONY_ASSAMD),
9768	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9769	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9770	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
9771	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
9772	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
9773	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9774	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9775	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
9776	{}
9777};
9778
9779static struct alc_config_preset alc262_presets[] = {
9780	[ALC262_BASIC] = {
9781		.mixers = { alc262_base_mixer },
9782		.init_verbs = { alc262_init_verbs },
9783		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9784		.dac_nids = alc262_dac_nids,
9785		.hp_nid = 0x03,
9786		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9787		.channel_mode = alc262_modes,
9788		.input_mux = &alc262_capture_source,
9789	},
9790	[ALC262_HIPPO] = {
9791		.mixers = { alc262_base_mixer },
9792		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9793		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9794		.dac_nids = alc262_dac_nids,
9795		.hp_nid = 0x03,
9796		.dig_out_nid = ALC262_DIGOUT_NID,
9797		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9798		.channel_mode = alc262_modes,
9799		.input_mux = &alc262_capture_source,
9800		.unsol_event = alc262_hippo_unsol_event,
9801		.init_hook = alc262_hippo_automute,
9802	},
9803	[ALC262_HIPPO_1] = {
9804		.mixers = { alc262_hippo1_mixer },
9805		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9806		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9807		.dac_nids = alc262_dac_nids,
9808		.hp_nid = 0x02,
9809		.dig_out_nid = ALC262_DIGOUT_NID,
9810		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9811		.channel_mode = alc262_modes,
9812		.input_mux = &alc262_capture_source,
9813		.unsol_event = alc262_hippo1_unsol_event,
9814		.init_hook = alc262_hippo1_automute,
9815	},
9816	[ALC262_FUJITSU] = {
9817		.mixers = { alc262_fujitsu_mixer },
9818		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9819				alc262_fujitsu_unsol_verbs },
9820		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9821		.dac_nids = alc262_dac_nids,
9822		.hp_nid = 0x03,
9823		.dig_out_nid = ALC262_DIGOUT_NID,
9824		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9825		.channel_mode = alc262_modes,
9826		.input_mux = &alc262_fujitsu_capture_source,
9827		.unsol_event = alc262_fujitsu_unsol_event,
9828		.init_hook = alc262_fujitsu_init_hook,
9829	},
9830	[ALC262_HP_BPC] = {
9831		.mixers = { alc262_HP_BPC_mixer },
9832		.init_verbs = { alc262_HP_BPC_init_verbs },
9833		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9834		.dac_nids = alc262_dac_nids,
9835		.hp_nid = 0x03,
9836		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9837		.channel_mode = alc262_modes,
9838		.input_mux = &alc262_HP_capture_source,
9839		.unsol_event = alc262_hp_bpc_unsol_event,
9840		.init_hook = alc262_hp_bpc_automute,
9841	},
9842	[ALC262_HP_BPC_D7000_WF] = {
9843		.mixers = { alc262_HP_BPC_WildWest_mixer },
9844		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9845		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9846		.dac_nids = alc262_dac_nids,
9847		.hp_nid = 0x03,
9848		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9849		.channel_mode = alc262_modes,
9850		.input_mux = &alc262_HP_D7000_capture_source,
9851		.unsol_event = alc262_hp_wildwest_unsol_event,
9852		.init_hook = alc262_hp_wildwest_automute,
9853	},
9854	[ALC262_HP_BPC_D7000_WL] = {
9855		.mixers = { alc262_HP_BPC_WildWest_mixer,
9856			    alc262_HP_BPC_WildWest_option_mixer },
9857		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9858		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9859		.dac_nids = alc262_dac_nids,
9860		.hp_nid = 0x03,
9861		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9862		.channel_mode = alc262_modes,
9863		.input_mux = &alc262_HP_D7000_capture_source,
9864		.unsol_event = alc262_hp_wildwest_unsol_event,
9865		.init_hook = alc262_hp_wildwest_automute,
9866	},
9867	[ALC262_HP_TC_T5735] = {
9868		.mixers = { alc262_hp_t5735_mixer },
9869		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9870		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9871		.dac_nids = alc262_dac_nids,
9872		.hp_nid = 0x03,
9873		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9874		.channel_mode = alc262_modes,
9875		.input_mux = &alc262_capture_source,
9876		.unsol_event = alc262_hp_t5735_unsol_event,
9877		.init_hook = alc262_hp_t5735_init_hook,
9878	},
9879	[ALC262_HP_RP5700] = {
9880		.mixers = { alc262_hp_rp5700_mixer },
9881		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9882		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9883		.dac_nids = alc262_dac_nids,
9884		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9885		.channel_mode = alc262_modes,
9886		.input_mux = &alc262_hp_rp5700_capture_source,
9887        },
9888	[ALC262_BENQ_ED8] = {
9889		.mixers = { alc262_base_mixer },
9890		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9891		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9892		.dac_nids = alc262_dac_nids,
9893		.hp_nid = 0x03,
9894		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9895		.channel_mode = alc262_modes,
9896		.input_mux = &alc262_capture_source,
9897	},
9898	[ALC262_SONY_ASSAMD] = {
9899		.mixers = { alc262_sony_mixer },
9900		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9901		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9902		.dac_nids = alc262_dac_nids,
9903		.hp_nid = 0x02,
9904		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9905		.channel_mode = alc262_modes,
9906		.input_mux = &alc262_capture_source,
9907		.unsol_event = alc262_hippo_unsol_event,
9908		.init_hook = alc262_hippo_automute,
9909	},
9910	[ALC262_BENQ_T31] = {
9911		.mixers = { alc262_benq_t31_mixer },
9912		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9913		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9914		.dac_nids = alc262_dac_nids,
9915		.hp_nid = 0x03,
9916		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9917		.channel_mode = alc262_modes,
9918		.input_mux = &alc262_capture_source,
9919		.unsol_event = alc262_hippo_unsol_event,
9920		.init_hook = alc262_hippo_automute,
9921	},
9922	[ALC262_ULTRA] = {
9923		.mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
9924		.init_verbs = { alc262_ultra_verbs },
9925		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9926		.dac_nids = alc262_dac_nids,
9927		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9928		.channel_mode = alc262_modes,
9929		.input_mux = &alc262_ultra_capture_source,
9930		.adc_nids = alc262_adc_nids, /* ADC0 */
9931		.capsrc_nids = alc262_capsrc_nids,
9932		.num_adc_nids = 1, /* single ADC */
9933		.unsol_event = alc262_ultra_unsol_event,
9934		.init_hook = alc262_ultra_automute,
9935	},
9936	[ALC262_LENOVO_3000] = {
9937		.mixers = { alc262_lenovo_3000_mixer },
9938		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9939				alc262_lenovo_3000_unsol_verbs },
9940		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9941		.dac_nids = alc262_dac_nids,
9942		.hp_nid = 0x03,
9943		.dig_out_nid = ALC262_DIGOUT_NID,
9944		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9945		.channel_mode = alc262_modes,
9946		.input_mux = &alc262_fujitsu_capture_source,
9947		.unsol_event = alc262_lenovo_3000_unsol_event,
9948	},
9949};
9950
9951static int patch_alc262(struct hda_codec *codec)
9952{
9953	struct alc_spec *spec;
9954	int board_config;
9955	int err;
9956
9957	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9958	if (spec == NULL)
9959		return -ENOMEM;
9960
9961	codec->spec = spec;
9962#if 0
9963	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
9964	 * under-run
9965	 */
9966	{
9967	int tmp;
9968	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9969	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9970	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9971	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9972	}
9973#endif
9974
9975	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9976
9977	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9978						  alc262_models,
9979						  alc262_cfg_tbl);
9980
9981	if (board_config < 0) {
9982		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9983		       "trying auto-probe from BIOS...\n");
9984		board_config = ALC262_AUTO;
9985	}
9986
9987	if (board_config == ALC262_AUTO) {
9988		/* automatic parse from the BIOS config */
9989		err = alc262_parse_auto_config(codec);
9990		if (err < 0) {
9991			alc_free(codec);
9992			return err;
9993		} else if (!err) {
9994			printk(KERN_INFO
9995			       "hda_codec: Cannot set up configuration "
9996			       "from BIOS.  Using base mode...\n");
9997			board_config = ALC262_BASIC;
9998		}
9999	}
10000
10001	if (board_config != ALC262_AUTO)
10002		setup_preset(spec, &alc262_presets[board_config]);
10003
10004	spec->stream_name_analog = "ALC262 Analog";
10005	spec->stream_analog_playback = &alc262_pcm_analog_playback;
10006	spec->stream_analog_capture = &alc262_pcm_analog_capture;
10007
10008	spec->stream_name_digital = "ALC262 Digital";
10009	spec->stream_digital_playback = &alc262_pcm_digital_playback;
10010	spec->stream_digital_capture = &alc262_pcm_digital_capture;
10011
10012	if (!spec->adc_nids && spec->input_mux) {
10013		/* check whether NID 0x07 is valid */
10014		unsigned int wcap = get_wcaps(codec, 0x07);
10015
10016		/* get type */
10017		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10018		if (wcap != AC_WID_AUD_IN) {
10019			spec->adc_nids = alc262_adc_nids_alt;
10020			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10021			spec->capsrc_nids = alc262_capsrc_nids_alt;
10022			spec->mixers[spec->num_mixers] =
10023				alc262_capture_alt_mixer;
10024			spec->num_mixers++;
10025		} else {
10026			spec->adc_nids = alc262_adc_nids;
10027			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10028			spec->capsrc_nids = alc262_capsrc_nids;
10029			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10030			spec->num_mixers++;
10031		}
10032	}
10033
10034	spec->vmaster_nid = 0x0c;
10035
10036	codec->patch_ops = alc_patch_ops;
10037	if (board_config == ALC262_AUTO)
10038		spec->init_hook = alc262_auto_init;
10039#ifdef CONFIG_SND_HDA_POWER_SAVE
10040	if (!spec->loopback.amplist)
10041		spec->loopback.amplist = alc262_loopbacks;
10042#endif
10043
10044	return 0;
10045}
10046
10047/*
10048 *  ALC268 channel source setting (2 channel)
10049 */
10050#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
10051#define alc268_modes		alc260_modes
10052
10053static hda_nid_t alc268_dac_nids[2] = {
10054	/* front, hp */
10055	0x02, 0x03
10056};
10057
10058static hda_nid_t alc268_adc_nids[2] = {
10059	/* ADC0-1 */
10060	0x08, 0x07
10061};
10062
10063static hda_nid_t alc268_adc_nids_alt[1] = {
10064	/* ADC0 */
10065	0x08
10066};
10067
10068static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10069
10070static struct snd_kcontrol_new alc268_base_mixer[] = {
10071	/* output mixer control */
10072	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10073	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10074	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10075	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10076	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10077	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10078	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10079	{ }
10080};
10081
10082/* bind Beep switches of both NID 0x0f and 0x10 */
10083static struct hda_bind_ctls alc268_bind_beep_sw = {
10084	.ops = &snd_hda_bind_sw,
10085	.values = {
10086		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10087		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10088		0
10089	},
10090};
10091
10092static struct snd_kcontrol_new alc268_beep_mixer[] = {
10093	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10094	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10095	{ }
10096};
10097
10098static struct hda_verb alc268_eapd_verbs[] = {
10099	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10100	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10101	{ }
10102};
10103
10104/* Toshiba specific */
10105#define alc268_toshiba_automute	alc262_hippo_automute
10106
10107static struct hda_verb alc268_toshiba_verbs[] = {
10108	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10109	{ } /* end */
10110};
10111
10112/* Acer specific */
10113/* bind volumes of both NID 0x02 and 0x03 */
10114static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10115	.ops = &snd_hda_bind_vol,
10116	.values = {
10117		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10118		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10119		0
10120	},
10121};
10122
10123/* mute/unmute internal speaker according to the hp jack and mute state */
10124static void alc268_acer_automute(struct hda_codec *codec, int force)
10125{
10126	struct alc_spec *spec = codec->spec;
10127	unsigned int mute;
10128
10129	if (force || !spec->sense_updated) {
10130		unsigned int present;
10131		present = snd_hda_codec_read(codec, 0x14, 0,
10132				    	 AC_VERB_GET_PIN_SENSE, 0);
10133		spec->jack_present = (present & 0x80000000) != 0;
10134		spec->sense_updated = 1;
10135	}
10136	if (spec->jack_present)
10137		mute = HDA_AMP_MUTE; /* mute internal speaker */
10138	else /* unmute internal speaker if necessary */
10139		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10140	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10141				 HDA_AMP_MUTE, mute);
10142}
10143
10144
10145/* bind hp and internal speaker mute (with plug check) */
10146static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10147				     struct snd_ctl_elem_value *ucontrol)
10148{
10149	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10150	long *valp = ucontrol->value.integer.value;
10151	int change;
10152
10153	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10154					  HDA_AMP_MUTE,
10155					  valp[0] ? 0 : HDA_AMP_MUTE);
10156	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10157					   HDA_AMP_MUTE,
10158					   valp[1] ? 0 : HDA_AMP_MUTE);
10159	if (change)
10160		alc268_acer_automute(codec, 0);
10161	return change;
10162}
10163
10164static struct snd_kcontrol_new alc268_acer_mixer[] = {
10165	/* output mixer control */
10166	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10167	{
10168		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10169		.name = "Master Playback Switch",
10170		.info = snd_hda_mixer_amp_switch_info,
10171		.get = snd_hda_mixer_amp_switch_get,
10172		.put = alc268_acer_master_sw_put,
10173		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10174	},
10175	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10176	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10177	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10178	{ }
10179};
10180
10181static struct hda_verb alc268_acer_verbs[] = {
10182	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10183	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10184	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10185	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10186	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10187	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10188
10189	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10190	{ }
10191};
10192
10193/* unsolicited event for HP jack sensing */
10194static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10195				       unsigned int res)
10196{
10197	if ((res >> 26) != ALC880_HP_EVENT)
10198		return;
10199	alc268_toshiba_automute(codec);
10200}
10201
10202static void alc268_acer_unsol_event(struct hda_codec *codec,
10203				       unsigned int res)
10204{
10205	if ((res >> 26) != ALC880_HP_EVENT)
10206		return;
10207	alc268_acer_automute(codec, 1);
10208}
10209
10210static void alc268_acer_init_hook(struct hda_codec *codec)
10211{
10212	alc268_acer_automute(codec, 1);
10213}
10214
10215static struct snd_kcontrol_new alc268_dell_mixer[] = {
10216	/* output mixer control */
10217	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10218	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10219	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10220	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10221	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10222	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10223	{ }
10224};
10225
10226static struct hda_verb alc268_dell_verbs[] = {
10227	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10228	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10229	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10230	{ }
10231};
10232
10233/* mute/unmute internal speaker according to the hp jack and mute state */
10234static void alc268_dell_automute(struct hda_codec *codec)
10235{
10236	unsigned int present;
10237	unsigned int mute;
10238
10239	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10240	if (present & 0x80000000)
10241		mute = HDA_AMP_MUTE;
10242	else
10243		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10244	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10245				 HDA_AMP_MUTE, mute);
10246}
10247
10248static void alc268_dell_unsol_event(struct hda_codec *codec,
10249				    unsigned int res)
10250{
10251	if ((res >> 26) != ALC880_HP_EVENT)
10252		return;
10253	alc268_dell_automute(codec);
10254}
10255
10256#define alc268_dell_init_hook	alc268_dell_automute
10257
10258static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10259	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10260	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10261	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10262	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10263	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10264	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10265	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10266	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10267	{ }
10268};
10269
10270static struct hda_verb alc267_quanta_il1_verbs[] = {
10271	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10272	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10273	{ }
10274};
10275
10276static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10277{
10278	unsigned int present;
10279
10280	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10281		& AC_PINSENSE_PRESENCE;
10282	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10283			    present ? 0 : PIN_OUT);
10284}
10285
10286static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10287{
10288	unsigned int present;
10289
10290	present = snd_hda_codec_read(codec, 0x18, 0,
10291				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10292	snd_hda_codec_write(codec, 0x23, 0,
10293			    AC_VERB_SET_CONNECT_SEL,
10294			    present ? 0x00 : 0x01);
10295}
10296
10297static void alc267_quanta_il1_automute(struct hda_codec *codec)
10298{
10299	alc267_quanta_il1_hp_automute(codec);
10300	alc267_quanta_il1_mic_automute(codec);
10301}
10302
10303static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10304					   unsigned int res)
10305{
10306	switch (res >> 26) {
10307	case ALC880_HP_EVENT:
10308		alc267_quanta_il1_hp_automute(codec);
10309		break;
10310	case ALC880_MIC_EVENT:
10311		alc267_quanta_il1_mic_automute(codec);
10312		break;
10313	}
10314}
10315
10316/*
10317 * generic initialization of ADC, input mixers and output mixers
10318 */
10319static struct hda_verb alc268_base_init_verbs[] = {
10320	/* Unmute DAC0-1 and set vol = 0 */
10321	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10322	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10323	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10324	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10325	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10326	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10327
10328	/*
10329	 * Set up output mixers (0x0c - 0x0e)
10330	 */
10331	/* set vol=0 to output mixers */
10332	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10333	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10334	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10335        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10336
10337	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10338	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10339
10340	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10341	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10342	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10343	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10344	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10345	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10346	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10347	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10348
10349	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10350	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10351	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10352	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10353	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10354	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10355	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10356
10357	/* set PCBEEP vol = 0, mute connections */
10358	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10359	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10360	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10361
10362	/* Unmute Selector 23h,24h and set the default input to mic-in */
10363
10364	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10365	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10366	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10367	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10368
10369	{ }
10370};
10371
10372/*
10373 * generic initialization of ADC, input mixers and output mixers
10374 */
10375static struct hda_verb alc268_volume_init_verbs[] = {
10376	/* set output DAC */
10377	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10378	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10379	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10380	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10381
10382	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10383	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10384	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10385	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10386	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10387
10388	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10389	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10390	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10391	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10392	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10393
10394	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10395	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10396	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10397	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10398
10399	/* set PCBEEP vol = 0, mute connections */
10400	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10401	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10402	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10403
10404	{ }
10405};
10406
10407#define alc268_mux_enum_info alc_mux_enum_info
10408#define alc268_mux_enum_get alc_mux_enum_get
10409#define alc268_mux_enum_put alc_mux_enum_put
10410
10411static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10412	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10413	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10414	{
10415		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10416		/* The multiple "Capture Source" controls confuse alsamixer
10417		 * So call somewhat different..
10418		 */
10419		/* .name = "Capture Source", */
10420		.name = "Input Source",
10421		.count = 1,
10422		.info = alc268_mux_enum_info,
10423		.get = alc268_mux_enum_get,
10424		.put = alc268_mux_enum_put,
10425	},
10426	{ } /* end */
10427};
10428
10429static struct snd_kcontrol_new alc268_capture_mixer[] = {
10430	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10431	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10432	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
10433	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
10434	{
10435		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10436		/* The multiple "Capture Source" controls confuse alsamixer
10437		 * So call somewhat different..
10438		 */
10439		/* .name = "Capture Source", */
10440		.name = "Input Source",
10441		.count = 2,
10442		.info = alc268_mux_enum_info,
10443		.get = alc268_mux_enum_get,
10444		.put = alc268_mux_enum_put,
10445	},
10446	{ } /* end */
10447};
10448
10449static struct hda_input_mux alc268_capture_source = {
10450	.num_items = 4,
10451	.items = {
10452		{ "Mic", 0x0 },
10453		{ "Front Mic", 0x1 },
10454		{ "Line", 0x2 },
10455		{ "CD", 0x3 },
10456	},
10457};
10458
10459static struct hda_input_mux alc268_acer_capture_source = {
10460	.num_items = 3,
10461	.items = {
10462		{ "Mic", 0x0 },
10463		{ "Internal Mic", 0x6 },
10464		{ "Line", 0x2 },
10465	},
10466};
10467
10468#ifdef CONFIG_SND_DEBUG
10469static struct snd_kcontrol_new alc268_test_mixer[] = {
10470	/* Volume widgets */
10471	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10472	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10473	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10474	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
10475	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
10476	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
10477	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
10478	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
10479	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
10480	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
10481	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
10482	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
10483	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
10484	/* The below appears problematic on some hardwares */
10485	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
10486	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10487	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
10488	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
10489	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
10490
10491	/* Modes for retasking pin widgets */
10492	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
10493	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
10494	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
10495	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
10496
10497	/* Controls for GPIO pins, assuming they are configured as outputs */
10498	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
10499	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
10500	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
10501	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
10502
10503	/* Switches to allow the digital SPDIF output pin to be enabled.
10504	 * The ALC268 does not have an SPDIF input.
10505	 */
10506	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
10507
10508	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
10509	 * this output to turn on an external amplifier.
10510	 */
10511	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
10512	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
10513
10514	{ } /* end */
10515};
10516#endif
10517
10518/* create input playback/capture controls for the given pin */
10519static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
10520				    const char *ctlname, int idx)
10521{
10522	char name[32];
10523	int err;
10524
10525	sprintf(name, "%s Playback Volume", ctlname);
10526	if (nid == 0x14) {
10527		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10528				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
10529						      HDA_OUTPUT));
10530		if (err < 0)
10531			return err;
10532	} else if (nid == 0x15) {
10533		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10534				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
10535						      HDA_OUTPUT));
10536		if (err < 0)
10537			return err;
10538	} else
10539		return -1;
10540	sprintf(name, "%s Playback Switch", ctlname);
10541	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10542			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
10543	if (err < 0)
10544		return err;
10545	return 0;
10546}
10547
10548/* add playback controls from the parsed DAC table */
10549static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10550					     const struct auto_pin_cfg *cfg)
10551{
10552	hda_nid_t nid;
10553	int err;
10554
10555	spec->multiout.num_dacs = 2;	/* only use one dac */
10556	spec->multiout.dac_nids = spec->private_dac_nids;
10557	spec->multiout.dac_nids[0] = 2;
10558	spec->multiout.dac_nids[1] = 3;
10559
10560	nid = cfg->line_out_pins[0];
10561	if (nid)
10562		alc268_new_analog_output(spec, nid, "Front", 0);
10563
10564	nid = cfg->speaker_pins[0];
10565	if (nid == 0x1d) {
10566		err = add_control(spec, ALC_CTL_WIDGET_VOL,
10567				  "Speaker Playback Volume",
10568				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10569		if (err < 0)
10570			return err;
10571	}
10572	nid = cfg->hp_pins[0];
10573	if (nid)
10574		alc268_new_analog_output(spec, nid, "Headphone", 0);
10575
10576	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
10577	if (nid == 0x16) {
10578		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10579				  "Mono Playback Switch",
10580				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
10581		if (err < 0)
10582			return err;
10583	}
10584	return 0;
10585}
10586
10587/* create playback/capture controls for input pins */
10588static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10589						const struct auto_pin_cfg *cfg)
10590{
10591	struct hda_input_mux *imux = &spec->private_imux;
10592	int i, idx1;
10593
10594	for (i = 0; i < AUTO_PIN_LAST; i++) {
10595		switch(cfg->input_pins[i]) {
10596		case 0x18:
10597			idx1 = 0;	/* Mic 1 */
10598			break;
10599		case 0x19:
10600			idx1 = 1;	/* Mic 2 */
10601			break;
10602		case 0x1a:
10603			idx1 = 2;	/* Line In */
10604			break;
10605		case 0x1c:
10606			idx1 = 3;	/* CD */
10607			break;
10608		case 0x12:
10609		case 0x13:
10610			idx1 = 6;	/* digital mics */
10611			break;
10612		default:
10613			continue;
10614		}
10615		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10616		imux->items[imux->num_items].index = idx1;
10617		imux->num_items++;
10618	}
10619	return 0;
10620}
10621
10622static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10623{
10624	struct alc_spec *spec = codec->spec;
10625	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10626	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10627	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10628	unsigned int	dac_vol1, dac_vol2;
10629
10630	if (speaker_nid) {
10631		snd_hda_codec_write(codec, speaker_nid, 0,
10632				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10633		snd_hda_codec_write(codec, 0x0f, 0,
10634				    AC_VERB_SET_AMP_GAIN_MUTE,
10635				    AMP_IN_UNMUTE(1));
10636		snd_hda_codec_write(codec, 0x10, 0,
10637				    AC_VERB_SET_AMP_GAIN_MUTE,
10638				    AMP_IN_UNMUTE(1));
10639	} else {
10640		snd_hda_codec_write(codec, 0x0f, 0,
10641				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10642		snd_hda_codec_write(codec, 0x10, 0,
10643				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10644	}
10645
10646	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
10647	if (line_nid == 0x14)
10648		dac_vol2 = AMP_OUT_ZERO;
10649	else if (line_nid == 0x15)
10650		dac_vol1 = AMP_OUT_ZERO;
10651	if (hp_nid == 0x14)
10652		dac_vol2 = AMP_OUT_ZERO;
10653	else if (hp_nid == 0x15)
10654		dac_vol1 = AMP_OUT_ZERO;
10655	if (line_nid != 0x16 || hp_nid != 0x16 ||
10656	    spec->autocfg.line_out_pins[1] != 0x16 ||
10657	    spec->autocfg.line_out_pins[2] != 0x16)
10658		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10659
10660	snd_hda_codec_write(codec, 0x02, 0,
10661			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10662	snd_hda_codec_write(codec, 0x03, 0,
10663			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10664}
10665
10666/* pcm configuration: identiacal with ALC880 */
10667#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
10668#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
10669#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
10670#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
10671
10672/*
10673 * BIOS auto configuration
10674 */
10675static int alc268_parse_auto_config(struct hda_codec *codec)
10676{
10677	struct alc_spec *spec = codec->spec;
10678	int err;
10679	static hda_nid_t alc268_ignore[] = { 0 };
10680
10681	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10682					   alc268_ignore);
10683	if (err < 0)
10684		return err;
10685	if (!spec->autocfg.line_outs)
10686		return 0; /* can't find valid BIOS pin config */
10687
10688	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10689	if (err < 0)
10690		return err;
10691	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10692	if (err < 0)
10693		return err;
10694
10695	spec->multiout.max_channels = 2;
10696
10697	/* digital only support output */
10698	if (spec->autocfg.dig_out_pin)
10699		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10700
10701	if (spec->kctl_alloc)
10702		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10703
10704	if (spec->autocfg.speaker_pins[0] != 0x1d)
10705		spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
10706
10707	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10708	spec->num_mux_defs = 1;
10709	spec->input_mux = &spec->private_imux;
10710
10711	err = alc_auto_add_mic_boost(codec);
10712	if (err < 0)
10713		return err;
10714
10715	return 1;
10716}
10717
10718#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
10719#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
10720#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
10721
10722/* init callback for auto-configuration model -- overriding the default init */
10723static void alc268_auto_init(struct hda_codec *codec)
10724{
10725	struct alc_spec *spec = codec->spec;
10726	alc268_auto_init_multi_out(codec);
10727	alc268_auto_init_hp_out(codec);
10728	alc268_auto_init_mono_speaker_out(codec);
10729	alc268_auto_init_analog_input(codec);
10730	if (spec->unsol_event)
10731		alc_sku_automute(codec);
10732}
10733
10734/*
10735 * configuration and preset
10736 */
10737static const char *alc268_models[ALC268_MODEL_LAST] = {
10738	[ALC267_QUANTA_IL1]	= "quanta-il1",
10739	[ALC268_3ST]		= "3stack",
10740	[ALC268_TOSHIBA]	= "toshiba",
10741	[ALC268_ACER]		= "acer",
10742	[ALC268_DELL]		= "dell",
10743	[ALC268_ZEPTO]		= "zepto",
10744#ifdef CONFIG_SND_DEBUG
10745	[ALC268_TEST]		= "test",
10746#endif
10747	[ALC268_AUTO]		= "auto",
10748};
10749
10750static struct snd_pci_quirk alc268_cfg_tbl[] = {
10751	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
10752	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
10753	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
10754	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
10755	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
10756	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
10757	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
10758	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
10759	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
10760	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
10761	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
10762	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
10763	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
10764	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
10765	{}
10766};
10767
10768static struct alc_config_preset alc268_presets[] = {
10769	[ALC267_QUANTA_IL1] = {
10770		.mixers = { alc267_quanta_il1_mixer },
10771		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10772				alc267_quanta_il1_verbs },
10773		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10774		.dac_nids = alc268_dac_nids,
10775		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10776		.adc_nids = alc268_adc_nids_alt,
10777		.hp_nid = 0x03,
10778		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10779		.channel_mode = alc268_modes,
10780		.input_mux = &alc268_capture_source,
10781		.unsol_event = alc267_quanta_il1_unsol_event,
10782		.init_hook = alc267_quanta_il1_automute,
10783	},
10784	[ALC268_3ST] = {
10785		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10786			    alc268_beep_mixer },
10787		.init_verbs = { alc268_base_init_verbs },
10788		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10789		.dac_nids = alc268_dac_nids,
10790                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10791                .adc_nids = alc268_adc_nids_alt,
10792		.capsrc_nids = alc268_capsrc_nids,
10793		.hp_nid = 0x03,
10794		.dig_out_nid = ALC268_DIGOUT_NID,
10795		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10796		.channel_mode = alc268_modes,
10797		.input_mux = &alc268_capture_source,
10798	},
10799	[ALC268_TOSHIBA] = {
10800		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10801			    alc268_beep_mixer },
10802		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10803				alc268_toshiba_verbs },
10804		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10805		.dac_nids = alc268_dac_nids,
10806		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10807		.adc_nids = alc268_adc_nids_alt,
10808		.capsrc_nids = alc268_capsrc_nids,
10809		.hp_nid = 0x03,
10810		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10811		.channel_mode = alc268_modes,
10812		.input_mux = &alc268_capture_source,
10813		.unsol_event = alc268_toshiba_unsol_event,
10814		.init_hook = alc268_toshiba_automute,
10815	},
10816	[ALC268_ACER] = {
10817		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
10818			    alc268_beep_mixer },
10819		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10820				alc268_acer_verbs },
10821		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10822		.dac_nids = alc268_dac_nids,
10823		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10824		.adc_nids = alc268_adc_nids_alt,
10825		.capsrc_nids = alc268_capsrc_nids,
10826		.hp_nid = 0x02,
10827		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10828		.channel_mode = alc268_modes,
10829		.input_mux = &alc268_acer_capture_source,
10830		.unsol_event = alc268_acer_unsol_event,
10831		.init_hook = alc268_acer_init_hook,
10832	},
10833	[ALC268_DELL] = {
10834		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
10835		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10836				alc268_dell_verbs },
10837		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10838		.dac_nids = alc268_dac_nids,
10839		.hp_nid = 0x02,
10840		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10841		.channel_mode = alc268_modes,
10842		.unsol_event = alc268_dell_unsol_event,
10843		.init_hook = alc268_dell_init_hook,
10844		.input_mux = &alc268_capture_source,
10845	},
10846	[ALC268_ZEPTO] = {
10847		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10848			    alc268_beep_mixer },
10849		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10850				alc268_toshiba_verbs },
10851		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10852		.dac_nids = alc268_dac_nids,
10853		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10854		.adc_nids = alc268_adc_nids_alt,
10855		.capsrc_nids = alc268_capsrc_nids,
10856		.hp_nid = 0x03,
10857		.dig_out_nid = ALC268_DIGOUT_NID,
10858		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10859		.channel_mode = alc268_modes,
10860		.input_mux = &alc268_capture_source,
10861		.unsol_event = alc268_toshiba_unsol_event,
10862		.init_hook = alc268_toshiba_automute
10863	},
10864#ifdef CONFIG_SND_DEBUG
10865	[ALC268_TEST] = {
10866		.mixers = { alc268_test_mixer, alc268_capture_mixer },
10867		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10868				alc268_volume_init_verbs },
10869		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10870		.dac_nids = alc268_dac_nids,
10871		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10872		.adc_nids = alc268_adc_nids_alt,
10873		.capsrc_nids = alc268_capsrc_nids,
10874		.hp_nid = 0x03,
10875		.dig_out_nid = ALC268_DIGOUT_NID,
10876		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10877		.channel_mode = alc268_modes,
10878		.input_mux = &alc268_capture_source,
10879	},
10880#endif
10881};
10882
10883static int patch_alc268(struct hda_codec *codec)
10884{
10885	struct alc_spec *spec;
10886	int board_config;
10887	int err;
10888
10889	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10890	if (spec == NULL)
10891		return -ENOMEM;
10892
10893	codec->spec = spec;
10894
10895	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10896						  alc268_models,
10897						  alc268_cfg_tbl);
10898
10899	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10900		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10901		       "trying auto-probe from BIOS...\n");
10902		board_config = ALC268_AUTO;
10903	}
10904
10905	if (board_config == ALC268_AUTO) {
10906		/* automatic parse from the BIOS config */
10907		err = alc268_parse_auto_config(codec);
10908		if (err < 0) {
10909			alc_free(codec);
10910			return err;
10911		} else if (!err) {
10912			printk(KERN_INFO
10913			       "hda_codec: Cannot set up configuration "
10914			       "from BIOS.  Using base mode...\n");
10915			board_config = ALC268_3ST;
10916		}
10917	}
10918
10919	if (board_config != ALC268_AUTO)
10920		setup_preset(spec, &alc268_presets[board_config]);
10921
10922	if (codec->vendor_id == 0x10ec0267) {
10923		spec->stream_name_analog = "ALC267 Analog";
10924		spec->stream_name_digital = "ALC267 Digital";
10925	} else {
10926		spec->stream_name_analog = "ALC268 Analog";
10927		spec->stream_name_digital = "ALC268 Digital";
10928	}
10929
10930	spec->stream_analog_playback = &alc268_pcm_analog_playback;
10931	spec->stream_analog_capture = &alc268_pcm_analog_capture;
10932	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
10933
10934	spec->stream_digital_playback = &alc268_pcm_digital_playback;
10935
10936	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
10937		/* override the amp caps for beep generator */
10938		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
10939					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
10940					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
10941					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
10942					  (0 << AC_AMPCAP_MUTE_SHIFT));
10943
10944	if (!spec->adc_nids && spec->input_mux) {
10945		/* check whether NID 0x07 is valid */
10946		unsigned int wcap = get_wcaps(codec, 0x07);
10947		int i;
10948
10949		/* get type */
10950		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10951		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
10952			spec->adc_nids = alc268_adc_nids_alt;
10953			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10954			spec->mixers[spec->num_mixers] =
10955					alc268_capture_alt_mixer;
10956			spec->num_mixers++;
10957		} else {
10958			spec->adc_nids = alc268_adc_nids;
10959			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10960			spec->mixers[spec->num_mixers] =
10961				alc268_capture_mixer;
10962			spec->num_mixers++;
10963		}
10964		spec->capsrc_nids = alc268_capsrc_nids;
10965		/* set default input source */
10966		for (i = 0; i < spec->num_adc_nids; i++)
10967			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
10968				0, AC_VERB_SET_CONNECT_SEL,
10969				spec->input_mux->items[0].index);
10970	}
10971
10972	spec->vmaster_nid = 0x02;
10973
10974	codec->patch_ops = alc_patch_ops;
10975	if (board_config == ALC268_AUTO)
10976		spec->init_hook = alc268_auto_init;
10977
10978	return 0;
10979}
10980
10981/*
10982 *  ALC269 channel source setting (2 channel)
10983 */
10984#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
10985
10986#define alc269_dac_nids		alc260_dac_nids
10987
10988static hda_nid_t alc269_adc_nids[1] = {
10989	/* ADC1 */
10990	0x08,
10991};
10992
10993static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
10994	.num_items = 2,
10995	.items = {
10996		{ "i-Mic", 0x5 },
10997		{ "e-Mic", 0x0 },
10998	},
10999};
11000
11001static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11002	.num_items = 2,
11003	.items = {
11004		{ "i-Mic", 0x1 },
11005		{ "e-Mic", 0x0 },
11006	},
11007};
11008
11009#define alc269_modes		alc260_modes
11010#define alc269_capture_source	alc880_lg_lw_capture_source
11011
11012static struct snd_kcontrol_new alc269_base_mixer[] = {
11013	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11014	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11015	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11016	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11017	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11018	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11019	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11020	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11021	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11022	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11023	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11024	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11025	{ } /* end */
11026};
11027
11028/* bind volumes of both NID 0x0c and 0x0d */
11029static struct hda_bind_ctls alc269_epc_bind_vol = {
11030	.ops = &snd_hda_bind_vol,
11031	.values = {
11032		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11033		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11034		0
11035	},
11036};
11037
11038static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11039	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11040	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11041	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11042	{ } /* end */
11043};
11044
11045/* capture mixer elements */
11046static struct snd_kcontrol_new alc269_capture_mixer[] = {
11047	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11048	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11049	{
11050		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11051		/* The multiple "Capture Source" controls confuse alsamixer
11052		 * So call somewhat different..
11053		 */
11054		/* .name = "Capture Source", */
11055		.name = "Input Source",
11056		.count = 1,
11057		.info = alc_mux_enum_info,
11058		.get = alc_mux_enum_get,
11059		.put = alc_mux_enum_put,
11060	},
11061	{ } /* end */
11062};
11063
11064/* capture mixer elements */
11065static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11066	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11067	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11068	{ } /* end */
11069};
11070
11071/*
11072 * generic initialization of ADC, input mixers and output mixers
11073 */
11074static struct hda_verb alc269_init_verbs[] = {
11075	/*
11076	 * Unmute ADC0 and set the default input to mic-in
11077	 */
11078	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11079
11080	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11081	 * analog-loopback mixer widget
11082	 * Note: PASD motherboards uses the Line In 2 as the input for
11083	 * front panel mic (mic 2)
11084	 */
11085	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11086	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11087	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11088	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11089	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11090	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11091
11092	/*
11093	 * Set up output mixers (0x0c - 0x0e)
11094	 */
11095	/* set vol=0 to output mixers */
11096	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11097	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11098
11099	/* set up input amps for analog loopback */
11100	/* Amp Indices: DAC = 0, mixer = 1 */
11101	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11102	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11103	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11104	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11105	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11106	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11107
11108	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11109	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11110	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11111	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11112	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11113	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11114	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11115
11116	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11117	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11118	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11119	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11120	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11121	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11122	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11123
11124	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11125	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11126
11127	/* FIXME: use matrix-type input source selection */
11128	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11129	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11130	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11131	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11132	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11133	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11134
11135	/* set EAPD */
11136	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11137	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11138	{ }
11139};
11140
11141static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11142	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11143	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11144	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11145	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11146	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11147	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11148	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11149	{}
11150};
11151
11152static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11153	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11154	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11155	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11156	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11157	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11158	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11159	{}
11160};
11161
11162/* toggle speaker-output according to the hp-jack state */
11163static void alc269_speaker_automute(struct hda_codec *codec)
11164{
11165	unsigned int present;
11166	unsigned int bits;
11167
11168	present = snd_hda_codec_read(codec, 0x15, 0,
11169				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11170	bits = present ? AMP_IN_MUTE(0) : 0;
11171	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11172				 AMP_IN_MUTE(0), bits);
11173	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11174				 AMP_IN_MUTE(0), bits);
11175}
11176
11177static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11178{
11179	unsigned int present;
11180
11181	present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
11182		& AC_PINSENSE_PRESENCE;
11183	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11184			    present ? 0 : 5);
11185}
11186
11187static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11188{
11189	unsigned int present;
11190
11191	present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
11192		& AC_PINSENSE_PRESENCE;
11193	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11194			    present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0));
11195	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11196			    present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1));
11197}
11198
11199/* unsolicited event for HP jack sensing */
11200static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11201					  unsigned int res)
11202{
11203	if ((res >> 26) == ALC880_HP_EVENT)
11204		alc269_speaker_automute(codec);
11205
11206	if ((res >> 26) == ALC880_MIC_EVENT)
11207		alc269_eeepc_dmic_automute(codec);
11208}
11209
11210static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11211{
11212	alc269_speaker_automute(codec);
11213	alc269_eeepc_dmic_automute(codec);
11214}
11215
11216/* unsolicited event for HP jack sensing */
11217static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11218					  unsigned int res)
11219{
11220	if ((res >> 26) == ALC880_HP_EVENT)
11221		alc269_speaker_automute(codec);
11222
11223	if ((res >> 26) == ALC880_MIC_EVENT)
11224		alc269_eeepc_amic_automute(codec);
11225}
11226
11227static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11228{
11229	alc269_speaker_automute(codec);
11230	alc269_eeepc_amic_automute(codec);
11231}
11232
11233/* add playback controls from the parsed DAC table */
11234static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11235					     const struct auto_pin_cfg *cfg)
11236{
11237	hda_nid_t nid;
11238	int err;
11239
11240	spec->multiout.num_dacs = 1;	/* only use one dac */
11241	spec->multiout.dac_nids = spec->private_dac_nids;
11242	spec->multiout.dac_nids[0] = 2;
11243
11244	nid = cfg->line_out_pins[0];
11245	if (nid) {
11246		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11247				  "Front Playback Volume",
11248				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
11249		if (err < 0)
11250			return err;
11251		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11252				  "Front Playback Switch",
11253				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11254		if (err < 0)
11255			return err;
11256	}
11257
11258	nid = cfg->speaker_pins[0];
11259	if (nid) {
11260		if (!cfg->line_out_pins[0]) {
11261			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11262					  "Speaker Playback Volume",
11263					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11264							      HDA_OUTPUT));
11265			if (err < 0)
11266				return err;
11267		}
11268		if (nid == 0x16) {
11269			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11270					  "Speaker Playback Switch",
11271					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11272							      HDA_OUTPUT));
11273			if (err < 0)
11274				return err;
11275		} else {
11276			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11277					  "Speaker Playback Switch",
11278					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11279							      HDA_OUTPUT));
11280			if (err < 0)
11281				return err;
11282		}
11283	}
11284	nid = cfg->hp_pins[0];
11285	if (nid) {
11286		/* spec->multiout.hp_nid = 2; */
11287		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
11288			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11289					  "Headphone Playback Volume",
11290					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11291							      HDA_OUTPUT));
11292			if (err < 0)
11293				return err;
11294		}
11295		if (nid == 0x16) {
11296			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11297					  "Headphone Playback Switch",
11298					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11299							      HDA_OUTPUT));
11300			if (err < 0)
11301				return err;
11302		} else {
11303			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11304					  "Headphone Playback Switch",
11305					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11306							      HDA_OUTPUT));
11307			if (err < 0)
11308				return err;
11309		}
11310	}
11311	return 0;
11312}
11313
11314#define alc269_auto_create_analog_input_ctls \
11315	alc880_auto_create_analog_input_ctls
11316
11317#ifdef CONFIG_SND_HDA_POWER_SAVE
11318#define alc269_loopbacks	alc880_loopbacks
11319#endif
11320
11321/* pcm configuration: identiacal with ALC880 */
11322#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
11323#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
11324#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
11325#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
11326
11327/*
11328 * BIOS auto configuration
11329 */
11330static int alc269_parse_auto_config(struct hda_codec *codec)
11331{
11332	struct alc_spec *spec = codec->spec;
11333	int err;
11334	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
11335
11336	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11337					   alc269_ignore);
11338	if (err < 0)
11339		return err;
11340
11341	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
11342	if (err < 0)
11343		return err;
11344	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
11345	if (err < 0)
11346		return err;
11347
11348	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11349
11350	if (spec->autocfg.dig_out_pin)
11351		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
11352
11353	if (spec->kctl_alloc)
11354		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11355
11356	spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
11357	spec->num_mux_defs = 1;
11358	spec->input_mux = &spec->private_imux;
11359
11360	err = alc_auto_add_mic_boost(codec);
11361	if (err < 0)
11362		return err;
11363
11364	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
11365	spec->num_mixers++;
11366
11367	return 1;
11368}
11369
11370#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
11371#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
11372#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
11373
11374
11375/* init callback for auto-configuration model -- overriding the default init */
11376static void alc269_auto_init(struct hda_codec *codec)
11377{
11378	struct alc_spec *spec = codec->spec;
11379	alc269_auto_init_multi_out(codec);
11380	alc269_auto_init_hp_out(codec);
11381	alc269_auto_init_analog_input(codec);
11382	if (spec->unsol_event)
11383		alc_sku_automute(codec);
11384}
11385
11386/*
11387 * configuration and preset
11388 */
11389static const char *alc269_models[ALC269_MODEL_LAST] = {
11390	[ALC269_BASIC]		= "basic",
11391};
11392
11393static struct snd_pci_quirk alc269_cfg_tbl[] = {
11394	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
11395		      ALC269_ASUS_EEEPC_P703),
11396	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
11397		      ALC269_ASUS_EEEPC_P901),
11398	{}
11399};
11400
11401static struct alc_config_preset alc269_presets[] = {
11402	[ALC269_BASIC] = {
11403		.mixers = { alc269_base_mixer, alc269_capture_mixer },
11404		.init_verbs = { alc269_init_verbs },
11405		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
11406		.dac_nids = alc269_dac_nids,
11407		.hp_nid = 0x03,
11408		.num_channel_mode = ARRAY_SIZE(alc269_modes),
11409		.channel_mode = alc269_modes,
11410		.input_mux = &alc269_capture_source,
11411	},
11412	[ALC269_ASUS_EEEPC_P703] = {
11413		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
11414		.init_verbs = { alc269_init_verbs,
11415				alc269_eeepc_amic_init_verbs },
11416		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
11417		.dac_nids = alc269_dac_nids,
11418		.hp_nid = 0x03,
11419		.num_channel_mode = ARRAY_SIZE(alc269_modes),
11420		.channel_mode = alc269_modes,
11421		.input_mux = &alc269_eeepc_amic_capture_source,
11422		.unsol_event = alc269_eeepc_amic_unsol_event,
11423		.init_hook = alc269_eeepc_amic_inithook,
11424	},
11425	[ALC269_ASUS_EEEPC_P901] = {
11426		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
11427		.init_verbs = { alc269_init_verbs,
11428				alc269_eeepc_dmic_init_verbs },
11429		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
11430		.dac_nids = alc269_dac_nids,
11431		.hp_nid = 0x03,
11432		.num_channel_mode = ARRAY_SIZE(alc269_modes),
11433		.channel_mode = alc269_modes,
11434		.input_mux = &alc269_eeepc_dmic_capture_source,
11435		.unsol_event = alc269_eeepc_dmic_unsol_event,
11436		.init_hook = alc269_eeepc_dmic_inithook,
11437	},
11438};
11439
11440static int patch_alc269(struct hda_codec *codec)
11441{
11442	struct alc_spec *spec;
11443	int board_config;
11444	int err;
11445
11446	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11447	if (spec == NULL)
11448		return -ENOMEM;
11449
11450	codec->spec = spec;
11451
11452	alc_fix_pll_init(codec, 0x20, 0x04, 15);
11453
11454	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
11455						  alc269_models,
11456						  alc269_cfg_tbl);
11457
11458	if (board_config < 0) {
11459		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
11460		       "trying auto-probe from BIOS...\n");
11461		board_config = ALC269_AUTO;
11462	}
11463
11464	if (board_config == ALC269_AUTO) {
11465		/* automatic parse from the BIOS config */
11466		err = alc269_parse_auto_config(codec);
11467		if (err < 0) {
11468			alc_free(codec);
11469			return err;
11470		} else if (!err) {
11471			printk(KERN_INFO
11472			       "hda_codec: Cannot set up configuration "
11473			       "from BIOS.  Using base mode...\n");
11474			board_config = ALC269_BASIC;
11475		}
11476	}
11477
11478	if (board_config != ALC269_AUTO)
11479		setup_preset(spec, &alc269_presets[board_config]);
11480
11481	spec->stream_name_analog = "ALC269 Analog";
11482	spec->stream_analog_playback = &alc269_pcm_analog_playback;
11483	spec->stream_analog_capture = &alc269_pcm_analog_capture;
11484
11485	spec->stream_name_digital = "ALC269 Digital";
11486	spec->stream_digital_playback = &alc269_pcm_digital_playback;
11487	spec->stream_digital_capture = &alc269_pcm_digital_capture;
11488
11489	spec->adc_nids = alc269_adc_nids;
11490	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
11491
11492	codec->patch_ops = alc_patch_ops;
11493	if (board_config == ALC269_AUTO)
11494		spec->init_hook = alc269_auto_init;
11495#ifdef CONFIG_SND_HDA_POWER_SAVE
11496	if (!spec->loopback.amplist)
11497		spec->loopback.amplist = alc269_loopbacks;
11498#endif
11499
11500	return 0;
11501}
11502
11503/*
11504 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
11505 */
11506
11507/*
11508 * set the path ways for 2 channel output
11509 * need to set the codec line out and mic 1 pin widgets to inputs
11510 */
11511static struct hda_verb alc861_threestack_ch2_init[] = {
11512	/* set pin widget 1Ah (line in) for input */
11513	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11514	/* set pin widget 18h (mic1/2) for input, for mic also enable
11515	 * the vref
11516	 */
11517	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11518
11519	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11520#if 0
11521	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11522	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11523#endif
11524	{ } /* end */
11525};
11526/*
11527 * 6ch mode
11528 * need to set the codec line out and mic 1 pin widgets to outputs
11529 */
11530static struct hda_verb alc861_threestack_ch6_init[] = {
11531	/* set pin widget 1Ah (line in) for output (Back Surround)*/
11532	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11533	/* set pin widget 18h (mic1) for output (CLFE)*/
11534	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11535
11536	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11537	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11538
11539	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11540#if 0
11541	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11542	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11543#endif
11544	{ } /* end */
11545};
11546
11547static struct hda_channel_mode alc861_threestack_modes[2] = {
11548	{ 2, alc861_threestack_ch2_init },
11549	{ 6, alc861_threestack_ch6_init },
11550};
11551/* Set mic1 as input and unmute the mixer */
11552static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
11553	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11554	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11555	{ } /* end */
11556};
11557/* Set mic1 as output and mute mixer */
11558static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
11559	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11560	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11561	{ } /* end */
11562};
11563
11564static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
11565	{ 2, alc861_uniwill_m31_ch2_init },
11566	{ 4, alc861_uniwill_m31_ch4_init },
11567};
11568
11569/* Set mic1 and line-in as input and unmute the mixer */
11570static struct hda_verb alc861_asus_ch2_init[] = {
11571	/* set pin widget 1Ah (line in) for input */
11572	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11573	/* set pin widget 18h (mic1/2) for input, for mic also enable
11574	 * the vref
11575	 */
11576	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11577
11578	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11579#if 0
11580	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11581	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11582#endif
11583	{ } /* end */
11584};
11585/* Set mic1 nad line-in as output and mute mixer */
11586static struct hda_verb alc861_asus_ch6_init[] = {
11587	/* set pin widget 1Ah (line in) for output (Back Surround)*/
11588	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11589	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11590	/* set pin widget 18h (mic1) for output (CLFE)*/
11591	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11592	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11593	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11594	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11595
11596	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11597#if 0
11598	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11599	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11600#endif
11601	{ } /* end */
11602};
11603
11604static struct hda_channel_mode alc861_asus_modes[2] = {
11605	{ 2, alc861_asus_ch2_init },
11606	{ 6, alc861_asus_ch6_init },
11607};
11608
11609/* patch-ALC861 */
11610
11611static struct snd_kcontrol_new alc861_base_mixer[] = {
11612        /* output mixer control */
11613	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11614	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11615	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11616	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11617	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11618
11619        /*Input mixer control */
11620	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11621	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11622	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11623	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11624	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11625	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11626	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11627	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11628	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11629	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11630
11631        /* Capture mixer control */
11632	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11633	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11634	{
11635		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11636		.name = "Capture Source",
11637		.count = 1,
11638		.info = alc_mux_enum_info,
11639		.get = alc_mux_enum_get,
11640		.put = alc_mux_enum_put,
11641	},
11642	{ } /* end */
11643};
11644
11645static struct snd_kcontrol_new alc861_3ST_mixer[] = {
11646        /* output mixer control */
11647	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11648	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11649	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11650	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11651	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11652
11653	/* Input mixer control */
11654	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11655	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11656	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11657	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11658	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11659	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11660	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11661	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11662	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11663	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11664
11665	/* Capture mixer control */
11666	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11667	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11668	{
11669		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11670		.name = "Capture Source",
11671		.count = 1,
11672		.info = alc_mux_enum_info,
11673		.get = alc_mux_enum_get,
11674		.put = alc_mux_enum_put,
11675	},
11676	{
11677		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11678		.name = "Channel Mode",
11679		.info = alc_ch_mode_info,
11680		.get = alc_ch_mode_get,
11681		.put = alc_ch_mode_put,
11682                .private_value = ARRAY_SIZE(alc861_threestack_modes),
11683	},
11684	{ } /* end */
11685};
11686
11687static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
11688        /* output mixer control */
11689	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11690	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11691	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11692
11693        /*Capture mixer control */
11694	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11695	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11696	{
11697		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11698		.name = "Capture Source",
11699		.count = 1,
11700		.info = alc_mux_enum_info,
11701		.get = alc_mux_enum_get,
11702		.put = alc_mux_enum_put,
11703	},
11704
11705	{ } /* end */
11706};
11707
11708static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
11709        /* output mixer control */
11710	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11711	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11712	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11713	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11714	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11715
11716	/* Input mixer control */
11717	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11718	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11719	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11720	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11721	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11722	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11723	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11724	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11725	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11726	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11727
11728	/* Capture mixer control */
11729	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11730	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11731	{
11732		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11733		.name = "Capture Source",
11734		.count = 1,
11735		.info = alc_mux_enum_info,
11736		.get = alc_mux_enum_get,
11737		.put = alc_mux_enum_put,
11738	},
11739	{
11740		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11741		.name = "Channel Mode",
11742		.info = alc_ch_mode_info,
11743		.get = alc_ch_mode_get,
11744		.put = alc_ch_mode_put,
11745                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
11746	},
11747	{ } /* end */
11748};
11749
11750static struct snd_kcontrol_new alc861_asus_mixer[] = {
11751        /* output mixer control */
11752	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11753	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11754	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11755	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11756	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11757
11758	/* Input mixer control */
11759	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11760	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11761	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11762	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11763	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11764	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11765	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11766	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11767	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11768	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
11769
11770	/* Capture mixer control */
11771	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11772	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11773	{
11774		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11775		.name = "Capture Source",
11776		.count = 1,
11777		.info = alc_mux_enum_info,
11778		.get = alc_mux_enum_get,
11779		.put = alc_mux_enum_put,
11780	},
11781	{
11782		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11783		.name = "Channel Mode",
11784		.info = alc_ch_mode_info,
11785		.get = alc_ch_mode_get,
11786		.put = alc_ch_mode_put,
11787                .private_value = ARRAY_SIZE(alc861_asus_modes),
11788	},
11789	{ }
11790};
11791
11792/* additional mixer */
11793static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
11794	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11795	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11796	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
11797	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
11798	{ }
11799};
11800
11801/*
11802 * generic initialization of ADC, input mixers and output mixers
11803 */
11804static struct hda_verb alc861_base_init_verbs[] = {
11805	/*
11806	 * Unmute ADC0 and set the default input to mic-in
11807	 */
11808	/* port-A for surround (rear panel) */
11809	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11810	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
11811	/* port-B for mic-in (rear panel) with vref */
11812	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11813	/* port-C for line-in (rear panel) */
11814	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11815	/* port-D for Front */
11816	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11817	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11818	/* port-E for HP out (front panel) */
11819	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11820	/* route front PCM to HP */
11821	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11822	/* port-F for mic-in (front panel) with vref */
11823	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11824	/* port-G for CLFE (rear panel) */
11825	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11826	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11827	/* port-H for side (rear panel) */
11828	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11829	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
11830	/* CD-in */
11831	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11832	/* route front mic to ADC1*/
11833	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11834	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11835
11836	/* Unmute DAC0~3 & spdif out*/
11837	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11838	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11839	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11840	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11841	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11842
11843	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11844	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11845        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11846	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11847        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11848
11849	/* Unmute Stereo Mixer 15 */
11850	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11851	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11852	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11853	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11854
11855	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11856	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11857	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11858	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11859	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11860	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11861	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11862	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11863	/* hp used DAC 3 (Front) */
11864	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11865        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11866
11867	{ }
11868};
11869
11870static struct hda_verb alc861_threestack_init_verbs[] = {
11871	/*
11872	 * Unmute ADC0 and set the default input to mic-in
11873	 */
11874	/* port-A for surround (rear panel) */
11875	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11876	/* port-B for mic-in (rear panel) with vref */
11877	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11878	/* port-C for line-in (rear panel) */
11879	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11880	/* port-D for Front */
11881	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11882	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11883	/* port-E for HP out (front panel) */
11884	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11885	/* route front PCM to HP */
11886	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11887	/* port-F for mic-in (front panel) with vref */
11888	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11889	/* port-G for CLFE (rear panel) */
11890	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11891	/* port-H for side (rear panel) */
11892	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11893	/* CD-in */
11894	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11895	/* route front mic to ADC1*/
11896	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11897	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11898	/* Unmute DAC0~3 & spdif out*/
11899	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11900	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11901	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11902	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11903	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11904
11905	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11906	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11907        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11908	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11909        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11910
11911	/* Unmute Stereo Mixer 15 */
11912	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11913	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11914	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11915	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11916
11917	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11918	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11919	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11920	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11921	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11922	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11923	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11924	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11925	/* hp used DAC 3 (Front) */
11926	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11927        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11928	{ }
11929};
11930
11931static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11932	/*
11933	 * Unmute ADC0 and set the default input to mic-in
11934	 */
11935	/* port-A for surround (rear panel) */
11936	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11937	/* port-B for mic-in (rear panel) with vref */
11938	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11939	/* port-C for line-in (rear panel) */
11940	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11941	/* port-D for Front */
11942	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11943	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11944	/* port-E for HP out (front panel) */
11945	/* this has to be set to VREF80 */
11946	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11947	/* route front PCM to HP */
11948	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11949	/* port-F for mic-in (front panel) with vref */
11950	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11951	/* port-G for CLFE (rear panel) */
11952	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11953	/* port-H for side (rear panel) */
11954	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11955	/* CD-in */
11956	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11957	/* route front mic to ADC1*/
11958	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11959	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11960	/* Unmute DAC0~3 & spdif out*/
11961	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11962	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11963	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11964	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11965	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11966
11967	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11968	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11969        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11970	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11971        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11972
11973	/* Unmute Stereo Mixer 15 */
11974	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11975	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11976	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11977	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11978
11979	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11980	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11981	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11982	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11983	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11984	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11985	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11986	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11987	/* hp used DAC 3 (Front) */
11988	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11989        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11990	{ }
11991};
11992
11993static struct hda_verb alc861_asus_init_verbs[] = {
11994	/*
11995	 * Unmute ADC0 and set the default input to mic-in
11996	 */
11997	/* port-A for surround (rear panel)
11998	 * according to codec#0 this is the HP jack
11999	 */
12000	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12001	/* route front PCM to HP */
12002	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12003	/* port-B for mic-in (rear panel) with vref */
12004	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12005	/* port-C for line-in (rear panel) */
12006	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12007	/* port-D for Front */
12008	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12009	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12010	/* port-E for HP out (front panel) */
12011	/* this has to be set to VREF80 */
12012	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12013	/* route front PCM to HP */
12014	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12015	/* port-F for mic-in (front panel) with vref */
12016	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12017	/* port-G for CLFE (rear panel) */
12018	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12019	/* port-H for side (rear panel) */
12020	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12021	/* CD-in */
12022	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12023	/* route front mic to ADC1*/
12024	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12025	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12026	/* Unmute DAC0~3 & spdif out*/
12027	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12028	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12029	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12030	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12031	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12032	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12033	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12034        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12035	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12036        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12037
12038	/* Unmute Stereo Mixer 15 */
12039	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12040	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12041	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12042	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12043
12044	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12045	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12046	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12047	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12048	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12049	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12050	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12051	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12052	/* hp used DAC 3 (Front) */
12053	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12054	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12055	{ }
12056};
12057
12058/* additional init verbs for ASUS laptops */
12059static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12060	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12061	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12062	{ }
12063};
12064
12065/*
12066 * generic initialization of ADC, input mixers and output mixers
12067 */
12068static struct hda_verb alc861_auto_init_verbs[] = {
12069	/*
12070	 * Unmute ADC0 and set the default input to mic-in
12071	 */
12072	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12073	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12074
12075	/* Unmute DAC0~3 & spdif out*/
12076	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12077	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12078	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12079	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12080	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12081
12082	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12083	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12084	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12085	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12086	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12087
12088	/* Unmute Stereo Mixer 15 */
12089	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12090	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12091	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12092	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12093
12094	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12095	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12096	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12098	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12099	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12100	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12101	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12102
12103	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12104	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12105	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12106	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12107	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12108	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12109	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12110	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12111
12112	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
12113
12114	{ }
12115};
12116
12117static struct hda_verb alc861_toshiba_init_verbs[] = {
12118	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12119
12120	{ }
12121};
12122
12123/* toggle speaker-output according to the hp-jack state */
12124static void alc861_toshiba_automute(struct hda_codec *codec)
12125{
12126	unsigned int present;
12127
12128	present = snd_hda_codec_read(codec, 0x0f, 0,
12129				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12130	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12131				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12132	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12133				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12134}
12135
12136static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12137				       unsigned int res)
12138{
12139	if ((res >> 26) == ALC880_HP_EVENT)
12140		alc861_toshiba_automute(codec);
12141}
12142
12143/* pcm configuration: identiacal with ALC880 */
12144#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
12145#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
12146#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
12147#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
12148
12149
12150#define ALC861_DIGOUT_NID	0x07
12151
12152static struct hda_channel_mode alc861_8ch_modes[1] = {
12153	{ 8, NULL }
12154};
12155
12156static hda_nid_t alc861_dac_nids[4] = {
12157	/* front, surround, clfe, side */
12158	0x03, 0x06, 0x05, 0x04
12159};
12160
12161static hda_nid_t alc660_dac_nids[3] = {
12162	/* front, clfe, surround */
12163	0x03, 0x05, 0x06
12164};
12165
12166static hda_nid_t alc861_adc_nids[1] = {
12167	/* ADC0-2 */
12168	0x08,
12169};
12170
12171static struct hda_input_mux alc861_capture_source = {
12172	.num_items = 5,
12173	.items = {
12174		{ "Mic", 0x0 },
12175		{ "Front Mic", 0x3 },
12176		{ "Line", 0x1 },
12177		{ "CD", 0x4 },
12178		{ "Mixer", 0x5 },
12179	},
12180};
12181
12182/* fill in the dac_nids table from the parsed pin configuration */
12183static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12184				     const struct auto_pin_cfg *cfg)
12185{
12186	int i;
12187	hda_nid_t nid;
12188
12189	spec->multiout.dac_nids = spec->private_dac_nids;
12190	for (i = 0; i < cfg->line_outs; i++) {
12191		nid = cfg->line_out_pins[i];
12192		if (nid) {
12193			if (i >= ARRAY_SIZE(alc861_dac_nids))
12194				continue;
12195			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12196		}
12197	}
12198	spec->multiout.num_dacs = cfg->line_outs;
12199	return 0;
12200}
12201
12202/* add playback controls from the parsed DAC table */
12203static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12204					     const struct auto_pin_cfg *cfg)
12205{
12206	char name[32];
12207	static const char *chname[4] = {
12208		"Front", "Surround", NULL /*CLFE*/, "Side"
12209	};
12210	hda_nid_t nid;
12211	int i, idx, err;
12212
12213	for (i = 0; i < cfg->line_outs; i++) {
12214		nid = spec->multiout.dac_nids[i];
12215		if (!nid)
12216			continue;
12217		if (nid == 0x05) {
12218			/* Center/LFE */
12219			err = add_control(spec, ALC_CTL_BIND_MUTE,
12220					  "Center Playback Switch",
12221					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12222							      HDA_OUTPUT));
12223			if (err < 0)
12224				return err;
12225			err = add_control(spec, ALC_CTL_BIND_MUTE,
12226					  "LFE Playback Switch",
12227					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12228							      HDA_OUTPUT));
12229			if (err < 0)
12230				return err;
12231		} else {
12232			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
12233			     idx++)
12234				if (nid == alc861_dac_nids[idx])
12235					break;
12236			sprintf(name, "%s Playback Switch", chname[idx]);
12237			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12238					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12239							      HDA_OUTPUT));
12240			if (err < 0)
12241				return err;
12242		}
12243	}
12244	return 0;
12245}
12246
12247static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
12248{
12249	int err;
12250	hda_nid_t nid;
12251
12252	if (!pin)
12253		return 0;
12254
12255	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
12256		nid = 0x03;
12257		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12258				  "Headphone Playback Switch",
12259				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12260		if (err < 0)
12261			return err;
12262		spec->multiout.hp_nid = nid;
12263	}
12264	return 0;
12265}
12266
12267/* create playback/capture controls for input pins */
12268static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
12269						const struct auto_pin_cfg *cfg)
12270{
12271	struct hda_input_mux *imux = &spec->private_imux;
12272	int i, err, idx, idx1;
12273
12274	for (i = 0; i < AUTO_PIN_LAST; i++) {
12275		switch (cfg->input_pins[i]) {
12276		case 0x0c:
12277			idx1 = 1;
12278			idx = 2;	/* Line In */
12279			break;
12280		case 0x0f:
12281			idx1 = 2;
12282			idx = 2;	/* Line In */
12283			break;
12284		case 0x0d:
12285			idx1 = 0;
12286			idx = 1;	/* Mic In */
12287			break;
12288		case 0x10:
12289			idx1 = 3;
12290			idx = 1;	/* Mic In */
12291			break;
12292		case 0x11:
12293			idx1 = 4;
12294			idx = 0;	/* CD */
12295			break;
12296		default:
12297			continue;
12298		}
12299
12300		err = new_analog_input(spec, cfg->input_pins[i],
12301				       auto_pin_cfg_labels[i], idx, 0x15);
12302		if (err < 0)
12303			return err;
12304
12305		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12306		imux->items[imux->num_items].index = idx1;
12307		imux->num_items++;
12308	}
12309	return 0;
12310}
12311
12312static struct snd_kcontrol_new alc861_capture_mixer[] = {
12313	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12314	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12315
12316	{
12317		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12318		/* The multiple "Capture Source" controls confuse alsamixer
12319		 * So call somewhat different..
12320		 */
12321		/* .name = "Capture Source", */
12322		.name = "Input Source",
12323		.count = 1,
12324		.info = alc_mux_enum_info,
12325		.get = alc_mux_enum_get,
12326		.put = alc_mux_enum_put,
12327	},
12328	{ } /* end */
12329};
12330
12331static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
12332					      hda_nid_t nid,
12333					      int pin_type, int dac_idx)
12334{
12335	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
12336			    pin_type);
12337	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12338			    AMP_OUT_UNMUTE);
12339}
12340
12341static void alc861_auto_init_multi_out(struct hda_codec *codec)
12342{
12343	struct alc_spec *spec = codec->spec;
12344	int i;
12345
12346	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
12347	for (i = 0; i < spec->autocfg.line_outs; i++) {
12348		hda_nid_t nid = spec->autocfg.line_out_pins[i];
12349		int pin_type = get_pin_type(spec->autocfg.line_out_type);
12350		if (nid)
12351			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
12352							  spec->multiout.dac_nids[i]);
12353	}
12354}
12355
12356static void alc861_auto_init_hp_out(struct hda_codec *codec)
12357{
12358	struct alc_spec *spec = codec->spec;
12359	hda_nid_t pin;
12360
12361	pin = spec->autocfg.hp_pins[0];
12362	if (pin) /* connect to front */
12363		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
12364						  spec->multiout.dac_nids[0]);
12365	pin = spec->autocfg.speaker_pins[0];
12366	if (pin)
12367		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
12368}
12369
12370static void alc861_auto_init_analog_input(struct hda_codec *codec)
12371{
12372	struct alc_spec *spec = codec->spec;
12373	int i;
12374
12375	for (i = 0; i < AUTO_PIN_LAST; i++) {
12376		hda_nid_t nid = spec->autocfg.input_pins[i];
12377		if (nid >= 0x0c && nid <= 0x11) {
12378			snd_hda_codec_write(codec, nid, 0,
12379					    AC_VERB_SET_PIN_WIDGET_CONTROL,
12380					    i <= AUTO_PIN_FRONT_MIC ?
12381					    PIN_VREF80 : PIN_IN);
12382		}
12383	}
12384}
12385
12386/* parse the BIOS configuration and set up the alc_spec */
12387/* return 1 if successful, 0 if the proper config is not found,
12388 * or a negative error code
12389 */
12390static int alc861_parse_auto_config(struct hda_codec *codec)
12391{
12392	struct alc_spec *spec = codec->spec;
12393	int err;
12394	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
12395
12396	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12397					   alc861_ignore);
12398	if (err < 0)
12399		return err;
12400	if (!spec->autocfg.line_outs)
12401		return 0; /* can't find valid BIOS pin config */
12402
12403	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
12404	if (err < 0)
12405		return err;
12406	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
12407	if (err < 0)
12408		return err;
12409	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
12410	if (err < 0)
12411		return err;
12412	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
12413	if (err < 0)
12414		return err;
12415
12416	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12417
12418	if (spec->autocfg.dig_out_pin)
12419		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
12420
12421	if (spec->kctl_alloc)
12422		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12423
12424	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
12425
12426	spec->num_mux_defs = 1;
12427	spec->input_mux = &spec->private_imux;
12428
12429	spec->adc_nids = alc861_adc_nids;
12430	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
12431	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
12432	spec->num_mixers++;
12433
12434	return 1;
12435}
12436
12437/* additional initialization for auto-configuration model */
12438static void alc861_auto_init(struct hda_codec *codec)
12439{
12440	struct alc_spec *spec = codec->spec;
12441	alc861_auto_init_multi_out(codec);
12442	alc861_auto_init_hp_out(codec);
12443	alc861_auto_init_analog_input(codec);
12444	if (spec->unsol_event)
12445		alc_sku_automute(codec);
12446}
12447
12448#ifdef CONFIG_SND_HDA_POWER_SAVE
12449static struct hda_amp_list alc861_loopbacks[] = {
12450	{ 0x15, HDA_INPUT, 0 },
12451	{ 0x15, HDA_INPUT, 1 },
12452	{ 0x15, HDA_INPUT, 2 },
12453	{ 0x15, HDA_INPUT, 3 },
12454	{ } /* end */
12455};
12456#endif
12457
12458
12459/*
12460 * configuration and preset
12461 */
12462static const char *alc861_models[ALC861_MODEL_LAST] = {
12463	[ALC861_3ST]		= "3stack",
12464	[ALC660_3ST]		= "3stack-660",
12465	[ALC861_3ST_DIG]	= "3stack-dig",
12466	[ALC861_6ST_DIG]	= "6stack-dig",
12467	[ALC861_UNIWILL_M31]	= "uniwill-m31",
12468	[ALC861_TOSHIBA]	= "toshiba",
12469	[ALC861_ASUS]		= "asus",
12470	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
12471	[ALC861_AUTO]		= "auto",
12472};
12473
12474static struct snd_pci_quirk alc861_cfg_tbl[] = {
12475	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
12476	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12477	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12478	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
12479	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
12480	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
12481	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
12482	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
12483	 *        Any other models that need this preset?
12484	 */
12485	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
12486	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
12487	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
12488	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
12489	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
12490	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
12491	/* FIXME: the below seems conflict */
12492	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
12493	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
12494	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
12495	{}
12496};
12497
12498static struct alc_config_preset alc861_presets[] = {
12499	[ALC861_3ST] = {
12500		.mixers = { alc861_3ST_mixer },
12501		.init_verbs = { alc861_threestack_init_verbs },
12502		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12503		.dac_nids = alc861_dac_nids,
12504		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12505		.channel_mode = alc861_threestack_modes,
12506		.need_dac_fix = 1,
12507		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12508		.adc_nids = alc861_adc_nids,
12509		.input_mux = &alc861_capture_source,
12510	},
12511	[ALC861_3ST_DIG] = {
12512		.mixers = { alc861_base_mixer },
12513		.init_verbs = { alc861_threestack_init_verbs },
12514		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12515		.dac_nids = alc861_dac_nids,
12516		.dig_out_nid = ALC861_DIGOUT_NID,
12517		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12518		.channel_mode = alc861_threestack_modes,
12519		.need_dac_fix = 1,
12520		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12521		.adc_nids = alc861_adc_nids,
12522		.input_mux = &alc861_capture_source,
12523	},
12524	[ALC861_6ST_DIG] = {
12525		.mixers = { alc861_base_mixer },
12526		.init_verbs = { alc861_base_init_verbs },
12527		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12528		.dac_nids = alc861_dac_nids,
12529		.dig_out_nid = ALC861_DIGOUT_NID,
12530		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
12531		.channel_mode = alc861_8ch_modes,
12532		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12533		.adc_nids = alc861_adc_nids,
12534		.input_mux = &alc861_capture_source,
12535	},
12536	[ALC660_3ST] = {
12537		.mixers = { alc861_3ST_mixer },
12538		.init_verbs = { alc861_threestack_init_verbs },
12539		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
12540		.dac_nids = alc660_dac_nids,
12541		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12542		.channel_mode = alc861_threestack_modes,
12543		.need_dac_fix = 1,
12544		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12545		.adc_nids = alc861_adc_nids,
12546		.input_mux = &alc861_capture_source,
12547	},
12548	[ALC861_UNIWILL_M31] = {
12549		.mixers = { alc861_uniwill_m31_mixer },
12550		.init_verbs = { alc861_uniwill_m31_init_verbs },
12551		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12552		.dac_nids = alc861_dac_nids,
12553		.dig_out_nid = ALC861_DIGOUT_NID,
12554		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
12555		.channel_mode = alc861_uniwill_m31_modes,
12556		.need_dac_fix = 1,
12557		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12558		.adc_nids = alc861_adc_nids,
12559		.input_mux = &alc861_capture_source,
12560	},
12561	[ALC861_TOSHIBA] = {
12562		.mixers = { alc861_toshiba_mixer },
12563		.init_verbs = { alc861_base_init_verbs,
12564				alc861_toshiba_init_verbs },
12565		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12566		.dac_nids = alc861_dac_nids,
12567		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12568		.channel_mode = alc883_3ST_2ch_modes,
12569		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12570		.adc_nids = alc861_adc_nids,
12571		.input_mux = &alc861_capture_source,
12572		.unsol_event = alc861_toshiba_unsol_event,
12573		.init_hook = alc861_toshiba_automute,
12574	},
12575	[ALC861_ASUS] = {
12576		.mixers = { alc861_asus_mixer },
12577		.init_verbs = { alc861_asus_init_verbs },
12578		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12579		.dac_nids = alc861_dac_nids,
12580		.dig_out_nid = ALC861_DIGOUT_NID,
12581		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
12582		.channel_mode = alc861_asus_modes,
12583		.need_dac_fix = 1,
12584		.hp_nid = 0x06,
12585		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12586		.adc_nids = alc861_adc_nids,
12587		.input_mux = &alc861_capture_source,
12588	},
12589	[ALC861_ASUS_LAPTOP] = {
12590		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
12591		.init_verbs = { alc861_asus_init_verbs,
12592				alc861_asus_laptop_init_verbs },
12593		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12594		.dac_nids = alc861_dac_nids,
12595		.dig_out_nid = ALC861_DIGOUT_NID,
12596		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12597		.channel_mode = alc883_3ST_2ch_modes,
12598		.need_dac_fix = 1,
12599		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12600		.adc_nids = alc861_adc_nids,
12601		.input_mux = &alc861_capture_source,
12602	},
12603};
12604
12605
12606static int patch_alc861(struct hda_codec *codec)
12607{
12608	struct alc_spec *spec;
12609	int board_config;
12610	int err;
12611
12612	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12613	if (spec == NULL)
12614		return -ENOMEM;
12615
12616	codec->spec = spec;
12617
12618        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
12619						  alc861_models,
12620						  alc861_cfg_tbl);
12621
12622	if (board_config < 0) {
12623		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
12624		       "trying auto-probe from BIOS...\n");
12625		board_config = ALC861_AUTO;
12626	}
12627
12628	if (board_config == ALC861_AUTO) {
12629		/* automatic parse from the BIOS config */
12630		err = alc861_parse_auto_config(codec);
12631		if (err < 0) {
12632			alc_free(codec);
12633			return err;
12634		} else if (!err) {
12635			printk(KERN_INFO
12636			       "hda_codec: Cannot set up configuration "
12637			       "from BIOS.  Using base mode...\n");
12638		   board_config = ALC861_3ST_DIG;
12639		}
12640	}
12641
12642	if (board_config != ALC861_AUTO)
12643		setup_preset(spec, &alc861_presets[board_config]);
12644
12645	spec->stream_name_analog = "ALC861 Analog";
12646	spec->stream_analog_playback = &alc861_pcm_analog_playback;
12647	spec->stream_analog_capture = &alc861_pcm_analog_capture;
12648
12649	spec->stream_name_digital = "ALC861 Digital";
12650	spec->stream_digital_playback = &alc861_pcm_digital_playback;
12651	spec->stream_digital_capture = &alc861_pcm_digital_capture;
12652
12653	spec->vmaster_nid = 0x03;
12654
12655	codec->patch_ops = alc_patch_ops;
12656	if (board_config == ALC861_AUTO)
12657		spec->init_hook = alc861_auto_init;
12658#ifdef CONFIG_SND_HDA_POWER_SAVE
12659	if (!spec->loopback.amplist)
12660		spec->loopback.amplist = alc861_loopbacks;
12661#endif
12662
12663	return 0;
12664}
12665
12666/*
12667 * ALC861-VD support
12668 *
12669 * Based on ALC882
12670 *
12671 * In addition, an independent DAC
12672 */
12673#define ALC861VD_DIGOUT_NID	0x06
12674
12675static hda_nid_t alc861vd_dac_nids[4] = {
12676	/* front, surr, clfe, side surr */
12677	0x02, 0x03, 0x04, 0x05
12678};
12679
12680/* dac_nids for ALC660vd are in a different order - according to
12681 * Realtek's driver.
12682 * This should probably tesult in a different mixer for 6stack models
12683 * of ALC660vd codecs, but for now there is only 3stack mixer
12684 * - and it is the same as in 861vd.
12685 * adc_nids in ALC660vd are (is) the same as in 861vd
12686 */
12687static hda_nid_t alc660vd_dac_nids[3] = {
12688	/* front, rear, clfe, rear_surr */
12689	0x02, 0x04, 0x03
12690};
12691
12692static hda_nid_t alc861vd_adc_nids[1] = {
12693	/* ADC0 */
12694	0x09,
12695};
12696
12697static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
12698
12699/* input MUX */
12700/* FIXME: should be a matrix-type input source selection */
12701static struct hda_input_mux alc861vd_capture_source = {
12702	.num_items = 4,
12703	.items = {
12704		{ "Mic", 0x0 },
12705		{ "Front Mic", 0x1 },
12706		{ "Line", 0x2 },
12707		{ "CD", 0x4 },
12708	},
12709};
12710
12711static struct hda_input_mux alc861vd_dallas_capture_source = {
12712	.num_items = 2,
12713	.items = {
12714		{ "Ext Mic", 0x0 },
12715		{ "Int Mic", 0x1 },
12716	},
12717};
12718
12719static struct hda_input_mux alc861vd_hp_capture_source = {
12720	.num_items = 2,
12721	.items = {
12722		{ "Front Mic", 0x0 },
12723		{ "ATAPI Mic", 0x1 },
12724	},
12725};
12726
12727#define alc861vd_mux_enum_info alc_mux_enum_info
12728#define alc861vd_mux_enum_get alc_mux_enum_get
12729/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
12730#define alc861vd_mux_enum_put alc882_mux_enum_put
12731
12732/*
12733 * 2ch mode
12734 */
12735static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
12736	{ 2, NULL }
12737};
12738
12739/*
12740 * 6ch mode
12741 */
12742static struct hda_verb alc861vd_6stack_ch6_init[] = {
12743	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12744	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12745	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12746	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12747	{ } /* end */
12748};
12749
12750/*
12751 * 8ch mode
12752 */
12753static struct hda_verb alc861vd_6stack_ch8_init[] = {
12754	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12755	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12756	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12757	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12758	{ } /* end */
12759};
12760
12761static struct hda_channel_mode alc861vd_6stack_modes[2] = {
12762	{ 6, alc861vd_6stack_ch6_init },
12763	{ 8, alc861vd_6stack_ch8_init },
12764};
12765
12766static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
12767	{
12768		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12769		.name = "Channel Mode",
12770		.info = alc_ch_mode_info,
12771		.get = alc_ch_mode_get,
12772		.put = alc_ch_mode_put,
12773	},
12774	{ } /* end */
12775};
12776
12777static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
12778	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12779	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12780
12781	{
12782		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12783		/* The multiple "Capture Source" controls confuse alsamixer
12784		 * So call somewhat different..
12785		 */
12786		/* .name = "Capture Source", */
12787		.name = "Input Source",
12788		.count = 1,
12789		.info = alc861vd_mux_enum_info,
12790		.get = alc861vd_mux_enum_get,
12791		.put = alc861vd_mux_enum_put,
12792	},
12793	{ } /* end */
12794};
12795
12796/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12797 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12798 */
12799static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
12800	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12801	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12802
12803	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12804	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
12805
12806	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
12807				HDA_OUTPUT),
12808	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
12809				HDA_OUTPUT),
12810	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12811	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
12812
12813	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
12814	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
12815
12816	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12817
12818	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12819	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12820	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12821
12822	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12823	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12824	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12825
12826	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12827	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12828
12829	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12830	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12831
12832	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12833	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12834
12835	{ } /* end */
12836};
12837
12838static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12839	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12840	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12841
12842	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12843
12844	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12845	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12846	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12847
12848	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12849	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12850	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12851
12852	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12853	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12854
12855	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12856	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12857
12858	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12859	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12860
12861	{ } /* end */
12862};
12863
12864static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12865	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12866	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12867	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12868
12869	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12870
12871	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12872	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12873	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12874
12875	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12876	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12877	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12878
12879	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12880	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12881
12882	{ } /* end */
12883};
12884
12885/* Pin assignment: Speaker=0x14, HP = 0x15,
12886 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
12887 */
12888static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12889	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12890	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
12891	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12892	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12893	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12894	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12895	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12896	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12897	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12898	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12899	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
12900	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
12901	{ } /* end */
12902};
12903
12904/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12905 *                 Front Mic=0x18, ATAPI Mic = 0x19,
12906 */
12907static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12908	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12909	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12910	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12911	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12912	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12913	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12914	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12915	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12916
12917	{ } /* end */
12918};
12919
12920/*
12921 * generic initialization of ADC, input mixers and output mixers
12922 */
12923static struct hda_verb alc861vd_volume_init_verbs[] = {
12924	/*
12925	 * Unmute ADC0 and set the default input to mic-in
12926	 */
12927	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12928	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12929
12930	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12931	 * the analog-loopback mixer widget
12932	 */
12933	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12934	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12935	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12936	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12937	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12938	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12939
12940	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
12941	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12942	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12943	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12944	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12945
12946	/*
12947	 * Set up output mixers (0x02 - 0x05)
12948	 */
12949	/* set vol=0 to output mixers */
12950	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12951	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12952	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12953	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12954
12955	/* set up input amps for analog loopback */
12956	/* Amp Indices: DAC = 0, mixer = 1 */
12957	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12958	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12959	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12960	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12961	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12962	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12963	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12964	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12965
12966	{ }
12967};
12968
12969/*
12970 * 3-stack pin configuration:
12971 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12972 */
12973static struct hda_verb alc861vd_3stack_init_verbs[] = {
12974	/*
12975	 * Set pin mode and muting
12976	 */
12977	/* set front pin widgets 0x14 for output */
12978	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12979	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12980	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12981
12982	/* Mic (rear) pin: input vref at 80% */
12983	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12984	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12985	/* Front Mic pin: input vref at 80% */
12986	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12987	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12988	/* Line In pin: input */
12989	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12990	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12991	/* Line-2 In: Headphone output (output 0 - 0x0c) */
12992	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12993	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12994	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12995	/* CD pin widget for input */
12996	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12997
12998	{ }
12999};
13000
13001/*
13002 * 6-stack pin configuration:
13003 */
13004static struct hda_verb alc861vd_6stack_init_verbs[] = {
13005	/*
13006	 * Set pin mode and muting
13007	 */
13008	/* set front pin widgets 0x14 for output */
13009	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13010	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13011	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13012
13013	/* Rear Pin: output 1 (0x0d) */
13014	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13015	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13016	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13017	/* CLFE Pin: output 2 (0x0e) */
13018	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13019	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13020	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13021	/* Side Pin: output 3 (0x0f) */
13022	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13023	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13024	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13025
13026	/* Mic (rear) pin: input vref at 80% */
13027	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13028	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13029	/* Front Mic pin: input vref at 80% */
13030	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13031	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13032	/* Line In pin: input */
13033	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13034	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13035	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13036	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13037	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13038	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13039	/* CD pin widget for input */
13040	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13041
13042	{ }
13043};
13044
13045static struct hda_verb alc861vd_eapd_verbs[] = {
13046	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13047	{ }
13048};
13049
13050static struct hda_verb alc660vd_eapd_verbs[] = {
13051	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13052	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13053	{ }
13054};
13055
13056static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13057	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13058	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13059	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13060	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13061	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13062	{}
13063};
13064
13065/* toggle speaker-output according to the hp-jack state */
13066static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13067{
13068	unsigned int present;
13069	unsigned char bits;
13070
13071	present = snd_hda_codec_read(codec, 0x1b, 0,
13072				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13073	bits = present ? HDA_AMP_MUTE : 0;
13074	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13075				 HDA_AMP_MUTE, bits);
13076}
13077
13078static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13079{
13080	unsigned int present;
13081	unsigned char bits;
13082
13083	present = snd_hda_codec_read(codec, 0x18, 0,
13084				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13085	bits = present ? HDA_AMP_MUTE : 0;
13086	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13087				 HDA_AMP_MUTE, bits);
13088}
13089
13090static void alc861vd_lenovo_automute(struct hda_codec *codec)
13091{
13092	alc861vd_lenovo_hp_automute(codec);
13093	alc861vd_lenovo_mic_automute(codec);
13094}
13095
13096static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13097					unsigned int res)
13098{
13099	switch (res >> 26) {
13100	case ALC880_HP_EVENT:
13101		alc861vd_lenovo_hp_automute(codec);
13102		break;
13103	case ALC880_MIC_EVENT:
13104		alc861vd_lenovo_mic_automute(codec);
13105		break;
13106	}
13107}
13108
13109static struct hda_verb alc861vd_dallas_verbs[] = {
13110	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13111	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13112	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13113	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13114
13115	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13116	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13117	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13118	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13119	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13120	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13121	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13122	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13123
13124	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13125	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13126	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13127	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13128	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13129	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13130	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13131	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13132
13133	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13134	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13135	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13136	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13137	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13138	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13139	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13140	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13141
13142	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13143	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13144	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13145	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13146
13147	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13148	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13149	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13150
13151	{ } /* end */
13152};
13153
13154/* toggle speaker-output according to the hp-jack state */
13155static void alc861vd_dallas_automute(struct hda_codec *codec)
13156{
13157	unsigned int present;
13158
13159	present = snd_hda_codec_read(codec, 0x15, 0,
13160				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13161	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13162				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13163}
13164
13165static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13166{
13167	if ((res >> 26) == ALC880_HP_EVENT)
13168		alc861vd_dallas_automute(codec);
13169}
13170
13171#ifdef CONFIG_SND_HDA_POWER_SAVE
13172#define alc861vd_loopbacks	alc880_loopbacks
13173#endif
13174
13175/* pcm configuration: identiacal with ALC880 */
13176#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
13177#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
13178#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
13179#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
13180
13181/*
13182 * configuration and preset
13183 */
13184static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13185	[ALC660VD_3ST]		= "3stack-660",
13186	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
13187	[ALC861VD_3ST]		= "3stack",
13188	[ALC861VD_3ST_DIG]	= "3stack-digout",
13189	[ALC861VD_6ST_DIG]	= "6stack-digout",
13190	[ALC861VD_LENOVO]	= "lenovo",
13191	[ALC861VD_DALLAS]	= "dallas",
13192	[ALC861VD_HP]		= "hp",
13193	[ALC861VD_AUTO]		= "auto",
13194};
13195
13196static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13197	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13198	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13199	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13200	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13201	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13202	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13203	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13204	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13205	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13206	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13207	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13208	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13209	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13210	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13211	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13212	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13213	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13214	{}
13215};
13216
13217static struct alc_config_preset alc861vd_presets[] = {
13218	[ALC660VD_3ST] = {
13219		.mixers = { alc861vd_3st_mixer },
13220		.init_verbs = { alc861vd_volume_init_verbs,
13221				 alc861vd_3stack_init_verbs },
13222		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13223		.dac_nids = alc660vd_dac_nids,
13224		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13225		.channel_mode = alc861vd_3stack_2ch_modes,
13226		.input_mux = &alc861vd_capture_source,
13227	},
13228	[ALC660VD_3ST_DIG] = {
13229		.mixers = { alc861vd_3st_mixer },
13230		.init_verbs = { alc861vd_volume_init_verbs,
13231				 alc861vd_3stack_init_verbs },
13232		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13233		.dac_nids = alc660vd_dac_nids,
13234		.dig_out_nid = ALC861VD_DIGOUT_NID,
13235		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13236		.channel_mode = alc861vd_3stack_2ch_modes,
13237		.input_mux = &alc861vd_capture_source,
13238	},
13239	[ALC861VD_3ST] = {
13240		.mixers = { alc861vd_3st_mixer },
13241		.init_verbs = { alc861vd_volume_init_verbs,
13242				 alc861vd_3stack_init_verbs },
13243		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13244		.dac_nids = alc861vd_dac_nids,
13245		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13246		.channel_mode = alc861vd_3stack_2ch_modes,
13247		.input_mux = &alc861vd_capture_source,
13248	},
13249	[ALC861VD_3ST_DIG] = {
13250		.mixers = { alc861vd_3st_mixer },
13251		.init_verbs = { alc861vd_volume_init_verbs,
13252		 		 alc861vd_3stack_init_verbs },
13253		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13254		.dac_nids = alc861vd_dac_nids,
13255		.dig_out_nid = ALC861VD_DIGOUT_NID,
13256		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13257		.channel_mode = alc861vd_3stack_2ch_modes,
13258		.input_mux = &alc861vd_capture_source,
13259	},
13260	[ALC861VD_6ST_DIG] = {
13261		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
13262		.init_verbs = { alc861vd_volume_init_verbs,
13263				alc861vd_6stack_init_verbs },
13264		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13265		.dac_nids = alc861vd_dac_nids,
13266		.dig_out_nid = ALC861VD_DIGOUT_NID,
13267		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
13268		.channel_mode = alc861vd_6stack_modes,
13269		.input_mux = &alc861vd_capture_source,
13270	},
13271	[ALC861VD_LENOVO] = {
13272		.mixers = { alc861vd_lenovo_mixer },
13273		.init_verbs = { alc861vd_volume_init_verbs,
13274				alc861vd_3stack_init_verbs,
13275				alc861vd_eapd_verbs,
13276				alc861vd_lenovo_unsol_verbs },
13277		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13278		.dac_nids = alc660vd_dac_nids,
13279		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13280		.channel_mode = alc861vd_3stack_2ch_modes,
13281		.input_mux = &alc861vd_capture_source,
13282		.unsol_event = alc861vd_lenovo_unsol_event,
13283		.init_hook = alc861vd_lenovo_automute,
13284	},
13285	[ALC861VD_DALLAS] = {
13286		.mixers = { alc861vd_dallas_mixer },
13287		.init_verbs = { alc861vd_dallas_verbs },
13288		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13289		.dac_nids = alc861vd_dac_nids,
13290		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13291		.channel_mode = alc861vd_3stack_2ch_modes,
13292		.input_mux = &alc861vd_dallas_capture_source,
13293		.unsol_event = alc861vd_dallas_unsol_event,
13294		.init_hook = alc861vd_dallas_automute,
13295	},
13296	[ALC861VD_HP] = {
13297		.mixers = { alc861vd_hp_mixer },
13298		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
13299		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13300		.dac_nids = alc861vd_dac_nids,
13301		.dig_out_nid = ALC861VD_DIGOUT_NID,
13302		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13303		.channel_mode = alc861vd_3stack_2ch_modes,
13304		.input_mux = &alc861vd_hp_capture_source,
13305		.unsol_event = alc861vd_dallas_unsol_event,
13306		.init_hook = alc861vd_dallas_automute,
13307	},
13308};
13309
13310/*
13311 * BIOS auto configuration
13312 */
13313static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
13314				hda_nid_t nid, int pin_type, int dac_idx)
13315{
13316	alc_set_pin_output(codec, nid, pin_type);
13317}
13318
13319static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
13320{
13321	struct alc_spec *spec = codec->spec;
13322	int i;
13323
13324	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13325	for (i = 0; i <= HDA_SIDE; i++) {
13326		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13327		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13328		if (nid)
13329			alc861vd_auto_set_output_and_unmute(codec, nid,
13330							    pin_type, i);
13331	}
13332}
13333
13334
13335static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
13336{
13337	struct alc_spec *spec = codec->spec;
13338	hda_nid_t pin;
13339
13340	pin = spec->autocfg.hp_pins[0];
13341	if (pin) /* connect to front and  use dac 0 */
13342		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13343	pin = spec->autocfg.speaker_pins[0];
13344	if (pin)
13345		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13346}
13347
13348#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
13349#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
13350
13351static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
13352{
13353	struct alc_spec *spec = codec->spec;
13354	int i;
13355
13356	for (i = 0; i < AUTO_PIN_LAST; i++) {
13357		hda_nid_t nid = spec->autocfg.input_pins[i];
13358		if (alc861vd_is_input_pin(nid)) {
13359			snd_hda_codec_write(codec, nid, 0,
13360					AC_VERB_SET_PIN_WIDGET_CONTROL,
13361					i <= AUTO_PIN_FRONT_MIC ?
13362							PIN_VREF80 : PIN_IN);
13363			if (nid != ALC861VD_PIN_CD_NID)
13364				snd_hda_codec_write(codec, nid, 0,
13365						AC_VERB_SET_AMP_GAIN_MUTE,
13366						AMP_OUT_MUTE);
13367		}
13368	}
13369}
13370
13371#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
13372
13373#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
13374#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
13375
13376/* add playback controls from the parsed DAC table */
13377/* Based on ALC880 version. But ALC861VD has separate,
13378 * different NIDs for mute/unmute switch and volume control */
13379static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
13380					     const struct auto_pin_cfg *cfg)
13381{
13382	char name[32];
13383	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
13384	hda_nid_t nid_v, nid_s;
13385	int i, err;
13386
13387	for (i = 0; i < cfg->line_outs; i++) {
13388		if (!spec->multiout.dac_nids[i])
13389			continue;
13390		nid_v = alc861vd_idx_to_mixer_vol(
13391				alc880_dac_to_idx(
13392					spec->multiout.dac_nids[i]));
13393		nid_s = alc861vd_idx_to_mixer_switch(
13394				alc880_dac_to_idx(
13395					spec->multiout.dac_nids[i]));
13396
13397		if (i == 2) {
13398			/* Center/LFE */
13399			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13400					  "Center Playback Volume",
13401					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
13402							      HDA_OUTPUT));
13403			if (err < 0)
13404				return err;
13405			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13406					  "LFE Playback Volume",
13407					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
13408							      HDA_OUTPUT));
13409			if (err < 0)
13410				return err;
13411			err = add_control(spec, ALC_CTL_BIND_MUTE,
13412					  "Center Playback Switch",
13413					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
13414							      HDA_INPUT));
13415			if (err < 0)
13416				return err;
13417			err = add_control(spec, ALC_CTL_BIND_MUTE,
13418					  "LFE Playback Switch",
13419					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
13420							      HDA_INPUT));
13421			if (err < 0)
13422				return err;
13423		} else {
13424			sprintf(name, "%s Playback Volume", chname[i]);
13425			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13426					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
13427							      HDA_OUTPUT));
13428			if (err < 0)
13429				return err;
13430			sprintf(name, "%s Playback Switch", chname[i]);
13431			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13432					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
13433							      HDA_INPUT));
13434			if (err < 0)
13435				return err;
13436		}
13437	}
13438	return 0;
13439}
13440
13441/* add playback controls for speaker and HP outputs */
13442/* Based on ALC880 version. But ALC861VD has separate,
13443 * different NIDs for mute/unmute switch and volume control */
13444static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
13445					hda_nid_t pin, const char *pfx)
13446{
13447	hda_nid_t nid_v, nid_s;
13448	int err;
13449	char name[32];
13450
13451	if (!pin)
13452		return 0;
13453
13454	if (alc880_is_fixed_pin(pin)) {
13455		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13456		/* specify the DAC as the extra output */
13457		if (!spec->multiout.hp_nid)
13458			spec->multiout.hp_nid = nid_v;
13459		else
13460			spec->multiout.extra_out_nid[0] = nid_v;
13461		/* control HP volume/switch on the output mixer amp */
13462		nid_v = alc861vd_idx_to_mixer_vol(
13463				alc880_fixed_pin_idx(pin));
13464		nid_s = alc861vd_idx_to_mixer_switch(
13465				alc880_fixed_pin_idx(pin));
13466
13467		sprintf(name, "%s Playback Volume", pfx);
13468		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13469				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
13470		if (err < 0)
13471			return err;
13472		sprintf(name, "%s Playback Switch", pfx);
13473		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13474				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
13475		if (err < 0)
13476			return err;
13477	} else if (alc880_is_multi_pin(pin)) {
13478		/* set manual connection */
13479		/* we have only a switch on HP-out PIN */
13480		sprintf(name, "%s Playback Switch", pfx);
13481		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13482				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13483		if (err < 0)
13484			return err;
13485	}
13486	return 0;
13487}
13488
13489/* parse the BIOS configuration and set up the alc_spec
13490 * return 1 if successful, 0 if the proper config is not found,
13491 * or a negative error code
13492 * Based on ALC880 version - had to change it to override
13493 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
13494static int alc861vd_parse_auto_config(struct hda_codec *codec)
13495{
13496	struct alc_spec *spec = codec->spec;
13497	int err;
13498	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
13499
13500	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13501					   alc861vd_ignore);
13502	if (err < 0)
13503		return err;
13504	if (!spec->autocfg.line_outs)
13505		return 0; /* can't find valid BIOS pin config */
13506
13507	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13508	if (err < 0)
13509		return err;
13510	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
13511	if (err < 0)
13512		return err;
13513	err = alc861vd_auto_create_extra_out(spec,
13514					     spec->autocfg.speaker_pins[0],
13515					     "Speaker");
13516	if (err < 0)
13517		return err;
13518	err = alc861vd_auto_create_extra_out(spec,
13519					     spec->autocfg.hp_pins[0],
13520					     "Headphone");
13521	if (err < 0)
13522		return err;
13523	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
13524	if (err < 0)
13525		return err;
13526
13527	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13528
13529	if (spec->autocfg.dig_out_pin)
13530		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
13531
13532	if (spec->kctl_alloc)
13533		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13534
13535	spec->init_verbs[spec->num_init_verbs++]
13536		= alc861vd_volume_init_verbs;
13537
13538	spec->num_mux_defs = 1;
13539	spec->input_mux = &spec->private_imux;
13540
13541	err = alc_auto_add_mic_boost(codec);
13542	if (err < 0)
13543		return err;
13544
13545	return 1;
13546}
13547
13548/* additional initialization for auto-configuration model */
13549static void alc861vd_auto_init(struct hda_codec *codec)
13550{
13551	struct alc_spec *spec = codec->spec;
13552	alc861vd_auto_init_multi_out(codec);
13553	alc861vd_auto_init_hp_out(codec);
13554	alc861vd_auto_init_analog_input(codec);
13555	alc861vd_auto_init_input_src(codec);
13556	if (spec->unsol_event)
13557		alc_sku_automute(codec);
13558}
13559
13560static int patch_alc861vd(struct hda_codec *codec)
13561{
13562	struct alc_spec *spec;
13563	int err, board_config;
13564
13565	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13566	if (spec == NULL)
13567		return -ENOMEM;
13568
13569	codec->spec = spec;
13570
13571	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
13572						  alc861vd_models,
13573						  alc861vd_cfg_tbl);
13574
13575	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
13576		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
13577			"ALC861VD, trying auto-probe from BIOS...\n");
13578		board_config = ALC861VD_AUTO;
13579	}
13580
13581	if (board_config == ALC861VD_AUTO) {
13582		/* automatic parse from the BIOS config */
13583		err = alc861vd_parse_auto_config(codec);
13584		if (err < 0) {
13585			alc_free(codec);
13586			return err;
13587		} else if (!err) {
13588			printk(KERN_INFO
13589			       "hda_codec: Cannot set up configuration "
13590			       "from BIOS.  Using base mode...\n");
13591			board_config = ALC861VD_3ST;
13592		}
13593	}
13594
13595	if (board_config != ALC861VD_AUTO)
13596		setup_preset(spec, &alc861vd_presets[board_config]);
13597
13598	if (codec->vendor_id == 0x10ec0660) {
13599		spec->stream_name_analog = "ALC660-VD Analog";
13600		spec->stream_name_digital = "ALC660-VD Digital";
13601		/* always turn on EAPD */
13602		spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
13603	} else {
13604		spec->stream_name_analog = "ALC861VD Analog";
13605		spec->stream_name_digital = "ALC861VD Digital";
13606	}
13607
13608	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
13609	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
13610
13611	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
13612	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
13613
13614	spec->adc_nids = alc861vd_adc_nids;
13615	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
13616	spec->capsrc_nids = alc861vd_capsrc_nids;
13617
13618	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
13619	spec->num_mixers++;
13620
13621	spec->vmaster_nid = 0x02;
13622
13623	codec->patch_ops = alc_patch_ops;
13624
13625	if (board_config == ALC861VD_AUTO)
13626		spec->init_hook = alc861vd_auto_init;
13627#ifdef CONFIG_SND_HDA_POWER_SAVE
13628	if (!spec->loopback.amplist)
13629		spec->loopback.amplist = alc861vd_loopbacks;
13630#endif
13631
13632	return 0;
13633}
13634
13635/*
13636 * ALC662 support
13637 *
13638 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
13639 * configuration.  Each pin widget can choose any input DACs and a mixer.
13640 * Each ADC is connected from a mixer of all inputs.  This makes possible
13641 * 6-channel independent captures.
13642 *
13643 * In addition, an independent DAC for the multi-playback (not used in this
13644 * driver yet).
13645 */
13646#define ALC662_DIGOUT_NID	0x06
13647#define ALC662_DIGIN_NID	0x0a
13648
13649static hda_nid_t alc662_dac_nids[4] = {
13650	/* front, rear, clfe, rear_surr */
13651	0x02, 0x03, 0x04
13652};
13653
13654static hda_nid_t alc662_adc_nids[1] = {
13655	/* ADC1-2 */
13656	0x09,
13657};
13658
13659static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
13660
13661/* input MUX */
13662/* FIXME: should be a matrix-type input source selection */
13663static struct hda_input_mux alc662_capture_source = {
13664	.num_items = 4,
13665	.items = {
13666		{ "Mic", 0x0 },
13667		{ "Front Mic", 0x1 },
13668		{ "Line", 0x2 },
13669		{ "CD", 0x4 },
13670	},
13671};
13672
13673static struct hda_input_mux alc662_lenovo_101e_capture_source = {
13674	.num_items = 2,
13675	.items = {
13676		{ "Mic", 0x1 },
13677		{ "Line", 0x2 },
13678	},
13679};
13680
13681static struct hda_input_mux alc662_eeepc_capture_source = {
13682	.num_items = 2,
13683	.items = {
13684		{ "i-Mic", 0x1 },
13685		{ "e-Mic", 0x0 },
13686	},
13687};
13688
13689static struct hda_input_mux alc663_capture_source = {
13690	.num_items = 3,
13691	.items = {
13692		{ "Mic", 0x0 },
13693		{ "Front Mic", 0x1 },
13694		{ "Line", 0x2 },
13695	},
13696};
13697
13698static struct hda_input_mux alc663_m51va_capture_source = {
13699	.num_items = 2,
13700	.items = {
13701		{ "Ext-Mic", 0x0 },
13702		{ "D-Mic", 0x9 },
13703	},
13704};
13705
13706#define alc662_mux_enum_info alc_mux_enum_info
13707#define alc662_mux_enum_get alc_mux_enum_get
13708#define alc662_mux_enum_put alc882_mux_enum_put
13709
13710/*
13711 * 2ch mode
13712 */
13713static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
13714	{ 2, NULL }
13715};
13716
13717/*
13718 * 2ch mode
13719 */
13720static struct hda_verb alc662_3ST_ch2_init[] = {
13721	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
13722	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13723	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
13724	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13725	{ } /* end */
13726};
13727
13728/*
13729 * 6ch mode
13730 */
13731static struct hda_verb alc662_3ST_ch6_init[] = {
13732	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13733	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13734	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
13735	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13736	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13737	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
13738	{ } /* end */
13739};
13740
13741static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
13742	{ 2, alc662_3ST_ch2_init },
13743	{ 6, alc662_3ST_ch6_init },
13744};
13745
13746/*
13747 * 2ch mode
13748 */
13749static struct hda_verb alc662_sixstack_ch6_init[] = {
13750	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13751	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13752	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13753	{ } /* end */
13754};
13755
13756/*
13757 * 6ch mode
13758 */
13759static struct hda_verb alc662_sixstack_ch8_init[] = {
13760	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13761	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13762	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13763	{ } /* end */
13764};
13765
13766static struct hda_channel_mode alc662_5stack_modes[2] = {
13767	{ 2, alc662_sixstack_ch6_init },
13768	{ 6, alc662_sixstack_ch8_init },
13769};
13770
13771/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13772 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13773 */
13774
13775static struct snd_kcontrol_new alc662_base_mixer[] = {
13776	/* output mixer control */
13777	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13778	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13779	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13780	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13781	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13782	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13783	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13784	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13785	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13786
13787	/*Input mixer control */
13788	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
13789	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
13790	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
13791	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
13792	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
13793	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
13794	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
13795	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
13796	{ } /* end */
13797};
13798
13799static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
13800	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13801	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13802	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13803	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13804	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13805	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13806	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13807	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13808	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13809	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13810	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13811	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13812	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13813	{ } /* end */
13814};
13815
13816static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
13817	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13818	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13819	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13820	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13821	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13822	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13823	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13824	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13825	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13826	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13827	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13828	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13829	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13830	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13831	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13832	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13833	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13834	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13835	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13836	{ } /* end */
13837};
13838
13839static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13840	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13841	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13842	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13843	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
13844	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13845	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13846	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13847	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13848	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13849	{ } /* end */
13850};
13851
13852static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
13853	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13854
13855	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13856	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13857
13858	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13859	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13860	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13861
13862	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13863	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13864	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13865	{ } /* end */
13866};
13867
13868static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13869	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13870	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13871	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13872	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13873	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13874	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13875	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13876	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
13877	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13878	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13879	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13880	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13881	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13882	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13883	{ } /* end */
13884};
13885
13886static struct snd_kcontrol_new alc663_m51va_mixer[] = {
13887	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13888	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13889	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13890	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13891	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13892	HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT),
13893	{ } /* end */
13894};
13895
13896static struct snd_kcontrol_new alc663_g71v_mixer[] = {
13897	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13898	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13899	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13900	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13901	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13902
13903	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13904	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13905	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13906	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13907	{ } /* end */
13908};
13909
13910static struct snd_kcontrol_new alc663_g50v_mixer[] = {
13911	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13912	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13913	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13914
13915	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13916	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13917	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13918	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13919	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13920	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13921	{ } /* end */
13922};
13923
13924static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13925	{
13926		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13927		.name = "Channel Mode",
13928		.info = alc_ch_mode_info,
13929		.get = alc_ch_mode_get,
13930		.put = alc_ch_mode_put,
13931	},
13932	{ } /* end */
13933};
13934
13935static struct hda_verb alc662_init_verbs[] = {
13936	/* ADC: mute amp left and right */
13937	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13938	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13939	/* Front mixer: unmute input/output amp left and right (volume = 0) */
13940
13941	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13942	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13943	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13944	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13945	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13946
13947	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13948	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13949	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13950	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13951	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13952	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13953
13954	/* Front Pin: output 0 (0x0c) */
13955	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13956	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13957
13958	/* Rear Pin: output 1 (0x0d) */
13959	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13960	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13961
13962	/* CLFE Pin: output 2 (0x0e) */
13963	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13964	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13965
13966	/* Mic (rear) pin: input vref at 80% */
13967	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13968	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13969	/* Front Mic pin: input vref at 80% */
13970	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13971	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13972	/* Line In pin: input */
13973	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13974	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13975	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13976	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13977	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13978	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13979	/* CD pin widget for input */
13980	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13981
13982	/* FIXME: use matrix-type input source selection */
13983	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13984	/* Input mixer */
13985	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13986	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13987	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13988	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13989
13990	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13991	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13992	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13993	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13994
13995	/* always trun on EAPD */
13996	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13997	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13998
13999	{ }
14000};
14001
14002static struct hda_verb alc662_sue_init_verbs[] = {
14003	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14004	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14005	{}
14006};
14007
14008static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14009	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14010	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14011	{}
14012};
14013
14014/* Set Unsolicited Event*/
14015static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14016	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14017	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14018	{}
14019};
14020
14021/*
14022 * generic initialization of ADC, input mixers and output mixers
14023 */
14024static struct hda_verb alc662_auto_init_verbs[] = {
14025	/*
14026	 * Unmute ADC and set the default input to mic-in
14027	 */
14028	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14029	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14030
14031	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14032	 * mixer widget
14033	 * Note: PASD motherboards uses the Line In 2 as the input for front
14034	 * panel mic (mic 2)
14035	 */
14036	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14037	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14038	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14039	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14040	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14041	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14042
14043	/*
14044	 * Set up output mixers (0x0c - 0x0f)
14045	 */
14046	/* set vol=0 to output mixers */
14047	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14048	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14049	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14050
14051	/* set up input amps for analog loopback */
14052	/* Amp Indices: DAC = 0, mixer = 1 */
14053	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14054	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14055	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14056	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14057	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14058	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14059
14060
14061	/* FIXME: use matrix-type input source selection */
14062	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14063	/* Input mixer */
14064	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14065	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14066	{ }
14067};
14068
14069/* additional verbs for ALC663 */
14070static struct hda_verb alc663_auto_init_verbs[] = {
14071	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14072	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14073	{ }
14074};
14075
14076static struct hda_verb alc663_m51va_init_verbs[] = {
14077	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14078	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14079	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14080
14081	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14082
14083	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14084	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14085	{}
14086};
14087
14088static struct hda_verb alc663_g71v_init_verbs[] = {
14089	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14090	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
14091	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
14092
14093	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14094	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14095	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14096
14097	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14098	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
14099	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14100	{}
14101};
14102
14103static struct hda_verb alc663_g50v_init_verbs[] = {
14104	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14105	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14106	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14107
14108	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14109	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14110	{}
14111};
14112
14113/* capture mixer elements */
14114static struct snd_kcontrol_new alc662_capture_mixer[] = {
14115	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14116	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14117	{
14118		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14119		/* The multiple "Capture Source" controls confuse alsamixer
14120		 * So call somewhat different..
14121		 */
14122		/* .name = "Capture Source", */
14123		.name = "Input Source",
14124		.count = 1,
14125		.info = alc662_mux_enum_info,
14126		.get = alc662_mux_enum_get,
14127		.put = alc662_mux_enum_put,
14128	},
14129	{ } /* end */
14130};
14131
14132static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
14133{
14134	unsigned int present;
14135	unsigned char bits;
14136
14137	present = snd_hda_codec_read(codec, 0x14, 0,
14138				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14139	bits = present ? HDA_AMP_MUTE : 0;
14140	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14141				 HDA_AMP_MUTE, bits);
14142}
14143
14144static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
14145{
14146	unsigned int present;
14147	unsigned char bits;
14148
14149 	present = snd_hda_codec_read(codec, 0x1b, 0,
14150				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14151	bits = present ? HDA_AMP_MUTE : 0;
14152	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14153				 HDA_AMP_MUTE, bits);
14154	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14155				 HDA_AMP_MUTE, bits);
14156}
14157
14158static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
14159					   unsigned int res)
14160{
14161	if ((res >> 26) == ALC880_HP_EVENT)
14162		alc662_lenovo_101e_all_automute(codec);
14163	if ((res >> 26) == ALC880_FRONT_EVENT)
14164		alc662_lenovo_101e_ispeaker_automute(codec);
14165}
14166
14167static void alc662_eeepc_mic_automute(struct hda_codec *codec)
14168{
14169	unsigned int present;
14170
14171	present = snd_hda_codec_read(codec, 0x18, 0,
14172				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14173	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14174			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14175	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14176			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14177	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14178			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14179	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14180			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14181}
14182
14183/* unsolicited event for HP jack sensing */
14184static void alc662_eeepc_unsol_event(struct hda_codec *codec,
14185				     unsigned int res)
14186{
14187	if ((res >> 26) == ALC880_HP_EVENT)
14188		alc262_hippo1_automute( codec );
14189
14190	if ((res >> 26) == ALC880_MIC_EVENT)
14191		alc662_eeepc_mic_automute(codec);
14192}
14193
14194static void alc662_eeepc_inithook(struct hda_codec *codec)
14195{
14196	alc262_hippo1_automute( codec );
14197	alc662_eeepc_mic_automute(codec);
14198}
14199
14200static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
14201{
14202	unsigned int mute;
14203	unsigned int present;
14204
14205	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
14206	present = snd_hda_codec_read(codec, 0x14, 0,
14207				     AC_VERB_GET_PIN_SENSE, 0);
14208	present = (present & 0x80000000) != 0;
14209	if (present) {
14210		/* mute internal speaker */
14211		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14212					 HDA_AMP_MUTE, HDA_AMP_MUTE);
14213	} else {
14214		/* unmute internal speaker if necessary */
14215		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
14216		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14217					 HDA_AMP_MUTE, mute);
14218	}
14219}
14220
14221/* unsolicited event for HP jack sensing */
14222static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
14223					  unsigned int res)
14224{
14225	if ((res >> 26) == ALC880_HP_EVENT)
14226		alc662_eeepc_ep20_automute(codec);
14227}
14228
14229static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
14230{
14231	alc662_eeepc_ep20_automute(codec);
14232}
14233
14234static void alc663_m51va_speaker_automute(struct hda_codec *codec)
14235{
14236	unsigned int present;
14237	unsigned char bits;
14238
14239	present = snd_hda_codec_read(codec, 0x21, 0,
14240				     AC_VERB_GET_PIN_SENSE, 0)
14241		& AC_PINSENSE_PRESENCE;
14242	bits = present ? HDA_AMP_MUTE : 0;
14243	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14244				 HDA_AMP_MUTE, bits);
14245}
14246
14247static void alc663_m51va_mic_automute(struct hda_codec *codec)
14248{
14249	unsigned int present;
14250
14251	present = snd_hda_codec_read(codec, 0x18, 0,
14252				     AC_VERB_GET_PIN_SENSE, 0)
14253		& AC_PINSENSE_PRESENCE;
14254	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14255			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14256	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14257			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14258	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14259			    0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14260	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14261			    0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14262}
14263
14264static void alc663_m51va_unsol_event(struct hda_codec *codec,
14265					   unsigned int res)
14266{
14267	switch (res >> 26) {
14268	case ALC880_HP_EVENT:
14269		alc663_m51va_speaker_automute(codec);
14270		break;
14271	case ALC880_MIC_EVENT:
14272		alc663_m51va_mic_automute(codec);
14273		break;
14274	}
14275}
14276
14277static void alc663_m51va_inithook(struct hda_codec *codec)
14278{
14279	alc663_m51va_speaker_automute(codec);
14280	alc663_m51va_mic_automute(codec);
14281}
14282
14283static void alc663_g71v_hp_automute(struct hda_codec *codec)
14284{
14285	unsigned int present;
14286	unsigned char bits;
14287
14288	present = snd_hda_codec_read(codec, 0x21, 0,
14289				     AC_VERB_GET_PIN_SENSE, 0)
14290		& AC_PINSENSE_PRESENCE;
14291	bits = present ? HDA_AMP_MUTE : 0;
14292	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14293				 HDA_AMP_MUTE, bits);
14294	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14295				 HDA_AMP_MUTE, bits);
14296}
14297
14298static void alc663_g71v_front_automute(struct hda_codec *codec)
14299{
14300	unsigned int present;
14301	unsigned char bits;
14302
14303	present = snd_hda_codec_read(codec, 0x15, 0,
14304				     AC_VERB_GET_PIN_SENSE, 0)
14305		& AC_PINSENSE_PRESENCE;
14306	bits = present ? HDA_AMP_MUTE : 0;
14307	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14308				 HDA_AMP_MUTE, bits);
14309}
14310
14311static void alc663_g71v_unsol_event(struct hda_codec *codec,
14312					   unsigned int res)
14313{
14314	switch (res >> 26) {
14315	case ALC880_HP_EVENT:
14316		alc663_g71v_hp_automute(codec);
14317		break;
14318	case ALC880_FRONT_EVENT:
14319		alc663_g71v_front_automute(codec);
14320		break;
14321	case ALC880_MIC_EVENT:
14322		alc662_eeepc_mic_automute(codec);
14323		break;
14324	}
14325}
14326
14327static void alc663_g71v_inithook(struct hda_codec *codec)
14328{
14329	alc663_g71v_front_automute(codec);
14330	alc663_g71v_hp_automute(codec);
14331	alc662_eeepc_mic_automute(codec);
14332}
14333
14334static void alc663_g50v_unsol_event(struct hda_codec *codec,
14335					   unsigned int res)
14336{
14337	switch (res >> 26) {
14338	case ALC880_HP_EVENT:
14339		alc663_m51va_speaker_automute(codec);
14340		break;
14341	case ALC880_MIC_EVENT:
14342		alc662_eeepc_mic_automute(codec);
14343		break;
14344	}
14345}
14346
14347static void alc663_g50v_inithook(struct hda_codec *codec)
14348{
14349	alc663_m51va_speaker_automute(codec);
14350	alc662_eeepc_mic_automute(codec);
14351}
14352
14353#ifdef CONFIG_SND_HDA_POWER_SAVE
14354#define alc662_loopbacks	alc880_loopbacks
14355#endif
14356
14357
14358/* pcm configuration: identiacal with ALC880 */
14359#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
14360#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
14361#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
14362#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
14363
14364/*
14365 * configuration and preset
14366 */
14367static const char *alc662_models[ALC662_MODEL_LAST] = {
14368	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
14369	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
14370	[ALC662_3ST_6ch]	= "3stack-6ch",
14371	[ALC662_5ST_DIG]	= "6stack-dig",
14372	[ALC662_LENOVO_101E]	= "lenovo-101e",
14373	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
14374	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
14375	[ALC663_ASUS_M51VA] = "m51va",
14376	[ALC663_ASUS_G71V] = "g71v",
14377	[ALC663_ASUS_H13] = "h13",
14378	[ALC663_ASUS_G50V] = "g50v",
14379	[ALC662_AUTO]		= "auto",
14380};
14381
14382static struct snd_pci_quirk alc662_cfg_tbl[] = {
14383	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V),
14384	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
14385	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
14386	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
14387	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
14388	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
14389	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
14390	SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
14391	SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
14392	SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
14393	{}
14394};
14395
14396static struct alc_config_preset alc662_presets[] = {
14397	[ALC662_3ST_2ch_DIG] = {
14398		.mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
14399		.init_verbs = { alc662_init_verbs },
14400		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14401		.dac_nids = alc662_dac_nids,
14402		.dig_out_nid = ALC662_DIGOUT_NID,
14403		.dig_in_nid = ALC662_DIGIN_NID,
14404		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14405		.channel_mode = alc662_3ST_2ch_modes,
14406		.input_mux = &alc662_capture_source,
14407	},
14408	[ALC662_3ST_6ch_DIG] = {
14409		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
14410			    alc662_capture_mixer },
14411		.init_verbs = { alc662_init_verbs },
14412		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14413		.dac_nids = alc662_dac_nids,
14414		.dig_out_nid = ALC662_DIGOUT_NID,
14415		.dig_in_nid = ALC662_DIGIN_NID,
14416		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14417		.channel_mode = alc662_3ST_6ch_modes,
14418		.need_dac_fix = 1,
14419		.input_mux = &alc662_capture_source,
14420	},
14421	[ALC662_3ST_6ch] = {
14422		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
14423			    alc662_capture_mixer },
14424		.init_verbs = { alc662_init_verbs },
14425		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14426		.dac_nids = alc662_dac_nids,
14427		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14428		.channel_mode = alc662_3ST_6ch_modes,
14429		.need_dac_fix = 1,
14430		.input_mux = &alc662_capture_source,
14431	},
14432	[ALC662_5ST_DIG] = {
14433		.mixers = { alc662_base_mixer, alc662_chmode_mixer,
14434			    alc662_capture_mixer },
14435		.init_verbs = { alc662_init_verbs },
14436		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14437		.dac_nids = alc662_dac_nids,
14438		.dig_out_nid = ALC662_DIGOUT_NID,
14439		.dig_in_nid = ALC662_DIGIN_NID,
14440		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
14441		.channel_mode = alc662_5stack_modes,
14442		.input_mux = &alc662_capture_source,
14443	},
14444	[ALC662_LENOVO_101E] = {
14445		.mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
14446		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
14447		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14448		.dac_nids = alc662_dac_nids,
14449		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14450		.channel_mode = alc662_3ST_2ch_modes,
14451		.input_mux = &alc662_lenovo_101e_capture_source,
14452		.unsol_event = alc662_lenovo_101e_unsol_event,
14453		.init_hook = alc662_lenovo_101e_all_automute,
14454	},
14455	[ALC662_ASUS_EEEPC_P701] = {
14456		.mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
14457		.init_verbs = { alc662_init_verbs,
14458				alc662_eeepc_sue_init_verbs },
14459		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14460		.dac_nids = alc662_dac_nids,
14461		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14462		.channel_mode = alc662_3ST_2ch_modes,
14463		.input_mux = &alc662_eeepc_capture_source,
14464		.unsol_event = alc662_eeepc_unsol_event,
14465		.init_hook = alc662_eeepc_inithook,
14466	},
14467	[ALC662_ASUS_EEEPC_EP20] = {
14468		.mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
14469			    alc662_chmode_mixer },
14470		.init_verbs = { alc662_init_verbs,
14471				alc662_eeepc_ep20_sue_init_verbs },
14472		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14473		.dac_nids = alc662_dac_nids,
14474		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14475		.channel_mode = alc662_3ST_6ch_modes,
14476		.input_mux = &alc662_lenovo_101e_capture_source,
14477		.unsol_event = alc662_eeepc_ep20_unsol_event,
14478		.init_hook = alc662_eeepc_ep20_inithook,
14479	},
14480	[ALC663_ASUS_M51VA] = {
14481		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14482		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14483		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14484		.dac_nids = alc662_dac_nids,
14485		.dig_out_nid = ALC662_DIGOUT_NID,
14486		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14487		.channel_mode = alc662_3ST_2ch_modes,
14488		.input_mux = &alc663_m51va_capture_source,
14489		.unsol_event = alc663_m51va_unsol_event,
14490		.init_hook = alc663_m51va_inithook,
14491	},
14492	[ALC663_ASUS_G71V] = {
14493		.mixers = { alc663_g71v_mixer, alc662_capture_mixer},
14494		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
14495		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14496		.dac_nids = alc662_dac_nids,
14497		.dig_out_nid = ALC662_DIGOUT_NID,
14498		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14499		.channel_mode = alc662_3ST_2ch_modes,
14500		.input_mux = &alc662_eeepc_capture_source,
14501		.unsol_event = alc663_g71v_unsol_event,
14502		.init_hook = alc663_g71v_inithook,
14503	},
14504	[ALC663_ASUS_H13] = {
14505		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14506		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14507		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14508		.dac_nids = alc662_dac_nids,
14509		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14510		.channel_mode = alc662_3ST_2ch_modes,
14511		.input_mux = &alc663_m51va_capture_source,
14512		.unsol_event = alc663_m51va_unsol_event,
14513		.init_hook = alc663_m51va_inithook,
14514	},
14515	[ALC663_ASUS_G50V] = {
14516		.mixers = { alc663_g50v_mixer, alc662_capture_mixer},
14517		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
14518		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14519		.dac_nids = alc662_dac_nids,
14520		.dig_out_nid = ALC662_DIGOUT_NID,
14521		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14522		.channel_mode = alc662_3ST_6ch_modes,
14523		.input_mux = &alc663_capture_source,
14524		.unsol_event = alc663_g50v_unsol_event,
14525		.init_hook = alc663_g50v_inithook,
14526	},
14527};
14528
14529
14530/*
14531 * BIOS auto configuration
14532 */
14533
14534/* add playback controls from the parsed DAC table */
14535static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
14536					     const struct auto_pin_cfg *cfg)
14537{
14538	char name[32];
14539	static const char *chname[4] = {
14540		"Front", "Surround", NULL /*CLFE*/, "Side"
14541	};
14542	hda_nid_t nid;
14543	int i, err;
14544
14545	for (i = 0; i < cfg->line_outs; i++) {
14546		if (!spec->multiout.dac_nids[i])
14547			continue;
14548		nid = alc880_idx_to_dac(i);
14549		if (i == 2) {
14550			/* Center/LFE */
14551			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14552					  "Center Playback Volume",
14553					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
14554							      HDA_OUTPUT));
14555			if (err < 0)
14556				return err;
14557			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14558					  "LFE Playback Volume",
14559					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14560							      HDA_OUTPUT));
14561			if (err < 0)
14562				return err;
14563			err = add_control(spec, ALC_CTL_BIND_MUTE,
14564					  "Center Playback Switch",
14565					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
14566							      HDA_INPUT));
14567			if (err < 0)
14568				return err;
14569			err = add_control(spec, ALC_CTL_BIND_MUTE,
14570					  "LFE Playback Switch",
14571					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
14572							      HDA_INPUT));
14573			if (err < 0)
14574				return err;
14575		} else {
14576			sprintf(name, "%s Playback Volume", chname[i]);
14577			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14578					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14579							      HDA_OUTPUT));
14580			if (err < 0)
14581				return err;
14582			sprintf(name, "%s Playback Switch", chname[i]);
14583			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14584					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
14585							      HDA_INPUT));
14586			if (err < 0)
14587				return err;
14588		}
14589	}
14590	return 0;
14591}
14592
14593/* add playback controls for speaker and HP outputs */
14594static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
14595					const char *pfx)
14596{
14597	hda_nid_t nid;
14598	int err;
14599	char name[32];
14600
14601	if (!pin)
14602		return 0;
14603
14604	if (pin == 0x17) {
14605		/* ALC663 has a mono output pin on 0x17 */
14606		sprintf(name, "%s Playback Switch", pfx);
14607		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14608				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
14609		return err;
14610	}
14611
14612	if (alc880_is_fixed_pin(pin)) {
14613		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14614                /* printk("DAC nid=%x\n",nid); */
14615		/* specify the DAC as the extra output */
14616		if (!spec->multiout.hp_nid)
14617			spec->multiout.hp_nid = nid;
14618		else
14619			spec->multiout.extra_out_nid[0] = nid;
14620		/* control HP volume/switch on the output mixer amp */
14621		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14622		sprintf(name, "%s Playback Volume", pfx);
14623		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14624				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
14625		if (err < 0)
14626			return err;
14627		sprintf(name, "%s Playback Switch", pfx);
14628		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14629				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
14630		if (err < 0)
14631			return err;
14632	} else if (alc880_is_multi_pin(pin)) {
14633		/* set manual connection */
14634		/* we have only a switch on HP-out PIN */
14635		sprintf(name, "%s Playback Switch", pfx);
14636		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14637				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14638		if (err < 0)
14639			return err;
14640	}
14641	return 0;
14642}
14643
14644/* create playback/capture controls for input pins */
14645static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
14646						const struct auto_pin_cfg *cfg)
14647{
14648	struct hda_input_mux *imux = &spec->private_imux;
14649	int i, err, idx;
14650
14651	for (i = 0; i < AUTO_PIN_LAST; i++) {
14652		if (alc880_is_input_pin(cfg->input_pins[i])) {
14653			idx = alc880_input_pin_idx(cfg->input_pins[i]);
14654			err = new_analog_input(spec, cfg->input_pins[i],
14655					       auto_pin_cfg_labels[i],
14656					       idx, 0x0b);
14657			if (err < 0)
14658				return err;
14659			imux->items[imux->num_items].label =
14660				auto_pin_cfg_labels[i];
14661			imux->items[imux->num_items].index =
14662				alc880_input_pin_idx(cfg->input_pins[i]);
14663			imux->num_items++;
14664		}
14665	}
14666	return 0;
14667}
14668
14669static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
14670					      hda_nid_t nid, int pin_type,
14671					      int dac_idx)
14672{
14673	alc_set_pin_output(codec, nid, pin_type);
14674	/* need the manual connection? */
14675	if (alc880_is_multi_pin(nid)) {
14676		struct alc_spec *spec = codec->spec;
14677		int idx = alc880_multi_pin_idx(nid);
14678		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
14679				    AC_VERB_SET_CONNECT_SEL,
14680				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
14681	}
14682}
14683
14684static void alc662_auto_init_multi_out(struct hda_codec *codec)
14685{
14686	struct alc_spec *spec = codec->spec;
14687	int i;
14688
14689	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14690	for (i = 0; i <= HDA_SIDE; i++) {
14691		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14692		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14693		if (nid)
14694			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
14695							  i);
14696	}
14697}
14698
14699static void alc662_auto_init_hp_out(struct hda_codec *codec)
14700{
14701	struct alc_spec *spec = codec->spec;
14702	hda_nid_t pin;
14703
14704	pin = spec->autocfg.hp_pins[0];
14705	if (pin) /* connect to front */
14706		/* use dac 0 */
14707		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14708	pin = spec->autocfg.speaker_pins[0];
14709	if (pin)
14710		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14711}
14712
14713#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
14714#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
14715
14716static void alc662_auto_init_analog_input(struct hda_codec *codec)
14717{
14718	struct alc_spec *spec = codec->spec;
14719	int i;
14720
14721	for (i = 0; i < AUTO_PIN_LAST; i++) {
14722		hda_nid_t nid = spec->autocfg.input_pins[i];
14723		if (alc662_is_input_pin(nid)) {
14724			snd_hda_codec_write(codec, nid, 0,
14725					    AC_VERB_SET_PIN_WIDGET_CONTROL,
14726					    (i <= AUTO_PIN_FRONT_MIC ?
14727					     PIN_VREF80 : PIN_IN));
14728			if (nid != ALC662_PIN_CD_NID)
14729				snd_hda_codec_write(codec, nid, 0,
14730						    AC_VERB_SET_AMP_GAIN_MUTE,
14731						    AMP_OUT_MUTE);
14732		}
14733	}
14734}
14735
14736#define alc662_auto_init_input_src	alc882_auto_init_input_src
14737
14738static int alc662_parse_auto_config(struct hda_codec *codec)
14739{
14740	struct alc_spec *spec = codec->spec;
14741	int err;
14742	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
14743
14744	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14745					   alc662_ignore);
14746	if (err < 0)
14747		return err;
14748	if (!spec->autocfg.line_outs)
14749		return 0; /* can't find valid BIOS pin config */
14750
14751	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14752	if (err < 0)
14753		return err;
14754	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
14755	if (err < 0)
14756		return err;
14757	err = alc662_auto_create_extra_out(spec,
14758					   spec->autocfg.speaker_pins[0],
14759					   "Speaker");
14760	if (err < 0)
14761		return err;
14762	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
14763					   "Headphone");
14764	if (err < 0)
14765		return err;
14766	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
14767	if (err < 0)
14768		return err;
14769
14770	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14771
14772	if (spec->autocfg.dig_out_pin)
14773		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
14774
14775	if (spec->kctl_alloc)
14776		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14777
14778	spec->num_mux_defs = 1;
14779	spec->input_mux = &spec->private_imux;
14780
14781	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
14782	if (codec->vendor_id == 0x10ec0663)
14783		spec->init_verbs[spec->num_init_verbs++] =
14784			alc663_auto_init_verbs;
14785	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
14786	spec->num_mixers++;
14787	return 1;
14788}
14789
14790/* additional initialization for auto-configuration model */
14791static void alc662_auto_init(struct hda_codec *codec)
14792{
14793	struct alc_spec *spec = codec->spec;
14794	alc662_auto_init_multi_out(codec);
14795	alc662_auto_init_hp_out(codec);
14796	alc662_auto_init_analog_input(codec);
14797	alc662_auto_init_input_src(codec);
14798	if (spec->unsol_event)
14799		alc_sku_automute(codec);
14800}
14801
14802static int patch_alc662(struct hda_codec *codec)
14803{
14804	struct alc_spec *spec;
14805	int err, board_config;
14806
14807	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14808	if (!spec)
14809		return -ENOMEM;
14810
14811	codec->spec = spec;
14812
14813	alc_fix_pll_init(codec, 0x20, 0x04, 15);
14814
14815	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
14816						  alc662_models,
14817			  	                  alc662_cfg_tbl);
14818	if (board_config < 0) {
14819		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
14820		       "trying auto-probe from BIOS...\n");
14821		board_config = ALC662_AUTO;
14822	}
14823
14824	if (board_config == ALC662_AUTO) {
14825		/* automatic parse from the BIOS config */
14826		err = alc662_parse_auto_config(codec);
14827		if (err < 0) {
14828			alc_free(codec);
14829			return err;
14830		} else if (!err) {
14831			printk(KERN_INFO
14832			       "hda_codec: Cannot set up configuration "
14833			       "from BIOS.  Using base mode...\n");
14834			board_config = ALC662_3ST_2ch_DIG;
14835		}
14836	}
14837
14838	if (board_config != ALC662_AUTO)
14839		setup_preset(spec, &alc662_presets[board_config]);
14840
14841	if (codec->vendor_id == 0x10ec0663) {
14842		spec->stream_name_analog = "ALC663 Analog";
14843		spec->stream_name_digital = "ALC663 Digital";
14844	} else {
14845		spec->stream_name_analog = "ALC662 Analog";
14846		spec->stream_name_digital = "ALC662 Digital";
14847	}
14848
14849	spec->stream_analog_playback = &alc662_pcm_analog_playback;
14850	spec->stream_analog_capture = &alc662_pcm_analog_capture;
14851
14852	spec->stream_digital_playback = &alc662_pcm_digital_playback;
14853	spec->stream_digital_capture = &alc662_pcm_digital_capture;
14854
14855	spec->adc_nids = alc662_adc_nids;
14856	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
14857	spec->capsrc_nids = alc662_capsrc_nids;
14858
14859	spec->vmaster_nid = 0x02;
14860
14861	codec->patch_ops = alc_patch_ops;
14862	if (board_config == ALC662_AUTO)
14863		spec->init_hook = alc662_auto_init;
14864#ifdef CONFIG_SND_HDA_POWER_SAVE
14865	if (!spec->loopback.amplist)
14866		spec->loopback.amplist = alc662_loopbacks;
14867#endif
14868
14869	return 0;
14870}
14871
14872/*
14873 * patch entries
14874 */
14875struct hda_codec_preset snd_hda_preset_realtek[] = {
14876	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
14877	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
14878	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
14879	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
14880	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
14881	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
14882	  .patch = patch_alc861 },
14883	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
14884	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
14885	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
14886	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
14887	  .patch = patch_alc883 },
14888	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
14889	  .patch = patch_alc662 },
14890	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
14891	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
14892	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
14893	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
14894	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
14895	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
14896	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
14897	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
14898	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
14899	{} /* terminator */
14900};
14901