patch_realtek.c revision ce22e03e62fd37fb2612abb7af1c66cc17038606
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
34#define ALC880_FRONT_EVENT		0x01
35#define ALC880_DCVOL_EVENT		0x02
36#define ALC880_HP_EVENT			0x04
37#define ALC880_MIC_EVENT		0x08
38
39/* ALC880 board config type */
40enum {
41	ALC880_3ST,
42	ALC880_3ST_DIG,
43	ALC880_5ST,
44	ALC880_5ST_DIG,
45	ALC880_W810,
46	ALC880_Z71V,
47	ALC880_6ST,
48	ALC880_6ST_DIG,
49	ALC880_F1734,
50	ALC880_ASUS,
51	ALC880_ASUS_DIG,
52	ALC880_ASUS_W1V,
53	ALC880_ASUS_DIG2,
54	ALC880_FUJITSU,
55	ALC880_UNIWILL_DIG,
56	ALC880_UNIWILL,
57	ALC880_UNIWILL_P53,
58	ALC880_CLEVO,
59	ALC880_TCL_S700,
60	ALC880_LG,
61	ALC880_LG_LW,
62#ifdef CONFIG_SND_DEBUG
63	ALC880_TEST,
64#endif
65	ALC880_AUTO,
66	ALC880_MODEL_LAST /* last tag */
67};
68
69/* ALC260 models */
70enum {
71	ALC260_BASIC,
72	ALC260_HP,
73	ALC260_HP_3013,
74	ALC260_FUJITSU_S702X,
75	ALC260_ACER,
76	ALC260_WILL,
77	ALC260_REPLACER_672V,
78#ifdef CONFIG_SND_DEBUG
79	ALC260_TEST,
80#endif
81	ALC260_AUTO,
82	ALC260_MODEL_LAST /* last tag */
83};
84
85/* ALC262 models */
86enum {
87	ALC262_BASIC,
88	ALC262_HIPPO,
89	ALC262_HIPPO_1,
90	ALC262_FUJITSU,
91	ALC262_HP_BPC,
92	ALC262_HP_BPC_D7000_WL,
93	ALC262_HP_BPC_D7000_WF,
94	ALC262_HP_TC_T5735,
95	ALC262_HP_RP5700,
96	ALC262_BENQ_ED8,
97	ALC262_SONY_ASSAMD,
98	ALC262_BENQ_T31,
99	ALC262_ULTRA,
100	ALC262_AUTO,
101	ALC262_MODEL_LAST /* last tag */
102};
103
104/* ALC268 models */
105enum {
106	ALC268_3ST,
107	ALC268_TOSHIBA,
108	ALC268_ACER,
109#ifdef CONFIG_SND_DEBUG
110	ALC268_TEST,
111#endif
112	ALC268_AUTO,
113	ALC268_MODEL_LAST /* last tag */
114};
115
116/* ALC269 models */
117enum {
118	ALC269_BASIC,
119	ALC269_AUTO,
120	ALC269_MODEL_LAST /* last tag */
121};
122
123/* ALC861 models */
124enum {
125	ALC861_3ST,
126	ALC660_3ST,
127	ALC861_3ST_DIG,
128	ALC861_6ST_DIG,
129	ALC861_UNIWILL_M31,
130	ALC861_TOSHIBA,
131	ALC861_ASUS,
132	ALC861_ASUS_LAPTOP,
133	ALC861_AUTO,
134	ALC861_MODEL_LAST,
135};
136
137/* ALC861-VD models */
138enum {
139	ALC660VD_3ST,
140	ALC660VD_3ST_DIG,
141	ALC861VD_3ST,
142	ALC861VD_3ST_DIG,
143	ALC861VD_6ST_DIG,
144	ALC861VD_LENOVO,
145	ALC861VD_DALLAS,
146	ALC861VD_HP,
147	ALC861VD_AUTO,
148	ALC861VD_MODEL_LAST,
149};
150
151/* ALC662 models */
152enum {
153	ALC662_3ST_2ch_DIG,
154	ALC662_3ST_6ch_DIG,
155	ALC662_3ST_6ch,
156	ALC662_5ST_DIG,
157	ALC662_LENOVO_101E,
158	ALC662_ASUS_EEEPC_P701,
159	ALC662_ASUS_EEEPC_EP20,
160	ALC662_AUTO,
161	ALC662_MODEL_LAST,
162};
163
164/* ALC882 models */
165enum {
166	ALC882_3ST_DIG,
167	ALC882_6ST_DIG,
168	ALC882_ARIMA,
169	ALC882_W2JC,
170	ALC882_TARGA,
171	ALC882_ASUS_A7J,
172	ALC882_ASUS_A7M,
173	ALC885_MACPRO,
174	ALC885_MBP3,
175	ALC885_IMAC24,
176	ALC882_AUTO,
177	ALC882_MODEL_LAST,
178};
179
180/* ALC883 models */
181enum {
182	ALC883_3ST_2ch_DIG,
183	ALC883_3ST_6ch_DIG,
184	ALC883_3ST_6ch,
185	ALC883_6ST_DIG,
186	ALC883_TARGA_DIG,
187	ALC883_TARGA_2ch_DIG,
188	ALC883_ACER,
189	ALC883_ACER_ASPIRE,
190	ALC883_MEDION,
191	ALC883_MEDION_MD2,
192	ALC883_LAPTOP_EAPD,
193	ALC883_LENOVO_101E_2ch,
194	ALC883_LENOVO_NB0763,
195	ALC888_LENOVO_MS7195_DIG,
196	ALC883_HAIER_W66,
197	ALC888_6ST_HP,
198	ALC888_3ST_HP,
199	ALC883_MITAC,
200	ALC883_AUTO,
201	ALC883_MODEL_LAST,
202};
203
204/* for GPIO Poll */
205#define GPIO_MASK	0x03
206
207struct alc_spec {
208	/* codec parameterization */
209	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
210	unsigned int num_mixers;
211
212	const struct hda_verb *init_verbs[5];	/* initialization verbs
213						 * don't forget NULL
214						 * termination!
215						 */
216	unsigned int num_init_verbs;
217
218	char *stream_name_analog;	/* analog PCM stream */
219	struct hda_pcm_stream *stream_analog_playback;
220	struct hda_pcm_stream *stream_analog_capture;
221
222	char *stream_name_digital;	/* digital PCM stream */
223	struct hda_pcm_stream *stream_digital_playback;
224	struct hda_pcm_stream *stream_digital_capture;
225
226	/* playback */
227	struct hda_multi_out multiout;	/* playback set-up
228					 * max_channels, dacs must be set
229					 * dig_out_nid and hp_nid are optional
230					 */
231
232	/* capture */
233	unsigned int num_adc_nids;
234	hda_nid_t *adc_nids;
235	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
236
237	/* capture source */
238	unsigned int num_mux_defs;
239	const struct hda_input_mux *input_mux;
240	unsigned int cur_mux[3];
241
242	/* channel model */
243	const struct hda_channel_mode *channel_mode;
244	int num_channel_mode;
245	int need_dac_fix;
246
247	/* PCM information */
248	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
249
250	/* dynamic controls, init_verbs and input_mux */
251	struct auto_pin_cfg autocfg;
252	unsigned int num_kctl_alloc, num_kctl_used;
253	struct snd_kcontrol_new *kctl_alloc;
254	struct hda_input_mux private_imux;
255	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
256
257	/* hooks */
258	void (*init_hook)(struct hda_codec *codec);
259	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
260
261	/* for pin sensing */
262	unsigned int sense_updated: 1;
263	unsigned int jack_present: 1;
264
265	/* for virtual master */
266	hda_nid_t vmaster_nid;
267	u32 vmaster_tlv[4];
268#ifdef CONFIG_SND_HDA_POWER_SAVE
269	struct hda_loopback_check loopback;
270#endif
271};
272
273/*
274 * configuration template - to be copied to the spec instance
275 */
276struct alc_config_preset {
277	struct snd_kcontrol_new *mixers[5]; /* should be identical size
278					     * with spec
279					     */
280	const struct hda_verb *init_verbs[5];
281	unsigned int num_dacs;
282	hda_nid_t *dac_nids;
283	hda_nid_t dig_out_nid;		/* optional */
284	hda_nid_t hp_nid;		/* optional */
285	unsigned int num_adc_nids;
286	hda_nid_t *adc_nids;
287	hda_nid_t dig_in_nid;
288	unsigned int num_channel_mode;
289	const struct hda_channel_mode *channel_mode;
290	int need_dac_fix;
291	unsigned int num_mux_defs;
292	const struct hda_input_mux *input_mux;
293	void (*unsol_event)(struct hda_codec *, unsigned int);
294	void (*init_hook)(struct hda_codec *);
295#ifdef CONFIG_SND_HDA_POWER_SAVE
296	struct hda_amp_list *loopbacks;
297#endif
298};
299
300
301/*
302 * input MUX handling
303 */
304static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
305			     struct snd_ctl_elem_info *uinfo)
306{
307	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
308	struct alc_spec *spec = codec->spec;
309	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
310	if (mux_idx >= spec->num_mux_defs)
311		mux_idx = 0;
312	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
313}
314
315static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
316			    struct snd_ctl_elem_value *ucontrol)
317{
318	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
319	struct alc_spec *spec = codec->spec;
320	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
321
322	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
323	return 0;
324}
325
326static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
327			    struct snd_ctl_elem_value *ucontrol)
328{
329	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
330	struct alc_spec *spec = codec->spec;
331	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
332	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
333	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
334				     spec->adc_nids[adc_idx],
335				     &spec->cur_mux[adc_idx]);
336}
337
338
339/*
340 * channel mode setting
341 */
342static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
343			    struct snd_ctl_elem_info *uinfo)
344{
345	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
346	struct alc_spec *spec = codec->spec;
347	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
348				    spec->num_channel_mode);
349}
350
351static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
352			   struct snd_ctl_elem_value *ucontrol)
353{
354	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
355	struct alc_spec *spec = codec->spec;
356	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
357				   spec->num_channel_mode,
358				   spec->multiout.max_channels);
359}
360
361static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
362			   struct snd_ctl_elem_value *ucontrol)
363{
364	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
365	struct alc_spec *spec = codec->spec;
366	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
367				      spec->num_channel_mode,
368				      &spec->multiout.max_channels);
369	if (err >= 0 && spec->need_dac_fix)
370		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
371	return err;
372}
373
374/*
375 * Control the mode of pin widget settings via the mixer.  "pc" is used
376 * instead of "%" to avoid consequences of accidently treating the % as
377 * being part of a format specifier.  Maximum allowed length of a value is
378 * 63 characters plus NULL terminator.
379 *
380 * Note: some retasking pin complexes seem to ignore requests for input
381 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
382 * are requested.  Therefore order this list so that this behaviour will not
383 * cause problems when mixer clients move through the enum sequentially.
384 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
385 * March 2006.
386 */
387static char *alc_pin_mode_names[] = {
388	"Mic 50pc bias", "Mic 80pc bias",
389	"Line in", "Line out", "Headphone out",
390};
391static unsigned char alc_pin_mode_values[] = {
392	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
393};
394/* The control can present all 5 options, or it can limit the options based
395 * in the pin being assumed to be exclusively an input or an output pin.  In
396 * addition, "input" pins may or may not process the mic bias option
397 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
398 * accept requests for bias as of chip versions up to March 2006) and/or
399 * wiring in the computer.
400 */
401#define ALC_PIN_DIR_IN              0x00
402#define ALC_PIN_DIR_OUT             0x01
403#define ALC_PIN_DIR_INOUT           0x02
404#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
405#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
406
407/* Info about the pin modes supported by the different pin direction modes.
408 * For each direction the minimum and maximum values are given.
409 */
410static signed char alc_pin_mode_dir_info[5][2] = {
411	{ 0, 2 },    /* ALC_PIN_DIR_IN */
412	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
413	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
414	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
415	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
416};
417#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
418#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
419#define alc_pin_mode_n_items(_dir) \
420	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
421
422static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
423			     struct snd_ctl_elem_info *uinfo)
424{
425	unsigned int item_num = uinfo->value.enumerated.item;
426	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
427
428	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
429	uinfo->count = 1;
430	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
431
432	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
433		item_num = alc_pin_mode_min(dir);
434	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
435	return 0;
436}
437
438static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
439			    struct snd_ctl_elem_value *ucontrol)
440{
441	unsigned int i;
442	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
443	hda_nid_t nid = kcontrol->private_value & 0xffff;
444	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
445	long *valp = ucontrol->value.integer.value;
446	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
447						 AC_VERB_GET_PIN_WIDGET_CONTROL,
448						 0x00);
449
450	/* Find enumerated value for current pinctl setting */
451	i = alc_pin_mode_min(dir);
452	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
453		i++;
454	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
455	return 0;
456}
457
458static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
459			    struct snd_ctl_elem_value *ucontrol)
460{
461	signed int change;
462	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
463	hda_nid_t nid = kcontrol->private_value & 0xffff;
464	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
465	long val = *ucontrol->value.integer.value;
466	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
467						 AC_VERB_GET_PIN_WIDGET_CONTROL,
468						 0x00);
469
470	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
471		val = alc_pin_mode_min(dir);
472
473	change = pinctl != alc_pin_mode_values[val];
474	if (change) {
475		/* Set pin mode to that requested */
476		snd_hda_codec_write_cache(codec, nid, 0,
477					  AC_VERB_SET_PIN_WIDGET_CONTROL,
478					  alc_pin_mode_values[val]);
479
480		/* Also enable the retasking pin's input/output as required
481		 * for the requested pin mode.  Enum values of 2 or less are
482		 * input modes.
483		 *
484		 * Dynamically switching the input/output buffers probably
485		 * reduces noise slightly (particularly on input) so we'll
486		 * do it.  However, having both input and output buffers
487		 * enabled simultaneously doesn't seem to be problematic if
488		 * this turns out to be necessary in the future.
489		 */
490		if (val <= 2) {
491			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
492						 HDA_AMP_MUTE, HDA_AMP_MUTE);
493			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
494						 HDA_AMP_MUTE, 0);
495		} else {
496			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
497						 HDA_AMP_MUTE, HDA_AMP_MUTE);
498			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
499						 HDA_AMP_MUTE, 0);
500		}
501	}
502	return change;
503}
504
505#define ALC_PIN_MODE(xname, nid, dir) \
506	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
507	  .info = alc_pin_mode_info, \
508	  .get = alc_pin_mode_get, \
509	  .put = alc_pin_mode_put, \
510	  .private_value = nid | (dir<<16) }
511
512/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
513 * together using a mask with more than one bit set.  This control is
514 * currently used only by the ALC260 test model.  At this stage they are not
515 * needed for any "production" models.
516 */
517#ifdef CONFIG_SND_DEBUG
518#define alc_gpio_data_info	snd_ctl_boolean_mono_info
519
520static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
521			     struct snd_ctl_elem_value *ucontrol)
522{
523	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
524	hda_nid_t nid = kcontrol->private_value & 0xffff;
525	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
526	long *valp = ucontrol->value.integer.value;
527	unsigned int val = snd_hda_codec_read(codec, nid, 0,
528					      AC_VERB_GET_GPIO_DATA, 0x00);
529
530	*valp = (val & mask) != 0;
531	return 0;
532}
533static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
534			     struct snd_ctl_elem_value *ucontrol)
535{
536	signed int change;
537	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538	hda_nid_t nid = kcontrol->private_value & 0xffff;
539	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
540	long val = *ucontrol->value.integer.value;
541	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
542						    AC_VERB_GET_GPIO_DATA,
543						    0x00);
544
545	/* Set/unset the masked GPIO bit(s) as needed */
546	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
547	if (val == 0)
548		gpio_data &= ~mask;
549	else
550		gpio_data |= mask;
551	snd_hda_codec_write_cache(codec, nid, 0,
552				  AC_VERB_SET_GPIO_DATA, gpio_data);
553
554	return change;
555}
556#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
557	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
558	  .info = alc_gpio_data_info, \
559	  .get = alc_gpio_data_get, \
560	  .put = alc_gpio_data_put, \
561	  .private_value = nid | (mask<<16) }
562#endif   /* CONFIG_SND_DEBUG */
563
564/* A switch control to allow the enabling of the digital IO pins on the
565 * ALC260.  This is incredibly simplistic; the intention of this control is
566 * to provide something in the test model allowing digital outputs to be
567 * identified if present.  If models are found which can utilise these
568 * outputs a more complete mixer control can be devised for those models if
569 * necessary.
570 */
571#ifdef CONFIG_SND_DEBUG
572#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
573
574static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
575			      struct snd_ctl_elem_value *ucontrol)
576{
577	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
578	hda_nid_t nid = kcontrol->private_value & 0xffff;
579	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
580	long *valp = ucontrol->value.integer.value;
581	unsigned int val = snd_hda_codec_read(codec, nid, 0,
582					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
583
584	*valp = (val & mask) != 0;
585	return 0;
586}
587static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
588			      struct snd_ctl_elem_value *ucontrol)
589{
590	signed int change;
591	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
592	hda_nid_t nid = kcontrol->private_value & 0xffff;
593	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
594	long val = *ucontrol->value.integer.value;
595	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
596						    AC_VERB_GET_DIGI_CONVERT_1,
597						    0x00);
598
599	/* Set/unset the masked control bit(s) as needed */
600	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
601	if (val==0)
602		ctrl_data &= ~mask;
603	else
604		ctrl_data |= mask;
605	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
606				  ctrl_data);
607
608	return change;
609}
610#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
611	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
612	  .info = alc_spdif_ctrl_info, \
613	  .get = alc_spdif_ctrl_get, \
614	  .put = alc_spdif_ctrl_put, \
615	  .private_value = nid | (mask<<16) }
616#endif   /* CONFIG_SND_DEBUG */
617
618/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
619 * Again, this is only used in the ALC26x test models to help identify when
620 * the EAPD line must be asserted for features to work.
621 */
622#ifdef CONFIG_SND_DEBUG
623#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
624
625static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
626			      struct snd_ctl_elem_value *ucontrol)
627{
628	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
629	hda_nid_t nid = kcontrol->private_value & 0xffff;
630	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
631	long *valp = ucontrol->value.integer.value;
632	unsigned int val = snd_hda_codec_read(codec, nid, 0,
633					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
634
635	*valp = (val & mask) != 0;
636	return 0;
637}
638
639static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
640			      struct snd_ctl_elem_value *ucontrol)
641{
642	int change;
643	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
644	hda_nid_t nid = kcontrol->private_value & 0xffff;
645	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
646	long val = *ucontrol->value.integer.value;
647	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
648						    AC_VERB_GET_EAPD_BTLENABLE,
649						    0x00);
650
651	/* Set/unset the masked control bit(s) as needed */
652	change = (!val ? 0 : mask) != (ctrl_data & mask);
653	if (!val)
654		ctrl_data &= ~mask;
655	else
656		ctrl_data |= mask;
657	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
658				  ctrl_data);
659
660	return change;
661}
662
663#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
664	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
665	  .info = alc_eapd_ctrl_info, \
666	  .get = alc_eapd_ctrl_get, \
667	  .put = alc_eapd_ctrl_put, \
668	  .private_value = nid | (mask<<16) }
669#endif   /* CONFIG_SND_DEBUG */
670
671/*
672 * set up from the preset table
673 */
674static void setup_preset(struct alc_spec *spec,
675			 const struct alc_config_preset *preset)
676{
677	int i;
678
679	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
680		spec->mixers[spec->num_mixers++] = preset->mixers[i];
681	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
682	     i++)
683		spec->init_verbs[spec->num_init_verbs++] =
684			preset->init_verbs[i];
685
686	spec->channel_mode = preset->channel_mode;
687	spec->num_channel_mode = preset->num_channel_mode;
688	spec->need_dac_fix = preset->need_dac_fix;
689
690	spec->multiout.max_channels = spec->channel_mode[0].channels;
691
692	spec->multiout.num_dacs = preset->num_dacs;
693	spec->multiout.dac_nids = preset->dac_nids;
694	spec->multiout.dig_out_nid = preset->dig_out_nid;
695	spec->multiout.hp_nid = preset->hp_nid;
696
697	spec->num_mux_defs = preset->num_mux_defs;
698	if (!spec->num_mux_defs)
699		spec->num_mux_defs = 1;
700	spec->input_mux = preset->input_mux;
701
702	spec->num_adc_nids = preset->num_adc_nids;
703	spec->adc_nids = preset->adc_nids;
704	spec->dig_in_nid = preset->dig_in_nid;
705
706	spec->unsol_event = preset->unsol_event;
707	spec->init_hook = preset->init_hook;
708#ifdef CONFIG_SND_HDA_POWER_SAVE
709	spec->loopback.amplist = preset->loopbacks;
710#endif
711}
712
713/* Enable GPIO mask and set output */
714static struct hda_verb alc_gpio1_init_verbs[] = {
715	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
716	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
717	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
718	{ }
719};
720
721static struct hda_verb alc_gpio2_init_verbs[] = {
722	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
723	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
724	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
725	{ }
726};
727
728static struct hda_verb alc_gpio3_init_verbs[] = {
729	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
730	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
731	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
732	{ }
733};
734
735static void alc_sku_automute(struct hda_codec *codec)
736{
737	struct alc_spec *spec = codec->spec;
738	unsigned int mute;
739	unsigned int present;
740	unsigned int hp_nid = spec->autocfg.hp_pins[0];
741	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
742
743	/* need to execute and sync at first */
744	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
745	present = snd_hda_codec_read(codec, hp_nid, 0,
746				     AC_VERB_GET_PIN_SENSE, 0);
747	spec->jack_present = (present & 0x80000000) != 0;
748	if (spec->jack_present) {
749		/* mute internal speaker */
750		snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
751					 HDA_AMP_MUTE, HDA_AMP_MUTE);
752	} else {
753		/* unmute internal speaker if necessary */
754		mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
755		snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
756					 HDA_AMP_MUTE, mute);
757	}
758}
759
760/* unsolicited event for HP jack sensing */
761static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
762{
763	if (codec->vendor_id == 0x10ec0880)
764		res >>= 28;
765	else
766		res >>= 26;
767	if (res != ALC880_HP_EVENT)
768		return;
769
770	alc_sku_automute(codec);
771}
772
773/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
774 *	31 ~ 16 :	Manufacture ID
775 *	15 ~ 8	:	SKU ID
776 *	7  ~ 0	:	Assembly ID
777 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
778 */
779static void alc_subsystem_id(struct hda_codec *codec,
780			     unsigned int porta, unsigned int porte,
781			     unsigned int portd)
782{
783	unsigned int ass, tmp, i;
784	unsigned nid;
785	struct alc_spec *spec = codec->spec;
786
787	ass = codec->subsystem_id & 0xffff;
788	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
789		goto do_sku;
790
791	/*
792	 * 31~30	: port conetcivity
793	 * 29~21	: reserve
794	 * 20		: PCBEEP input
795	 * 19~16	: Check sum (15:1)
796	 * 15~1		: Custom
797	 * 0		: override
798	*/
799	nid = 0x1d;
800	if (codec->vendor_id == 0x10ec0260)
801		nid = 0x17;
802	ass = snd_hda_codec_read(codec, nid, 0,
803				 AC_VERB_GET_CONFIG_DEFAULT, 0);
804	if (!(ass & 1) && !(ass & 0x100000))
805		return;
806	if ((ass >> 30) != 1)	/* no physical connection */
807		return;
808
809	/* check sum */
810	tmp = 0;
811	for (i = 1; i < 16; i++) {
812		if ((ass >> i) & 1)
813			tmp++;
814	}
815	if (((ass >> 16) & 0xf) != tmp)
816		return;
817do_sku:
818	/*
819	 * 0 : override
820	 * 1 :	Swap Jack
821	 * 2 : 0 --> Desktop, 1 --> Laptop
822	 * 3~5 : External Amplifier control
823	 * 7~6 : Reserved
824	*/
825	tmp = (ass & 0x38) >> 3;	/* external Amp control */
826	switch (tmp) {
827	case 1:
828		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
829		break;
830	case 3:
831		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
832		break;
833	case 7:
834		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
835		break;
836	case 5:	/* set EAPD output high */
837		switch (codec->vendor_id) {
838		case 0x10ec0260:
839			snd_hda_codec_write(codec, 0x0f, 0,
840					    AC_VERB_SET_EAPD_BTLENABLE, 2);
841			snd_hda_codec_write(codec, 0x10, 0,
842					    AC_VERB_SET_EAPD_BTLENABLE, 2);
843			break;
844		case 0x10ec0262:
845		case 0x10ec0267:
846		case 0x10ec0268:
847		case 0x10ec0269:
848		case 0x10ec0862:
849		case 0x10ec0662:
850			snd_hda_codec_write(codec, 0x14, 0,
851					    AC_VERB_SET_EAPD_BTLENABLE, 2);
852			snd_hda_codec_write(codec, 0x15, 0,
853					    AC_VERB_SET_EAPD_BTLENABLE, 2);
854			break;
855		}
856		switch (codec->vendor_id) {
857		case 0x10ec0260:
858			snd_hda_codec_write(codec, 0x1a, 0,
859					    AC_VERB_SET_COEF_INDEX, 7);
860			tmp = snd_hda_codec_read(codec, 0x1a, 0,
861						 AC_VERB_GET_PROC_COEF, 0);
862			snd_hda_codec_write(codec, 0x1a, 0,
863					    AC_VERB_SET_COEF_INDEX, 7);
864			snd_hda_codec_write(codec, 0x1a, 0,
865					    AC_VERB_SET_PROC_COEF,
866					    tmp | 0x2010);
867			break;
868		case 0x10ec0262:
869		case 0x10ec0880:
870		case 0x10ec0882:
871		case 0x10ec0883:
872		case 0x10ec0885:
873		case 0x10ec0888:
874			snd_hda_codec_write(codec, 0x20, 0,
875					    AC_VERB_SET_COEF_INDEX, 7);
876			tmp = snd_hda_codec_read(codec, 0x20, 0,
877						 AC_VERB_GET_PROC_COEF, 0);
878			snd_hda_codec_write(codec, 0x20, 0,
879					    AC_VERB_SET_COEF_INDEX, 7);
880			snd_hda_codec_write(codec, 0x20, 0,
881					    AC_VERB_SET_PROC_COEF,
882					    tmp | 0x2010);
883			break;
884		case 0x10ec0267:
885		case 0x10ec0268:
886			snd_hda_codec_write(codec, 0x20, 0,
887					    AC_VERB_SET_COEF_INDEX, 7);
888			tmp = snd_hda_codec_read(codec, 0x20, 0,
889						 AC_VERB_GET_PROC_COEF, 0);
890			snd_hda_codec_write(codec, 0x20, 0,
891					    AC_VERB_SET_COEF_INDEX, 7);
892			snd_hda_codec_write(codec, 0x20, 0,
893					    AC_VERB_SET_PROC_COEF,
894					    tmp | 0x3000);
895			break;
896		}
897	default:
898		break;
899	}
900
901	/* is laptop or Desktop and enable the function "Mute internal speaker
902	 * when the external headphone out jack is plugged"
903	 */
904	if (!(ass & 0x8000))
905		return;
906	/*
907	 * 10~8 : Jack location
908	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
909	 * 14~13: Resvered
910	 * 15   : 1 --> enable the function "Mute internal speaker
911	 *	        when the external headphone out jack is plugged"
912	 */
913	if (!spec->autocfg.speaker_pins[0]) {
914		if (spec->autocfg.line_out_pins[0])
915			spec->autocfg.speaker_pins[0] =
916				spec->autocfg.line_out_pins[0];
917		else
918			return;
919	}
920
921	if (!spec->autocfg.hp_pins[0]) {
922		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
923		if (tmp == 0)
924			spec->autocfg.hp_pins[0] = porta;
925		else if (tmp == 1)
926			spec->autocfg.hp_pins[0] = porte;
927		else if (tmp == 2)
928			spec->autocfg.hp_pins[0] = portd;
929		else
930			return;
931	}
932
933	snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
934			    AC_VERB_SET_UNSOLICITED_ENABLE,
935			    AC_USRSP_EN | ALC880_HP_EVENT);
936	spec->unsol_event = alc_sku_unsol_event;
937	spec->init_hook = alc_sku_automute;
938}
939
940/*
941 * Fix-up pin default configurations
942 */
943
944struct alc_pincfg {
945	hda_nid_t nid;
946	u32 val;
947};
948
949static void alc_fix_pincfg(struct hda_codec *codec,
950			   const struct snd_pci_quirk *quirk,
951			   const struct alc_pincfg **pinfix)
952{
953	const struct alc_pincfg *cfg;
954
955	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
956	if (!quirk)
957		return;
958
959	cfg = pinfix[quirk->value];
960	for (; cfg->nid; cfg++) {
961		int i;
962		u32 val = cfg->val;
963		for (i = 0; i < 4; i++) {
964			snd_hda_codec_write(codec, cfg->nid, 0,
965				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
966				    val & 0xff);
967			val >>= 8;
968		}
969	}
970}
971
972/*
973 * ALC880 3-stack model
974 *
975 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
976 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
977 *                 F-Mic = 0x1b, HP = 0x19
978 */
979
980static hda_nid_t alc880_dac_nids[4] = {
981	/* front, rear, clfe, rear_surr */
982	0x02, 0x05, 0x04, 0x03
983};
984
985static hda_nid_t alc880_adc_nids[3] = {
986	/* ADC0-2 */
987	0x07, 0x08, 0x09,
988};
989
990/* The datasheet says the node 0x07 is connected from inputs,
991 * but it shows zero connection in the real implementation on some devices.
992 * Note: this is a 915GAV bug, fixed on 915GLV
993 */
994static hda_nid_t alc880_adc_nids_alt[2] = {
995	/* ADC1-2 */
996	0x08, 0x09,
997};
998
999#define ALC880_DIGOUT_NID	0x06
1000#define ALC880_DIGIN_NID	0x0a
1001
1002static struct hda_input_mux alc880_capture_source = {
1003	.num_items = 4,
1004	.items = {
1005		{ "Mic", 0x0 },
1006		{ "Front Mic", 0x3 },
1007		{ "Line", 0x2 },
1008		{ "CD", 0x4 },
1009	},
1010};
1011
1012/* channel source setting (2/6 channel selection for 3-stack) */
1013/* 2ch mode */
1014static struct hda_verb alc880_threestack_ch2_init[] = {
1015	/* set line-in to input, mute it */
1016	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1017	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1018	/* set mic-in to input vref 80%, mute it */
1019	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1020	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1021	{ } /* end */
1022};
1023
1024/* 6ch mode */
1025static struct hda_verb alc880_threestack_ch6_init[] = {
1026	/* set line-in to output, unmute it */
1027	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1029	/* set mic-in to output, unmute it */
1030	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1031	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1032	{ } /* end */
1033};
1034
1035static struct hda_channel_mode alc880_threestack_modes[2] = {
1036	{ 2, alc880_threestack_ch2_init },
1037	{ 6, alc880_threestack_ch6_init },
1038};
1039
1040static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1041	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1042	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1043	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1044	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1045	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1046	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1047	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1048	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1049	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1050	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1051	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1052	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1053	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1054	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1055	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1056	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1057	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1058	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1059	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1060	{
1061		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1062		.name = "Channel Mode",
1063		.info = alc_ch_mode_info,
1064		.get = alc_ch_mode_get,
1065		.put = alc_ch_mode_put,
1066	},
1067	{ } /* end */
1068};
1069
1070/* capture mixer elements */
1071static struct snd_kcontrol_new alc880_capture_mixer[] = {
1072	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1073	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1074	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1075	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1076	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1077	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1078	{
1079		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1080		/* The multiple "Capture Source" controls confuse alsamixer
1081		 * So call somewhat different..
1082		 * FIXME: the controls appear in the "playback" view!
1083		 */
1084		/* .name = "Capture Source", */
1085		.name = "Input Source",
1086		.count = 3,
1087		.info = alc_mux_enum_info,
1088		.get = alc_mux_enum_get,
1089		.put = alc_mux_enum_put,
1090	},
1091	{ } /* end */
1092};
1093
1094/* capture mixer elements (in case NID 0x07 not available) */
1095static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1096	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1097	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1098	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1099	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1100	{
1101		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1102		/* The multiple "Capture Source" controls confuse alsamixer
1103		 * So call somewhat different..
1104		 * FIXME: the controls appear in the "playback" view!
1105		 */
1106		/* .name = "Capture Source", */
1107		.name = "Input Source",
1108		.count = 2,
1109		.info = alc_mux_enum_info,
1110		.get = alc_mux_enum_get,
1111		.put = alc_mux_enum_put,
1112	},
1113	{ } /* end */
1114};
1115
1116
1117
1118/*
1119 * ALC880 5-stack model
1120 *
1121 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1122 *      Side = 0x02 (0xd)
1123 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1124 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1125 */
1126
1127/* additional mixers to alc880_three_stack_mixer */
1128static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1129	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1130	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1131	{ } /* end */
1132};
1133
1134/* channel source setting (6/8 channel selection for 5-stack) */
1135/* 6ch mode */
1136static struct hda_verb alc880_fivestack_ch6_init[] = {
1137	/* set line-in to input, mute it */
1138	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1139	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1140	{ } /* end */
1141};
1142
1143/* 8ch mode */
1144static struct hda_verb alc880_fivestack_ch8_init[] = {
1145	/* set line-in to output, unmute it */
1146	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1147	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1148	{ } /* end */
1149};
1150
1151static struct hda_channel_mode alc880_fivestack_modes[2] = {
1152	{ 6, alc880_fivestack_ch6_init },
1153	{ 8, alc880_fivestack_ch8_init },
1154};
1155
1156
1157/*
1158 * ALC880 6-stack model
1159 *
1160 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1161 *      Side = 0x05 (0x0f)
1162 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1163 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1164 */
1165
1166static hda_nid_t alc880_6st_dac_nids[4] = {
1167	/* front, rear, clfe, rear_surr */
1168	0x02, 0x03, 0x04, 0x05
1169};
1170
1171static struct hda_input_mux alc880_6stack_capture_source = {
1172	.num_items = 4,
1173	.items = {
1174		{ "Mic", 0x0 },
1175		{ "Front Mic", 0x1 },
1176		{ "Line", 0x2 },
1177		{ "CD", 0x4 },
1178	},
1179};
1180
1181/* fixed 8-channels */
1182static struct hda_channel_mode alc880_sixstack_modes[1] = {
1183	{ 8, NULL },
1184};
1185
1186static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1187	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1188	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1189	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1190	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1191	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1192	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1193	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1194	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1195	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1196	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1197	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1198	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1199	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1200	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1201	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1202	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1203	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1204	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1205	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1206	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1207	{
1208		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1209		.name = "Channel Mode",
1210		.info = alc_ch_mode_info,
1211		.get = alc_ch_mode_get,
1212		.put = alc_ch_mode_put,
1213	},
1214	{ } /* end */
1215};
1216
1217
1218/*
1219 * ALC880 W810 model
1220 *
1221 * W810 has rear IO for:
1222 * Front (DAC 02)
1223 * Surround (DAC 03)
1224 * Center/LFE (DAC 04)
1225 * Digital out (06)
1226 *
1227 * The system also has a pair of internal speakers, and a headphone jack.
1228 * These are both connected to Line2 on the codec, hence to DAC 02.
1229 *
1230 * There is a variable resistor to control the speaker or headphone
1231 * volume. This is a hardware-only device without a software API.
1232 *
1233 * Plugging headphones in will disable the internal speakers. This is
1234 * implemented in hardware, not via the driver using jack sense. In
1235 * a similar fashion, plugging into the rear socket marked "front" will
1236 * disable both the speakers and headphones.
1237 *
1238 * For input, there's a microphone jack, and an "audio in" jack.
1239 * These may not do anything useful with this driver yet, because I
1240 * haven't setup any initialization verbs for these yet...
1241 */
1242
1243static hda_nid_t alc880_w810_dac_nids[3] = {
1244	/* front, rear/surround, clfe */
1245	0x02, 0x03, 0x04
1246};
1247
1248/* fixed 6 channels */
1249static struct hda_channel_mode alc880_w810_modes[1] = {
1250	{ 6, NULL }
1251};
1252
1253/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1254static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1255	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1256	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1257	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1258	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1259	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1260	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1261	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1262	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1263	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1264	{ } /* end */
1265};
1266
1267
1268/*
1269 * Z710V model
1270 *
1271 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1272 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1273 *                 Line = 0x1a
1274 */
1275
1276static hda_nid_t alc880_z71v_dac_nids[1] = {
1277	0x02
1278};
1279#define ALC880_Z71V_HP_DAC	0x03
1280
1281/* fixed 2 channels */
1282static struct hda_channel_mode alc880_2_jack_modes[1] = {
1283	{ 2, NULL }
1284};
1285
1286static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1287	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1288	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1289	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1290	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1291	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1292	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1293	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1294	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1295	{ } /* end */
1296};
1297
1298
1299/* FIXME! */
1300/*
1301 * ALC880 F1734 model
1302 *
1303 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1304 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1305 */
1306
1307static hda_nid_t alc880_f1734_dac_nids[1] = {
1308	0x03
1309};
1310#define ALC880_F1734_HP_DAC	0x02
1311
1312static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1313	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1314	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1315	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1316	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1317	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1318	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1319	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1320	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1321	{ } /* end */
1322};
1323
1324
1325/* FIXME! */
1326/*
1327 * ALC880 ASUS model
1328 *
1329 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1330 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1331 *  Mic = 0x18, Line = 0x1a
1332 */
1333
1334#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1335#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1336
1337static struct snd_kcontrol_new alc880_asus_mixer[] = {
1338	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1339	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1340	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1341	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1342	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1343	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1344	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1345	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1346	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1347	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1348	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1349	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1350	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1351	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1352	{
1353		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1354		.name = "Channel Mode",
1355		.info = alc_ch_mode_info,
1356		.get = alc_ch_mode_get,
1357		.put = alc_ch_mode_put,
1358	},
1359	{ } /* end */
1360};
1361
1362/* FIXME! */
1363/*
1364 * ALC880 ASUS W1V model
1365 *
1366 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1367 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1368 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1369 */
1370
1371/* additional mixers to alc880_asus_mixer */
1372static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1373	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1374	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1375	{ } /* end */
1376};
1377
1378/* additional mixers to alc880_asus_mixer */
1379static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1380	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1381	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1382	{ } /* end */
1383};
1384
1385/* TCL S700 */
1386static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1387	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1388	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1389	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1390	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1391	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1392	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1393	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1394	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1395	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1396	{
1397		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1398		/* The multiple "Capture Source" controls confuse alsamixer
1399		 * So call somewhat different..
1400		 * FIXME: the controls appear in the "playback" view!
1401		 */
1402		/* .name = "Capture Source", */
1403		.name = "Input Source",
1404		.count = 1,
1405		.info = alc_mux_enum_info,
1406		.get = alc_mux_enum_get,
1407		.put = alc_mux_enum_put,
1408	},
1409	{ } /* end */
1410};
1411
1412/* Uniwill */
1413static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1414	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1415	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1416	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1417	HDA_BIND_MUTE("Speaker 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	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1429	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1430	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1431	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1432	{
1433		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1434		.name = "Channel Mode",
1435		.info = alc_ch_mode_info,
1436		.get = alc_ch_mode_get,
1437		.put = alc_ch_mode_put,
1438	},
1439	{ } /* end */
1440};
1441
1442static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1443	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1444	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1445	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1446	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1447	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1448	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1449	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1450	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1451	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1452	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1453	{ } /* end */
1454};
1455
1456static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1457	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1458	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1459	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1460	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1461	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1462	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1463	{ } /* end */
1464};
1465
1466/*
1467 * virtual master controls
1468 */
1469
1470/*
1471 * slave controls for virtual master
1472 */
1473static const char *alc_slave_vols[] = {
1474	"Front Playback Volume",
1475	"Surround Playback Volume",
1476	"Center Playback Volume",
1477	"LFE Playback Volume",
1478	"Side Playback Volume",
1479	"Headphone Playback Volume",
1480	"Speaker Playback Volume",
1481	"Mono Playback Volume",
1482	"iSpeaker Playback Volume",
1483	"Line-Out Playback Volume",
1484	NULL,
1485};
1486
1487static const char *alc_slave_sws[] = {
1488	"Front Playback Switch",
1489	"Surround Playback Switch",
1490	"Center Playback Switch",
1491	"LFE Playback Switch",
1492	"Side Playback Switch",
1493	"Headphone Playback Switch",
1494	"Speaker Playback Switch",
1495	"Mono Playback Switch",
1496	"iSpeaker Playback Switch",
1497	NULL,
1498};
1499
1500/*
1501 * build control elements
1502 */
1503static int alc_build_controls(struct hda_codec *codec)
1504{
1505	struct alc_spec *spec = codec->spec;
1506	int err;
1507	int i;
1508
1509	for (i = 0; i < spec->num_mixers; i++) {
1510		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1511		if (err < 0)
1512			return err;
1513	}
1514
1515	if (spec->multiout.dig_out_nid) {
1516		err = snd_hda_create_spdif_out_ctls(codec,
1517						    spec->multiout.dig_out_nid);
1518		if (err < 0)
1519			return err;
1520	}
1521	if (spec->dig_in_nid) {
1522		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1523		if (err < 0)
1524			return err;
1525	}
1526
1527	/* if we have no master control, let's create it */
1528	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1529		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1530					HDA_OUTPUT, spec->vmaster_tlv);
1531		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1532					  spec->vmaster_tlv, alc_slave_vols);
1533		if (err < 0)
1534			return err;
1535	}
1536	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1537		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1538					  NULL, alc_slave_sws);
1539		if (err < 0)
1540			return err;
1541	}
1542
1543	return 0;
1544}
1545
1546
1547/*
1548 * initialize the codec volumes, etc
1549 */
1550
1551/*
1552 * generic initialization of ADC, input mixers and output mixers
1553 */
1554static struct hda_verb alc880_volume_init_verbs[] = {
1555	/*
1556	 * Unmute ADC0-2 and set the default input to mic-in
1557	 */
1558	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1559	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1560	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1561	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1562	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1563	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1564
1565	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1566	 * mixer widget
1567	 * Note: PASD motherboards uses the Line In 2 as the input for front
1568	 * panel mic (mic 2)
1569	 */
1570	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1571	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1572	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1573	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1574	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1575	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1576	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1577	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1578
1579	/*
1580	 * Set up output mixers (0x0c - 0x0f)
1581	 */
1582	/* set vol=0 to output mixers */
1583	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1584	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1585	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1586	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1587	/* set up input amps for analog loopback */
1588	/* Amp Indices: DAC = 0, mixer = 1 */
1589	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1590	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1591	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1592	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1593	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1594	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1595	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1596	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1597
1598	{ }
1599};
1600
1601/*
1602 * 3-stack pin configuration:
1603 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1604 */
1605static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1606	/*
1607	 * preset connection lists of input pins
1608	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1609	 */
1610	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1611	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1612	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1613
1614	/*
1615	 * Set pin mode and muting
1616	 */
1617	/* set front pin widgets 0x14 for output */
1618	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1619	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1620	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1621	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1622	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1623	/* Mic2 (as headphone out) for HP output */
1624	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1625	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1626	/* Line In pin widget for input */
1627	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1628	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1629	/* Line2 (as front mic) pin widget for input and vref at 80% */
1630	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1631	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1632	/* CD pin widget for input */
1633	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1634
1635	{ }
1636};
1637
1638/*
1639 * 5-stack pin configuration:
1640 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1641 * line-in/side = 0x1a, f-mic = 0x1b
1642 */
1643static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1644	/*
1645	 * preset connection lists of input pins
1646	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1647	 */
1648	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1649	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1650
1651	/*
1652	 * Set pin mode and muting
1653	 */
1654	/* set pin widgets 0x14-0x17 for output */
1655	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1656	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1657	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1658	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1659	/* unmute pins for output (no gain on this amp) */
1660	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1663	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1664
1665	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1666	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1667	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1668	/* Mic2 (as headphone out) for HP output */
1669	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1670	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671	/* Line In pin widget for input */
1672	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1673	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1674	/* Line2 (as front mic) pin widget for input and vref at 80% */
1675	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1676	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1677	/* CD pin widget for input */
1678	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1679
1680	{ }
1681};
1682
1683/*
1684 * W810 pin configuration:
1685 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1686 */
1687static struct hda_verb alc880_pin_w810_init_verbs[] = {
1688	/* hphone/speaker input selector: front DAC */
1689	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1690
1691	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1694	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1696	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1697
1698	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1699	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1700
1701	{ }
1702};
1703
1704/*
1705 * Z71V pin configuration:
1706 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1707 */
1708static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1709	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1710	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1711	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1712	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1713
1714	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1715	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1716	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1717	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1718
1719	{ }
1720};
1721
1722/*
1723 * 6-stack pin configuration:
1724 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1725 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1726 */
1727static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1728	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1729
1730	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1731	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1733	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1734	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1736	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1737	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1738
1739	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1740	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1741	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1742	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1743	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1744	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1745	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1746	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1747	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1748
1749	{ }
1750};
1751
1752/*
1753 * Uniwill pin configuration:
1754 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1755 * line = 0x1a
1756 */
1757static struct hda_verb alc880_uniwill_init_verbs[] = {
1758	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1759
1760	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1761	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1762	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1763	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1764	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1765	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1766	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1767	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1768	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1769	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1770	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1771	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1772	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1773	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1774
1775	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1776	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1777	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1778	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1779	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1780	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1781	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1782	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1783	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1784
1785	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1786	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1787
1788	{ }
1789};
1790
1791/*
1792* Uniwill P53
1793* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1794 */
1795static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1796	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1797
1798	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1799	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1800	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1801	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1802	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1803	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1804	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1805	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1806	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1807	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1808	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1809	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1810
1811	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1812	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1813	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1814	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1815	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1816	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1817
1818	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1819	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1820
1821	{ }
1822};
1823
1824static struct hda_verb alc880_beep_init_verbs[] = {
1825	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1826	{ }
1827};
1828
1829/* toggle speaker-output according to the hp-jack state */
1830static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1831{
1832 	unsigned int present;
1833	unsigned char bits;
1834
1835 	present = snd_hda_codec_read(codec, 0x14, 0,
1836				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1837	bits = present ? HDA_AMP_MUTE : 0;
1838	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1839				 HDA_AMP_MUTE, bits);
1840	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1841				 HDA_AMP_MUTE, bits);
1842}
1843
1844/* auto-toggle front mic */
1845static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1846{
1847 	unsigned int present;
1848	unsigned char bits;
1849
1850	present = snd_hda_codec_read(codec, 0x18, 0,
1851				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1852	bits = present ? HDA_AMP_MUTE : 0;
1853	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1854}
1855
1856static void alc880_uniwill_automute(struct hda_codec *codec)
1857{
1858	alc880_uniwill_hp_automute(codec);
1859	alc880_uniwill_mic_automute(codec);
1860}
1861
1862static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1863				       unsigned int res)
1864{
1865	/* Looks like the unsol event is incompatible with the standard
1866	 * definition.  4bit tag is placed at 28 bit!
1867	 */
1868	switch (res >> 28) {
1869	case ALC880_HP_EVENT:
1870		alc880_uniwill_hp_automute(codec);
1871		break;
1872	case ALC880_MIC_EVENT:
1873		alc880_uniwill_mic_automute(codec);
1874		break;
1875	}
1876}
1877
1878static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1879{
1880 	unsigned int present;
1881	unsigned char bits;
1882
1883 	present = snd_hda_codec_read(codec, 0x14, 0,
1884				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1885	bits = present ? HDA_AMP_MUTE : 0;
1886	snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1887}
1888
1889static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1890{
1891	unsigned int present;
1892
1893	present = snd_hda_codec_read(codec, 0x21, 0,
1894				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1895	present &= HDA_AMP_VOLMASK;
1896	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1897				 HDA_AMP_VOLMASK, present);
1898	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1899				 HDA_AMP_VOLMASK, present);
1900}
1901
1902static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1903					   unsigned int res)
1904{
1905	/* Looks like the unsol event is incompatible with the standard
1906	 * definition.  4bit tag is placed at 28 bit!
1907	 */
1908	if ((res >> 28) == ALC880_HP_EVENT)
1909		alc880_uniwill_p53_hp_automute(codec);
1910	if ((res >> 28) == ALC880_DCVOL_EVENT)
1911		alc880_uniwill_p53_dcvol_automute(codec);
1912}
1913
1914/* FIXME! */
1915/*
1916 * F1734 pin configuration:
1917 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1918 */
1919static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1920	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1921	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1922	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1923	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1924
1925	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1926	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1927	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929
1930	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1931	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1932	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1933	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1934	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1935	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1936	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1937	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1938	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1939
1940	{ }
1941};
1942
1943/* FIXME! */
1944/*
1945 * ASUS pin configuration:
1946 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1947 */
1948static struct hda_verb alc880_pin_asus_init_verbs[] = {
1949	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1950	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1951	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1952	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1953
1954	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1955	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1956	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1957	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1958	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1959	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1960	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1961	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1962
1963	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1964	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1965	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1966	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1967	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1968	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1969	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1970	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1971	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1972
1973	{ }
1974};
1975
1976/* Enable GPIO mask and set output */
1977#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1978#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1979
1980/* Clevo m520g init */
1981static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1982	/* headphone output */
1983	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1984	/* line-out */
1985	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1986	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1987	/* Line-in */
1988	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1989	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1990	/* CD */
1991	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1992	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1993	/* Mic1 (rear panel) */
1994	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1995	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1996	/* Mic2 (front panel) */
1997	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1998	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999	/* headphone */
2000	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2001	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2002        /* change to EAPD mode */
2003	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2004	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2005
2006	{ }
2007};
2008
2009static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2010	/* change to EAPD mode */
2011	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2012	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2013
2014	/* Headphone output */
2015	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2016	/* Front output*/
2017	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2018	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2019
2020	/* Line In pin widget for input */
2021	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2022	/* CD pin widget for input */
2023	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2024	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2025	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2026
2027	/* change to EAPD mode */
2028	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2029	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2030
2031	{ }
2032};
2033
2034/*
2035 * LG m1 express dual
2036 *
2037 * Pin assignment:
2038 *   Rear Line-In/Out (blue): 0x14
2039 *   Build-in Mic-In: 0x15
2040 *   Speaker-out: 0x17
2041 *   HP-Out (green): 0x1b
2042 *   Mic-In/Out (red): 0x19
2043 *   SPDIF-Out: 0x1e
2044 */
2045
2046/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2047static hda_nid_t alc880_lg_dac_nids[3] = {
2048	0x05, 0x02, 0x03
2049};
2050
2051/* seems analog CD is not working */
2052static struct hda_input_mux alc880_lg_capture_source = {
2053	.num_items = 3,
2054	.items = {
2055		{ "Mic", 0x1 },
2056		{ "Line", 0x5 },
2057		{ "Internal Mic", 0x6 },
2058	},
2059};
2060
2061/* 2,4,6 channel modes */
2062static struct hda_verb alc880_lg_ch2_init[] = {
2063	/* set line-in and mic-in to input */
2064	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2065	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2066	{ }
2067};
2068
2069static struct hda_verb alc880_lg_ch4_init[] = {
2070	/* set line-in to out and mic-in to input */
2071	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2072	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2073	{ }
2074};
2075
2076static struct hda_verb alc880_lg_ch6_init[] = {
2077	/* set line-in and mic-in to output */
2078	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2079	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2080	{ }
2081};
2082
2083static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2084	{ 2, alc880_lg_ch2_init },
2085	{ 4, alc880_lg_ch4_init },
2086	{ 6, alc880_lg_ch6_init },
2087};
2088
2089static struct snd_kcontrol_new alc880_lg_mixer[] = {
2090	/* FIXME: it's not really "master" but front channels */
2091	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2092	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2093	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2094	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2095	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2096	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2097	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2098	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2099	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2100	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2101	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2102	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2103	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2104	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2105	{
2106		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2107		.name = "Channel Mode",
2108		.info = alc_ch_mode_info,
2109		.get = alc_ch_mode_get,
2110		.put = alc_ch_mode_put,
2111	},
2112	{ } /* end */
2113};
2114
2115static struct hda_verb alc880_lg_init_verbs[] = {
2116	/* set capture source to mic-in */
2117	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2118	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2119	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2120	/* mute all amp mixer inputs */
2121	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2122	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2123	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2124	/* line-in to input */
2125	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2126	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2127	/* built-in mic */
2128	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2129	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2130	/* speaker-out */
2131	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2132	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2133	/* mic-in to input */
2134	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2135	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2136	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2137	/* HP-out */
2138	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2139	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2140	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2141	/* jack sense */
2142	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2143	{ }
2144};
2145
2146/* toggle speaker-output according to the hp-jack state */
2147static void alc880_lg_automute(struct hda_codec *codec)
2148{
2149	unsigned int present;
2150	unsigned char bits;
2151
2152	present = snd_hda_codec_read(codec, 0x1b, 0,
2153				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2154	bits = present ? HDA_AMP_MUTE : 0;
2155	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2156				 HDA_AMP_MUTE, bits);
2157}
2158
2159static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2160{
2161	/* Looks like the unsol event is incompatible with the standard
2162	 * definition.  4bit tag is placed at 28 bit!
2163	 */
2164	if ((res >> 28) == 0x01)
2165		alc880_lg_automute(codec);
2166}
2167
2168/*
2169 * LG LW20
2170 *
2171 * Pin assignment:
2172 *   Speaker-out: 0x14
2173 *   Mic-In: 0x18
2174 *   Built-in Mic-In: 0x19
2175 *   Line-In: 0x1b
2176 *   HP-Out: 0x1a
2177 *   SPDIF-Out: 0x1e
2178 */
2179
2180static struct hda_input_mux alc880_lg_lw_capture_source = {
2181	.num_items = 3,
2182	.items = {
2183		{ "Mic", 0x0 },
2184		{ "Internal Mic", 0x1 },
2185		{ "Line In", 0x2 },
2186	},
2187};
2188
2189#define alc880_lg_lw_modes alc880_threestack_modes
2190
2191static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2192	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2193	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2194	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2195	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2196	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2197	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2198	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2199	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2200	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2201	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2202	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2203	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2204	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2205	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2206	{
2207		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2208		.name = "Channel Mode",
2209		.info = alc_ch_mode_info,
2210		.get = alc_ch_mode_get,
2211		.put = alc_ch_mode_put,
2212	},
2213	{ } /* end */
2214};
2215
2216static struct hda_verb alc880_lg_lw_init_verbs[] = {
2217	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2218	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2219	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2220
2221	/* set capture source to mic-in */
2222	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2223	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2224	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2225	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2226	/* speaker-out */
2227	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2228	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229	/* HP-out */
2230	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2231	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2232	/* mic-in to input */
2233	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2234	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2235	/* built-in mic */
2236	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2237	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238	/* jack sense */
2239	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2240	{ }
2241};
2242
2243/* toggle speaker-output according to the hp-jack state */
2244static void alc880_lg_lw_automute(struct hda_codec *codec)
2245{
2246	unsigned int present;
2247	unsigned char bits;
2248
2249	present = snd_hda_codec_read(codec, 0x1b, 0,
2250				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2251	bits = present ? HDA_AMP_MUTE : 0;
2252	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2253				 HDA_AMP_MUTE, bits);
2254}
2255
2256static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2257{
2258	/* Looks like the unsol event is incompatible with the standard
2259	 * definition.  4bit tag is placed at 28 bit!
2260	 */
2261	if ((res >> 28) == 0x01)
2262		alc880_lg_lw_automute(codec);
2263}
2264
2265#ifdef CONFIG_SND_HDA_POWER_SAVE
2266static struct hda_amp_list alc880_loopbacks[] = {
2267	{ 0x0b, HDA_INPUT, 0 },
2268	{ 0x0b, HDA_INPUT, 1 },
2269	{ 0x0b, HDA_INPUT, 2 },
2270	{ 0x0b, HDA_INPUT, 3 },
2271	{ 0x0b, HDA_INPUT, 4 },
2272	{ } /* end */
2273};
2274
2275static struct hda_amp_list alc880_lg_loopbacks[] = {
2276	{ 0x0b, HDA_INPUT, 1 },
2277	{ 0x0b, HDA_INPUT, 6 },
2278	{ 0x0b, HDA_INPUT, 7 },
2279	{ } /* end */
2280};
2281#endif
2282
2283/*
2284 * Common callbacks
2285 */
2286
2287static int alc_init(struct hda_codec *codec)
2288{
2289	struct alc_spec *spec = codec->spec;
2290	unsigned int i;
2291
2292	for (i = 0; i < spec->num_init_verbs; i++)
2293		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2294
2295	if (spec->init_hook)
2296		spec->init_hook(codec);
2297
2298	return 0;
2299}
2300
2301static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2302{
2303	struct alc_spec *spec = codec->spec;
2304
2305	if (spec->unsol_event)
2306		spec->unsol_event(codec, res);
2307}
2308
2309#ifdef CONFIG_SND_HDA_POWER_SAVE
2310static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2311{
2312	struct alc_spec *spec = codec->spec;
2313	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2314}
2315#endif
2316
2317/*
2318 * Analog playback callbacks
2319 */
2320static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2321				    struct hda_codec *codec,
2322				    struct snd_pcm_substream *substream)
2323{
2324	struct alc_spec *spec = codec->spec;
2325	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2326}
2327
2328static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2329				       struct hda_codec *codec,
2330				       unsigned int stream_tag,
2331				       unsigned int format,
2332				       struct snd_pcm_substream *substream)
2333{
2334	struct alc_spec *spec = codec->spec;
2335	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2336						stream_tag, format, substream);
2337}
2338
2339static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2340				       struct hda_codec *codec,
2341				       struct snd_pcm_substream *substream)
2342{
2343	struct alc_spec *spec = codec->spec;
2344	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2345}
2346
2347/*
2348 * Digital out
2349 */
2350static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2351					struct hda_codec *codec,
2352					struct snd_pcm_substream *substream)
2353{
2354	struct alc_spec *spec = codec->spec;
2355	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2356}
2357
2358static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2359					   struct hda_codec *codec,
2360					   unsigned int stream_tag,
2361					   unsigned int format,
2362					   struct snd_pcm_substream *substream)
2363{
2364	struct alc_spec *spec = codec->spec;
2365	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2366					     stream_tag, format, substream);
2367}
2368
2369static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2370					 struct hda_codec *codec,
2371					 struct snd_pcm_substream *substream)
2372{
2373	struct alc_spec *spec = codec->spec;
2374	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2375}
2376
2377/*
2378 * Analog capture
2379 */
2380static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2381				      struct hda_codec *codec,
2382				      unsigned int stream_tag,
2383				      unsigned int format,
2384				      struct snd_pcm_substream *substream)
2385{
2386	struct alc_spec *spec = codec->spec;
2387
2388	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2389				   stream_tag, 0, format);
2390	return 0;
2391}
2392
2393static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2394				      struct hda_codec *codec,
2395				      struct snd_pcm_substream *substream)
2396{
2397	struct alc_spec *spec = codec->spec;
2398
2399	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2400				   0, 0, 0);
2401	return 0;
2402}
2403
2404
2405/*
2406 */
2407static struct hda_pcm_stream alc880_pcm_analog_playback = {
2408	.substreams = 1,
2409	.channels_min = 2,
2410	.channels_max = 8,
2411	/* NID is set in alc_build_pcms */
2412	.ops = {
2413		.open = alc880_playback_pcm_open,
2414		.prepare = alc880_playback_pcm_prepare,
2415		.cleanup = alc880_playback_pcm_cleanup
2416	},
2417};
2418
2419static struct hda_pcm_stream alc880_pcm_analog_capture = {
2420	.substreams = 2,
2421	.channels_min = 2,
2422	.channels_max = 2,
2423	/* NID is set in alc_build_pcms */
2424	.ops = {
2425		.prepare = alc880_capture_pcm_prepare,
2426		.cleanup = alc880_capture_pcm_cleanup
2427	},
2428};
2429
2430static struct hda_pcm_stream alc880_pcm_digital_playback = {
2431	.substreams = 1,
2432	.channels_min = 2,
2433	.channels_max = 2,
2434	/* NID is set in alc_build_pcms */
2435	.ops = {
2436		.open = alc880_dig_playback_pcm_open,
2437		.close = alc880_dig_playback_pcm_close,
2438		.prepare = alc880_dig_playback_pcm_prepare
2439	},
2440};
2441
2442static struct hda_pcm_stream alc880_pcm_digital_capture = {
2443	.substreams = 1,
2444	.channels_min = 2,
2445	.channels_max = 2,
2446	/* NID is set in alc_build_pcms */
2447};
2448
2449/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2450static struct hda_pcm_stream alc_pcm_null_playback = {
2451	.substreams = 0,
2452	.channels_min = 0,
2453	.channels_max = 0,
2454};
2455
2456static int alc_build_pcms(struct hda_codec *codec)
2457{
2458	struct alc_spec *spec = codec->spec;
2459	struct hda_pcm *info = spec->pcm_rec;
2460	int i;
2461
2462	codec->num_pcms = 1;
2463	codec->pcm_info = info;
2464
2465	info->name = spec->stream_name_analog;
2466	if (spec->stream_analog_playback) {
2467		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2468		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2469		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2470	}
2471	if (spec->stream_analog_capture) {
2472		snd_assert(spec->adc_nids, return -EINVAL);
2473		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2474		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2475	}
2476
2477	if (spec->channel_mode) {
2478		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2479		for (i = 0; i < spec->num_channel_mode; i++) {
2480			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2481				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2482			}
2483		}
2484	}
2485
2486	/* SPDIF for stream index #1 */
2487	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2488		codec->num_pcms = 2;
2489		info = spec->pcm_rec + 1;
2490		info->name = spec->stream_name_digital;
2491		if (spec->multiout.dig_out_nid &&
2492		    spec->stream_digital_playback) {
2493			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2494			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2495		}
2496		if (spec->dig_in_nid &&
2497		    spec->stream_digital_capture) {
2498			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2499			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2500		}
2501	}
2502
2503	/* If the use of more than one ADC is requested for the current
2504	 * model, configure a second analog capture-only PCM.
2505	 */
2506	/* Additional Analaog capture for index #2 */
2507	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2508	    spec->adc_nids) {
2509		codec->num_pcms = 3;
2510		info = spec->pcm_rec + 2;
2511		info->name = spec->stream_name_analog;
2512		/* No playback stream for second PCM */
2513		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2514		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2515		if (spec->stream_analog_capture) {
2516			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2517			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2518		}
2519	}
2520
2521	return 0;
2522}
2523
2524static void alc_free(struct hda_codec *codec)
2525{
2526	struct alc_spec *spec = codec->spec;
2527	unsigned int i;
2528
2529	if (!spec)
2530		return;
2531
2532	if (spec->kctl_alloc) {
2533		for (i = 0; i < spec->num_kctl_used; i++)
2534			kfree(spec->kctl_alloc[i].name);
2535		kfree(spec->kctl_alloc);
2536	}
2537	kfree(spec);
2538}
2539
2540/*
2541 */
2542static struct hda_codec_ops alc_patch_ops = {
2543	.build_controls = alc_build_controls,
2544	.build_pcms = alc_build_pcms,
2545	.init = alc_init,
2546	.free = alc_free,
2547	.unsol_event = alc_unsol_event,
2548#ifdef CONFIG_SND_HDA_POWER_SAVE
2549	.check_power_status = alc_check_power_status,
2550#endif
2551};
2552
2553
2554/*
2555 * Test configuration for debugging
2556 *
2557 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2558 * enum controls.
2559 */
2560#ifdef CONFIG_SND_DEBUG
2561static hda_nid_t alc880_test_dac_nids[4] = {
2562	0x02, 0x03, 0x04, 0x05
2563};
2564
2565static struct hda_input_mux alc880_test_capture_source = {
2566	.num_items = 7,
2567	.items = {
2568		{ "In-1", 0x0 },
2569		{ "In-2", 0x1 },
2570		{ "In-3", 0x2 },
2571		{ "In-4", 0x3 },
2572		{ "CD", 0x4 },
2573		{ "Front", 0x5 },
2574		{ "Surround", 0x6 },
2575	},
2576};
2577
2578static struct hda_channel_mode alc880_test_modes[4] = {
2579	{ 2, NULL },
2580	{ 4, NULL },
2581	{ 6, NULL },
2582	{ 8, NULL },
2583};
2584
2585static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2586				 struct snd_ctl_elem_info *uinfo)
2587{
2588	static char *texts[] = {
2589		"N/A", "Line Out", "HP Out",
2590		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2591	};
2592	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2593	uinfo->count = 1;
2594	uinfo->value.enumerated.items = 8;
2595	if (uinfo->value.enumerated.item >= 8)
2596		uinfo->value.enumerated.item = 7;
2597	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2598	return 0;
2599}
2600
2601static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2602				struct snd_ctl_elem_value *ucontrol)
2603{
2604	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2605	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2606	unsigned int pin_ctl, item = 0;
2607
2608	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2609				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2610	if (pin_ctl & AC_PINCTL_OUT_EN) {
2611		if (pin_ctl & AC_PINCTL_HP_EN)
2612			item = 2;
2613		else
2614			item = 1;
2615	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2616		switch (pin_ctl & AC_PINCTL_VREFEN) {
2617		case AC_PINCTL_VREF_HIZ: item = 3; break;
2618		case AC_PINCTL_VREF_50:  item = 4; break;
2619		case AC_PINCTL_VREF_GRD: item = 5; break;
2620		case AC_PINCTL_VREF_80:  item = 6; break;
2621		case AC_PINCTL_VREF_100: item = 7; break;
2622		}
2623	}
2624	ucontrol->value.enumerated.item[0] = item;
2625	return 0;
2626}
2627
2628static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2629				struct snd_ctl_elem_value *ucontrol)
2630{
2631	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2632	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2633	static unsigned int ctls[] = {
2634		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2635		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2636		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2637		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2638		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2639		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2640	};
2641	unsigned int old_ctl, new_ctl;
2642
2643	old_ctl = snd_hda_codec_read(codec, nid, 0,
2644				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2645	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2646	if (old_ctl != new_ctl) {
2647		int val;
2648		snd_hda_codec_write_cache(codec, nid, 0,
2649					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2650					  new_ctl);
2651		val = ucontrol->value.enumerated.item[0] >= 3 ?
2652			HDA_AMP_MUTE : 0;
2653		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2654					 HDA_AMP_MUTE, val);
2655		return 1;
2656	}
2657	return 0;
2658}
2659
2660static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2661				 struct snd_ctl_elem_info *uinfo)
2662{
2663	static char *texts[] = {
2664		"Front", "Surround", "CLFE", "Side"
2665	};
2666	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2667	uinfo->count = 1;
2668	uinfo->value.enumerated.items = 4;
2669	if (uinfo->value.enumerated.item >= 4)
2670		uinfo->value.enumerated.item = 3;
2671	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2672	return 0;
2673}
2674
2675static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2676				struct snd_ctl_elem_value *ucontrol)
2677{
2678	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2679	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2680	unsigned int sel;
2681
2682	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2683	ucontrol->value.enumerated.item[0] = sel & 3;
2684	return 0;
2685}
2686
2687static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2688				struct snd_ctl_elem_value *ucontrol)
2689{
2690	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2691	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2692	unsigned int sel;
2693
2694	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2695	if (ucontrol->value.enumerated.item[0] != sel) {
2696		sel = ucontrol->value.enumerated.item[0] & 3;
2697		snd_hda_codec_write_cache(codec, nid, 0,
2698					  AC_VERB_SET_CONNECT_SEL, sel);
2699		return 1;
2700	}
2701	return 0;
2702}
2703
2704#define PIN_CTL_TEST(xname,nid) {			\
2705		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2706			.name = xname,		       \
2707			.info = alc_test_pin_ctl_info, \
2708			.get = alc_test_pin_ctl_get,   \
2709			.put = alc_test_pin_ctl_put,   \
2710			.private_value = nid	       \
2711			}
2712
2713#define PIN_SRC_TEST(xname,nid) {			\
2714		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2715			.name = xname,		       \
2716			.info = alc_test_pin_src_info, \
2717			.get = alc_test_pin_src_get,   \
2718			.put = alc_test_pin_src_put,   \
2719			.private_value = nid	       \
2720			}
2721
2722static struct snd_kcontrol_new alc880_test_mixer[] = {
2723	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2724	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2725	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2726	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2727	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2728	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2729	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2730	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2731	PIN_CTL_TEST("Front Pin Mode", 0x14),
2732	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2733	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2734	PIN_CTL_TEST("Side Pin Mode", 0x17),
2735	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2736	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2737	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2738	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2739	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2740	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2741	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2742	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2743	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2744	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2745	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2746	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2747	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2748	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2749	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2750	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2751	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2752	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2753	{
2754		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2755		.name = "Channel Mode",
2756		.info = alc_ch_mode_info,
2757		.get = alc_ch_mode_get,
2758		.put = alc_ch_mode_put,
2759	},
2760	{ } /* end */
2761};
2762
2763static struct hda_verb alc880_test_init_verbs[] = {
2764	/* Unmute inputs of 0x0c - 0x0f */
2765	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2766	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2767	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2768	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2769	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2770	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2771	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2772	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2773	/* Vol output for 0x0c-0x0f */
2774	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2775	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2776	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2777	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2778	/* Set output pins 0x14-0x17 */
2779	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2780	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2781	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2782	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2783	/* Unmute output pins 0x14-0x17 */
2784	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2785	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2786	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2787	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2788	/* Set input pins 0x18-0x1c */
2789	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2790	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2791	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2792	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2793	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2794	/* Mute input pins 0x18-0x1b */
2795	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2796	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2797	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2798	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2799	/* ADC set up */
2800	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2801	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2802	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2803	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2804	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2805	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2806	/* Analog input/passthru */
2807	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2808	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2809	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2810	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2811	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2812	{ }
2813};
2814#endif
2815
2816/*
2817 */
2818
2819static const char *alc880_models[ALC880_MODEL_LAST] = {
2820	[ALC880_3ST]		= "3stack",
2821	[ALC880_TCL_S700]	= "tcl",
2822	[ALC880_3ST_DIG]	= "3stack-digout",
2823	[ALC880_CLEVO]		= "clevo",
2824	[ALC880_5ST]		= "5stack",
2825	[ALC880_5ST_DIG]	= "5stack-digout",
2826	[ALC880_W810]		= "w810",
2827	[ALC880_Z71V]		= "z71v",
2828	[ALC880_6ST]		= "6stack",
2829	[ALC880_6ST_DIG]	= "6stack-digout",
2830	[ALC880_ASUS]		= "asus",
2831	[ALC880_ASUS_W1V]	= "asus-w1v",
2832	[ALC880_ASUS_DIG]	= "asus-dig",
2833	[ALC880_ASUS_DIG2]	= "asus-dig2",
2834	[ALC880_UNIWILL_DIG]	= "uniwill",
2835	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2836	[ALC880_FUJITSU]	= "fujitsu",
2837	[ALC880_F1734]		= "F1734",
2838	[ALC880_LG]		= "lg",
2839	[ALC880_LG_LW]		= "lg-lw",
2840#ifdef CONFIG_SND_DEBUG
2841	[ALC880_TEST]		= "test",
2842#endif
2843	[ALC880_AUTO]		= "auto",
2844};
2845
2846static struct snd_pci_quirk alc880_cfg_tbl[] = {
2847	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2848	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2849	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2850	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2851	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2852	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2853	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2854	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2855	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2856	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2857	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2858	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2859	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2860	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2861	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2862	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2863	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2864	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2865	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2866	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2867	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2868	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2869	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2870	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2871	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2872	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2873	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2874	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2875	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2876	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2877	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2878	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2879	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2880	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2881	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2882	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2883	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2884	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2885	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2886	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2887	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2888	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2889	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2890	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2891	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2892	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2893	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2894	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2895	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2896	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2897	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2898	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2899	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2900	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2901	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2902	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2903	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2904	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2905	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2906	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2907	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2908	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2909	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2910	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2911	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2912	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2913	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2914	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2915	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2916	{}
2917};
2918
2919/*
2920 * ALC880 codec presets
2921 */
2922static struct alc_config_preset alc880_presets[] = {
2923	[ALC880_3ST] = {
2924		.mixers = { alc880_three_stack_mixer },
2925		.init_verbs = { alc880_volume_init_verbs,
2926				alc880_pin_3stack_init_verbs },
2927		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2928		.dac_nids = alc880_dac_nids,
2929		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2930		.channel_mode = alc880_threestack_modes,
2931		.need_dac_fix = 1,
2932		.input_mux = &alc880_capture_source,
2933	},
2934	[ALC880_3ST_DIG] = {
2935		.mixers = { alc880_three_stack_mixer },
2936		.init_verbs = { alc880_volume_init_verbs,
2937				alc880_pin_3stack_init_verbs },
2938		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2939		.dac_nids = alc880_dac_nids,
2940		.dig_out_nid = ALC880_DIGOUT_NID,
2941		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2942		.channel_mode = alc880_threestack_modes,
2943		.need_dac_fix = 1,
2944		.input_mux = &alc880_capture_source,
2945	},
2946	[ALC880_TCL_S700] = {
2947		.mixers = { alc880_tcl_s700_mixer },
2948		.init_verbs = { alc880_volume_init_verbs,
2949				alc880_pin_tcl_S700_init_verbs,
2950				alc880_gpio2_init_verbs },
2951		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2952		.dac_nids = alc880_dac_nids,
2953		.hp_nid = 0x03,
2954		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2955		.channel_mode = alc880_2_jack_modes,
2956		.input_mux = &alc880_capture_source,
2957	},
2958	[ALC880_5ST] = {
2959		.mixers = { alc880_three_stack_mixer,
2960			    alc880_five_stack_mixer},
2961		.init_verbs = { alc880_volume_init_verbs,
2962				alc880_pin_5stack_init_verbs },
2963		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2964		.dac_nids = alc880_dac_nids,
2965		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2966		.channel_mode = alc880_fivestack_modes,
2967		.input_mux = &alc880_capture_source,
2968	},
2969	[ALC880_5ST_DIG] = {
2970		.mixers = { alc880_three_stack_mixer,
2971			    alc880_five_stack_mixer },
2972		.init_verbs = { alc880_volume_init_verbs,
2973				alc880_pin_5stack_init_verbs },
2974		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2975		.dac_nids = alc880_dac_nids,
2976		.dig_out_nid = ALC880_DIGOUT_NID,
2977		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2978		.channel_mode = alc880_fivestack_modes,
2979		.input_mux = &alc880_capture_source,
2980	},
2981	[ALC880_6ST] = {
2982		.mixers = { alc880_six_stack_mixer },
2983		.init_verbs = { alc880_volume_init_verbs,
2984				alc880_pin_6stack_init_verbs },
2985		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2986		.dac_nids = alc880_6st_dac_nids,
2987		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2988		.channel_mode = alc880_sixstack_modes,
2989		.input_mux = &alc880_6stack_capture_source,
2990	},
2991	[ALC880_6ST_DIG] = {
2992		.mixers = { alc880_six_stack_mixer },
2993		.init_verbs = { alc880_volume_init_verbs,
2994				alc880_pin_6stack_init_verbs },
2995		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2996		.dac_nids = alc880_6st_dac_nids,
2997		.dig_out_nid = ALC880_DIGOUT_NID,
2998		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2999		.channel_mode = alc880_sixstack_modes,
3000		.input_mux = &alc880_6stack_capture_source,
3001	},
3002	[ALC880_W810] = {
3003		.mixers = { alc880_w810_base_mixer },
3004		.init_verbs = { alc880_volume_init_verbs,
3005				alc880_pin_w810_init_verbs,
3006				alc880_gpio2_init_verbs },
3007		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3008		.dac_nids = alc880_w810_dac_nids,
3009		.dig_out_nid = ALC880_DIGOUT_NID,
3010		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3011		.channel_mode = alc880_w810_modes,
3012		.input_mux = &alc880_capture_source,
3013	},
3014	[ALC880_Z71V] = {
3015		.mixers = { alc880_z71v_mixer },
3016		.init_verbs = { alc880_volume_init_verbs,
3017				alc880_pin_z71v_init_verbs },
3018		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3019		.dac_nids = alc880_z71v_dac_nids,
3020		.dig_out_nid = ALC880_DIGOUT_NID,
3021		.hp_nid = 0x03,
3022		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3023		.channel_mode = alc880_2_jack_modes,
3024		.input_mux = &alc880_capture_source,
3025	},
3026	[ALC880_F1734] = {
3027		.mixers = { alc880_f1734_mixer },
3028		.init_verbs = { alc880_volume_init_verbs,
3029				alc880_pin_f1734_init_verbs },
3030		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3031		.dac_nids = alc880_f1734_dac_nids,
3032		.hp_nid = 0x02,
3033		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3034		.channel_mode = alc880_2_jack_modes,
3035		.input_mux = &alc880_capture_source,
3036	},
3037	[ALC880_ASUS] = {
3038		.mixers = { alc880_asus_mixer },
3039		.init_verbs = { alc880_volume_init_verbs,
3040				alc880_pin_asus_init_verbs,
3041				alc880_gpio1_init_verbs },
3042		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3043		.dac_nids = alc880_asus_dac_nids,
3044		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3045		.channel_mode = alc880_asus_modes,
3046		.need_dac_fix = 1,
3047		.input_mux = &alc880_capture_source,
3048	},
3049	[ALC880_ASUS_DIG] = {
3050		.mixers = { alc880_asus_mixer },
3051		.init_verbs = { alc880_volume_init_verbs,
3052				alc880_pin_asus_init_verbs,
3053				alc880_gpio1_init_verbs },
3054		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3055		.dac_nids = alc880_asus_dac_nids,
3056		.dig_out_nid = ALC880_DIGOUT_NID,
3057		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3058		.channel_mode = alc880_asus_modes,
3059		.need_dac_fix = 1,
3060		.input_mux = &alc880_capture_source,
3061	},
3062	[ALC880_ASUS_DIG2] = {
3063		.mixers = { alc880_asus_mixer },
3064		.init_verbs = { alc880_volume_init_verbs,
3065				alc880_pin_asus_init_verbs,
3066				alc880_gpio2_init_verbs }, /* use GPIO2 */
3067		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3068		.dac_nids = alc880_asus_dac_nids,
3069		.dig_out_nid = ALC880_DIGOUT_NID,
3070		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3071		.channel_mode = alc880_asus_modes,
3072		.need_dac_fix = 1,
3073		.input_mux = &alc880_capture_source,
3074	},
3075	[ALC880_ASUS_W1V] = {
3076		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3077		.init_verbs = { alc880_volume_init_verbs,
3078				alc880_pin_asus_init_verbs,
3079				alc880_gpio1_init_verbs },
3080		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3081		.dac_nids = alc880_asus_dac_nids,
3082		.dig_out_nid = ALC880_DIGOUT_NID,
3083		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3084		.channel_mode = alc880_asus_modes,
3085		.need_dac_fix = 1,
3086		.input_mux = &alc880_capture_source,
3087	},
3088	[ALC880_UNIWILL_DIG] = {
3089		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3090		.init_verbs = { alc880_volume_init_verbs,
3091				alc880_pin_asus_init_verbs },
3092		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3093		.dac_nids = alc880_asus_dac_nids,
3094		.dig_out_nid = ALC880_DIGOUT_NID,
3095		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3096		.channel_mode = alc880_asus_modes,
3097		.need_dac_fix = 1,
3098		.input_mux = &alc880_capture_source,
3099	},
3100	[ALC880_UNIWILL] = {
3101		.mixers = { alc880_uniwill_mixer },
3102		.init_verbs = { alc880_volume_init_verbs,
3103				alc880_uniwill_init_verbs },
3104		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3105		.dac_nids = alc880_asus_dac_nids,
3106		.dig_out_nid = ALC880_DIGOUT_NID,
3107		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3108		.channel_mode = alc880_threestack_modes,
3109		.need_dac_fix = 1,
3110		.input_mux = &alc880_capture_source,
3111		.unsol_event = alc880_uniwill_unsol_event,
3112		.init_hook = alc880_uniwill_automute,
3113	},
3114	[ALC880_UNIWILL_P53] = {
3115		.mixers = { alc880_uniwill_p53_mixer },
3116		.init_verbs = { alc880_volume_init_verbs,
3117				alc880_uniwill_p53_init_verbs },
3118		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3119		.dac_nids = alc880_asus_dac_nids,
3120		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3121		.channel_mode = alc880_threestack_modes,
3122		.input_mux = &alc880_capture_source,
3123		.unsol_event = alc880_uniwill_p53_unsol_event,
3124		.init_hook = alc880_uniwill_p53_hp_automute,
3125	},
3126	[ALC880_FUJITSU] = {
3127		.mixers = { alc880_fujitsu_mixer,
3128			    alc880_pcbeep_mixer, },
3129		.init_verbs = { alc880_volume_init_verbs,
3130				alc880_uniwill_p53_init_verbs,
3131	       			alc880_beep_init_verbs },
3132		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3133		.dac_nids = alc880_dac_nids,
3134		.dig_out_nid = ALC880_DIGOUT_NID,
3135		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3136		.channel_mode = alc880_2_jack_modes,
3137		.input_mux = &alc880_capture_source,
3138		.unsol_event = alc880_uniwill_p53_unsol_event,
3139		.init_hook = alc880_uniwill_p53_hp_automute,
3140	},
3141	[ALC880_CLEVO] = {
3142		.mixers = { alc880_three_stack_mixer },
3143		.init_verbs = { alc880_volume_init_verbs,
3144				alc880_pin_clevo_init_verbs },
3145		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3146		.dac_nids = alc880_dac_nids,
3147		.hp_nid = 0x03,
3148		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3149		.channel_mode = alc880_threestack_modes,
3150		.need_dac_fix = 1,
3151		.input_mux = &alc880_capture_source,
3152	},
3153	[ALC880_LG] = {
3154		.mixers = { alc880_lg_mixer },
3155		.init_verbs = { alc880_volume_init_verbs,
3156				alc880_lg_init_verbs },
3157		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3158		.dac_nids = alc880_lg_dac_nids,
3159		.dig_out_nid = ALC880_DIGOUT_NID,
3160		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3161		.channel_mode = alc880_lg_ch_modes,
3162		.need_dac_fix = 1,
3163		.input_mux = &alc880_lg_capture_source,
3164		.unsol_event = alc880_lg_unsol_event,
3165		.init_hook = alc880_lg_automute,
3166#ifdef CONFIG_SND_HDA_POWER_SAVE
3167		.loopbacks = alc880_lg_loopbacks,
3168#endif
3169	},
3170	[ALC880_LG_LW] = {
3171		.mixers = { alc880_lg_lw_mixer },
3172		.init_verbs = { alc880_volume_init_verbs,
3173				alc880_lg_lw_init_verbs },
3174		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3175		.dac_nids = alc880_dac_nids,
3176		.dig_out_nid = ALC880_DIGOUT_NID,
3177		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3178		.channel_mode = alc880_lg_lw_modes,
3179		.input_mux = &alc880_lg_lw_capture_source,
3180		.unsol_event = alc880_lg_lw_unsol_event,
3181		.init_hook = alc880_lg_lw_automute,
3182	},
3183#ifdef CONFIG_SND_DEBUG
3184	[ALC880_TEST] = {
3185		.mixers = { alc880_test_mixer },
3186		.init_verbs = { alc880_test_init_verbs },
3187		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3188		.dac_nids = alc880_test_dac_nids,
3189		.dig_out_nid = ALC880_DIGOUT_NID,
3190		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3191		.channel_mode = alc880_test_modes,
3192		.input_mux = &alc880_test_capture_source,
3193	},
3194#endif
3195};
3196
3197/*
3198 * Automatic parse of I/O pins from the BIOS configuration
3199 */
3200
3201#define NUM_CONTROL_ALLOC	32
3202#define NUM_VERB_ALLOC		32
3203
3204enum {
3205	ALC_CTL_WIDGET_VOL,
3206	ALC_CTL_WIDGET_MUTE,
3207	ALC_CTL_BIND_MUTE,
3208};
3209static struct snd_kcontrol_new alc880_control_templates[] = {
3210	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3211	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3212	HDA_BIND_MUTE(NULL, 0, 0, 0),
3213};
3214
3215/* add dynamic controls */
3216static int add_control(struct alc_spec *spec, int type, const char *name,
3217		       unsigned long val)
3218{
3219	struct snd_kcontrol_new *knew;
3220
3221	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3222		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3223
3224		/* array + terminator */
3225		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3226		if (!knew)
3227			return -ENOMEM;
3228		if (spec->kctl_alloc) {
3229			memcpy(knew, spec->kctl_alloc,
3230			       sizeof(*knew) * spec->num_kctl_alloc);
3231			kfree(spec->kctl_alloc);
3232		}
3233		spec->kctl_alloc = knew;
3234		spec->num_kctl_alloc = num;
3235	}
3236
3237	knew = &spec->kctl_alloc[spec->num_kctl_used];
3238	*knew = alc880_control_templates[type];
3239	knew->name = kstrdup(name, GFP_KERNEL);
3240	if (!knew->name)
3241		return -ENOMEM;
3242	knew->private_value = val;
3243	spec->num_kctl_used++;
3244	return 0;
3245}
3246
3247#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3248#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3249#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3250#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3251#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3252#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3253#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3254#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3255#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3256#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3257#define ALC880_PIN_CD_NID		0x1c
3258
3259/* fill in the dac_nids table from the parsed pin configuration */
3260static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3261				     const struct auto_pin_cfg *cfg)
3262{
3263	hda_nid_t nid;
3264	int assigned[4];
3265	int i, j;
3266
3267	memset(assigned, 0, sizeof(assigned));
3268	spec->multiout.dac_nids = spec->private_dac_nids;
3269
3270	/* check the pins hardwired to audio widget */
3271	for (i = 0; i < cfg->line_outs; i++) {
3272		nid = cfg->line_out_pins[i];
3273		if (alc880_is_fixed_pin(nid)) {
3274			int idx = alc880_fixed_pin_idx(nid);
3275			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3276			assigned[idx] = 1;
3277		}
3278	}
3279	/* left pins can be connect to any audio widget */
3280	for (i = 0; i < cfg->line_outs; i++) {
3281		nid = cfg->line_out_pins[i];
3282		if (alc880_is_fixed_pin(nid))
3283			continue;
3284		/* search for an empty channel */
3285		for (j = 0; j < cfg->line_outs; j++) {
3286			if (!assigned[j]) {
3287				spec->multiout.dac_nids[i] =
3288					alc880_idx_to_dac(j);
3289				assigned[j] = 1;
3290				break;
3291			}
3292		}
3293	}
3294	spec->multiout.num_dacs = cfg->line_outs;
3295	return 0;
3296}
3297
3298/* add playback controls from the parsed DAC table */
3299static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3300					     const struct auto_pin_cfg *cfg)
3301{
3302	char name[32];
3303	static const char *chname[4] = {
3304		"Front", "Surround", NULL /*CLFE*/, "Side"
3305	};
3306	hda_nid_t nid;
3307	int i, err;
3308
3309	for (i = 0; i < cfg->line_outs; i++) {
3310		if (!spec->multiout.dac_nids[i])
3311			continue;
3312		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3313		if (i == 2) {
3314			/* Center/LFE */
3315			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3316					  "Center Playback Volume",
3317					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3318							      HDA_OUTPUT));
3319			if (err < 0)
3320				return err;
3321			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3322					  "LFE Playback Volume",
3323					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3324							      HDA_OUTPUT));
3325			if (err < 0)
3326				return err;
3327			err = add_control(spec, ALC_CTL_BIND_MUTE,
3328					  "Center Playback Switch",
3329					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3330							      HDA_INPUT));
3331			if (err < 0)
3332				return err;
3333			err = add_control(spec, ALC_CTL_BIND_MUTE,
3334					  "LFE Playback Switch",
3335					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3336							      HDA_INPUT));
3337			if (err < 0)
3338				return err;
3339		} else {
3340			sprintf(name, "%s Playback Volume", chname[i]);
3341			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3342					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3343							      HDA_OUTPUT));
3344			if (err < 0)
3345				return err;
3346			sprintf(name, "%s Playback Switch", chname[i]);
3347			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3348					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3349							      HDA_INPUT));
3350			if (err < 0)
3351				return err;
3352		}
3353	}
3354	return 0;
3355}
3356
3357/* add playback controls for speaker and HP outputs */
3358static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3359					const char *pfx)
3360{
3361	hda_nid_t nid;
3362	int err;
3363	char name[32];
3364
3365	if (!pin)
3366		return 0;
3367
3368	if (alc880_is_fixed_pin(pin)) {
3369		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3370		/* specify the DAC as the extra output */
3371		if (!spec->multiout.hp_nid)
3372			spec->multiout.hp_nid = nid;
3373		else
3374			spec->multiout.extra_out_nid[0] = nid;
3375		/* control HP volume/switch on the output mixer amp */
3376		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3377		sprintf(name, "%s Playback Volume", pfx);
3378		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3379				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3380		if (err < 0)
3381			return err;
3382		sprintf(name, "%s Playback Switch", pfx);
3383		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3384				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3385		if (err < 0)
3386			return err;
3387	} else if (alc880_is_multi_pin(pin)) {
3388		/* set manual connection */
3389		/* we have only a switch on HP-out PIN */
3390		sprintf(name, "%s Playback Switch", pfx);
3391		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3392				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3393		if (err < 0)
3394			return err;
3395	}
3396	return 0;
3397}
3398
3399/* create input playback/capture controls for the given pin */
3400static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3401			    const char *ctlname,
3402			    int idx, hda_nid_t mix_nid)
3403{
3404	char name[32];
3405	int err;
3406
3407	sprintf(name, "%s Playback Volume", ctlname);
3408	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3409			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3410	if (err < 0)
3411		return err;
3412	sprintf(name, "%s Playback Switch", ctlname);
3413	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3414			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3415	if (err < 0)
3416		return err;
3417	return 0;
3418}
3419
3420/* create playback/capture controls for input pins */
3421static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3422						const struct auto_pin_cfg *cfg)
3423{
3424	struct hda_input_mux *imux = &spec->private_imux;
3425	int i, err, idx;
3426
3427	for (i = 0; i < AUTO_PIN_LAST; i++) {
3428		if (alc880_is_input_pin(cfg->input_pins[i])) {
3429			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3430			err = new_analog_input(spec, cfg->input_pins[i],
3431					       auto_pin_cfg_labels[i],
3432					       idx, 0x0b);
3433			if (err < 0)
3434				return err;
3435			imux->items[imux->num_items].label =
3436				auto_pin_cfg_labels[i];
3437			imux->items[imux->num_items].index =
3438				alc880_input_pin_idx(cfg->input_pins[i]);
3439			imux->num_items++;
3440		}
3441	}
3442	return 0;
3443}
3444
3445static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3446					      hda_nid_t nid, int pin_type,
3447					      int dac_idx)
3448{
3449	/* set as output */
3450	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3451			    pin_type);
3452	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3453			    AMP_OUT_UNMUTE);
3454	/* need the manual connection? */
3455	if (alc880_is_multi_pin(nid)) {
3456		struct alc_spec *spec = codec->spec;
3457		int idx = alc880_multi_pin_idx(nid);
3458		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3459				    AC_VERB_SET_CONNECT_SEL,
3460				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3461	}
3462}
3463
3464static int get_pin_type(int line_out_type)
3465{
3466	if (line_out_type == AUTO_PIN_HP_OUT)
3467		return PIN_HP;
3468	else
3469		return PIN_OUT;
3470}
3471
3472static void alc880_auto_init_multi_out(struct hda_codec *codec)
3473{
3474	struct alc_spec *spec = codec->spec;
3475	int i;
3476
3477	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3478	for (i = 0; i < spec->autocfg.line_outs; i++) {
3479		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3480		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3481		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3482	}
3483}
3484
3485static void alc880_auto_init_extra_out(struct hda_codec *codec)
3486{
3487	struct alc_spec *spec = codec->spec;
3488	hda_nid_t pin;
3489
3490	pin = spec->autocfg.speaker_pins[0];
3491	if (pin) /* connect to front */
3492		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3493	pin = spec->autocfg.hp_pins[0];
3494	if (pin) /* connect to front */
3495		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3496}
3497
3498static void alc880_auto_init_analog_input(struct hda_codec *codec)
3499{
3500	struct alc_spec *spec = codec->spec;
3501	int i;
3502
3503	for (i = 0; i < AUTO_PIN_LAST; i++) {
3504		hda_nid_t nid = spec->autocfg.input_pins[i];
3505		if (alc880_is_input_pin(nid)) {
3506			snd_hda_codec_write(codec, nid, 0,
3507					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3508					    i <= AUTO_PIN_FRONT_MIC ?
3509					    PIN_VREF80 : PIN_IN);
3510			if (nid != ALC880_PIN_CD_NID)
3511				snd_hda_codec_write(codec, nid, 0,
3512						    AC_VERB_SET_AMP_GAIN_MUTE,
3513						    AMP_OUT_MUTE);
3514		}
3515	}
3516}
3517
3518/* parse the BIOS configuration and set up the alc_spec */
3519/* return 1 if successful, 0 if the proper config is not found,
3520 * or a negative error code
3521 */
3522static int alc880_parse_auto_config(struct hda_codec *codec)
3523{
3524	struct alc_spec *spec = codec->spec;
3525	int err;
3526	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3527
3528	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3529					   alc880_ignore);
3530	if (err < 0)
3531		return err;
3532	if (!spec->autocfg.line_outs)
3533		return 0; /* can't find valid BIOS pin config */
3534
3535	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3536	if (err < 0)
3537		return err;
3538	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3539	if (err < 0)
3540		return err;
3541	err = alc880_auto_create_extra_out(spec,
3542					   spec->autocfg.speaker_pins[0],
3543					   "Speaker");
3544	if (err < 0)
3545		return err;
3546	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3547					   "Headphone");
3548	if (err < 0)
3549		return err;
3550	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3551	if (err < 0)
3552		return err;
3553
3554	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3555
3556	if (spec->autocfg.dig_out_pin)
3557		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3558	if (spec->autocfg.dig_in_pin)
3559		spec->dig_in_nid = ALC880_DIGIN_NID;
3560
3561	if (spec->kctl_alloc)
3562		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3563
3564	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3565
3566	spec->num_mux_defs = 1;
3567	spec->input_mux = &spec->private_imux;
3568
3569	return 1;
3570}
3571
3572/* additional initialization for auto-configuration model */
3573static void alc880_auto_init(struct hda_codec *codec)
3574{
3575	alc880_auto_init_multi_out(codec);
3576	alc880_auto_init_extra_out(codec);
3577	alc880_auto_init_analog_input(codec);
3578}
3579
3580/*
3581 * OK, here we have finally the patch for ALC880
3582 */
3583
3584static int patch_alc880(struct hda_codec *codec)
3585{
3586	struct alc_spec *spec;
3587	int board_config;
3588	int err;
3589
3590	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3591	if (spec == NULL)
3592		return -ENOMEM;
3593
3594	codec->spec = spec;
3595
3596	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3597						  alc880_models,
3598						  alc880_cfg_tbl);
3599	if (board_config < 0) {
3600		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3601		       "trying auto-probe from BIOS...\n");
3602		board_config = ALC880_AUTO;
3603	}
3604
3605	if (board_config == ALC880_AUTO) {
3606		/* automatic parse from the BIOS config */
3607		err = alc880_parse_auto_config(codec);
3608		if (err < 0) {
3609			alc_free(codec);
3610			return err;
3611		} else if (!err) {
3612			printk(KERN_INFO
3613			       "hda_codec: Cannot set up configuration "
3614			       "from BIOS.  Using 3-stack mode...\n");
3615			board_config = ALC880_3ST;
3616		}
3617	}
3618
3619	if (board_config != ALC880_AUTO)
3620		setup_preset(spec, &alc880_presets[board_config]);
3621
3622	spec->stream_name_analog = "ALC880 Analog";
3623	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3624	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3625
3626	spec->stream_name_digital = "ALC880 Digital";
3627	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3628	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3629
3630	if (!spec->adc_nids && spec->input_mux) {
3631		/* check whether NID 0x07 is valid */
3632		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3633		/* get type */
3634		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3635		if (wcap != AC_WID_AUD_IN) {
3636			spec->adc_nids = alc880_adc_nids_alt;
3637			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3638			spec->mixers[spec->num_mixers] =
3639				alc880_capture_alt_mixer;
3640			spec->num_mixers++;
3641		} else {
3642			spec->adc_nids = alc880_adc_nids;
3643			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3644			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3645			spec->num_mixers++;
3646		}
3647	}
3648
3649	spec->vmaster_nid = 0x0c;
3650
3651	codec->patch_ops = alc_patch_ops;
3652	if (board_config == ALC880_AUTO)
3653		spec->init_hook = alc880_auto_init;
3654#ifdef CONFIG_SND_HDA_POWER_SAVE
3655	if (!spec->loopback.amplist)
3656		spec->loopback.amplist = alc880_loopbacks;
3657#endif
3658
3659	return 0;
3660}
3661
3662
3663/*
3664 * ALC260 support
3665 */
3666
3667static hda_nid_t alc260_dac_nids[1] = {
3668	/* front */
3669	0x02,
3670};
3671
3672static hda_nid_t alc260_adc_nids[1] = {
3673	/* ADC0 */
3674	0x04,
3675};
3676
3677static hda_nid_t alc260_adc_nids_alt[1] = {
3678	/* ADC1 */
3679	0x05,
3680};
3681
3682static hda_nid_t alc260_hp_adc_nids[2] = {
3683	/* ADC1, 0 */
3684	0x05, 0x04
3685};
3686
3687/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3688 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3689 */
3690static hda_nid_t alc260_dual_adc_nids[2] = {
3691	/* ADC0, ADC1 */
3692	0x04, 0x05
3693};
3694
3695#define ALC260_DIGOUT_NID	0x03
3696#define ALC260_DIGIN_NID	0x06
3697
3698static struct hda_input_mux alc260_capture_source = {
3699	.num_items = 4,
3700	.items = {
3701		{ "Mic", 0x0 },
3702		{ "Front Mic", 0x1 },
3703		{ "Line", 0x2 },
3704		{ "CD", 0x4 },
3705	},
3706};
3707
3708/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3709 * headphone jack and the internal CD lines since these are the only pins at
3710 * which audio can appear.  For flexibility, also allow the option of
3711 * recording the mixer output on the second ADC (ADC0 doesn't have a
3712 * connection to the mixer output).
3713 */
3714static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3715	{
3716		.num_items = 3,
3717		.items = {
3718			{ "Mic/Line", 0x0 },
3719			{ "CD", 0x4 },
3720			{ "Headphone", 0x2 },
3721		},
3722	},
3723	{
3724		.num_items = 4,
3725		.items = {
3726			{ "Mic/Line", 0x0 },
3727			{ "CD", 0x4 },
3728			{ "Headphone", 0x2 },
3729			{ "Mixer", 0x5 },
3730		},
3731	},
3732
3733};
3734
3735/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3736 * the Fujitsu S702x, but jacks are marked differently.
3737 */
3738static struct hda_input_mux alc260_acer_capture_sources[2] = {
3739	{
3740		.num_items = 4,
3741		.items = {
3742			{ "Mic", 0x0 },
3743			{ "Line", 0x2 },
3744			{ "CD", 0x4 },
3745			{ "Headphone", 0x5 },
3746		},
3747	},
3748	{
3749		.num_items = 5,
3750		.items = {
3751			{ "Mic", 0x0 },
3752			{ "Line", 0x2 },
3753			{ "CD", 0x4 },
3754			{ "Headphone", 0x6 },
3755			{ "Mixer", 0x5 },
3756		},
3757	},
3758};
3759/*
3760 * This is just place-holder, so there's something for alc_build_pcms to look
3761 * at when it calculates the maximum number of channels. ALC260 has no mixer
3762 * element which allows changing the channel mode, so the verb list is
3763 * never used.
3764 */
3765static struct hda_channel_mode alc260_modes[1] = {
3766	{ 2, NULL },
3767};
3768
3769
3770/* Mixer combinations
3771 *
3772 * basic: base_output + input + pc_beep + capture
3773 * HP: base_output + input + capture_alt
3774 * HP_3013: hp_3013 + input + capture
3775 * fujitsu: fujitsu + capture
3776 * acer: acer + capture
3777 */
3778
3779static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3780	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3781	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3782	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3783	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3784	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3785	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3786	{ } /* end */
3787};
3788
3789static struct snd_kcontrol_new alc260_input_mixer[] = {
3790	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3791	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3792	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3793	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3794	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3795	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3796	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3797	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3798	{ } /* end */
3799};
3800
3801static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3802	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3803	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3804	{ } /* end */
3805};
3806
3807static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3808	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3809	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3810	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3811	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3812	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3813	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3814	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3815	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3816	{ } /* end */
3817};
3818
3819/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3820 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3821 */
3822static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3823	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3824	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3825	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3826	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3827	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3828	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3829	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3830	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3831	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3832	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3833	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3834	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3835	{ } /* end */
3836};
3837
3838/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3839 * versions of the ALC260 don't act on requests to enable mic bias from NID
3840 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3841 * datasheet doesn't mention this restriction.  At this stage it's not clear
3842 * whether this behaviour is intentional or is a hardware bug in chip
3843 * revisions available in early 2006.  Therefore for now allow the
3844 * "Headphone Jack Mode" control to span all choices, but if it turns out
3845 * that the lack of mic bias for this NID is intentional we could change the
3846 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3847 *
3848 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3849 * don't appear to make the mic bias available from the "line" jack, even
3850 * though the NID used for this jack (0x14) can supply it.  The theory is
3851 * that perhaps Acer have included blocking capacitors between the ALC260
3852 * and the output jack.  If this turns out to be the case for all such
3853 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3854 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3855 *
3856 * The C20x Tablet series have a mono internal speaker which is controlled
3857 * via the chip's Mono sum widget and pin complex, so include the necessary
3858 * controls for such models.  On models without a "mono speaker" the control
3859 * won't do anything.
3860 */
3861static struct snd_kcontrol_new alc260_acer_mixer[] = {
3862	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3863	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3864	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3865	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3866			      HDA_OUTPUT),
3867	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3868			   HDA_INPUT),
3869	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3870	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3871	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3872	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3873	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3874	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3875	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3876	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3877	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3878	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3879	{ } /* end */
3880};
3881
3882/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3883 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3884 */
3885static struct snd_kcontrol_new alc260_will_mixer[] = {
3886	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3887	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3888	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3889	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3890	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3891	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3892	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3893	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3894	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3895	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3896	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3897	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3898	{ } /* end */
3899};
3900
3901/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3902 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3903 */
3904static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3905	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3906	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3907	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3908	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3909	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3910	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3911	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3912	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3913	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3914	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3915	{ } /* end */
3916};
3917
3918/* capture mixer elements */
3919static struct snd_kcontrol_new alc260_capture_mixer[] = {
3920	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3921	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3922	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3923	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3924	{
3925		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3926		/* The multiple "Capture Source" controls confuse alsamixer
3927		 * So call somewhat different..
3928		 * FIXME: the controls appear in the "playback" view!
3929		 */
3930		/* .name = "Capture Source", */
3931		.name = "Input Source",
3932		.count = 2,
3933		.info = alc_mux_enum_info,
3934		.get = alc_mux_enum_get,
3935		.put = alc_mux_enum_put,
3936	},
3937	{ } /* end */
3938};
3939
3940static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3941	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3942	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3943	{
3944		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3945		/* The multiple "Capture Source" controls confuse alsamixer
3946		 * So call somewhat different..
3947		 * FIXME: the controls appear in the "playback" view!
3948		 */
3949		/* .name = "Capture Source", */
3950		.name = "Input Source",
3951		.count = 1,
3952		.info = alc_mux_enum_info,
3953		.get = alc_mux_enum_get,
3954		.put = alc_mux_enum_put,
3955	},
3956	{ } /* end */
3957};
3958
3959/*
3960 * initialization verbs
3961 */
3962static struct hda_verb alc260_init_verbs[] = {
3963	/* Line In pin widget for input */
3964	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3965	/* CD pin widget for input */
3966	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3967	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3968	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3969	/* Mic2 (front panel) pin widget for input and vref at 80% */
3970	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3971	/* LINE-2 is used for line-out in rear */
3972	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3973	/* select line-out */
3974	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3975	/* LINE-OUT pin */
3976	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3977	/* enable HP */
3978	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3979	/* enable Mono */
3980	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3981	/* mute capture amp left and right */
3982	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3983	/* set connection select to line in (default select for this ADC) */
3984	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3985	/* mute capture amp left and right */
3986	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3987	/* set connection select to line in (default select for this ADC) */
3988	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3989	/* set vol=0 Line-Out mixer amp left and right */
3990	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3991	/* unmute pin widget amp left and right (no gain on this amp) */
3992	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3993	/* set vol=0 HP mixer amp left and right */
3994	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3995	/* unmute pin widget amp left and right (no gain on this amp) */
3996	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3997	/* set vol=0 Mono mixer amp left and right */
3998	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3999	/* unmute pin widget amp left and right (no gain on this amp) */
4000	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4001	/* unmute LINE-2 out pin */
4002	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4003	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4004	 * Line In 2 = 0x03
4005	 */
4006	/* mute analog inputs */
4007	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4008	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4009	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4010	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4011	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4012	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4013	/* mute Front out path */
4014	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4015	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4016	/* mute Headphone out path */
4017	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4018	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4019	/* mute Mono out path */
4020	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4021	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4022	{ }
4023};
4024
4025#if 0 /* should be identical with alc260_init_verbs? */
4026static struct hda_verb alc260_hp_init_verbs[] = {
4027	/* Headphone and output */
4028	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4029	/* mono output */
4030	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4031	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4032	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4033	/* Mic2 (front panel) pin widget for input and vref at 80% */
4034	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4035	/* Line In pin widget for input */
4036	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4037	/* Line-2 pin widget for output */
4038	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4039	/* CD pin widget for input */
4040	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4041	/* unmute amp left and right */
4042	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4043	/* set connection select to line in (default select for this ADC) */
4044	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4045	/* unmute Line-Out mixer amp left and right (volume = 0) */
4046	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4047	/* mute pin widget amp left and right (no gain on this amp) */
4048	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4049	/* unmute HP mixer amp left and right (volume = 0) */
4050	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4051	/* mute pin widget amp left and right (no gain on this amp) */
4052	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4053	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4054	 * Line In 2 = 0x03
4055	 */
4056	/* mute analog inputs */
4057	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4058	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4059	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4060	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4061	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4062	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4063	/* Unmute Front out path */
4064	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4065	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4066	/* Unmute Headphone out path */
4067	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4068	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4069	/* Unmute Mono out path */
4070	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4071	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4072	{ }
4073};
4074#endif
4075
4076static struct hda_verb alc260_hp_3013_init_verbs[] = {
4077	/* Line out and output */
4078	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4079	/* mono output */
4080	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4081	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4082	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4083	/* Mic2 (front panel) pin widget for input and vref at 80% */
4084	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4085	/* Line In pin widget for input */
4086	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4087	/* Headphone pin widget for output */
4088	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4089	/* CD pin widget for input */
4090	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4091	/* unmute amp left and right */
4092	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4093	/* set connection select to line in (default select for this ADC) */
4094	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4095	/* unmute Line-Out mixer amp left and right (volume = 0) */
4096	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4097	/* mute pin widget amp left and right (no gain on this amp) */
4098	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4099	/* unmute HP mixer amp left and right (volume = 0) */
4100	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4101	/* mute pin widget amp left and right (no gain on this amp) */
4102	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4103	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4104	 * Line In 2 = 0x03
4105	 */
4106	/* mute analog inputs */
4107	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4108	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4109	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4110	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4111	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4112	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4113	/* Unmute Front out path */
4114	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4115	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4116	/* Unmute Headphone out path */
4117	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4118	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4119	/* Unmute Mono out path */
4120	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4121	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4122	{ }
4123};
4124
4125/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4126 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4127 * audio = 0x16, internal speaker = 0x10.
4128 */
4129static struct hda_verb alc260_fujitsu_init_verbs[] = {
4130	/* Disable all GPIOs */
4131	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4132	/* Internal speaker is connected to headphone pin */
4133	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4134	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4135	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4136	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4137	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4138	/* Ensure all other unused pins are disabled and muted. */
4139	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4140	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4141	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4142	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4143	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4144	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4145	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4146	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4147
4148	/* Disable digital (SPDIF) pins */
4149	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4150	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4151
4152	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4153	 * when acting as an output.
4154	 */
4155	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4156
4157	/* Start with output sum widgets muted and their output gains at min */
4158	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4159	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4160	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4161	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4162	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4163	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4164	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4165	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4166	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4167
4168	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4169	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4170	/* Unmute Line1 pin widget output buffer since it starts as an output.
4171	 * If the pin mode is changed by the user the pin mode control will
4172	 * take care of enabling the pin's input/output buffers as needed.
4173	 * Therefore there's no need to enable the input buffer at this
4174	 * stage.
4175	 */
4176	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4177	/* Unmute input buffer of pin widget used for Line-in (no equiv
4178	 * mixer ctrl)
4179	 */
4180	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4181
4182	/* Mute capture amp left and right */
4183	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4184	/* Set ADC connection select to match default mixer setting - line
4185	 * in (on mic1 pin)
4186	 */
4187	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4188
4189	/* Do the same for the second ADC: mute capture input amp and
4190	 * set ADC connection to line in (on mic1 pin)
4191	 */
4192	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4193	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4194
4195	/* Mute all inputs to mixer widget (even unconnected ones) */
4196	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4197	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4198	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4199	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4200	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4201	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4202	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4203	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4204
4205	{ }
4206};
4207
4208/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4209 * similar laptops (adapted from Fujitsu init verbs).
4210 */
4211static struct hda_verb alc260_acer_init_verbs[] = {
4212	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4213	 * the headphone jack.  Turn this on and rely on the standard mute
4214	 * methods whenever the user wants to turn these outputs off.
4215	 */
4216	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4217	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4218	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4219	/* Internal speaker/Headphone jack is connected to Line-out pin */
4220	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4221	/* Internal microphone/Mic jack is connected to Mic1 pin */
4222	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4223	/* Line In jack is connected to Line1 pin */
4224	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4225	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4226	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4227	/* Ensure all other unused pins are disabled and muted. */
4228	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4229	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4230	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4231	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4232	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4233	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4234	/* Disable digital (SPDIF) pins */
4235	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4236	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4237
4238	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4239	 * bus when acting as outputs.
4240	 */
4241	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4242	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4243
4244	/* Start with output sum widgets muted and their output gains at min */
4245	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4246	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4247	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4248	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4249	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4250	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4251	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4252	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4253	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4254
4255	/* Unmute Line-out pin widget amp left and right
4256	 * (no equiv mixer ctrl)
4257	 */
4258	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4259	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4260	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4261	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4262	 * inputs. If the pin mode is changed by the user the pin mode control
4263	 * will take care of enabling the pin's input/output buffers as needed.
4264	 * Therefore there's no need to enable the input buffer at this
4265	 * stage.
4266	 */
4267	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4268	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4269
4270	/* Mute capture amp left and right */
4271	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4272	/* Set ADC connection select to match default mixer setting - mic
4273	 * (on mic1 pin)
4274	 */
4275	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4276
4277	/* Do similar with the second ADC: mute capture input amp and
4278	 * set ADC connection to mic to match ALSA's default state.
4279	 */
4280	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4281	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4282
4283	/* Mute all inputs to mixer widget (even unconnected ones) */
4284	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4285	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4286	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4287	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4288	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4289	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4290	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4291	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4292
4293	{ }
4294};
4295
4296static struct hda_verb alc260_will_verbs[] = {
4297	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4298	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4299	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4300	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4301	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4302	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4303	{}
4304};
4305
4306static struct hda_verb alc260_replacer_672v_verbs[] = {
4307	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4308	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4309	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4310
4311	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4312	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4313	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4314
4315	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4316	{}
4317};
4318
4319/* toggle speaker-output according to the hp-jack state */
4320static void alc260_replacer_672v_automute(struct hda_codec *codec)
4321{
4322        unsigned int present;
4323
4324	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4325        present = snd_hda_codec_read(codec, 0x0f, 0,
4326                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4327	if (present) {
4328		snd_hda_codec_write_cache(codec, 0x01, 0,
4329					  AC_VERB_SET_GPIO_DATA, 1);
4330		snd_hda_codec_write_cache(codec, 0x0f, 0,
4331					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4332					  PIN_HP);
4333	} else {
4334		snd_hda_codec_write_cache(codec, 0x01, 0,
4335					  AC_VERB_SET_GPIO_DATA, 0);
4336		snd_hda_codec_write_cache(codec, 0x0f, 0,
4337					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4338					  PIN_OUT);
4339	}
4340}
4341
4342static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4343                                       unsigned int res)
4344{
4345        if ((res >> 26) == ALC880_HP_EVENT)
4346                alc260_replacer_672v_automute(codec);
4347}
4348
4349/* Test configuration for debugging, modelled after the ALC880 test
4350 * configuration.
4351 */
4352#ifdef CONFIG_SND_DEBUG
4353static hda_nid_t alc260_test_dac_nids[1] = {
4354	0x02,
4355};
4356static hda_nid_t alc260_test_adc_nids[2] = {
4357	0x04, 0x05,
4358};
4359/* For testing the ALC260, each input MUX needs its own definition since
4360 * the signal assignments are different.  This assumes that the first ADC
4361 * is NID 0x04.
4362 */
4363static struct hda_input_mux alc260_test_capture_sources[2] = {
4364	{
4365		.num_items = 7,
4366		.items = {
4367			{ "MIC1 pin", 0x0 },
4368			{ "MIC2 pin", 0x1 },
4369			{ "LINE1 pin", 0x2 },
4370			{ "LINE2 pin", 0x3 },
4371			{ "CD pin", 0x4 },
4372			{ "LINE-OUT pin", 0x5 },
4373			{ "HP-OUT pin", 0x6 },
4374		},
4375        },
4376	{
4377		.num_items = 8,
4378		.items = {
4379			{ "MIC1 pin", 0x0 },
4380			{ "MIC2 pin", 0x1 },
4381			{ "LINE1 pin", 0x2 },
4382			{ "LINE2 pin", 0x3 },
4383			{ "CD pin", 0x4 },
4384			{ "Mixer", 0x5 },
4385			{ "LINE-OUT pin", 0x6 },
4386			{ "HP-OUT pin", 0x7 },
4387		},
4388        },
4389};
4390static struct snd_kcontrol_new alc260_test_mixer[] = {
4391	/* Output driver widgets */
4392	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4393	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4394	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4395	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4396	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4397	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4398
4399	/* Modes for retasking pin widgets
4400	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4401         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4402         * mention this restriction.  At this stage it's not clear whether
4403         * this behaviour is intentional or is a hardware bug in chip
4404         * revisions available at least up until early 2006.  Therefore for
4405         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4406         * choices, but if it turns out that the lack of mic bias for these
4407         * NIDs is intentional we could change their modes from
4408         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4409	 */
4410	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4411	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4412	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4413	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4414	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4415	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4416
4417	/* Loopback mixer controls */
4418	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4419	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4420	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4421	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4422	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4423	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4424	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4425	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4426	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4427	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4428	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4429	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4430	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4431	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4432	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4433	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4434
4435	/* Controls for GPIO pins, assuming they are configured as outputs */
4436	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4437	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4438	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4439	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4440
4441	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4442	 * is ambigious as to which NID is which; testing on laptops which
4443	 * make this output available should provide clarification.
4444	 */
4445	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4446	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4447
4448	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
4449	 * this output to turn on an external amplifier.
4450	 */
4451	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4452	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4453
4454	{ } /* end */
4455};
4456static struct hda_verb alc260_test_init_verbs[] = {
4457	/* Enable all GPIOs as outputs with an initial value of 0 */
4458	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4459	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4460	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4461
4462	/* Enable retasking pins as output, initially without power amp */
4463	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4464	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4465	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4466	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4467	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4468	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4469
4470	/* Disable digital (SPDIF) pins initially, but users can enable
4471	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4472	 * payload also sets the generation to 0, output to be in "consumer"
4473	 * PCM format, copyright asserted, no pre-emphasis and no validity
4474	 * control.
4475	 */
4476	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4477	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4478
4479	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4480	 * OUT1 sum bus when acting as an output.
4481	 */
4482	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4483	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4484	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4485	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4486
4487	/* Start with output sum widgets muted and their output gains at min */
4488	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4489	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4490	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4491	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4492	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4493	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4494	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4495	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4496	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4497
4498	/* Unmute retasking pin widget output buffers since the default
4499	 * state appears to be output.  As the pin mode is changed by the
4500	 * user the pin mode control will take care of enabling the pin's
4501	 * input/output buffers as needed.
4502	 */
4503	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4504	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4505	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4506	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4507	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4508	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4509	/* Also unmute the mono-out pin widget */
4510	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4511
4512	/* Mute capture amp left and right */
4513	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4514	/* Set ADC connection select to match default mixer setting (mic1
4515	 * pin)
4516	 */
4517	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4518
4519	/* Do the same for the second ADC: mute capture input amp and
4520	 * set ADC connection to mic1 pin
4521	 */
4522	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4523	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4524
4525	/* Mute all inputs to mixer widget (even unconnected ones) */
4526	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4527	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4528	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4529	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4530	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4531	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4532	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4533	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4534
4535	{ }
4536};
4537#endif
4538
4539static struct hda_pcm_stream alc260_pcm_analog_playback = {
4540	.substreams = 1,
4541	.channels_min = 2,
4542	.channels_max = 2,
4543};
4544
4545static struct hda_pcm_stream alc260_pcm_analog_capture = {
4546	.substreams = 1,
4547	.channels_min = 2,
4548	.channels_max = 2,
4549};
4550
4551#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4552#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4553
4554/*
4555 * for BIOS auto-configuration
4556 */
4557
4558static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4559					const char *pfx)
4560{
4561	hda_nid_t nid_vol;
4562	unsigned long vol_val, sw_val;
4563	char name[32];
4564	int err;
4565
4566	if (nid >= 0x0f && nid < 0x11) {
4567		nid_vol = nid - 0x7;
4568		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4569		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4570	} else if (nid == 0x11) {
4571		nid_vol = nid - 0x7;
4572		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4573		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4574	} else if (nid >= 0x12 && nid <= 0x15) {
4575		nid_vol = 0x08;
4576		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4577		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4578	} else
4579		return 0; /* N/A */
4580
4581	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4582	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4583	if (err < 0)
4584		return err;
4585	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4586	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4587	if (err < 0)
4588		return err;
4589	return 1;
4590}
4591
4592/* add playback controls from the parsed DAC table */
4593static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4594					     const struct auto_pin_cfg *cfg)
4595{
4596	hda_nid_t nid;
4597	int err;
4598
4599	spec->multiout.num_dacs = 1;
4600	spec->multiout.dac_nids = spec->private_dac_nids;
4601	spec->multiout.dac_nids[0] = 0x02;
4602
4603	nid = cfg->line_out_pins[0];
4604	if (nid) {
4605		err = alc260_add_playback_controls(spec, nid, "Front");
4606		if (err < 0)
4607			return err;
4608	}
4609
4610	nid = cfg->speaker_pins[0];
4611	if (nid) {
4612		err = alc260_add_playback_controls(spec, nid, "Speaker");
4613		if (err < 0)
4614			return err;
4615	}
4616
4617	nid = cfg->hp_pins[0];
4618	if (nid) {
4619		err = alc260_add_playback_controls(spec, nid, "Headphone");
4620		if (err < 0)
4621			return err;
4622	}
4623	return 0;
4624}
4625
4626/* create playback/capture controls for input pins */
4627static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4628						const struct auto_pin_cfg *cfg)
4629{
4630	struct hda_input_mux *imux = &spec->private_imux;
4631	int i, err, idx;
4632
4633	for (i = 0; i < AUTO_PIN_LAST; i++) {
4634		if (cfg->input_pins[i] >= 0x12) {
4635			idx = cfg->input_pins[i] - 0x12;
4636			err = new_analog_input(spec, cfg->input_pins[i],
4637					       auto_pin_cfg_labels[i], idx,
4638					       0x07);
4639			if (err < 0)
4640				return err;
4641			imux->items[imux->num_items].label =
4642				auto_pin_cfg_labels[i];
4643			imux->items[imux->num_items].index = idx;
4644			imux->num_items++;
4645		}
4646		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4647			idx = cfg->input_pins[i] - 0x09;
4648			err = new_analog_input(spec, cfg->input_pins[i],
4649					       auto_pin_cfg_labels[i], idx,
4650					       0x07);
4651			if (err < 0)
4652				return err;
4653			imux->items[imux->num_items].label =
4654				auto_pin_cfg_labels[i];
4655			imux->items[imux->num_items].index = idx;
4656			imux->num_items++;
4657		}
4658	}
4659	return 0;
4660}
4661
4662static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4663					      hda_nid_t nid, int pin_type,
4664					      int sel_idx)
4665{
4666	/* set as output */
4667	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4668			    pin_type);
4669	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4670			    AMP_OUT_UNMUTE);
4671	/* need the manual connection? */
4672	if (nid >= 0x12) {
4673		int idx = nid - 0x12;
4674		snd_hda_codec_write(codec, idx + 0x0b, 0,
4675				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4676	}
4677}
4678
4679static void alc260_auto_init_multi_out(struct hda_codec *codec)
4680{
4681	struct alc_spec *spec = codec->spec;
4682	hda_nid_t nid;
4683
4684	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4685	nid = spec->autocfg.line_out_pins[0];
4686	if (nid) {
4687		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4688		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4689	}
4690
4691	nid = spec->autocfg.speaker_pins[0];
4692	if (nid)
4693		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4694
4695	nid = spec->autocfg.hp_pins[0];
4696	if (nid)
4697		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4698}
4699
4700#define ALC260_PIN_CD_NID		0x16
4701static void alc260_auto_init_analog_input(struct hda_codec *codec)
4702{
4703	struct alc_spec *spec = codec->spec;
4704	int i;
4705
4706	for (i = 0; i < AUTO_PIN_LAST; i++) {
4707		hda_nid_t nid = spec->autocfg.input_pins[i];
4708		if (nid >= 0x12) {
4709			snd_hda_codec_write(codec, nid, 0,
4710					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4711					    i <= AUTO_PIN_FRONT_MIC ?
4712					    PIN_VREF80 : PIN_IN);
4713			if (nid != ALC260_PIN_CD_NID)
4714				snd_hda_codec_write(codec, nid, 0,
4715						    AC_VERB_SET_AMP_GAIN_MUTE,
4716						    AMP_OUT_MUTE);
4717		}
4718	}
4719}
4720
4721/*
4722 * generic initialization of ADC, input mixers and output mixers
4723 */
4724static struct hda_verb alc260_volume_init_verbs[] = {
4725	/*
4726	 * Unmute ADC0-1 and set the default input to mic-in
4727	 */
4728	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4729	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4730	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4731	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4732
4733	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4734	 * mixer widget
4735	 * Note: PASD motherboards uses the Line In 2 as the input for
4736	 * front panel mic (mic 2)
4737	 */
4738	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4739	/* mute analog inputs */
4740	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4741	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4742	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4743	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4744	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4745
4746	/*
4747	 * Set up output mixers (0x08 - 0x0a)
4748	 */
4749	/* set vol=0 to output mixers */
4750	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4751	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4752	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4753	/* set up input amps for analog loopback */
4754	/* Amp Indices: DAC = 0, mixer = 1 */
4755	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4756	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4757	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4758	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4759	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4760	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4761
4762	{ }
4763};
4764
4765static int alc260_parse_auto_config(struct hda_codec *codec)
4766{
4767	struct alc_spec *spec = codec->spec;
4768	unsigned int wcap;
4769	int err;
4770	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4771
4772	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4773					   alc260_ignore);
4774	if (err < 0)
4775		return err;
4776	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4777	if (err < 0)
4778		return err;
4779	if (!spec->kctl_alloc)
4780		return 0; /* can't find valid BIOS pin config */
4781	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4782	if (err < 0)
4783		return err;
4784
4785	spec->multiout.max_channels = 2;
4786
4787	if (spec->autocfg.dig_out_pin)
4788		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4789	if (spec->kctl_alloc)
4790		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4791
4792	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4793
4794	spec->num_mux_defs = 1;
4795	spec->input_mux = &spec->private_imux;
4796
4797	/* check whether NID 0x04 is valid */
4798	wcap = get_wcaps(codec, 0x04);
4799	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4800	if (wcap != AC_WID_AUD_IN) {
4801		spec->adc_nids = alc260_adc_nids_alt;
4802		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4803		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4804	} else {
4805		spec->adc_nids = alc260_adc_nids;
4806		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4807		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4808	}
4809	spec->num_mixers++;
4810
4811	return 1;
4812}
4813
4814/* additional initialization for auto-configuration model */
4815static void alc260_auto_init(struct hda_codec *codec)
4816{
4817	alc260_auto_init_multi_out(codec);
4818	alc260_auto_init_analog_input(codec);
4819}
4820
4821#ifdef CONFIG_SND_HDA_POWER_SAVE
4822static struct hda_amp_list alc260_loopbacks[] = {
4823	{ 0x07, HDA_INPUT, 0 },
4824	{ 0x07, HDA_INPUT, 1 },
4825	{ 0x07, HDA_INPUT, 2 },
4826	{ 0x07, HDA_INPUT, 3 },
4827	{ 0x07, HDA_INPUT, 4 },
4828	{ } /* end */
4829};
4830#endif
4831
4832/*
4833 * ALC260 configurations
4834 */
4835static const char *alc260_models[ALC260_MODEL_LAST] = {
4836	[ALC260_BASIC]		= "basic",
4837	[ALC260_HP]		= "hp",
4838	[ALC260_HP_3013]	= "hp-3013",
4839	[ALC260_FUJITSU_S702X]	= "fujitsu",
4840	[ALC260_ACER]		= "acer",
4841	[ALC260_WILL]		= "will",
4842	[ALC260_REPLACER_672V]	= "replacer",
4843#ifdef CONFIG_SND_DEBUG
4844	[ALC260_TEST]		= "test",
4845#endif
4846	[ALC260_AUTO]		= "auto",
4847};
4848
4849static struct snd_pci_quirk alc260_cfg_tbl[] = {
4850	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4851	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4852	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4853	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4854	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4855	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4856	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4857	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4858	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4859	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4860	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4861	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4862	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4863	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4864	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4865	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4866	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4867	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4868	{}
4869};
4870
4871static struct alc_config_preset alc260_presets[] = {
4872	[ALC260_BASIC] = {
4873		.mixers = { alc260_base_output_mixer,
4874			    alc260_input_mixer,
4875			    alc260_pc_beep_mixer,
4876			    alc260_capture_mixer },
4877		.init_verbs = { alc260_init_verbs },
4878		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4879		.dac_nids = alc260_dac_nids,
4880		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4881		.adc_nids = alc260_adc_nids,
4882		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4883		.channel_mode = alc260_modes,
4884		.input_mux = &alc260_capture_source,
4885	},
4886	[ALC260_HP] = {
4887		.mixers = { alc260_base_output_mixer,
4888			    alc260_input_mixer,
4889			    alc260_capture_alt_mixer },
4890		.init_verbs = { alc260_init_verbs },
4891		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4892		.dac_nids = alc260_dac_nids,
4893		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4894		.adc_nids = alc260_hp_adc_nids,
4895		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4896		.channel_mode = alc260_modes,
4897		.input_mux = &alc260_capture_source,
4898	},
4899	[ALC260_HP_3013] = {
4900		.mixers = { alc260_hp_3013_mixer,
4901			    alc260_input_mixer,
4902			    alc260_capture_alt_mixer },
4903		.init_verbs = { alc260_hp_3013_init_verbs },
4904		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4905		.dac_nids = alc260_dac_nids,
4906		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4907		.adc_nids = alc260_hp_adc_nids,
4908		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4909		.channel_mode = alc260_modes,
4910		.input_mux = &alc260_capture_source,
4911	},
4912	[ALC260_FUJITSU_S702X] = {
4913		.mixers = { alc260_fujitsu_mixer,
4914			    alc260_capture_mixer },
4915		.init_verbs = { alc260_fujitsu_init_verbs },
4916		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4917		.dac_nids = alc260_dac_nids,
4918		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4919		.adc_nids = alc260_dual_adc_nids,
4920		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4921		.channel_mode = alc260_modes,
4922		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4923		.input_mux = alc260_fujitsu_capture_sources,
4924	},
4925	[ALC260_ACER] = {
4926		.mixers = { alc260_acer_mixer,
4927			    alc260_capture_mixer },
4928		.init_verbs = { alc260_acer_init_verbs },
4929		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4930		.dac_nids = alc260_dac_nids,
4931		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4932		.adc_nids = alc260_dual_adc_nids,
4933		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4934		.channel_mode = alc260_modes,
4935		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4936		.input_mux = alc260_acer_capture_sources,
4937	},
4938	[ALC260_WILL] = {
4939		.mixers = { alc260_will_mixer,
4940			    alc260_capture_mixer },
4941		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4942		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4943		.dac_nids = alc260_dac_nids,
4944		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4945		.adc_nids = alc260_adc_nids,
4946		.dig_out_nid = ALC260_DIGOUT_NID,
4947		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4948		.channel_mode = alc260_modes,
4949		.input_mux = &alc260_capture_source,
4950	},
4951	[ALC260_REPLACER_672V] = {
4952		.mixers = { alc260_replacer_672v_mixer,
4953			    alc260_capture_mixer },
4954		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4955		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4956		.dac_nids = alc260_dac_nids,
4957		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4958		.adc_nids = alc260_adc_nids,
4959		.dig_out_nid = ALC260_DIGOUT_NID,
4960		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4961		.channel_mode = alc260_modes,
4962		.input_mux = &alc260_capture_source,
4963		.unsol_event = alc260_replacer_672v_unsol_event,
4964		.init_hook = alc260_replacer_672v_automute,
4965	},
4966#ifdef CONFIG_SND_DEBUG
4967	[ALC260_TEST] = {
4968		.mixers = { alc260_test_mixer,
4969			    alc260_capture_mixer },
4970		.init_verbs = { alc260_test_init_verbs },
4971		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4972		.dac_nids = alc260_test_dac_nids,
4973		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4974		.adc_nids = alc260_test_adc_nids,
4975		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4976		.channel_mode = alc260_modes,
4977		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4978		.input_mux = alc260_test_capture_sources,
4979	},
4980#endif
4981};
4982
4983static int patch_alc260(struct hda_codec *codec)
4984{
4985	struct alc_spec *spec;
4986	int err, board_config;
4987
4988	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4989	if (spec == NULL)
4990		return -ENOMEM;
4991
4992	codec->spec = spec;
4993
4994	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4995						  alc260_models,
4996						  alc260_cfg_tbl);
4997	if (board_config < 0) {
4998		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4999			   "trying auto-probe from BIOS...\n");
5000		board_config = ALC260_AUTO;
5001	}
5002
5003	if (board_config == ALC260_AUTO) {
5004		/* automatic parse from the BIOS config */
5005		err = alc260_parse_auto_config(codec);
5006		if (err < 0) {
5007			alc_free(codec);
5008			return err;
5009		} else if (!err) {
5010			printk(KERN_INFO
5011			       "hda_codec: Cannot set up configuration "
5012			       "from BIOS.  Using base mode...\n");
5013			board_config = ALC260_BASIC;
5014		}
5015	}
5016
5017	if (board_config != ALC260_AUTO)
5018		setup_preset(spec, &alc260_presets[board_config]);
5019
5020	spec->stream_name_analog = "ALC260 Analog";
5021	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5022	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5023
5024	spec->stream_name_digital = "ALC260 Digital";
5025	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5026	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5027
5028	spec->vmaster_nid = 0x08;
5029
5030	codec->patch_ops = alc_patch_ops;
5031	if (board_config == ALC260_AUTO)
5032		spec->init_hook = alc260_auto_init;
5033#ifdef CONFIG_SND_HDA_POWER_SAVE
5034	if (!spec->loopback.amplist)
5035		spec->loopback.amplist = alc260_loopbacks;
5036#endif
5037
5038	return 0;
5039}
5040
5041
5042/*
5043 * ALC882 support
5044 *
5045 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5046 * configuration.  Each pin widget can choose any input DACs and a mixer.
5047 * Each ADC is connected from a mixer of all inputs.  This makes possible
5048 * 6-channel independent captures.
5049 *
5050 * In addition, an independent DAC for the multi-playback (not used in this
5051 * driver yet).
5052 */
5053#define ALC882_DIGOUT_NID	0x06
5054#define ALC882_DIGIN_NID	0x0a
5055
5056static struct hda_channel_mode alc882_ch_modes[1] = {
5057	{ 8, NULL }
5058};
5059
5060static hda_nid_t alc882_dac_nids[4] = {
5061	/* front, rear, clfe, rear_surr */
5062	0x02, 0x03, 0x04, 0x05
5063};
5064
5065/* identical with ALC880 */
5066#define alc882_adc_nids		alc880_adc_nids
5067#define alc882_adc_nids_alt	alc880_adc_nids_alt
5068
5069/* input MUX */
5070/* FIXME: should be a matrix-type input source selection */
5071
5072static struct hda_input_mux alc882_capture_source = {
5073	.num_items = 4,
5074	.items = {
5075		{ "Mic", 0x0 },
5076		{ "Front Mic", 0x1 },
5077		{ "Line", 0x2 },
5078		{ "CD", 0x4 },
5079	},
5080};
5081#define alc882_mux_enum_info alc_mux_enum_info
5082#define alc882_mux_enum_get alc_mux_enum_get
5083
5084static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5085			       struct snd_ctl_elem_value *ucontrol)
5086{
5087	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5088	struct alc_spec *spec = codec->spec;
5089	const struct hda_input_mux *imux = spec->input_mux;
5090	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5091	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5092	hda_nid_t nid = capture_mixers[adc_idx];
5093	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5094	unsigned int i, idx;
5095
5096	idx = ucontrol->value.enumerated.item[0];
5097	if (idx >= imux->num_items)
5098		idx = imux->num_items - 1;
5099	if (*cur_val == idx)
5100		return 0;
5101	for (i = 0; i < imux->num_items; i++) {
5102		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5103		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5104					 imux->items[i].index,
5105					 HDA_AMP_MUTE, v);
5106	}
5107	*cur_val = idx;
5108	return 1;
5109}
5110
5111/*
5112 * 2ch mode
5113 */
5114static struct hda_verb alc882_3ST_ch2_init[] = {
5115	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5116	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5117	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5118	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5119	{ } /* end */
5120};
5121
5122/*
5123 * 6ch mode
5124 */
5125static struct hda_verb alc882_3ST_ch6_init[] = {
5126	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5127	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5128	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5129	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5130	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5131	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5132	{ } /* end */
5133};
5134
5135static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5136	{ 2, alc882_3ST_ch2_init },
5137	{ 6, alc882_3ST_ch6_init },
5138};
5139
5140/*
5141 * 6ch mode
5142 */
5143static struct hda_verb alc882_sixstack_ch6_init[] = {
5144	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5145	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5146	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5147	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5148	{ } /* end */
5149};
5150
5151/*
5152 * 8ch mode
5153 */
5154static struct hda_verb alc882_sixstack_ch8_init[] = {
5155	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5156	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5157	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5158	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5159	{ } /* end */
5160};
5161
5162static struct hda_channel_mode alc882_sixstack_modes[2] = {
5163	{ 6, alc882_sixstack_ch6_init },
5164	{ 8, alc882_sixstack_ch8_init },
5165};
5166
5167/*
5168 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5169 */
5170
5171/*
5172 * 2ch mode
5173 */
5174static struct hda_verb alc885_mbp_ch2_init[] = {
5175	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5176	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5177	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5178	{ } /* end */
5179};
5180
5181/*
5182 * 6ch mode
5183 */
5184static struct hda_verb alc885_mbp_ch6_init[] = {
5185	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5186	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5187	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5188	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5189	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5190	{ } /* end */
5191};
5192
5193static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5194	{ 2, alc885_mbp_ch2_init },
5195	{ 6, alc885_mbp_ch6_init },
5196};
5197
5198
5199/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5200 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5201 */
5202static struct snd_kcontrol_new alc882_base_mixer[] = {
5203	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5204	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5205	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5206	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5207	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5208	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5209	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5210	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5211	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5212	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5213	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5214	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5215	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5216	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5217	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5218	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5219	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5220	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5221	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5222	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5223	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5224	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5225	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5226	{ } /* end */
5227};
5228
5229static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5230	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5231	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5232	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5233	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5234	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5235	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5236	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5237	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5238	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5239	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5240	{ } /* end */
5241};
5242static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5243	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5244	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5245	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5246	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5247	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5248	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5249	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5250	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5251	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5252	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5253	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5254	{ } /* end */
5255};
5256
5257static struct snd_kcontrol_new alc882_targa_mixer[] = {
5258	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5259	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5260	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5261	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5262	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5263	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5264	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5265	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5266	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5267	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5268	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5269	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5270	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5271	{ } /* end */
5272};
5273
5274/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5275 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5276 */
5277static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5278	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5279	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5280	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5281	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5282	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5283	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5284	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5285	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5286	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5287	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5288	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5289	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5290	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5291	{ } /* end */
5292};
5293
5294static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5295	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5296	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5297	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5298	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5299	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5300	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5301	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5302	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5303	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5304	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5305	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5306	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5307	{ } /* end */
5308};
5309
5310static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5311	{
5312		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5313		.name = "Channel Mode",
5314		.info = alc_ch_mode_info,
5315		.get = alc_ch_mode_get,
5316		.put = alc_ch_mode_put,
5317	},
5318	{ } /* end */
5319};
5320
5321static struct hda_verb alc882_init_verbs[] = {
5322	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5324	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5325	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5326	/* Rear mixer */
5327	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5328	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5329	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5330	/* CLFE mixer */
5331	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5332	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5333	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5334	/* Side mixer */
5335	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5336	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5337	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5338
5339	/* Front Pin: output 0 (0x0c) */
5340	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5341	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5342	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5343	/* Rear Pin: output 1 (0x0d) */
5344	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5345	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5346	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5347	/* CLFE Pin: output 2 (0x0e) */
5348	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5349	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5350	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5351	/* Side Pin: output 3 (0x0f) */
5352	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5353	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5354	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5355	/* Mic (rear) pin: input vref at 80% */
5356	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5357	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5358	/* Front Mic pin: input vref at 80% */
5359	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5360	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5361	/* Line In pin: input */
5362	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5363	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5364	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5365	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5366	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5367	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5368	/* CD pin widget for input */
5369	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5370
5371	/* FIXME: use matrix-type input source selection */
5372	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5373	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5374	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5375	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5376	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5377	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5378	/* Input mixer2 */
5379	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5380	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5381	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5382	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5383	/* Input mixer3 */
5384	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5385	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5386	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5387	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5388	/* ADC1: mute amp left and right */
5389	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5390	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5391	/* ADC2: mute amp left and right */
5392	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5393	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5394	/* ADC3: mute amp left and right */
5395	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5396	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5397
5398	{ }
5399};
5400
5401static struct hda_verb alc882_eapd_verbs[] = {
5402	/* change to EAPD mode */
5403	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5404	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5405	{ }
5406};
5407
5408/* Mac Pro test */
5409static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5410	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5411	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5412	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5413	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5414	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5415	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5416	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5417	{ } /* end */
5418};
5419
5420static struct hda_verb alc882_macpro_init_verbs[] = {
5421	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5422	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5423	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5424	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5425	/* Front Pin: output 0 (0x0c) */
5426	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5427	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5428	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5429	/* Front Mic pin: input vref at 80% */
5430	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5431	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5432	/* Speaker:  output */
5433	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5434	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5435	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5436	/* Headphone output (output 0 - 0x0c) */
5437	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5438	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5439	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5440
5441	/* FIXME: use matrix-type input source selection */
5442	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5443	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5444	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5445	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5446	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5447	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5448	/* Input mixer2 */
5449	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5450	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5451	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5452	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5453	/* Input mixer3 */
5454	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5455	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5456	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5457	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5458	/* ADC1: mute amp left and right */
5459	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5460	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5461	/* ADC2: mute amp left and right */
5462	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5463	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5464	/* ADC3: mute amp left and right */
5465	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5466	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5467
5468	{ }
5469};
5470
5471/* Macbook Pro rev3 */
5472static struct hda_verb alc885_mbp3_init_verbs[] = {
5473	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5474	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5475	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5476	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5477	/* Rear mixer */
5478	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5479	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5480	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5481	/* Front Pin: output 0 (0x0c) */
5482	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5483	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5484	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5485	/* HP Pin: output 0 (0x0d) */
5486	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5487	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5488	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5489	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5490	/* Mic (rear) pin: input vref at 80% */
5491	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5492	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5493	/* Front Mic pin: input vref at 80% */
5494	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5495	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5496	/* Line In pin: use output 1 when in LineOut mode */
5497	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5498	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5499	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5500
5501	/* FIXME: use matrix-type input source selection */
5502	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5503	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5504	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5505	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5506	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5507	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5508	/* Input mixer2 */
5509	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5510	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5511	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5512	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5513	/* Input mixer3 */
5514	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5515	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5516	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5517	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5518	/* ADC1: mute amp left and right */
5519	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5520	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5521	/* ADC2: mute amp left and right */
5522	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5523	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5524	/* ADC3: mute amp left and right */
5525	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5526	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5527
5528	{ }
5529};
5530
5531/* iMac 24 mixer. */
5532static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5533	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5534	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5535	{ } /* end */
5536};
5537
5538/* iMac 24 init verbs. */
5539static struct hda_verb alc885_imac24_init_verbs[] = {
5540	/* Internal speakers: output 0 (0x0c) */
5541	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5542	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5543	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5544	/* Internal speakers: output 0 (0x0c) */
5545	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5546	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5547	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5548	/* Headphone: output 0 (0x0c) */
5549	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5550	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5551	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5552	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5553	/* Front Mic: input vref at 80% */
5554	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5555	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5556	{ }
5557};
5558
5559/* Toggle speaker-output according to the hp-jack state */
5560static void alc885_imac24_automute(struct hda_codec *codec)
5561{
5562 	unsigned int present;
5563
5564 	present = snd_hda_codec_read(codec, 0x14, 0,
5565				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5566	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5567				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5568	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5569				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5570}
5571
5572/* Processes unsolicited events. */
5573static void alc885_imac24_unsol_event(struct hda_codec *codec,
5574				      unsigned int res)
5575{
5576	/* Headphone insertion or removal. */
5577	if ((res >> 26) == ALC880_HP_EVENT)
5578		alc885_imac24_automute(codec);
5579}
5580
5581static void alc885_mbp3_automute(struct hda_codec *codec)
5582{
5583 	unsigned int present;
5584
5585 	present = snd_hda_codec_read(codec, 0x15, 0,
5586				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5587	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5588				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5589	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5590				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5591
5592}
5593static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5594				    unsigned int res)
5595{
5596	/* Headphone insertion or removal. */
5597	if ((res >> 26) == ALC880_HP_EVENT)
5598		alc885_mbp3_automute(codec);
5599}
5600
5601
5602static struct hda_verb alc882_targa_verbs[] = {
5603	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5604	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5605
5606	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5607	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5608
5609	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5610	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5611	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5612
5613	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5614	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5615	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5616	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5617	{ } /* end */
5618};
5619
5620/* toggle speaker-output according to the hp-jack state */
5621static void alc882_targa_automute(struct hda_codec *codec)
5622{
5623 	unsigned int present;
5624
5625 	present = snd_hda_codec_read(codec, 0x14, 0,
5626				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5627	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5628				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5629	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5630				  present ? 1 : 3);
5631}
5632
5633static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5634{
5635	/* Looks like the unsol event is incompatible with the standard
5636	 * definition.  4bit tag is placed at 26 bit!
5637	 */
5638	if (((res >> 26) == ALC880_HP_EVENT)) {
5639		alc882_targa_automute(codec);
5640	}
5641}
5642
5643static struct hda_verb alc882_asus_a7j_verbs[] = {
5644	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5645	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5646
5647	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5648	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5649	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5650
5651	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5652	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5653	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5654
5655	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5656	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5657	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5658	{ } /* end */
5659};
5660
5661static struct hda_verb alc882_asus_a7m_verbs[] = {
5662	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5663	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5664
5665	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5666	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5667	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5668
5669	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5670	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5671	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5672
5673	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5674	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5675	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5676 	{ } /* end */
5677};
5678
5679static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5680{
5681	unsigned int gpiostate, gpiomask, gpiodir;
5682
5683	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5684				       AC_VERB_GET_GPIO_DATA, 0);
5685
5686	if (!muted)
5687		gpiostate |= (1 << pin);
5688	else
5689		gpiostate &= ~(1 << pin);
5690
5691	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5692				      AC_VERB_GET_GPIO_MASK, 0);
5693	gpiomask |= (1 << pin);
5694
5695	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5696				     AC_VERB_GET_GPIO_DIRECTION, 0);
5697	gpiodir |= (1 << pin);
5698
5699
5700	snd_hda_codec_write(codec, codec->afg, 0,
5701			    AC_VERB_SET_GPIO_MASK, gpiomask);
5702	snd_hda_codec_write(codec, codec->afg, 0,
5703			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5704
5705	msleep(1);
5706
5707	snd_hda_codec_write(codec, codec->afg, 0,
5708			    AC_VERB_SET_GPIO_DATA, gpiostate);
5709}
5710
5711/* set up GPIO at initialization */
5712static void alc885_macpro_init_hook(struct hda_codec *codec)
5713{
5714	alc882_gpio_mute(codec, 0, 0);
5715	alc882_gpio_mute(codec, 1, 0);
5716}
5717
5718/* set up GPIO and update auto-muting at initialization */
5719static void alc885_imac24_init_hook(struct hda_codec *codec)
5720{
5721	alc885_macpro_init_hook(codec);
5722	alc885_imac24_automute(codec);
5723}
5724
5725/*
5726 * generic initialization of ADC, input mixers and output mixers
5727 */
5728static struct hda_verb alc882_auto_init_verbs[] = {
5729	/*
5730	 * Unmute ADC0-2 and set the default input to mic-in
5731	 */
5732	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5733	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5734	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5735	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5736	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5737	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5738
5739	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5740	 * mixer widget
5741	 * Note: PASD motherboards uses the Line In 2 as the input for
5742	 * front panel mic (mic 2)
5743	 */
5744	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5745	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5746	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5747	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5748	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5749	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5750
5751	/*
5752	 * Set up output mixers (0x0c - 0x0f)
5753	 */
5754	/* set vol=0 to output mixers */
5755	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5756	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5757	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5758	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5759	/* set up input amps for analog loopback */
5760	/* Amp Indices: DAC = 0, mixer = 1 */
5761	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5762	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5763	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5764	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5765	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5766	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5767	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5768	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5769	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5770	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5771
5772	/* FIXME: use matrix-type input source selection */
5773	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5774	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5775	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5776	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5777	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5778	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5779	/* Input mixer2 */
5780	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5781	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5782	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5783	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5784	/* Input mixer3 */
5785	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5786	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5787	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5788	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5789
5790	{ }
5791};
5792
5793/* capture mixer elements */
5794static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5795	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5796	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5797	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5798	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5799	{
5800		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5801		/* The multiple "Capture Source" controls confuse alsamixer
5802		 * So call somewhat different..
5803		 * FIXME: the controls appear in the "playback" view!
5804		 */
5805		/* .name = "Capture Source", */
5806		.name = "Input Source",
5807		.count = 2,
5808		.info = alc882_mux_enum_info,
5809		.get = alc882_mux_enum_get,
5810		.put = alc882_mux_enum_put,
5811	},
5812	{ } /* end */
5813};
5814
5815static struct snd_kcontrol_new alc882_capture_mixer[] = {
5816	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5817	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5818	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5819	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5820	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5821	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5822	{
5823		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5824		/* The multiple "Capture Source" controls confuse alsamixer
5825		 * So call somewhat different..
5826		 * FIXME: the controls appear in the "playback" view!
5827		 */
5828		/* .name = "Capture Source", */
5829		.name = "Input Source",
5830		.count = 3,
5831		.info = alc882_mux_enum_info,
5832		.get = alc882_mux_enum_get,
5833		.put = alc882_mux_enum_put,
5834	},
5835	{ } /* end */
5836};
5837
5838#ifdef CONFIG_SND_HDA_POWER_SAVE
5839#define alc882_loopbacks	alc880_loopbacks
5840#endif
5841
5842/* pcm configuration: identiacal with ALC880 */
5843#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5844#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5845#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5846#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5847
5848/*
5849 * configuration and preset
5850 */
5851static const char *alc882_models[ALC882_MODEL_LAST] = {
5852	[ALC882_3ST_DIG]	= "3stack-dig",
5853	[ALC882_6ST_DIG]	= "6stack-dig",
5854	[ALC882_ARIMA]		= "arima",
5855	[ALC882_W2JC]		= "w2jc",
5856	[ALC882_TARGA]		= "targa",
5857	[ALC882_ASUS_A7J]	= "asus-a7j",
5858	[ALC882_ASUS_A7M]	= "asus-a7m",
5859	[ALC885_MACPRO]		= "macpro",
5860	[ALC885_MBP3]		= "mbp3",
5861	[ALC885_IMAC24]		= "imac24",
5862	[ALC882_AUTO]		= "auto",
5863};
5864
5865static struct snd_pci_quirk alc882_cfg_tbl[] = {
5866	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5867	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5868	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5869	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5870	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5871	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5872	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5873	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5874	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5875	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5876	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5877	{}
5878};
5879
5880static struct alc_config_preset alc882_presets[] = {
5881	[ALC882_3ST_DIG] = {
5882		.mixers = { alc882_base_mixer },
5883		.init_verbs = { alc882_init_verbs },
5884		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5885		.dac_nids = alc882_dac_nids,
5886		.dig_out_nid = ALC882_DIGOUT_NID,
5887		.dig_in_nid = ALC882_DIGIN_NID,
5888		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5889		.channel_mode = alc882_ch_modes,
5890		.need_dac_fix = 1,
5891		.input_mux = &alc882_capture_source,
5892	},
5893	[ALC882_6ST_DIG] = {
5894		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5895		.init_verbs = { alc882_init_verbs },
5896		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5897		.dac_nids = alc882_dac_nids,
5898		.dig_out_nid = ALC882_DIGOUT_NID,
5899		.dig_in_nid = ALC882_DIGIN_NID,
5900		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5901		.channel_mode = alc882_sixstack_modes,
5902		.input_mux = &alc882_capture_source,
5903	},
5904	[ALC882_ARIMA] = {
5905		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5906		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5907		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5908		.dac_nids = alc882_dac_nids,
5909		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5910		.channel_mode = alc882_sixstack_modes,
5911		.input_mux = &alc882_capture_source,
5912	},
5913	[ALC882_W2JC] = {
5914		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5915		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5916				alc880_gpio1_init_verbs },
5917		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5918		.dac_nids = alc882_dac_nids,
5919		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5920		.channel_mode = alc880_threestack_modes,
5921		.need_dac_fix = 1,
5922		.input_mux = &alc882_capture_source,
5923		.dig_out_nid = ALC882_DIGOUT_NID,
5924	},
5925	[ALC885_MBP3] = {
5926		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5927		.init_verbs = { alc885_mbp3_init_verbs,
5928				alc880_gpio1_init_verbs },
5929		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5930		.dac_nids = alc882_dac_nids,
5931		.channel_mode = alc885_mbp_6ch_modes,
5932		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5933		.input_mux = &alc882_capture_source,
5934		.dig_out_nid = ALC882_DIGOUT_NID,
5935		.dig_in_nid = ALC882_DIGIN_NID,
5936		.unsol_event = alc885_mbp3_unsol_event,
5937		.init_hook = alc885_mbp3_automute,
5938	},
5939	[ALC885_MACPRO] = {
5940		.mixers = { alc882_macpro_mixer },
5941		.init_verbs = { alc882_macpro_init_verbs },
5942		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5943		.dac_nids = alc882_dac_nids,
5944		.dig_out_nid = ALC882_DIGOUT_NID,
5945		.dig_in_nid = ALC882_DIGIN_NID,
5946		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5947		.channel_mode = alc882_ch_modes,
5948		.input_mux = &alc882_capture_source,
5949		.init_hook = alc885_macpro_init_hook,
5950	},
5951	[ALC885_IMAC24] = {
5952		.mixers = { alc885_imac24_mixer },
5953		.init_verbs = { alc885_imac24_init_verbs },
5954		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5955		.dac_nids = alc882_dac_nids,
5956		.dig_out_nid = ALC882_DIGOUT_NID,
5957		.dig_in_nid = ALC882_DIGIN_NID,
5958		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5959		.channel_mode = alc882_ch_modes,
5960		.input_mux = &alc882_capture_source,
5961		.unsol_event = alc885_imac24_unsol_event,
5962		.init_hook = alc885_imac24_init_hook,
5963	},
5964	[ALC882_TARGA] = {
5965		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5966			    alc882_capture_mixer },
5967		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5968		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5969		.dac_nids = alc882_dac_nids,
5970		.dig_out_nid = ALC882_DIGOUT_NID,
5971		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5972		.adc_nids = alc882_adc_nids,
5973		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5974		.channel_mode = alc882_3ST_6ch_modes,
5975		.need_dac_fix = 1,
5976		.input_mux = &alc882_capture_source,
5977		.unsol_event = alc882_targa_unsol_event,
5978		.init_hook = alc882_targa_automute,
5979	},
5980	[ALC882_ASUS_A7J] = {
5981		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5982			    alc882_capture_mixer },
5983		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5984		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5985		.dac_nids = alc882_dac_nids,
5986		.dig_out_nid = ALC882_DIGOUT_NID,
5987		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5988		.adc_nids = alc882_adc_nids,
5989		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5990		.channel_mode = alc882_3ST_6ch_modes,
5991		.need_dac_fix = 1,
5992		.input_mux = &alc882_capture_source,
5993	},
5994	[ALC882_ASUS_A7M] = {
5995		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5996		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5997				alc880_gpio1_init_verbs,
5998				alc882_asus_a7m_verbs },
5999		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6000		.dac_nids = alc882_dac_nids,
6001		.dig_out_nid = ALC882_DIGOUT_NID,
6002		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6003		.channel_mode = alc880_threestack_modes,
6004		.need_dac_fix = 1,
6005		.input_mux = &alc882_capture_source,
6006	},
6007};
6008
6009
6010/*
6011 * Pin config fixes
6012 */
6013enum {
6014	PINFIX_ABIT_AW9D_MAX
6015};
6016
6017static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6018	{ 0x15, 0x01080104 }, /* side */
6019	{ 0x16, 0x01011012 }, /* rear */
6020	{ 0x17, 0x01016011 }, /* clfe */
6021	{ }
6022};
6023
6024static const struct alc_pincfg *alc882_pin_fixes[] = {
6025	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6026};
6027
6028static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6029	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6030	{}
6031};
6032
6033/*
6034 * BIOS auto configuration
6035 */
6036static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6037					      hda_nid_t nid, int pin_type,
6038					      int dac_idx)
6039{
6040	/* set as output */
6041	struct alc_spec *spec = codec->spec;
6042	int idx;
6043
6044	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6045		idx = 4;
6046	else
6047		idx = spec->multiout.dac_nids[dac_idx] - 2;
6048
6049	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6050			    pin_type);
6051	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6052			    AMP_OUT_UNMUTE);
6053	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6054
6055}
6056
6057static void alc882_auto_init_multi_out(struct hda_codec *codec)
6058{
6059	struct alc_spec *spec = codec->spec;
6060	int i;
6061
6062	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6063	for (i = 0; i <= HDA_SIDE; i++) {
6064		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6065		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6066		if (nid)
6067			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6068							  i);
6069	}
6070}
6071
6072static void alc882_auto_init_hp_out(struct hda_codec *codec)
6073{
6074	struct alc_spec *spec = codec->spec;
6075	hda_nid_t pin;
6076
6077	pin = spec->autocfg.hp_pins[0];
6078	if (pin) /* connect to front */
6079		/* use dac 0 */
6080		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6081}
6082
6083#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6084#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6085
6086static void alc882_auto_init_analog_input(struct hda_codec *codec)
6087{
6088	struct alc_spec *spec = codec->spec;
6089	int i;
6090
6091	for (i = 0; i < AUTO_PIN_LAST; i++) {
6092		hda_nid_t nid = spec->autocfg.input_pins[i];
6093		if (alc882_is_input_pin(nid)) {
6094			snd_hda_codec_write(codec, nid, 0,
6095					    AC_VERB_SET_PIN_WIDGET_CONTROL,
6096					    i <= AUTO_PIN_FRONT_MIC ?
6097					    PIN_VREF80 : PIN_IN);
6098			if (nid != ALC882_PIN_CD_NID)
6099				snd_hda_codec_write(codec, nid, 0,
6100						    AC_VERB_SET_AMP_GAIN_MUTE,
6101						    AMP_OUT_MUTE);
6102		}
6103	}
6104}
6105
6106/* add mic boosts if needed */
6107static int alc_auto_add_mic_boost(struct hda_codec *codec)
6108{
6109	struct alc_spec *spec = codec->spec;
6110	int err;
6111	hda_nid_t nid;
6112
6113	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6114	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6115		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6116				  "Mic Boost",
6117				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6118		if (err < 0)
6119			return err;
6120	}
6121	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6122	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6123		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6124				  "Front Mic Boost",
6125				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6126		if (err < 0)
6127			return err;
6128	}
6129	return 0;
6130}
6131
6132/* almost identical with ALC880 parser... */
6133static int alc882_parse_auto_config(struct hda_codec *codec)
6134{
6135	struct alc_spec *spec = codec->spec;
6136	int err = alc880_parse_auto_config(codec);
6137
6138	if (err < 0)
6139		return err;
6140	else if (!err)
6141		return 0; /* no config found */
6142
6143	err = alc_auto_add_mic_boost(codec);
6144	if (err < 0)
6145		return err;
6146
6147	/* hack - override the init verbs */
6148	spec->init_verbs[0] = alc882_auto_init_verbs;
6149
6150	return 1; /* config found */
6151}
6152
6153/* additional initialization for auto-configuration model */
6154static void alc882_auto_init(struct hda_codec *codec)
6155{
6156	alc882_auto_init_multi_out(codec);
6157	alc882_auto_init_hp_out(codec);
6158	alc882_auto_init_analog_input(codec);
6159}
6160
6161static int patch_alc882(struct hda_codec *codec)
6162{
6163	struct alc_spec *spec;
6164	int err, board_config;
6165
6166	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6167	if (spec == NULL)
6168		return -ENOMEM;
6169
6170	codec->spec = spec;
6171
6172	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6173						  alc882_models,
6174						  alc882_cfg_tbl);
6175
6176	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6177		/* Pick up systems that don't supply PCI SSID */
6178		switch (codec->subsystem_id) {
6179		case 0x106b0c00: /* Mac Pro */
6180			board_config = ALC885_MACPRO;
6181			break;
6182		case 0x106b1000: /* iMac 24 */
6183			board_config = ALC885_IMAC24;
6184			break;
6185		case 0x106b00a1: /* Macbook */
6186		case 0x106b2c00: /* Macbook Pro rev3 */
6187			board_config = ALC885_MBP3;
6188			break;
6189		default:
6190			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6191		       			 "trying auto-probe from BIOS...\n");
6192			board_config = ALC882_AUTO;
6193		}
6194	}
6195
6196	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6197
6198	if (board_config == ALC882_AUTO) {
6199		/* automatic parse from the BIOS config */
6200		err = alc882_parse_auto_config(codec);
6201		if (err < 0) {
6202			alc_free(codec);
6203			return err;
6204		} else if (!err) {
6205			printk(KERN_INFO
6206			       "hda_codec: Cannot set up configuration "
6207			       "from BIOS.  Using base mode...\n");
6208			board_config = ALC882_3ST_DIG;
6209		}
6210	}
6211
6212	if (board_config != ALC882_AUTO)
6213		setup_preset(spec, &alc882_presets[board_config]);
6214
6215	spec->stream_name_analog = "ALC882 Analog";
6216	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6217	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6218
6219	spec->stream_name_digital = "ALC882 Digital";
6220	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6221	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6222
6223	if (!spec->adc_nids && spec->input_mux) {
6224		/* check whether NID 0x07 is valid */
6225		unsigned int wcap = get_wcaps(codec, 0x07);
6226		/* get type */
6227		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6228		if (wcap != AC_WID_AUD_IN) {
6229			spec->adc_nids = alc882_adc_nids_alt;
6230			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6231			spec->mixers[spec->num_mixers] =
6232				alc882_capture_alt_mixer;
6233			spec->num_mixers++;
6234		} else {
6235			spec->adc_nids = alc882_adc_nids;
6236			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6237			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6238			spec->num_mixers++;
6239		}
6240	}
6241
6242	spec->vmaster_nid = 0x0c;
6243
6244	codec->patch_ops = alc_patch_ops;
6245	if (board_config == ALC882_AUTO)
6246		spec->init_hook = alc882_auto_init;
6247#ifdef CONFIG_SND_HDA_POWER_SAVE
6248	if (!spec->loopback.amplist)
6249		spec->loopback.amplist = alc882_loopbacks;
6250#endif
6251
6252	return 0;
6253}
6254
6255/*
6256 * ALC883 support
6257 *
6258 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6259 * configuration.  Each pin widget can choose any input DACs and a mixer.
6260 * Each ADC is connected from a mixer of all inputs.  This makes possible
6261 * 6-channel independent captures.
6262 *
6263 * In addition, an independent DAC for the multi-playback (not used in this
6264 * driver yet).
6265 */
6266#define ALC883_DIGOUT_NID	0x06
6267#define ALC883_DIGIN_NID	0x0a
6268
6269static hda_nid_t alc883_dac_nids[4] = {
6270	/* front, rear, clfe, rear_surr */
6271	0x02, 0x04, 0x03, 0x05
6272};
6273
6274static hda_nid_t alc883_adc_nids[2] = {
6275	/* ADC1-2 */
6276	0x08, 0x09,
6277};
6278
6279/* input MUX */
6280/* FIXME: should be a matrix-type input source selection */
6281
6282static struct hda_input_mux alc883_capture_source = {
6283	.num_items = 4,
6284	.items = {
6285		{ "Mic", 0x0 },
6286		{ "Front Mic", 0x1 },
6287		{ "Line", 0x2 },
6288		{ "CD", 0x4 },
6289	},
6290};
6291
6292static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6293	.num_items = 2,
6294	.items = {
6295		{ "Mic", 0x1 },
6296		{ "Line", 0x2 },
6297	},
6298};
6299
6300static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6301	.num_items = 4,
6302	.items = {
6303		{ "Mic", 0x0 },
6304		{ "iMic", 0x1 },
6305		{ "Line", 0x2 },
6306		{ "CD", 0x4 },
6307	},
6308};
6309
6310#define alc883_mux_enum_info alc_mux_enum_info
6311#define alc883_mux_enum_get alc_mux_enum_get
6312
6313static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6314			       struct snd_ctl_elem_value *ucontrol)
6315{
6316	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6317	struct alc_spec *spec = codec->spec;
6318	const struct hda_input_mux *imux = spec->input_mux;
6319	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6320	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6321	hda_nid_t nid = capture_mixers[adc_idx];
6322	unsigned int *cur_val = &spec->cur_mux[adc_idx];
6323	unsigned int i, idx;
6324
6325	idx = ucontrol->value.enumerated.item[0];
6326	if (idx >= imux->num_items)
6327		idx = imux->num_items - 1;
6328	if (*cur_val == idx)
6329		return 0;
6330	for (i = 0; i < imux->num_items; i++) {
6331		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6332		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6333					 imux->items[i].index,
6334					 HDA_AMP_MUTE, v);
6335	}
6336	*cur_val = idx;
6337	return 1;
6338}
6339
6340/*
6341 * 2ch mode
6342 */
6343static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6344	{ 2, NULL }
6345};
6346
6347/*
6348 * 2ch mode
6349 */
6350static struct hda_verb alc883_3ST_ch2_init[] = {
6351	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6352	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6353	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6354	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6355	{ } /* end */
6356};
6357
6358/*
6359 * 4ch mode
6360 */
6361static struct hda_verb alc883_3ST_ch4_init[] = {
6362	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6363	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6364	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6365	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6366	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6367	{ } /* end */
6368};
6369
6370/*
6371 * 6ch mode
6372 */
6373static struct hda_verb alc883_3ST_ch6_init[] = {
6374	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6375	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6376	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6377	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6378	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6379	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6380	{ } /* end */
6381};
6382
6383static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6384	{ 2, alc883_3ST_ch2_init },
6385	{ 4, alc883_3ST_ch4_init },
6386	{ 6, alc883_3ST_ch6_init },
6387};
6388
6389/*
6390 * 6ch mode
6391 */
6392static struct hda_verb alc883_sixstack_ch6_init[] = {
6393	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6394	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6395	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6396	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6397	{ } /* end */
6398};
6399
6400/*
6401 * 8ch mode
6402 */
6403static struct hda_verb alc883_sixstack_ch8_init[] = {
6404	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6405	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6406	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6407	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6408	{ } /* end */
6409};
6410
6411static struct hda_channel_mode alc883_sixstack_modes[2] = {
6412	{ 6, alc883_sixstack_ch6_init },
6413	{ 8, alc883_sixstack_ch8_init },
6414};
6415
6416static struct hda_verb alc883_medion_eapd_verbs[] = {
6417        /* eanable EAPD on medion laptop */
6418	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6419	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6420	{ }
6421};
6422
6423/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6424 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6425 */
6426
6427static struct snd_kcontrol_new alc883_base_mixer[] = {
6428	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6429	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6430	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6431	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6432	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6433	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6434	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6435	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6436	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6437	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6438	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6439	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6440	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6441	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6442	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6443	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6444	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6445	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6446	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6447	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6448	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6449	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6450	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6451	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6452	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6453	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6454	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6455	{
6456		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6457		/* .name = "Capture Source", */
6458		.name = "Input Source",
6459		.count = 2,
6460		.info = alc883_mux_enum_info,
6461		.get = alc883_mux_enum_get,
6462		.put = alc883_mux_enum_put,
6463	},
6464	{ } /* end */
6465};
6466
6467static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6468	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6469	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6470	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6471	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6472	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6473	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6474	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6475	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6476	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6477	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6478	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6479	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6480	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6481	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6482	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6483	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6484	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6485	{
6486		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6487		/* .name = "Capture Source", */
6488		.name = "Input Source",
6489		.count = 2,
6490		.info = alc883_mux_enum_info,
6491		.get = alc883_mux_enum_get,
6492		.put = alc883_mux_enum_put,
6493	},
6494	{ } /* end */
6495};
6496
6497static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6498	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6499	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6500	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6501	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6502	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6503	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6504	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6505	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6506	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6507	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6508	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6509	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6510	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6511	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6512	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6513	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6514	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6515	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6516	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6517	{
6518		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6519		/* .name = "Capture Source", */
6520		.name = "Input Source",
6521		.count = 2,
6522		.info = alc883_mux_enum_info,
6523		.get = alc883_mux_enum_get,
6524		.put = alc883_mux_enum_put,
6525	},
6526	{ } /* end */
6527};
6528
6529static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6530	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6531	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6532	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6533	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6534	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6535	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6536	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6537	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6538	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6539	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6540	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6541	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6542	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6543	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6544	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6545	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6546	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6547	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6548	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6549	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6550	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6551	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6552	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6553	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6554	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6555	{
6556		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6557		/* .name = "Capture Source", */
6558		.name = "Input Source",
6559		.count = 2,
6560		.info = alc883_mux_enum_info,
6561		.get = alc883_mux_enum_get,
6562		.put = alc883_mux_enum_put,
6563	},
6564	{ } /* end */
6565};
6566
6567static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6568	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6569	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6570	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6571	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6572	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6573	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6574	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6575	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6576	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6577	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6578	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6579	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6580	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6581	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6582	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6583	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6584	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6585	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6586	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6587	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6588	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6589	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6590	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6591
6592	{
6593		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6594		/* .name = "Capture Source", */
6595		.name = "Input Source",
6596		.count = 1,
6597		.info = alc883_mux_enum_info,
6598		.get = alc883_mux_enum_get,
6599		.put = alc883_mux_enum_put,
6600	},
6601	{ } /* end */
6602};
6603
6604static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6605	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6606	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6607	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6608	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6609	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6610	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6611	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6612	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6613	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6614	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6615	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6616	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6617	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6618	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6619	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6620	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6621	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6622	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6623	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6624	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6625	{
6626		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6627		/* .name = "Capture Source", */
6628		.name = "Input Source",
6629		.count = 2,
6630		.info = alc883_mux_enum_info,
6631		.get = alc883_mux_enum_get,
6632		.put = alc883_mux_enum_put,
6633	},
6634	{ } /* end */
6635};
6636
6637static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6638	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6639	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6640	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6641	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6642	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6643	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6644	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6645	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6646	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6647	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6648	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6649	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6650	{
6651		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6652		/* .name = "Capture Source", */
6653		.name = "Input Source",
6654		.count = 2,
6655		.info = alc883_mux_enum_info,
6656		.get = alc883_mux_enum_get,
6657		.put = alc883_mux_enum_put,
6658	},
6659	{ } /* end */
6660};
6661
6662static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6663	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6664	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6665	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6666	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6667	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6668	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6669	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6670	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6671	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6672	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6673	{
6674		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6675		/* .name = "Capture Source", */
6676		.name = "Input Source",
6677		.count = 1,
6678		.info = alc883_mux_enum_info,
6679		.get = alc883_mux_enum_get,
6680		.put = alc883_mux_enum_put,
6681	},
6682	{ } /* end */
6683};
6684
6685static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6686	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6687	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6688	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6689	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6690	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6691	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6692	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6693	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6694	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6695	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6696	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6697	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6698	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6699	{
6700		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6701		/* .name = "Capture Source", */
6702		.name = "Input Source",
6703		.count = 2,
6704		.info = alc883_mux_enum_info,
6705		.get = alc883_mux_enum_get,
6706		.put = alc883_mux_enum_put,
6707	},
6708	{ } /* end */
6709};
6710
6711static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6712	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6713	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6714	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6715	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6716	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6717	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6718	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6719	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6720	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6721	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6722	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6723	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6724	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6725	{
6726		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6727		/* .name = "Capture Source", */
6728		.name = "Input Source",
6729		.count = 2,
6730		.info = alc883_mux_enum_info,
6731		.get = alc883_mux_enum_get,
6732		.put = alc883_mux_enum_put,
6733	},
6734	{ } /* end */
6735};
6736
6737static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6738	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6739	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6740	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6741	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6742	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6743	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6744	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6745	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6746	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6747	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6748	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6749	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6750	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6751	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6752	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6753	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6754	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6755	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6756	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6757	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6758	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6759	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6760	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6761	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6762	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6763	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6764	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6765	{
6766		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6767		/* .name = "Capture Source", */
6768		.name = "Input Source",
6769		.count = 2,
6770		.info = alc883_mux_enum_info,
6771		.get = alc883_mux_enum_get,
6772		.put = alc883_mux_enum_put,
6773	},
6774	{ } /* end */
6775};
6776
6777static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6778	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6779	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6780	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6781	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6782	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6783	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6784	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6785	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6786	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6787	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6788	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6789	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6790	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6791	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6792	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6793	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6794	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6795	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6796	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6797	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6798	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6799	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6800	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6801	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6802	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6803	{
6804		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6805		/* .name = "Capture Source", */
6806		.name = "Input Source",
6807		.count = 2,
6808		.info = alc883_mux_enum_info,
6809		.get = alc883_mux_enum_get,
6810		.put = alc883_mux_enum_put,
6811	},
6812	{ } /* end */
6813};
6814
6815static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6816	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6817	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6818	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6819	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6820	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6821	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6822	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6823	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6824	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6825	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6826	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6827	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6828	{
6829		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6830		/* .name = "Capture Source", */
6831		.name = "Input Source",
6832		.count = 2,
6833		.info = alc883_mux_enum_info,
6834		.get = alc883_mux_enum_get,
6835		.put = alc883_mux_enum_put,
6836	},
6837	{ } /* end */
6838};
6839
6840static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6841	{
6842		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6843		.name = "Channel Mode",
6844		.info = alc_ch_mode_info,
6845		.get = alc_ch_mode_get,
6846		.put = alc_ch_mode_put,
6847	},
6848	{ } /* end */
6849};
6850
6851static struct hda_verb alc883_init_verbs[] = {
6852	/* ADC1: mute amp left and right */
6853	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6854	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6855	/* ADC2: mute amp left and right */
6856	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6857	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6858	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6859	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6860	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6862	/* Rear mixer */
6863	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6864	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6865	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6866	/* CLFE mixer */
6867	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6868	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6869	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6870	/* Side mixer */
6871	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6872	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6873	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6874
6875	/* mute analog input loopbacks */
6876	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6877	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6878	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6879	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6880	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6881
6882	/* Front Pin: output 0 (0x0c) */
6883	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6884	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6885	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6886	/* Rear Pin: output 1 (0x0d) */
6887	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6888	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6889	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6890	/* CLFE Pin: output 2 (0x0e) */
6891	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6892	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6893	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6894	/* Side Pin: output 3 (0x0f) */
6895	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6896	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6897	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6898	/* Mic (rear) pin: input vref at 80% */
6899	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6900	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6901	/* Front Mic pin: input vref at 80% */
6902	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6903	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6904	/* Line In pin: input */
6905	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6906	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6907	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6908	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6909	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6910	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6911	/* CD pin widget for input */
6912	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6913
6914	/* FIXME: use matrix-type input source selection */
6915	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6916	/* Input mixer2 */
6917	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6918	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6919	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6920	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6921	/* Input mixer3 */
6922	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6923	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6924	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6925	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6926	{ }
6927};
6928
6929/* toggle speaker-output according to the hp-jack state */
6930static void alc883_mitac_hp_automute(struct hda_codec *codec)
6931{
6932	unsigned int present;
6933
6934	present = snd_hda_codec_read(codec, 0x15, 0,
6935				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6936	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6937				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6938	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
6939				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6940}
6941
6942/* auto-toggle front mic */
6943/*
6944static void alc883_mitac_mic_automute(struct hda_codec *codec)
6945{
6946	unsigned int present;
6947	unsigned char bits;
6948
6949	present = snd_hda_codec_read(codec, 0x18, 0,
6950				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6951	bits = present ? HDA_AMP_MUTE : 0;
6952	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
6953}
6954*/
6955
6956static void alc883_mitac_automute(struct hda_codec *codec)
6957{
6958	alc883_mitac_hp_automute(codec);
6959	/* alc883_mitac_mic_automute(codec); */
6960}
6961
6962static void alc883_mitac_unsol_event(struct hda_codec *codec,
6963					   unsigned int res)
6964{
6965	switch (res >> 26) {
6966	case ALC880_HP_EVENT:
6967		alc883_mitac_hp_automute(codec);
6968		break;
6969	case ALC880_MIC_EVENT:
6970		/* alc883_mitac_mic_automute(codec); */
6971		break;
6972	}
6973}
6974
6975static struct hda_verb alc883_mitac_verbs[] = {
6976	/* HP */
6977	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6978	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6979	/* Subwoofer */
6980	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
6981	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6982
6983	/* enable unsolicited event */
6984	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6985	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
6986
6987	{ } /* end */
6988};
6989
6990static struct hda_verb alc883_tagra_verbs[] = {
6991	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6992	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6993
6994	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6995	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6996
6997	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6998	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6999	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7000
7001	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7002	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7003	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7004	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7005
7006	{ } /* end */
7007};
7008
7009static struct hda_verb alc883_lenovo_101e_verbs[] = {
7010	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7011	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7012        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7013	{ } /* end */
7014};
7015
7016static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7017        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7018	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7019        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7020        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7021	{ } /* end */
7022};
7023
7024static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7025	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7026	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7027	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7028	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7029	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7030	{ } /* end */
7031};
7032
7033static struct hda_verb alc883_haier_w66_verbs[] = {
7034	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7035	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7036
7037	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7038
7039	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7040	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7041	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7042	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7043	{ } /* end */
7044};
7045
7046static struct hda_verb alc888_6st_hp_verbs[] = {
7047	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7048	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},	/* Rear : output 2 (0x0e) */
7049	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* CLFE : output 1 (0x0d) */
7050	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},	/* Side : output 3 (0x0f) */
7051	{ }
7052};
7053
7054static struct hda_verb alc888_3st_hp_verbs[] = {
7055	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7056	{0x18, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7057	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7058	{ }
7059};
7060
7061static struct hda_verb alc888_3st_hp_2ch_init[] = {
7062	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7063	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7064	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7065	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7066	{ }
7067};
7068
7069static struct hda_verb alc888_3st_hp_6ch_init[] = {
7070	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7071	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7072	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7073	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7074	{ }
7075};
7076
7077static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7078	{ 2, alc888_3st_hp_2ch_init },
7079	{ 6, alc888_3st_hp_6ch_init },
7080};
7081
7082/* toggle front-jack and RCA according to the hp-jack state */
7083static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7084{
7085 	unsigned int present;
7086
7087 	present = snd_hda_codec_read(codec, 0x1b, 0,
7088				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7089	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7090				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7091	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7092				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7093}
7094
7095/* toggle RCA according to the front-jack state */
7096static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7097{
7098 	unsigned int present;
7099
7100 	present = snd_hda_codec_read(codec, 0x14, 0,
7101				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7102	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7103				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7104}
7105
7106static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7107					     unsigned int res)
7108{
7109	if ((res >> 26) == ALC880_HP_EVENT)
7110		alc888_lenovo_ms7195_front_automute(codec);
7111	if ((res >> 26) == ALC880_FRONT_EVENT)
7112		alc888_lenovo_ms7195_rca_automute(codec);
7113}
7114
7115static struct hda_verb alc883_medion_md2_verbs[] = {
7116	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7117	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7118
7119	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7120
7121	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7122	{ } /* end */
7123};
7124
7125/* toggle speaker-output according to the hp-jack state */
7126static void alc883_medion_md2_automute(struct hda_codec *codec)
7127{
7128 	unsigned int present;
7129
7130 	present = snd_hda_codec_read(codec, 0x14, 0,
7131				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7132	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7133				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7134}
7135
7136static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7137					  unsigned int res)
7138{
7139	if ((res >> 26) == ALC880_HP_EVENT)
7140		alc883_medion_md2_automute(codec);
7141}
7142
7143/* toggle speaker-output according to the hp-jack state */
7144static void alc883_tagra_automute(struct hda_codec *codec)
7145{
7146 	unsigned int present;
7147	unsigned char bits;
7148
7149 	present = snd_hda_codec_read(codec, 0x14, 0,
7150				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7151	bits = present ? HDA_AMP_MUTE : 0;
7152	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7153				 HDA_AMP_MUTE, bits);
7154	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7155				  present ? 1 : 3);
7156}
7157
7158static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7159{
7160	if ((res >> 26) == ALC880_HP_EVENT)
7161		alc883_tagra_automute(codec);
7162}
7163
7164static void alc883_haier_w66_automute(struct hda_codec *codec)
7165{
7166	unsigned int present;
7167	unsigned char bits;
7168
7169	present = snd_hda_codec_read(codec, 0x1b, 0,
7170				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7171	bits = present ? 0x80 : 0;
7172	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7173				 0x80, bits);
7174}
7175
7176static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7177					 unsigned int res)
7178{
7179	if ((res >> 26) == ALC880_HP_EVENT)
7180		alc883_haier_w66_automute(codec);
7181}
7182
7183static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7184{
7185 	unsigned int present;
7186	unsigned char bits;
7187
7188 	present = snd_hda_codec_read(codec, 0x14, 0,
7189				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7190	bits = present ? HDA_AMP_MUTE : 0;
7191	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7192				 HDA_AMP_MUTE, bits);
7193}
7194
7195static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7196{
7197 	unsigned int present;
7198	unsigned char bits;
7199
7200 	present = snd_hda_codec_read(codec, 0x1b, 0,
7201				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7202	bits = present ? HDA_AMP_MUTE : 0;
7203	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7204				 HDA_AMP_MUTE, bits);
7205	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7206				 HDA_AMP_MUTE, bits);
7207}
7208
7209static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7210					   unsigned int res)
7211{
7212	if ((res >> 26) == ALC880_HP_EVENT)
7213		alc883_lenovo_101e_all_automute(codec);
7214	if ((res >> 26) == ALC880_FRONT_EVENT)
7215		alc883_lenovo_101e_ispeaker_automute(codec);
7216}
7217
7218/* toggle speaker-output according to the hp-jack state */
7219static void alc883_acer_aspire_automute(struct hda_codec *codec)
7220{
7221 	unsigned int present;
7222
7223 	present = snd_hda_codec_read(codec, 0x14, 0,
7224				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7225	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7226				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7227	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7228				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7229}
7230
7231static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7232					   unsigned int res)
7233{
7234	if ((res >> 26) == ALC880_HP_EVENT)
7235		alc883_acer_aspire_automute(codec);
7236}
7237
7238static struct hda_verb alc883_acer_eapd_verbs[] = {
7239	/* HP Pin: output 0 (0x0c) */
7240	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7241	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7242	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7243	/* Front Pin: output 0 (0x0c) */
7244	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7245	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7246	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7247	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7248        /* eanable EAPD on medion laptop */
7249	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7250	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7251	/* enable unsolicited event */
7252	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7253	{ }
7254};
7255
7256/*
7257 * generic initialization of ADC, input mixers and output mixers
7258 */
7259static struct hda_verb alc883_auto_init_verbs[] = {
7260	/*
7261	 * Unmute ADC0-2 and set the default input to mic-in
7262	 */
7263	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7264	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7265	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7266	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7267
7268	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7269	 * mixer widget
7270	 * Note: PASD motherboards uses the Line In 2 as the input for
7271	 * front panel mic (mic 2)
7272	 */
7273	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7274	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7275	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7276	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7277	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7278	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7279
7280	/*
7281	 * Set up output mixers (0x0c - 0x0f)
7282	 */
7283	/* set vol=0 to output mixers */
7284	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7285	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7286	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7287	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7288	/* set up input amps for analog loopback */
7289	/* Amp Indices: DAC = 0, mixer = 1 */
7290	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7291	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7292	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7293	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7294	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7295	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7296	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7297	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7298	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7299	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7300
7301	/* FIXME: use matrix-type input source selection */
7302	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7303	/* Input mixer1 */
7304	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7305	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7306	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7307	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7308	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7309	/* Input mixer2 */
7310	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7311	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7312	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7313	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7314	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7315
7316	{ }
7317};
7318
7319/* capture mixer elements */
7320static struct snd_kcontrol_new alc883_capture_mixer[] = {
7321	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7322	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7323	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7324	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7325	{
7326		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7327		/* The multiple "Capture Source" controls confuse alsamixer
7328		 * So call somewhat different..
7329		 * FIXME: the controls appear in the "playback" view!
7330		 */
7331		/* .name = "Capture Source", */
7332		.name = "Input Source",
7333		.count = 2,
7334		.info = alc882_mux_enum_info,
7335		.get = alc882_mux_enum_get,
7336		.put = alc882_mux_enum_put,
7337	},
7338	{ } /* end */
7339};
7340
7341#ifdef CONFIG_SND_HDA_POWER_SAVE
7342#define alc883_loopbacks	alc880_loopbacks
7343#endif
7344
7345/* pcm configuration: identiacal with ALC880 */
7346#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
7347#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
7348#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
7349#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
7350
7351/*
7352 * configuration and preset
7353 */
7354static const char *alc883_models[ALC883_MODEL_LAST] = {
7355	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
7356	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
7357	[ALC883_3ST_6ch]	= "3stack-6ch",
7358	[ALC883_6ST_DIG]	= "6stack-dig",
7359	[ALC883_TARGA_DIG]	= "targa-dig",
7360	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
7361	[ALC883_ACER]		= "acer",
7362	[ALC883_ACER_ASPIRE]	= "acer-aspire",
7363	[ALC883_MEDION]		= "medion",
7364	[ALC883_MEDION_MD2]	= "medion-md2",
7365	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
7366	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7367	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
7368	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7369	[ALC883_HAIER_W66] 	= "haier-w66",
7370	[ALC888_6ST_HP]		= "6stack-hp",
7371	[ALC888_3ST_HP]		= "3stack-hp",
7372	[ALC883_MITAC]		= "mitac",
7373	[ALC883_AUTO]		= "auto",
7374};
7375
7376static struct snd_pci_quirk alc883_cfg_tbl[] = {
7377	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7378	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7379	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7380	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7381	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7382	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7383	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7384	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7385	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7386	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7387	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7388	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7389	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7390	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7391	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7392	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7393	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7394	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7395	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7396	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7397	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7398	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7399	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7400	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7401	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7402	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7403	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7404	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7405	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7406	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7407	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7408	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7409	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7410	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7411	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7412	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7413	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7414	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7415	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7416	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7417	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7418	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7419	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7420	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7421	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7422	{}
7423};
7424
7425static struct alc_config_preset alc883_presets[] = {
7426	[ALC883_3ST_2ch_DIG] = {
7427		.mixers = { alc883_3ST_2ch_mixer },
7428		.init_verbs = { alc883_init_verbs },
7429		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7430		.dac_nids = alc883_dac_nids,
7431		.dig_out_nid = ALC883_DIGOUT_NID,
7432		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7433		.adc_nids = alc883_adc_nids,
7434		.dig_in_nid = ALC883_DIGIN_NID,
7435		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7436		.channel_mode = alc883_3ST_2ch_modes,
7437		.input_mux = &alc883_capture_source,
7438	},
7439	[ALC883_3ST_6ch_DIG] = {
7440		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7441		.init_verbs = { alc883_init_verbs },
7442		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7443		.dac_nids = alc883_dac_nids,
7444		.dig_out_nid = ALC883_DIGOUT_NID,
7445		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7446		.adc_nids = alc883_adc_nids,
7447		.dig_in_nid = ALC883_DIGIN_NID,
7448		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7449		.channel_mode = alc883_3ST_6ch_modes,
7450		.need_dac_fix = 1,
7451		.input_mux = &alc883_capture_source,
7452	},
7453	[ALC883_3ST_6ch] = {
7454		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7455		.init_verbs = { alc883_init_verbs },
7456		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7457		.dac_nids = alc883_dac_nids,
7458		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7459		.adc_nids = alc883_adc_nids,
7460		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7461		.channel_mode = alc883_3ST_6ch_modes,
7462		.need_dac_fix = 1,
7463		.input_mux = &alc883_capture_source,
7464	},
7465	[ALC883_6ST_DIG] = {
7466		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
7467		.init_verbs = { alc883_init_verbs },
7468		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7469		.dac_nids = alc883_dac_nids,
7470		.dig_out_nid = ALC883_DIGOUT_NID,
7471		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7472		.adc_nids = alc883_adc_nids,
7473		.dig_in_nid = ALC883_DIGIN_NID,
7474		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7475		.channel_mode = alc883_sixstack_modes,
7476		.input_mux = &alc883_capture_source,
7477	},
7478	[ALC883_TARGA_DIG] = {
7479		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7480		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7481		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7482		.dac_nids = alc883_dac_nids,
7483		.dig_out_nid = ALC883_DIGOUT_NID,
7484		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7485		.adc_nids = alc883_adc_nids,
7486		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7487		.channel_mode = alc883_3ST_6ch_modes,
7488		.need_dac_fix = 1,
7489		.input_mux = &alc883_capture_source,
7490		.unsol_event = alc883_tagra_unsol_event,
7491		.init_hook = alc883_tagra_automute,
7492	},
7493	[ALC883_TARGA_2ch_DIG] = {
7494		.mixers = { alc883_tagra_2ch_mixer},
7495		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7496		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7497		.dac_nids = alc883_dac_nids,
7498		.dig_out_nid = ALC883_DIGOUT_NID,
7499		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7500		.adc_nids = alc883_adc_nids,
7501		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7502		.channel_mode = alc883_3ST_2ch_modes,
7503		.input_mux = &alc883_capture_source,
7504		.unsol_event = alc883_tagra_unsol_event,
7505		.init_hook = alc883_tagra_automute,
7506	},
7507	[ALC883_ACER] = {
7508		.mixers = { alc883_base_mixer },
7509		/* On TravelMate laptops, GPIO 0 enables the internal speaker
7510		 * and the headphone jack.  Turn this on and rely on the
7511		 * standard mute methods whenever the user wants to turn
7512		 * these outputs off.
7513		 */
7514		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7515		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7516		.dac_nids = alc883_dac_nids,
7517		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7518		.adc_nids = alc883_adc_nids,
7519		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7520		.channel_mode = alc883_3ST_2ch_modes,
7521		.input_mux = &alc883_capture_source,
7522	},
7523	[ALC883_ACER_ASPIRE] = {
7524		.mixers = { alc883_acer_aspire_mixer },
7525		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7526		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7527		.dac_nids = alc883_dac_nids,
7528		.dig_out_nid = ALC883_DIGOUT_NID,
7529		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7530		.adc_nids = alc883_adc_nids,
7531		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7532		.channel_mode = alc883_3ST_2ch_modes,
7533		.input_mux = &alc883_capture_source,
7534		.unsol_event = alc883_acer_aspire_unsol_event,
7535		.init_hook = alc883_acer_aspire_automute,
7536	},
7537	[ALC883_MEDION] = {
7538		.mixers = { alc883_fivestack_mixer,
7539			    alc883_chmode_mixer },
7540		.init_verbs = { alc883_init_verbs,
7541				alc883_medion_eapd_verbs },
7542		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7543		.dac_nids = alc883_dac_nids,
7544		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7545		.adc_nids = alc883_adc_nids,
7546		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7547		.channel_mode = alc883_sixstack_modes,
7548		.input_mux = &alc883_capture_source,
7549	},
7550	[ALC883_MEDION_MD2] = {
7551		.mixers = { alc883_medion_md2_mixer},
7552		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7553		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7554		.dac_nids = alc883_dac_nids,
7555		.dig_out_nid = ALC883_DIGOUT_NID,
7556		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7557		.adc_nids = alc883_adc_nids,
7558		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7559		.channel_mode = alc883_3ST_2ch_modes,
7560		.input_mux = &alc883_capture_source,
7561		.unsol_event = alc883_medion_md2_unsol_event,
7562		.init_hook = alc883_medion_md2_automute,
7563	},
7564	[ALC883_LAPTOP_EAPD] = {
7565		.mixers = { alc883_base_mixer },
7566		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7567		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7568		.dac_nids = alc883_dac_nids,
7569		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7570		.adc_nids = alc883_adc_nids,
7571		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7572		.channel_mode = alc883_3ST_2ch_modes,
7573		.input_mux = &alc883_capture_source,
7574	},
7575	[ALC883_LENOVO_101E_2ch] = {
7576		.mixers = { alc883_lenovo_101e_2ch_mixer},
7577		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7578		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7579		.dac_nids = alc883_dac_nids,
7580		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7581		.adc_nids = alc883_adc_nids,
7582		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7583		.channel_mode = alc883_3ST_2ch_modes,
7584		.input_mux = &alc883_lenovo_101e_capture_source,
7585		.unsol_event = alc883_lenovo_101e_unsol_event,
7586		.init_hook = alc883_lenovo_101e_all_automute,
7587	},
7588	[ALC883_LENOVO_NB0763] = {
7589		.mixers = { alc883_lenovo_nb0763_mixer },
7590		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7591		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7592		.dac_nids = alc883_dac_nids,
7593		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7594		.adc_nids = alc883_adc_nids,
7595		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7596		.channel_mode = alc883_3ST_2ch_modes,
7597		.need_dac_fix = 1,
7598		.input_mux = &alc883_lenovo_nb0763_capture_source,
7599		.unsol_event = alc883_medion_md2_unsol_event,
7600		.init_hook = alc883_medion_md2_automute,
7601	},
7602	[ALC888_LENOVO_MS7195_DIG] = {
7603		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7604		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7605		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7606		.dac_nids = alc883_dac_nids,
7607		.dig_out_nid = ALC883_DIGOUT_NID,
7608		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7609		.adc_nids = alc883_adc_nids,
7610		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7611		.channel_mode = alc883_3ST_6ch_modes,
7612		.need_dac_fix = 1,
7613		.input_mux = &alc883_capture_source,
7614		.unsol_event = alc883_lenovo_ms7195_unsol_event,
7615		.init_hook = alc888_lenovo_ms7195_front_automute,
7616	},
7617	[ALC883_HAIER_W66] = {
7618		.mixers = { alc883_tagra_2ch_mixer},
7619		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7620		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7621		.dac_nids = alc883_dac_nids,
7622		.dig_out_nid = ALC883_DIGOUT_NID,
7623		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7624		.adc_nids = alc883_adc_nids,
7625		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7626		.channel_mode = alc883_3ST_2ch_modes,
7627		.input_mux = &alc883_capture_source,
7628		.unsol_event = alc883_haier_w66_unsol_event,
7629		.init_hook = alc883_haier_w66_automute,
7630	},
7631	[ALC888_6ST_HP] = {
7632		.mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7633		.init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7634		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7635		.dac_nids = alc883_dac_nids,
7636		.dig_out_nid = ALC883_DIGOUT_NID,
7637		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7638		.adc_nids = alc883_adc_nids,
7639		.dig_in_nid = ALC883_DIGIN_NID,
7640		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7641		.channel_mode = alc883_sixstack_modes,
7642		.input_mux = &alc883_capture_source,
7643	},
7644	[ALC888_3ST_HP] = {
7645		.mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7646		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7647		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7648		.dac_nids = alc883_dac_nids,
7649		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7650		.adc_nids = alc883_adc_nids,
7651		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7652		.channel_mode = alc888_3st_hp_modes,
7653		.need_dac_fix = 1,
7654		.input_mux = &alc883_capture_source,
7655	},
7656	[ALC883_MITAC] = {
7657		.mixers = { alc883_mitac_mixer },
7658		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7659		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7660		.dac_nids = alc883_dac_nids,
7661		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7662		.adc_nids = alc883_adc_nids,
7663		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7664		.channel_mode = alc883_3ST_2ch_modes,
7665		.input_mux = &alc883_capture_source,
7666		.unsol_event = alc883_mitac_unsol_event,
7667		.init_hook = alc883_mitac_automute,
7668	},
7669};
7670
7671
7672/*
7673 * BIOS auto configuration
7674 */
7675static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7676					      hda_nid_t nid, int pin_type,
7677					      int dac_idx)
7678{
7679	/* set as output */
7680	struct alc_spec *spec = codec->spec;
7681	int idx;
7682
7683	if (spec->multiout.dac_nids[dac_idx] == 0x25)
7684		idx = 4;
7685	else
7686		idx = spec->multiout.dac_nids[dac_idx] - 2;
7687
7688	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7689			    pin_type);
7690	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7691			    AMP_OUT_UNMUTE);
7692	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7693
7694}
7695
7696static void alc883_auto_init_multi_out(struct hda_codec *codec)
7697{
7698	struct alc_spec *spec = codec->spec;
7699	int i;
7700
7701	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7702	for (i = 0; i <= HDA_SIDE; i++) {
7703		hda_nid_t nid = spec->autocfg.line_out_pins[i];
7704		int pin_type = get_pin_type(spec->autocfg.line_out_type);
7705		if (nid)
7706			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7707							  i);
7708	}
7709}
7710
7711static void alc883_auto_init_hp_out(struct hda_codec *codec)
7712{
7713	struct alc_spec *spec = codec->spec;
7714	hda_nid_t pin;
7715
7716	pin = spec->autocfg.hp_pins[0];
7717	if (pin) /* connect to front */
7718		/* use dac 0 */
7719		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7720}
7721
7722#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
7723#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
7724
7725static void alc883_auto_init_analog_input(struct hda_codec *codec)
7726{
7727	struct alc_spec *spec = codec->spec;
7728	int i;
7729
7730	for (i = 0; i < AUTO_PIN_LAST; i++) {
7731		hda_nid_t nid = spec->autocfg.input_pins[i];
7732		if (alc883_is_input_pin(nid)) {
7733			snd_hda_codec_write(codec, nid, 0,
7734					    AC_VERB_SET_PIN_WIDGET_CONTROL,
7735					    (i <= AUTO_PIN_FRONT_MIC ?
7736					     PIN_VREF80 : PIN_IN));
7737			if (nid != ALC883_PIN_CD_NID)
7738				snd_hda_codec_write(codec, nid, 0,
7739						    AC_VERB_SET_AMP_GAIN_MUTE,
7740						    AMP_OUT_MUTE);
7741		}
7742	}
7743}
7744
7745/* almost identical with ALC880 parser... */
7746static int alc883_parse_auto_config(struct hda_codec *codec)
7747{
7748	struct alc_spec *spec = codec->spec;
7749	int err = alc880_parse_auto_config(codec);
7750
7751	if (err < 0)
7752		return err;
7753	else if (!err)
7754		return 0; /* no config found */
7755
7756	err = alc_auto_add_mic_boost(codec);
7757	if (err < 0)
7758		return err;
7759
7760	/* hack - override the init verbs */
7761	spec->init_verbs[0] = alc883_auto_init_verbs;
7762	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7763	spec->num_mixers++;
7764
7765	return 1; /* config found */
7766}
7767
7768/* additional initialization for auto-configuration model */
7769static void alc883_auto_init(struct hda_codec *codec)
7770{
7771	alc883_auto_init_multi_out(codec);
7772	alc883_auto_init_hp_out(codec);
7773	alc883_auto_init_analog_input(codec);
7774}
7775
7776static int patch_alc883(struct hda_codec *codec)
7777{
7778	struct alc_spec *spec;
7779	int err, board_config;
7780
7781	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7782	if (spec == NULL)
7783		return -ENOMEM;
7784
7785	codec->spec = spec;
7786
7787	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7788						  alc883_models,
7789						  alc883_cfg_tbl);
7790	if (board_config < 0) {
7791		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7792		       "trying auto-probe from BIOS...\n");
7793		board_config = ALC883_AUTO;
7794	}
7795
7796	if (board_config == ALC883_AUTO) {
7797		/* automatic parse from the BIOS config */
7798		err = alc883_parse_auto_config(codec);
7799		if (err < 0) {
7800			alc_free(codec);
7801			return err;
7802		} else if (!err) {
7803			printk(KERN_INFO
7804			       "hda_codec: Cannot set up configuration "
7805			       "from BIOS.  Using base mode...\n");
7806			board_config = ALC883_3ST_2ch_DIG;
7807		}
7808	}
7809
7810	if (board_config != ALC883_AUTO)
7811		setup_preset(spec, &alc883_presets[board_config]);
7812
7813	spec->stream_name_analog = "ALC883 Analog";
7814	spec->stream_analog_playback = &alc883_pcm_analog_playback;
7815	spec->stream_analog_capture = &alc883_pcm_analog_capture;
7816
7817	spec->stream_name_digital = "ALC883 Digital";
7818	spec->stream_digital_playback = &alc883_pcm_digital_playback;
7819	spec->stream_digital_capture = &alc883_pcm_digital_capture;
7820
7821	if (!spec->adc_nids && spec->input_mux) {
7822		spec->adc_nids = alc883_adc_nids;
7823		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7824	}
7825
7826	spec->vmaster_nid = 0x0c;
7827
7828	codec->patch_ops = alc_patch_ops;
7829	if (board_config == ALC883_AUTO)
7830		spec->init_hook = alc883_auto_init;
7831#ifdef CONFIG_SND_HDA_POWER_SAVE
7832	if (!spec->loopback.amplist)
7833		spec->loopback.amplist = alc883_loopbacks;
7834#endif
7835
7836	return 0;
7837}
7838
7839/*
7840 * ALC262 support
7841 */
7842
7843#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
7844#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
7845
7846#define alc262_dac_nids		alc260_dac_nids
7847#define alc262_adc_nids		alc882_adc_nids
7848#define alc262_adc_nids_alt	alc882_adc_nids_alt
7849
7850#define alc262_modes		alc260_modes
7851#define alc262_capture_source	alc882_capture_source
7852
7853static struct snd_kcontrol_new alc262_base_mixer[] = {
7854	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7855	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7856	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7857	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7858	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7859	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7860	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7861	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7862	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7863	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7864	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7865	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7866	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7867	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7868	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7869	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7870	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7871	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7872	{ } /* end */
7873};
7874
7875static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7876	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7877	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7878	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7879	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7880	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7881	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7882	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7883	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7884	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7885	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7886	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7887	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7888	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7889	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7890	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7891	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7892	{ } /* end */
7893};
7894
7895static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7896	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7897	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7898	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7899	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7900	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7901
7902	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7903	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7904	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7905	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7906	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7907	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7908	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7909	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7910	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7911	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7912	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7913	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7914	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7915	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7916	{ } /* end */
7917};
7918
7919static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7920	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7921	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7922	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7923	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7924	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7925	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7926	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7927	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7928	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7929	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7930	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7932	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7933	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7934	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7935	{ } /* end */
7936};
7937
7938static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7939	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7940	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7941	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7942	{ } /* end */
7943};
7944
7945static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7946	.ops = &snd_hda_bind_vol,
7947	.values = {
7948		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7949		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7950		0
7951	},
7952};
7953
7954static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7955	.ops = &snd_hda_bind_sw,
7956	.values = {
7957		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7958		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7959		0
7960	},
7961};
7962
7963/* mute/unmute internal speaker according to the hp jack and mute state */
7964static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7965{
7966	struct alc_spec *spec = codec->spec;
7967	unsigned int mute;
7968
7969	if (force || !spec->sense_updated) {
7970		unsigned int present;
7971		present = snd_hda_codec_read(codec, 0x15, 0,
7972					     AC_VERB_GET_PIN_SENSE, 0);
7973		spec->jack_present = (present & 0x80000000) != 0;
7974		spec->sense_updated = 1;
7975	}
7976	if (spec->jack_present)
7977		mute = (0x7080 | ((0)<<8));  /* mute internal speaker */
7978	else	/* unmute internal speaker if necessary */
7979		mute = (0x7000 | ((0)<<8));
7980       	snd_hda_codec_write(codec, 0x0c, 0,
7981			    AC_VERB_SET_AMP_GAIN_MUTE, mute );
7982}
7983
7984static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7985					unsigned int res)
7986{
7987	if ((res >> 26) != ALC880_HP_EVENT)
7988		return;
7989	alc262_hp_t5735_automute(codec, 1);
7990}
7991
7992static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7993{
7994	alc262_hp_t5735_automute(codec, 1);
7995}
7996
7997static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7998	HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7999	HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
8000	HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8001	HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8002	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8003	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8004	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8005	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8006	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8007	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8008	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8009	{ } /* end */
8010};
8011
8012static struct hda_verb alc262_hp_t5735_verbs[] = {
8013	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8014	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8015
8016	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8017	{ }
8018};
8019
8020static struct hda_bind_ctls alc262_hp_rp5700_bind_front_vol = {
8021	.ops = &snd_hda_bind_vol,
8022	.values = {
8023		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8024		HDA_COMPOSE_AMP_VAL(0x0e, 3, 0, HDA_OUTPUT),
8025		0
8026	},
8027};
8028
8029static struct hda_bind_ctls alc262_hp_rp5700_bind_front_sw = {
8030	.ops = &snd_hda_bind_sw,
8031	.values = {
8032		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
8033		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
8034		0
8035	},
8036};
8037
8038static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8039	HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_rp5700_bind_front_vol),
8040	HDA_BIND_SW("PCM Playback Switch", &alc262_hp_rp5700_bind_front_sw),
8041	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8042	HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8043	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8044	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8045	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8046	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8047	{ } /* end */
8048};
8049
8050static struct hda_verb alc262_hp_rp5700_verbs[] = {
8051	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8052	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8053	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8054	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8055	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8056	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8057	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8058	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8059	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8060	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8061	{}
8062};
8063
8064static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8065	.num_items = 1,
8066	.items = {
8067		{ "Line", 0x1 },
8068	},
8069};
8070
8071/* bind hp and internal speaker mute (with plug check) */
8072static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8073				     struct snd_ctl_elem_value *ucontrol)
8074{
8075	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8076	long *valp = ucontrol->value.integer.value;
8077	int change;
8078
8079	/* change hp mute */
8080	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8081					  HDA_AMP_MUTE,
8082					  valp[0] ? 0 : HDA_AMP_MUTE);
8083	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8084					   HDA_AMP_MUTE,
8085					   valp[1] ? 0 : HDA_AMP_MUTE);
8086	if (change) {
8087		/* change speaker according to HP jack state */
8088		struct alc_spec *spec = codec->spec;
8089		unsigned int mute;
8090		if (spec->jack_present)
8091			mute = HDA_AMP_MUTE;
8092		else
8093			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8094						      HDA_OUTPUT, 0);
8095		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8096					 HDA_AMP_MUTE, mute);
8097	}
8098	return change;
8099}
8100
8101static struct snd_kcontrol_new alc262_sony_mixer[] = {
8102	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8103	{
8104		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8105		.name = "Master Playback Switch",
8106		.info = snd_hda_mixer_amp_switch_info,
8107		.get = snd_hda_mixer_amp_switch_get,
8108		.put = alc262_sony_master_sw_put,
8109		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8110	},
8111	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8112	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8113	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8114	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8115	{ } /* end */
8116};
8117
8118static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8119	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8120	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8121	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8122	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8123	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8124	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8125	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8126	{ } /* end */
8127};
8128
8129#define alc262_capture_mixer		alc882_capture_mixer
8130#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
8131
8132/*
8133 * generic initialization of ADC, input mixers and output mixers
8134 */
8135static struct hda_verb alc262_init_verbs[] = {
8136	/*
8137	 * Unmute ADC0-2 and set the default input to mic-in
8138	 */
8139	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8140	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8141	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8142	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8143	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8144	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8145
8146	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8147	 * mixer widget
8148	 * Note: PASD motherboards uses the Line In 2 as the input for
8149	 * front panel mic (mic 2)
8150	 */
8151	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8152	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8153	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8154	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8155	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8156	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8157
8158	/*
8159	 * Set up output mixers (0x0c - 0x0e)
8160	 */
8161	/* set vol=0 to output mixers */
8162	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8163	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8164	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8165	/* set up input amps for analog loopback */
8166	/* Amp Indices: DAC = 0, mixer = 1 */
8167	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8168	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8169	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8170	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8171	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8172	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8173
8174	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8175	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8176	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8177	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8178	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8179	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8180
8181	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8182	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8183	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8184	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8185	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8186
8187	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8188	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8189
8190	/* FIXME: use matrix-type input source selection */
8191	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8192	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8193	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8194	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8195	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8196	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8197	/* Input mixer2 */
8198	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8199	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8200	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8201	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8202	/* Input mixer3 */
8203	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8204	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8205	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8206	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8207
8208	{ }
8209};
8210
8211static struct hda_verb alc262_hippo_unsol_verbs[] = {
8212	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8213	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8214	{}
8215};
8216
8217static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8218	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8219	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8220	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8221
8222	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8223	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8224	{}
8225};
8226
8227static struct hda_verb alc262_sony_unsol_verbs[] = {
8228	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8229	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8230	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
8231
8232	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8233	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8234};
8235
8236/* mute/unmute internal speaker according to the hp jack and mute state */
8237static void alc262_hippo_automute(struct hda_codec *codec)
8238{
8239	struct alc_spec *spec = codec->spec;
8240	unsigned int mute;
8241	unsigned int present;
8242
8243	/* need to execute and sync at first */
8244	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8245	present = snd_hda_codec_read(codec, 0x15, 0,
8246				     AC_VERB_GET_PIN_SENSE, 0);
8247	spec->jack_present = (present & 0x80000000) != 0;
8248	if (spec->jack_present) {
8249		/* mute internal speaker */
8250		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8251					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8252	} else {
8253		/* unmute internal speaker if necessary */
8254		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8255		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8256					 HDA_AMP_MUTE, mute);
8257	}
8258}
8259
8260/* unsolicited event for HP jack sensing */
8261static void alc262_hippo_unsol_event(struct hda_codec *codec,
8262				       unsigned int res)
8263{
8264	if ((res >> 26) != ALC880_HP_EVENT)
8265		return;
8266	alc262_hippo_automute(codec);
8267}
8268
8269static void alc262_hippo1_automute(struct hda_codec *codec)
8270{
8271	unsigned int mute;
8272	unsigned int present;
8273
8274	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8275	present = snd_hda_codec_read(codec, 0x1b, 0,
8276				     AC_VERB_GET_PIN_SENSE, 0);
8277	present = (present & 0x80000000) != 0;
8278	if (present) {
8279		/* mute internal speaker */
8280		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8281					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8282	} else {
8283		/* unmute internal speaker if necessary */
8284		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8285		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8286					 HDA_AMP_MUTE, mute);
8287	}
8288}
8289
8290/* unsolicited event for HP jack sensing */
8291static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8292				       unsigned int res)
8293{
8294	if ((res >> 26) != ALC880_HP_EVENT)
8295		return;
8296	alc262_hippo1_automute(codec);
8297}
8298
8299/*
8300 * fujitsu model
8301 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
8302 */
8303
8304#define ALC_HP_EVENT	0x37
8305
8306static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8307	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8308	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8309	{}
8310};
8311
8312static struct hda_input_mux alc262_fujitsu_capture_source = {
8313	.num_items = 3,
8314	.items = {
8315		{ "Mic", 0x0 },
8316		{ "Int Mic", 0x1 },
8317		{ "CD", 0x4 },
8318	},
8319};
8320
8321static struct hda_input_mux alc262_HP_capture_source = {
8322	.num_items = 5,
8323	.items = {
8324		{ "Mic", 0x0 },
8325		{ "Front Mic", 0x1 },
8326		{ "Line", 0x2 },
8327		{ "CD", 0x4 },
8328		{ "AUX IN", 0x6 },
8329	},
8330};
8331
8332static struct hda_input_mux alc262_HP_D7000_capture_source = {
8333	.num_items = 4,
8334	.items = {
8335		{ "Mic", 0x0 },
8336		{ "Front Mic", 0x2 },
8337		{ "Line", 0x1 },
8338		{ "CD", 0x4 },
8339	},
8340};
8341
8342/* mute/unmute internal speaker according to the hp jack and mute state */
8343static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8344{
8345	struct alc_spec *spec = codec->spec;
8346	unsigned int mute;
8347
8348	if (force || !spec->sense_updated) {
8349		unsigned int present;
8350		/* need to execute and sync at first */
8351		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8352		present = snd_hda_codec_read(codec, 0x14, 0,
8353				    	 AC_VERB_GET_PIN_SENSE, 0);
8354		spec->jack_present = (present & 0x80000000) != 0;
8355		spec->sense_updated = 1;
8356	}
8357	if (spec->jack_present) {
8358		/* mute internal speaker */
8359		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8360					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8361	} else {
8362		/* unmute internal speaker if necessary */
8363		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8364		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8365					 HDA_AMP_MUTE, mute);
8366	}
8367}
8368
8369/* unsolicited event for HP jack sensing */
8370static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8371				       unsigned int res)
8372{
8373	if ((res >> 26) != ALC_HP_EVENT)
8374		return;
8375	alc262_fujitsu_automute(codec, 1);
8376}
8377
8378/* bind volumes of both NID 0x0c and 0x0d */
8379static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8380	.ops = &snd_hda_bind_vol,
8381	.values = {
8382		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8383		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8384		0
8385	},
8386};
8387
8388/* bind hp and internal speaker mute (with plug check) */
8389static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8390					 struct snd_ctl_elem_value *ucontrol)
8391{
8392	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8393	long *valp = ucontrol->value.integer.value;
8394	int change;
8395
8396	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8397					  HDA_AMP_MUTE,
8398					  valp[0] ? 0 : HDA_AMP_MUTE);
8399	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8400					   HDA_AMP_MUTE,
8401					   valp[1] ? 0 : HDA_AMP_MUTE);
8402	if (change)
8403		alc262_fujitsu_automute(codec, 0);
8404	return change;
8405}
8406
8407static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8408	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8409	{
8410		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8411		.name = "Master Playback Switch",
8412		.info = snd_hda_mixer_amp_switch_info,
8413		.get = snd_hda_mixer_amp_switch_get,
8414		.put = alc262_fujitsu_master_sw_put,
8415		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8416	},
8417	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8418	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8419	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8420	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8421	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8422	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8423	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8424	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8425	{ } /* end */
8426};
8427
8428/* additional init verbs for Benq laptops */
8429static struct hda_verb alc262_EAPD_verbs[] = {
8430	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8431	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
8432	{}
8433};
8434
8435static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8436	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8437	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8438
8439	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8440	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
8441	{}
8442};
8443
8444/* Samsung Q1 Ultra Vista model setup */
8445static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8446	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8447	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8448	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8449	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8450	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8451	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8452	{ } /* end */
8453};
8454
8455static struct hda_verb alc262_ultra_verbs[] = {
8456	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8457	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8458	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8459	/* Mic is on Node 0x19 */
8460	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8461	{0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8462	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8463	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8464	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8465	{0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8466	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8467	{}
8468};
8469
8470static struct hda_input_mux alc262_ultra_capture_source = {
8471	.num_items = 1,
8472	.items = {
8473		{ "Mic", 0x1 },
8474	},
8475};
8476
8477/* mute/unmute internal speaker according to the hp jack and mute state */
8478static void alc262_ultra_automute(struct hda_codec *codec)
8479{
8480	struct alc_spec *spec = codec->spec;
8481	unsigned int mute;
8482	unsigned int present;
8483
8484	/* need to execute and sync at first */
8485	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8486	present = snd_hda_codec_read(codec, 0x15, 0,
8487				     AC_VERB_GET_PIN_SENSE, 0);
8488	spec->jack_present = (present & 0x80000000) != 0;
8489	if (spec->jack_present) {
8490		/* mute internal speaker */
8491		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8492					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8493	} else {
8494		/* unmute internal speaker if necessary */
8495		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8496		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8497					 HDA_AMP_MUTE, mute);
8498	}
8499}
8500
8501/* unsolicited event for HP jack sensing */
8502static void alc262_ultra_unsol_event(struct hda_codec *codec,
8503				       unsigned int res)
8504{
8505	if ((res >> 26) != ALC880_HP_EVENT)
8506		return;
8507	alc262_ultra_automute(codec);
8508}
8509
8510/* add playback controls from the parsed DAC table */
8511static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8512					     const struct auto_pin_cfg *cfg)
8513{
8514	hda_nid_t nid;
8515	int err;
8516
8517	spec->multiout.num_dacs = 1;	/* only use one dac */
8518	spec->multiout.dac_nids = spec->private_dac_nids;
8519	spec->multiout.dac_nids[0] = 2;
8520
8521	nid = cfg->line_out_pins[0];
8522	if (nid) {
8523		err = add_control(spec, ALC_CTL_WIDGET_VOL,
8524				  "Front Playback Volume",
8525				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8526		if (err < 0)
8527			return err;
8528		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8529				  "Front Playback Switch",
8530				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8531		if (err < 0)
8532			return err;
8533	}
8534
8535	nid = cfg->speaker_pins[0];
8536	if (nid) {
8537		if (nid == 0x16) {
8538			err = add_control(spec, ALC_CTL_WIDGET_VOL,
8539					  "Speaker Playback Volume",
8540					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8541							      HDA_OUTPUT));
8542			if (err < 0)
8543				return err;
8544			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8545					  "Speaker Playback Switch",
8546					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8547							      HDA_OUTPUT));
8548			if (err < 0)
8549				return err;
8550		} else {
8551			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8552					  "Speaker Playback Switch",
8553					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8554							      HDA_OUTPUT));
8555			if (err < 0)
8556				return err;
8557		}
8558	}
8559	nid = cfg->hp_pins[0];
8560	if (nid) {
8561		/* spec->multiout.hp_nid = 2; */
8562		if (nid == 0x16) {
8563			err = add_control(spec, ALC_CTL_WIDGET_VOL,
8564					  "Headphone Playback Volume",
8565					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8566							      HDA_OUTPUT));
8567			if (err < 0)
8568				return err;
8569			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8570					  "Headphone Playback Switch",
8571					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8572							      HDA_OUTPUT));
8573			if (err < 0)
8574				return err;
8575		} else {
8576			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8577					  "Headphone Playback Switch",
8578					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8579							      HDA_OUTPUT));
8580			if (err < 0)
8581				return err;
8582		}
8583	}
8584	return 0;
8585}
8586
8587/* identical with ALC880 */
8588#define alc262_auto_create_analog_input_ctls \
8589	alc880_auto_create_analog_input_ctls
8590
8591/*
8592 * generic initialization of ADC, input mixers and output mixers
8593 */
8594static struct hda_verb alc262_volume_init_verbs[] = {
8595	/*
8596	 * Unmute ADC0-2 and set the default input to mic-in
8597	 */
8598	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8599	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8600	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8601	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8602	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8603	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8604
8605	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8606	 * mixer widget
8607	 * Note: PASD motherboards uses the Line In 2 as the input for
8608	 * front panel mic (mic 2)
8609	 */
8610	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8611	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8612	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8613	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8614	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8615	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8616
8617	/*
8618	 * Set up output mixers (0x0c - 0x0f)
8619	 */
8620	/* set vol=0 to output mixers */
8621	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8622	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8623	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8624
8625	/* set up input amps for analog loopback */
8626	/* Amp Indices: DAC = 0, mixer = 1 */
8627	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8628	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8629	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8630	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8631	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8632	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8633
8634	/* FIXME: use matrix-type input source selection */
8635	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8636	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8637	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8638	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8639	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8640	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8641	/* Input mixer2 */
8642	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8643	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8644	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8645	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8646	/* Input mixer3 */
8647	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8648	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8649	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8650	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8651
8652	{ }
8653};
8654
8655static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8656	/*
8657	 * Unmute ADC0-2 and set the default input to mic-in
8658	 */
8659	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8660	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8661	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8662	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8663	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8664	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8665
8666	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8667	 * mixer widget
8668	 * Note: PASD motherboards uses the Line In 2 as the input for
8669	 * front panel mic (mic 2)
8670	 */
8671	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8672	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8673	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8674	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8675	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8676	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8677	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8678        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8679
8680	/*
8681	 * Set up output mixers (0x0c - 0x0e)
8682	 */
8683	/* set vol=0 to output mixers */
8684	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8685	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8686	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8687
8688	/* set up input amps for analog loopback */
8689	/* Amp Indices: DAC = 0, mixer = 1 */
8690	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8691	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8692	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8693	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8694	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8695	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8696
8697	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8698	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8699	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8700
8701	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8702	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8703
8704	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8705	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8706
8707	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8708	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8709        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8710	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8711	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8712
8713	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8714	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8715        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8716	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8717	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8718	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8719
8720
8721	/* FIXME: use matrix-type input source selection */
8722	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8723	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8724	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8725	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8726	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8727	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8728	/* Input mixer2 */
8729	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8730	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8731	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8732	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8733	/* Input mixer3 */
8734	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8735	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8736	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8737	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8738
8739	{ }
8740};
8741
8742static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8743	/*
8744	 * Unmute ADC0-2 and set the default input to mic-in
8745	 */
8746	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8747	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8748	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8749	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8750	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8751	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8752
8753	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8754	 * mixer widget
8755	 * Note: PASD motherboards uses the Line In 2 as the input for front
8756	 * panel mic (mic 2)
8757	 */
8758	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8759	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8760	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8761	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8762	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8763	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8764	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8765	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8766	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8767	/*
8768	 * Set up output mixers (0x0c - 0x0e)
8769	 */
8770	/* set vol=0 to output mixers */
8771	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8772	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8773	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8774
8775	/* set up input amps for analog loopback */
8776	/* Amp Indices: DAC = 0, mixer = 1 */
8777	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8778	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8779	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8780	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8781	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8782	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8783
8784
8785	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
8786	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
8787	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
8788	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
8789	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
8790	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
8791	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
8792
8793	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8794	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8795
8796	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8797	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8798
8799	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8800	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8801	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8802	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8803	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8804	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8805
8806	/* FIXME: use matrix-type input source selection */
8807	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8808	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8809	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8810	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8811	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8812	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8813	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8814        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8815	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8816	/* Input mixer2 */
8817	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8818	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8819	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8820	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8821	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8822        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8823	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8824	/* Input mixer3 */
8825	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8826	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8827	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8828	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8829	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8830        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8831	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8832
8833	{ }
8834};
8835
8836#ifdef CONFIG_SND_HDA_POWER_SAVE
8837#define alc262_loopbacks	alc880_loopbacks
8838#endif
8839
8840/* pcm configuration: identiacal with ALC880 */
8841#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
8842#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
8843#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
8844#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
8845
8846/*
8847 * BIOS auto configuration
8848 */
8849static int alc262_parse_auto_config(struct hda_codec *codec)
8850{
8851	struct alc_spec *spec = codec->spec;
8852	int err;
8853	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8854
8855	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8856					   alc262_ignore);
8857	if (err < 0)
8858		return err;
8859	if (!spec->autocfg.line_outs)
8860		return 0; /* can't find valid BIOS pin config */
8861	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8862	if (err < 0)
8863		return err;
8864	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8865	if (err < 0)
8866		return err;
8867
8868	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8869
8870	if (spec->autocfg.dig_out_pin)
8871		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8872	if (spec->autocfg.dig_in_pin)
8873		spec->dig_in_nid = ALC262_DIGIN_NID;
8874
8875	if (spec->kctl_alloc)
8876		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8877
8878	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8879	spec->num_mux_defs = 1;
8880	spec->input_mux = &spec->private_imux;
8881
8882	err = alc_auto_add_mic_boost(codec);
8883	if (err < 0)
8884		return err;
8885
8886	return 1;
8887}
8888
8889#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
8890#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
8891#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
8892
8893
8894/* init callback for auto-configuration model -- overriding the default init */
8895static void alc262_auto_init(struct hda_codec *codec)
8896{
8897	alc262_auto_init_multi_out(codec);
8898	alc262_auto_init_hp_out(codec);
8899	alc262_auto_init_analog_input(codec);
8900}
8901
8902/*
8903 * configuration and preset
8904 */
8905static const char *alc262_models[ALC262_MODEL_LAST] = {
8906	[ALC262_BASIC]		= "basic",
8907	[ALC262_HIPPO]		= "hippo",
8908	[ALC262_HIPPO_1]	= "hippo_1",
8909	[ALC262_FUJITSU]	= "fujitsu",
8910	[ALC262_HP_BPC]		= "hp-bpc",
8911	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8912	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
8913	[ALC262_HP_RP5700]	= "hp-rp5700",
8914	[ALC262_BENQ_ED8]	= "benq",
8915	[ALC262_BENQ_T31]	= "benq-t31",
8916	[ALC262_SONY_ASSAMD]	= "sony-assamd",
8917	[ALC262_ULTRA]		= "ultra",
8918	[ALC262_AUTO]		= "auto",
8919};
8920
8921static struct snd_pci_quirk alc262_cfg_tbl[] = {
8922	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8923	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8924	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8925	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8926	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8927	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8928	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
8929	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
8930	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
8931	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8932	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8933	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8934	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8935	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8936	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8937	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8938	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8939	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8940	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8941	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8942	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8943		      ALC262_HP_TC_T5735),
8944	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
8945	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8946	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8947	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8948	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8949	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8950	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8951	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
8952	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8953	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8954	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8955	{}
8956};
8957
8958static struct alc_config_preset alc262_presets[] = {
8959	[ALC262_BASIC] = {
8960		.mixers = { alc262_base_mixer },
8961		.init_verbs = { alc262_init_verbs },
8962		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8963		.dac_nids = alc262_dac_nids,
8964		.hp_nid = 0x03,
8965		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8966		.channel_mode = alc262_modes,
8967		.input_mux = &alc262_capture_source,
8968	},
8969	[ALC262_HIPPO] = {
8970		.mixers = { alc262_base_mixer },
8971		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8972		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8973		.dac_nids = alc262_dac_nids,
8974		.hp_nid = 0x03,
8975		.dig_out_nid = ALC262_DIGOUT_NID,
8976		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8977		.channel_mode = alc262_modes,
8978		.input_mux = &alc262_capture_source,
8979		.unsol_event = alc262_hippo_unsol_event,
8980		.init_hook = alc262_hippo_automute,
8981	},
8982	[ALC262_HIPPO_1] = {
8983		.mixers = { alc262_hippo1_mixer },
8984		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8985		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8986		.dac_nids = alc262_dac_nids,
8987		.hp_nid = 0x02,
8988		.dig_out_nid = ALC262_DIGOUT_NID,
8989		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8990		.channel_mode = alc262_modes,
8991		.input_mux = &alc262_capture_source,
8992		.unsol_event = alc262_hippo1_unsol_event,
8993		.init_hook = alc262_hippo1_automute,
8994	},
8995	[ALC262_FUJITSU] = {
8996		.mixers = { alc262_fujitsu_mixer },
8997		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8998				alc262_fujitsu_unsol_verbs },
8999		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9000		.dac_nids = alc262_dac_nids,
9001		.hp_nid = 0x03,
9002		.dig_out_nid = ALC262_DIGOUT_NID,
9003		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9004		.channel_mode = alc262_modes,
9005		.input_mux = &alc262_fujitsu_capture_source,
9006		.unsol_event = alc262_fujitsu_unsol_event,
9007	},
9008	[ALC262_HP_BPC] = {
9009		.mixers = { alc262_HP_BPC_mixer },
9010		.init_verbs = { alc262_HP_BPC_init_verbs },
9011		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9012		.dac_nids = alc262_dac_nids,
9013		.hp_nid = 0x03,
9014		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9015		.channel_mode = alc262_modes,
9016		.input_mux = &alc262_HP_capture_source,
9017	},
9018	[ALC262_HP_BPC_D7000_WF] = {
9019		.mixers = { alc262_HP_BPC_WildWest_mixer },
9020		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9021		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9022		.dac_nids = alc262_dac_nids,
9023		.hp_nid = 0x03,
9024		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9025		.channel_mode = alc262_modes,
9026		.input_mux = &alc262_HP_D7000_capture_source,
9027	},
9028	[ALC262_HP_BPC_D7000_WL] = {
9029		.mixers = { alc262_HP_BPC_WildWest_mixer,
9030			    alc262_HP_BPC_WildWest_option_mixer },
9031		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9032		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9033		.dac_nids = alc262_dac_nids,
9034		.hp_nid = 0x03,
9035		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9036		.channel_mode = alc262_modes,
9037		.input_mux = &alc262_HP_D7000_capture_source,
9038	},
9039	[ALC262_HP_TC_T5735] = {
9040		.mixers = { alc262_hp_t5735_mixer },
9041		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9042		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9043		.dac_nids = alc262_dac_nids,
9044		.hp_nid = 0x03,
9045		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9046		.channel_mode = alc262_modes,
9047		.input_mux = &alc262_capture_source,
9048		.unsol_event = alc262_hp_t5735_unsol_event,
9049		.init_hook = alc262_hp_t5735_init_hook,
9050	},
9051	[ALC262_HP_RP5700] = {
9052		.mixers = { alc262_hp_rp5700_mixer },
9053		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9054		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9055		.dac_nids = alc262_dac_nids,
9056		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9057		.channel_mode = alc262_modes,
9058		.input_mux = &alc262_hp_rp5700_capture_source,
9059        },
9060	[ALC262_BENQ_ED8] = {
9061		.mixers = { alc262_base_mixer },
9062		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9063		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9064		.dac_nids = alc262_dac_nids,
9065		.hp_nid = 0x03,
9066		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9067		.channel_mode = alc262_modes,
9068		.input_mux = &alc262_capture_source,
9069	},
9070	[ALC262_SONY_ASSAMD] = {
9071		.mixers = { alc262_sony_mixer },
9072		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9073		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9074		.dac_nids = alc262_dac_nids,
9075		.hp_nid = 0x02,
9076		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9077		.channel_mode = alc262_modes,
9078		.input_mux = &alc262_capture_source,
9079		.unsol_event = alc262_hippo_unsol_event,
9080		.init_hook = alc262_hippo_automute,
9081	},
9082	[ALC262_BENQ_T31] = {
9083		.mixers = { alc262_benq_t31_mixer },
9084		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9085		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9086		.dac_nids = alc262_dac_nids,
9087		.hp_nid = 0x03,
9088		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9089		.channel_mode = alc262_modes,
9090		.input_mux = &alc262_capture_source,
9091		.unsol_event = alc262_hippo_unsol_event,
9092		.init_hook = alc262_hippo_automute,
9093	},
9094	[ALC262_ULTRA] = {
9095		.mixers = { alc262_ultra_mixer },
9096		.init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
9097		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9098		.dac_nids = alc262_dac_nids,
9099		.hp_nid = 0x03,
9100		.dig_out_nid = ALC262_DIGOUT_NID,
9101		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9102		.channel_mode = alc262_modes,
9103		.input_mux = &alc262_ultra_capture_source,
9104		.unsol_event = alc262_ultra_unsol_event,
9105		.init_hook = alc262_ultra_automute,
9106	},
9107};
9108
9109static int patch_alc262(struct hda_codec *codec)
9110{
9111	struct alc_spec *spec;
9112	int board_config;
9113	int err;
9114
9115	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9116	if (spec == NULL)
9117		return -ENOMEM;
9118
9119	codec->spec = spec;
9120#if 0
9121	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
9122	 * under-run
9123	 */
9124	{
9125	int tmp;
9126	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9127	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9128	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9129	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9130	}
9131#endif
9132
9133	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9134						  alc262_models,
9135						  alc262_cfg_tbl);
9136
9137	if (board_config < 0) {
9138		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9139		       "trying auto-probe from BIOS...\n");
9140		board_config = ALC262_AUTO;
9141	}
9142
9143	if (board_config == ALC262_AUTO) {
9144		/* automatic parse from the BIOS config */
9145		err = alc262_parse_auto_config(codec);
9146		if (err < 0) {
9147			alc_free(codec);
9148			return err;
9149		} else if (!err) {
9150			printk(KERN_INFO
9151			       "hda_codec: Cannot set up configuration "
9152			       "from BIOS.  Using base mode...\n");
9153			board_config = ALC262_BASIC;
9154		}
9155	}
9156
9157	if (board_config != ALC262_AUTO)
9158		setup_preset(spec, &alc262_presets[board_config]);
9159
9160	spec->stream_name_analog = "ALC262 Analog";
9161	spec->stream_analog_playback = &alc262_pcm_analog_playback;
9162	spec->stream_analog_capture = &alc262_pcm_analog_capture;
9163
9164	spec->stream_name_digital = "ALC262 Digital";
9165	spec->stream_digital_playback = &alc262_pcm_digital_playback;
9166	spec->stream_digital_capture = &alc262_pcm_digital_capture;
9167
9168	if (!spec->adc_nids && spec->input_mux) {
9169		/* check whether NID 0x07 is valid */
9170		unsigned int wcap = get_wcaps(codec, 0x07);
9171
9172		/* get type */
9173		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9174		if (wcap != AC_WID_AUD_IN) {
9175			spec->adc_nids = alc262_adc_nids_alt;
9176			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
9177			spec->mixers[spec->num_mixers] =
9178				alc262_capture_alt_mixer;
9179			spec->num_mixers++;
9180		} else {
9181			spec->adc_nids = alc262_adc_nids;
9182			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9183			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9184			spec->num_mixers++;
9185		}
9186	}
9187
9188	spec->vmaster_nid = 0x0c;
9189
9190	codec->patch_ops = alc_patch_ops;
9191	if (board_config == ALC262_AUTO)
9192		spec->init_hook = alc262_auto_init;
9193#ifdef CONFIG_SND_HDA_POWER_SAVE
9194	if (!spec->loopback.amplist)
9195		spec->loopback.amplist = alc262_loopbacks;
9196#endif
9197
9198	return 0;
9199}
9200
9201/*
9202 *  ALC268 channel source setting (2 channel)
9203 */
9204#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
9205#define alc268_modes		alc260_modes
9206
9207static hda_nid_t alc268_dac_nids[2] = {
9208	/* front, hp */
9209	0x02, 0x03
9210};
9211
9212static hda_nid_t alc268_adc_nids[2] = {
9213	/* ADC0-1 */
9214	0x08, 0x07
9215};
9216
9217static hda_nid_t alc268_adc_nids_alt[1] = {
9218	/* ADC0 */
9219	0x08
9220};
9221
9222static struct snd_kcontrol_new alc268_base_mixer[] = {
9223	/* output mixer control */
9224	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9225	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9226	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9227	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9228	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9229	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9230	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9231	{ }
9232};
9233
9234static struct hda_verb alc268_eapd_verbs[] = {
9235	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9236	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9237	{ }
9238};
9239
9240/* Toshiba specific */
9241#define alc268_toshiba_automute	alc262_hippo_automute
9242
9243static struct hda_verb alc268_toshiba_verbs[] = {
9244	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9245	{ } /* end */
9246};
9247
9248/* Acer specific */
9249/* bind volumes of both NID 0x02 and 0x03 */
9250static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9251	.ops = &snd_hda_bind_vol,
9252	.values = {
9253		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9254		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9255		0
9256	},
9257};
9258
9259/* mute/unmute internal speaker according to the hp jack and mute state */
9260static void alc268_acer_automute(struct hda_codec *codec, int force)
9261{
9262	struct alc_spec *spec = codec->spec;
9263	unsigned int mute;
9264
9265	if (force || !spec->sense_updated) {
9266		unsigned int present;
9267		present = snd_hda_codec_read(codec, 0x14, 0,
9268				    	 AC_VERB_GET_PIN_SENSE, 0);
9269		spec->jack_present = (present & 0x80000000) != 0;
9270		spec->sense_updated = 1;
9271	}
9272	if (spec->jack_present)
9273		mute = HDA_AMP_MUTE; /* mute internal speaker */
9274	else /* unmute internal speaker if necessary */
9275		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9276	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9277				 HDA_AMP_MUTE, mute);
9278}
9279
9280
9281/* bind hp and internal speaker mute (with plug check) */
9282static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9283				     struct snd_ctl_elem_value *ucontrol)
9284{
9285	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9286	long *valp = ucontrol->value.integer.value;
9287	int change;
9288
9289	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9290					  HDA_AMP_MUTE,
9291					  valp[0] ? 0 : HDA_AMP_MUTE);
9292	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9293					   HDA_AMP_MUTE,
9294					   valp[1] ? 0 : HDA_AMP_MUTE);
9295	if (change)
9296		alc268_acer_automute(codec, 0);
9297	return change;
9298}
9299
9300static struct snd_kcontrol_new alc268_acer_mixer[] = {
9301	/* output mixer control */
9302	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9303	{
9304		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9305		.name = "Master Playback Switch",
9306		.info = snd_hda_mixer_amp_switch_info,
9307		.get = snd_hda_mixer_amp_switch_get,
9308		.put = alc268_acer_master_sw_put,
9309		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9310	},
9311	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9312	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9313	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9314	{ }
9315};
9316
9317static struct hda_verb alc268_acer_verbs[] = {
9318	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9319	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9320
9321	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9322	{ }
9323};
9324
9325/* unsolicited event for HP jack sensing */
9326static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9327				       unsigned int res)
9328{
9329	if ((res >> 26) != ALC880_HP_EVENT)
9330		return;
9331	alc268_toshiba_automute(codec);
9332}
9333
9334static void alc268_acer_unsol_event(struct hda_codec *codec,
9335				       unsigned int res)
9336{
9337	if ((res >> 26) != ALC880_HP_EVENT)
9338		return;
9339	alc268_acer_automute(codec, 1);
9340}
9341
9342static void alc268_acer_init_hook(struct hda_codec *codec)
9343{
9344	alc268_acer_automute(codec, 1);
9345}
9346
9347/*
9348 * generic initialization of ADC, input mixers and output mixers
9349 */
9350static struct hda_verb alc268_base_init_verbs[] = {
9351	/* Unmute DAC0-1 and set vol = 0 */
9352	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9353	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9354	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9355	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9356	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9357	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9358
9359	/*
9360	 * Set up output mixers (0x0c - 0x0e)
9361	 */
9362	/* set vol=0 to output mixers */
9363	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9364	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9365	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9366        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9367
9368	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9369	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9370
9371	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9372	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9373	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9374	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9375	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9376	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9377	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9378	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9379
9380	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9381	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9382	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9383	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9384	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9385	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9386	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9387	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9388
9389	/* Unmute Selector 23h,24h and set the default input to mic-in */
9390
9391	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9392	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9393	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9394	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9395
9396	{ }
9397};
9398
9399/*
9400 * generic initialization of ADC, input mixers and output mixers
9401 */
9402static struct hda_verb alc268_volume_init_verbs[] = {
9403	/* set output DAC */
9404	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9405	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9406	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9407	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9408
9409	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9410	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9411	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9412	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9413	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9414
9415	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9416	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9417	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9418	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9419	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9420
9421	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9422	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9423	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9424	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9425
9426	/* set PCBEEP vol = 0 */
9427	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9428
9429	{ }
9430};
9431
9432#define alc268_mux_enum_info alc_mux_enum_info
9433#define alc268_mux_enum_get alc_mux_enum_get
9434
9435static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9436			       struct snd_ctl_elem_value *ucontrol)
9437{
9438	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9439	struct alc_spec *spec = codec->spec;
9440
9441	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9442	static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9443	hda_nid_t nid = capture_mixers[adc_idx];
9444
9445	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
9446				     nid,
9447				     &spec->cur_mux[adc_idx]);
9448}
9449
9450static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9451	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9452	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9453	{
9454		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9455		/* The multiple "Capture Source" controls confuse alsamixer
9456		 * So call somewhat different..
9457		 * FIXME: the controls appear in the "playback" view!
9458		 */
9459		/* .name = "Capture Source", */
9460		.name = "Input Source",
9461		.count = 1,
9462		.info = alc268_mux_enum_info,
9463		.get = alc268_mux_enum_get,
9464		.put = alc268_mux_enum_put,
9465	},
9466	{ } /* end */
9467};
9468
9469static struct snd_kcontrol_new alc268_capture_mixer[] = {
9470	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9471	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9472	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9473	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9474	{
9475		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9476		/* The multiple "Capture Source" controls confuse alsamixer
9477		 * So call somewhat different..
9478		 * FIXME: the controls appear in the "playback" view!
9479		 */
9480		/* .name = "Capture Source", */
9481		.name = "Input Source",
9482		.count = 2,
9483		.info = alc268_mux_enum_info,
9484		.get = alc268_mux_enum_get,
9485		.put = alc268_mux_enum_put,
9486	},
9487	{ } /* end */
9488};
9489
9490static struct hda_input_mux alc268_capture_source = {
9491	.num_items = 4,
9492	.items = {
9493		{ "Mic", 0x0 },
9494		{ "Front Mic", 0x1 },
9495		{ "Line", 0x2 },
9496		{ "CD", 0x3 },
9497	},
9498};
9499
9500#ifdef CONFIG_SND_DEBUG
9501static struct snd_kcontrol_new alc268_test_mixer[] = {
9502	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9503	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9504	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9505	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9506
9507	/* Volume widgets */
9508	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9509	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9510	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9511	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9512	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9513	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9514	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9515	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9516	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9517	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9518	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9519	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9520	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
9521	HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),
9522	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9523	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9524	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9525	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9526
9527	/* Modes for retasking pin widgets */
9528	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9529	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9530	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9531	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9532
9533	/* Controls for GPIO pins, assuming they are configured as outputs */
9534	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9535	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9536	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9537	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9538
9539	/* Switches to allow the digital SPDIF output pin to be enabled.
9540	 * The ALC268 does not have an SPDIF input.
9541	 */
9542	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9543
9544	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
9545	 * this output to turn on an external amplifier.
9546	 */
9547	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9548	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9549
9550	{ } /* end */
9551};
9552#endif
9553
9554/* create input playback/capture controls for the given pin */
9555static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9556				    const char *ctlname, int idx)
9557{
9558	char name[32];
9559	int err;
9560
9561	sprintf(name, "%s Playback Volume", ctlname);
9562	if (nid == 0x14) {
9563		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9564				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9565						      HDA_OUTPUT));
9566		if (err < 0)
9567			return err;
9568	} else if (nid == 0x15) {
9569		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9570				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9571						      HDA_OUTPUT));
9572		if (err < 0)
9573			return err;
9574	} else
9575		return -1;
9576	sprintf(name, "%s Playback Switch", ctlname);
9577	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9578			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9579	if (err < 0)
9580		return err;
9581	return 0;
9582}
9583
9584/* add playback controls from the parsed DAC table */
9585static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9586					     const struct auto_pin_cfg *cfg)
9587{
9588	hda_nid_t nid;
9589	int err;
9590
9591	spec->multiout.num_dacs = 2;	/* only use one dac */
9592	spec->multiout.dac_nids = spec->private_dac_nids;
9593	spec->multiout.dac_nids[0] = 2;
9594	spec->multiout.dac_nids[1] = 3;
9595
9596	nid = cfg->line_out_pins[0];
9597	if (nid)
9598		alc268_new_analog_output(spec, nid, "Front", 0);
9599
9600	nid = cfg->speaker_pins[0];
9601	if (nid == 0x1d) {
9602		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9603				  "Speaker Playback Volume",
9604				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9605		if (err < 0)
9606			return err;
9607	}
9608	nid = cfg->hp_pins[0];
9609	if (nid)
9610		alc268_new_analog_output(spec, nid, "Headphone", 0);
9611
9612	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9613	if (nid == 0x16) {
9614		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9615				  "Mono Playback Switch",
9616				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9617		if (err < 0)
9618			return err;
9619	}
9620	return 0;
9621}
9622
9623/* create playback/capture controls for input pins */
9624static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9625						const struct auto_pin_cfg *cfg)
9626{
9627	struct hda_input_mux *imux = &spec->private_imux;
9628	int i, idx1;
9629
9630	for (i = 0; i < AUTO_PIN_LAST; i++) {
9631		switch(cfg->input_pins[i]) {
9632		case 0x18:
9633			idx1 = 0;	/* Mic 1 */
9634			break;
9635		case 0x19:
9636			idx1 = 1;	/* Mic 2 */
9637			break;
9638		case 0x1a:
9639			idx1 = 2;	/* Line In */
9640			break;
9641		case 0x1c:
9642			idx1 = 3;	/* CD */
9643			break;
9644		default:
9645			continue;
9646		}
9647		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9648		imux->items[imux->num_items].index = idx1;
9649		imux->num_items++;
9650	}
9651	return 0;
9652}
9653
9654static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9655{
9656	struct alc_spec *spec = codec->spec;
9657	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9658	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9659	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9660	unsigned int	dac_vol1, dac_vol2;
9661
9662	if (speaker_nid) {
9663		snd_hda_codec_write(codec, speaker_nid, 0,
9664				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9665		snd_hda_codec_write(codec, 0x0f, 0,
9666				    AC_VERB_SET_AMP_GAIN_MUTE,
9667				    AMP_IN_UNMUTE(1));
9668		snd_hda_codec_write(codec, 0x10, 0,
9669				    AC_VERB_SET_AMP_GAIN_MUTE,
9670				    AMP_IN_UNMUTE(1));
9671	} else {
9672		snd_hda_codec_write(codec, 0x0f, 0,
9673				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9674		snd_hda_codec_write(codec, 0x10, 0,
9675				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9676	}
9677
9678	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
9679	if (line_nid == 0x14)
9680		dac_vol2 = AMP_OUT_ZERO;
9681	else if (line_nid == 0x15)
9682		dac_vol1 = AMP_OUT_ZERO;
9683	if (hp_nid == 0x14)
9684		dac_vol2 = AMP_OUT_ZERO;
9685	else if (hp_nid == 0x15)
9686		dac_vol1 = AMP_OUT_ZERO;
9687	if (line_nid != 0x16 || hp_nid != 0x16 ||
9688	    spec->autocfg.line_out_pins[1] != 0x16 ||
9689	    spec->autocfg.line_out_pins[2] != 0x16)
9690		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9691
9692	snd_hda_codec_write(codec, 0x02, 0,
9693			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9694	snd_hda_codec_write(codec, 0x03, 0,
9695			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9696}
9697
9698/* pcm configuration: identiacal with ALC880 */
9699#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
9700#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
9701#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
9702
9703/*
9704 * BIOS auto configuration
9705 */
9706static int alc268_parse_auto_config(struct hda_codec *codec)
9707{
9708	struct alc_spec *spec = codec->spec;
9709	int err;
9710	static hda_nid_t alc268_ignore[] = { 0 };
9711
9712	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9713					   alc268_ignore);
9714	if (err < 0)
9715		return err;
9716	if (!spec->autocfg.line_outs)
9717		return 0; /* can't find valid BIOS pin config */
9718
9719	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9720	if (err < 0)
9721		return err;
9722	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9723	if (err < 0)
9724		return err;
9725
9726	spec->multiout.max_channels = 2;
9727
9728	/* digital only support output */
9729	if (spec->autocfg.dig_out_pin)
9730		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9731
9732	if (spec->kctl_alloc)
9733		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9734
9735	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9736	spec->num_mux_defs = 1;
9737	spec->input_mux = &spec->private_imux;
9738
9739	err = alc_auto_add_mic_boost(codec);
9740	if (err < 0)
9741		return err;
9742
9743	return 1;
9744}
9745
9746#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
9747#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
9748#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
9749
9750/* init callback for auto-configuration model -- overriding the default init */
9751static void alc268_auto_init(struct hda_codec *codec)
9752{
9753	alc268_auto_init_multi_out(codec);
9754	alc268_auto_init_hp_out(codec);
9755	alc268_auto_init_mono_speaker_out(codec);
9756	alc268_auto_init_analog_input(codec);
9757}
9758
9759/*
9760 * configuration and preset
9761 */
9762static const char *alc268_models[ALC268_MODEL_LAST] = {
9763	[ALC268_3ST]		= "3stack",
9764	[ALC268_TOSHIBA]	= "toshiba",
9765	[ALC268_ACER]		= "acer",
9766#ifdef CONFIG_SND_DEBUG
9767	[ALC268_TEST]		= "test",
9768#endif
9769	[ALC268_AUTO]		= "auto",
9770};
9771
9772static struct snd_pci_quirk alc268_cfg_tbl[] = {
9773	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9774	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9775	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9776	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9777	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9778	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9779	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9780	{}
9781};
9782
9783static struct alc_config_preset alc268_presets[] = {
9784	[ALC268_3ST] = {
9785		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9786		.init_verbs = { alc268_base_init_verbs },
9787		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
9788		.dac_nids = alc268_dac_nids,
9789                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9790                .adc_nids = alc268_adc_nids_alt,
9791		.hp_nid = 0x03,
9792		.dig_out_nid = ALC268_DIGOUT_NID,
9793		.num_channel_mode = ARRAY_SIZE(alc268_modes),
9794		.channel_mode = alc268_modes,
9795		.input_mux = &alc268_capture_source,
9796	},
9797	[ALC268_TOSHIBA] = {
9798		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9799		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9800				alc268_toshiba_verbs },
9801		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
9802		.dac_nids = alc268_dac_nids,
9803		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9804		.adc_nids = alc268_adc_nids_alt,
9805		.hp_nid = 0x03,
9806		.num_channel_mode = ARRAY_SIZE(alc268_modes),
9807		.channel_mode = alc268_modes,
9808		.input_mux = &alc268_capture_source,
9809		.unsol_event = alc268_toshiba_unsol_event,
9810		.init_hook = alc268_toshiba_automute,
9811	},
9812	[ALC268_ACER] = {
9813		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9814		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9815				alc268_acer_verbs },
9816		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
9817		.dac_nids = alc268_dac_nids,
9818		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9819		.adc_nids = alc268_adc_nids_alt,
9820		.hp_nid = 0x02,
9821		.num_channel_mode = ARRAY_SIZE(alc268_modes),
9822		.channel_mode = alc268_modes,
9823		.input_mux = &alc268_capture_source,
9824		.unsol_event = alc268_acer_unsol_event,
9825		.init_hook = alc268_acer_init_hook,
9826	},
9827#ifdef CONFIG_SND_DEBUG
9828	[ALC268_TEST] = {
9829		.mixers = { alc268_test_mixer, alc268_capture_mixer },
9830		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9831				alc268_volume_init_verbs },
9832		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
9833		.dac_nids = alc268_dac_nids,
9834		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9835		.adc_nids = alc268_adc_nids_alt,
9836		.hp_nid = 0x03,
9837		.dig_out_nid = ALC268_DIGOUT_NID,
9838		.num_channel_mode = ARRAY_SIZE(alc268_modes),
9839		.channel_mode = alc268_modes,
9840		.input_mux = &alc268_capture_source,
9841	},
9842#endif
9843};
9844
9845static int patch_alc268(struct hda_codec *codec)
9846{
9847	struct alc_spec *spec;
9848	int board_config;
9849	int err;
9850
9851	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9852	if (spec == NULL)
9853		return -ENOMEM;
9854
9855	codec->spec = spec;
9856
9857	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9858						  alc268_models,
9859						  alc268_cfg_tbl);
9860
9861	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9862		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9863		       "trying auto-probe from BIOS...\n");
9864		board_config = ALC268_AUTO;
9865	}
9866
9867	if (board_config == ALC268_AUTO) {
9868		/* automatic parse from the BIOS config */
9869		err = alc268_parse_auto_config(codec);
9870		if (err < 0) {
9871			alc_free(codec);
9872			return err;
9873		} else if (!err) {
9874			printk(KERN_INFO
9875			       "hda_codec: Cannot set up configuration "
9876			       "from BIOS.  Using base mode...\n");
9877			board_config = ALC268_3ST;
9878		}
9879	}
9880
9881	if (board_config != ALC268_AUTO)
9882		setup_preset(spec, &alc268_presets[board_config]);
9883
9884	spec->stream_name_analog = "ALC268 Analog";
9885	spec->stream_analog_playback = &alc268_pcm_analog_playback;
9886	spec->stream_analog_capture = &alc268_pcm_analog_capture;
9887
9888	spec->stream_name_digital = "ALC268 Digital";
9889	spec->stream_digital_playback = &alc268_pcm_digital_playback;
9890
9891	if (board_config == ALC268_AUTO) {
9892		if (!spec->adc_nids && spec->input_mux) {
9893			/* check whether NID 0x07 is valid */
9894			unsigned int wcap = get_wcaps(codec, 0x07);
9895
9896			/* get type */
9897			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9898			if (wcap != AC_WID_AUD_IN) {
9899				spec->adc_nids = alc268_adc_nids_alt;
9900				spec->num_adc_nids =
9901					ARRAY_SIZE(alc268_adc_nids_alt);
9902				spec->mixers[spec->num_mixers] =
9903					alc268_capture_alt_mixer;
9904				spec->num_mixers++;
9905			} else {
9906				spec->adc_nids = alc268_adc_nids;
9907				spec->num_adc_nids =
9908					ARRAY_SIZE(alc268_adc_nids);
9909				spec->mixers[spec->num_mixers] =
9910					alc268_capture_mixer;
9911				spec->num_mixers++;
9912			}
9913		}
9914	}
9915
9916	spec->vmaster_nid = 0x02;
9917
9918	codec->patch_ops = alc_patch_ops;
9919	if (board_config == ALC268_AUTO)
9920		spec->init_hook = alc268_auto_init;
9921
9922	return 0;
9923}
9924
9925/*
9926 *  ALC269 channel source setting (2 channel)
9927 */
9928#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
9929
9930#define alc269_dac_nids		alc260_dac_nids
9931
9932static hda_nid_t alc269_adc_nids[1] = {
9933	/* ADC1 */
9934	0x07,
9935};
9936
9937#define alc269_modes		alc260_modes
9938#define alc269_capture_source	alc880_lg_lw_capture_source
9939
9940static struct snd_kcontrol_new alc269_base_mixer[] = {
9941	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9942	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9943	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9944	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9945	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9946	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9947	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9948	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9949	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9950	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9951	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9952	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9953	{ } /* end */
9954};
9955
9956/* capture mixer elements */
9957static struct snd_kcontrol_new alc269_capture_mixer[] = {
9958	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9959	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9960	{
9961		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9962		/* The multiple "Capture Source" controls confuse alsamixer
9963		 * So call somewhat different..
9964		 * FIXME: the controls appear in the "playback" view!
9965		 */
9966		/* .name = "Capture Source", */
9967		.name = "Input Source",
9968		.count = 1,
9969		.info = alc_mux_enum_info,
9970		.get = alc_mux_enum_get,
9971		.put = alc_mux_enum_put,
9972	},
9973	{ } /* end */
9974};
9975
9976/*
9977 * generic initialization of ADC, input mixers and output mixers
9978 */
9979static struct hda_verb alc269_init_verbs[] = {
9980	/*
9981	 * Unmute ADC0 and set the default input to mic-in
9982	 */
9983	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9984
9985	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
9986	 * analog-loopback mixer widget
9987	 * Note: PASD motherboards uses the Line In 2 as the input for
9988	 * front panel mic (mic 2)
9989	 */
9990	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9991	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9992	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9993	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9994	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9995	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9996
9997	/*
9998	 * Set up output mixers (0x0c - 0x0e)
9999	 */
10000	/* set vol=0 to output mixers */
10001	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10002	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10003
10004	/* set up input amps for analog loopback */
10005	/* Amp Indices: DAC = 0, mixer = 1 */
10006	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10007	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10008	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10009	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10010	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10011	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10012
10013	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10014	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10015	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10016	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10017	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10018	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10019	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10020
10021	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10022	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10023	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10024	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10025	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10026	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10027	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10028
10029	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10030	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10031
10032	/* FIXME: use matrix-type input source selection */
10033	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10034	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10035	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10036	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10037	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10038	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10039
10040	/* set EAPD */
10041	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10042	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10043	{ }
10044};
10045
10046/* add playback controls from the parsed DAC table */
10047static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10048					     const struct auto_pin_cfg *cfg)
10049{
10050	hda_nid_t nid;
10051	int err;
10052
10053	spec->multiout.num_dacs = 1;	/* only use one dac */
10054	spec->multiout.dac_nids = spec->private_dac_nids;
10055	spec->multiout.dac_nids[0] = 2;
10056
10057	nid = cfg->line_out_pins[0];
10058	if (nid) {
10059		err = add_control(spec, ALC_CTL_WIDGET_VOL,
10060				  "Front Playback Volume",
10061				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10062		if (err < 0)
10063			return err;
10064		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10065				  "Front Playback Switch",
10066				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10067		if (err < 0)
10068			return err;
10069	}
10070
10071	nid = cfg->speaker_pins[0];
10072	if (nid) {
10073		if (!cfg->line_out_pins[0]) {
10074			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10075					  "Speaker Playback Volume",
10076					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10077							      HDA_OUTPUT));
10078			if (err < 0)
10079				return err;
10080		}
10081		if (nid == 0x16) {
10082			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10083					  "Speaker Playback Switch",
10084					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10085							      HDA_OUTPUT));
10086			if (err < 0)
10087				return err;
10088		} else {
10089			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10090					  "Speaker Playback Switch",
10091					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10092							      HDA_OUTPUT));
10093			if (err < 0)
10094				return err;
10095		}
10096	}
10097	nid = cfg->hp_pins[0];
10098	if (nid) {
10099		/* spec->multiout.hp_nid = 2; */
10100		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10101			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10102					  "Headphone Playback Volume",
10103					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10104							      HDA_OUTPUT));
10105			if (err < 0)
10106				return err;
10107		}
10108		if (nid == 0x16) {
10109			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10110					  "Headphone Playback Switch",
10111					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10112							      HDA_OUTPUT));
10113			if (err < 0)
10114				return err;
10115		} else {
10116			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10117					  "Headphone Playback Switch",
10118					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10119							      HDA_OUTPUT));
10120			if (err < 0)
10121				return err;
10122		}
10123	}
10124	return 0;
10125}
10126
10127#define alc269_auto_create_analog_input_ctls \
10128	alc880_auto_create_analog_input_ctls
10129
10130#ifdef CONFIG_SND_HDA_POWER_SAVE
10131#define alc269_loopbacks	alc880_loopbacks
10132#endif
10133
10134/* pcm configuration: identiacal with ALC880 */
10135#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
10136#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
10137#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
10138#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
10139
10140/*
10141 * BIOS auto configuration
10142 */
10143static int alc269_parse_auto_config(struct hda_codec *codec)
10144{
10145	struct alc_spec *spec = codec->spec;
10146	int err;
10147	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10148
10149	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10150					   alc269_ignore);
10151	if (err < 0)
10152		return err;
10153
10154	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10155	if (err < 0)
10156		return err;
10157	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10158	if (err < 0)
10159		return err;
10160
10161	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10162
10163	if (spec->autocfg.dig_out_pin)
10164		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10165
10166	if (spec->kctl_alloc)
10167		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10168
10169	spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10170	spec->num_mux_defs = 1;
10171	spec->input_mux = &spec->private_imux;
10172
10173	err = alc_auto_add_mic_boost(codec);
10174	if (err < 0)
10175		return err;
10176
10177	return 1;
10178}
10179
10180#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
10181#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
10182#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
10183
10184
10185/* init callback for auto-configuration model -- overriding the default init */
10186static void alc269_auto_init(struct hda_codec *codec)
10187{
10188	alc269_auto_init_multi_out(codec);
10189	alc269_auto_init_hp_out(codec);
10190	alc269_auto_init_analog_input(codec);
10191}
10192
10193/*
10194 * configuration and preset
10195 */
10196static const char *alc269_models[ALC269_MODEL_LAST] = {
10197	[ALC269_BASIC]		= "basic",
10198};
10199
10200static struct snd_pci_quirk alc269_cfg_tbl[] = {
10201	{}
10202};
10203
10204static struct alc_config_preset alc269_presets[] = {
10205	[ALC269_BASIC] = {
10206		.mixers = { alc269_base_mixer },
10207		.init_verbs = { alc269_init_verbs },
10208		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
10209		.dac_nids = alc269_dac_nids,
10210		.hp_nid = 0x03,
10211		.num_channel_mode = ARRAY_SIZE(alc269_modes),
10212		.channel_mode = alc269_modes,
10213		.input_mux = &alc269_capture_source,
10214	},
10215};
10216
10217static int patch_alc269(struct hda_codec *codec)
10218{
10219	struct alc_spec *spec;
10220	int board_config;
10221	int err;
10222
10223	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10224	if (spec == NULL)
10225		return -ENOMEM;
10226
10227	codec->spec = spec;
10228
10229	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10230						  alc269_models,
10231						  alc269_cfg_tbl);
10232
10233	if (board_config < 0) {
10234		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10235		       "trying auto-probe from BIOS...\n");
10236		board_config = ALC269_AUTO;
10237	}
10238
10239	if (board_config == ALC269_AUTO) {
10240		/* automatic parse from the BIOS config */
10241		err = alc269_parse_auto_config(codec);
10242		if (err < 0) {
10243			alc_free(codec);
10244			return err;
10245		} else if (!err) {
10246			printk(KERN_INFO
10247			       "hda_codec: Cannot set up configuration "
10248			       "from BIOS.  Using base mode...\n");
10249			board_config = ALC269_BASIC;
10250		}
10251	}
10252
10253	if (board_config != ALC269_AUTO)
10254		setup_preset(spec, &alc269_presets[board_config]);
10255
10256	spec->stream_name_analog = "ALC269 Analog";
10257	spec->stream_analog_playback = &alc269_pcm_analog_playback;
10258	spec->stream_analog_capture = &alc269_pcm_analog_capture;
10259
10260	spec->stream_name_digital = "ALC269 Digital";
10261	spec->stream_digital_playback = &alc269_pcm_digital_playback;
10262	spec->stream_digital_capture = &alc269_pcm_digital_capture;
10263
10264	spec->adc_nids = alc269_adc_nids;
10265	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10266	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10267	spec->num_mixers++;
10268
10269	codec->patch_ops = alc_patch_ops;
10270	if (board_config == ALC269_AUTO)
10271		spec->init_hook = alc269_auto_init;
10272#ifdef CONFIG_SND_HDA_POWER_SAVE
10273	if (!spec->loopback.amplist)
10274		spec->loopback.amplist = alc269_loopbacks;
10275#endif
10276
10277	return 0;
10278}
10279
10280/*
10281 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
10282 */
10283
10284/*
10285 * set the path ways for 2 channel output
10286 * need to set the codec line out and mic 1 pin widgets to inputs
10287 */
10288static struct hda_verb alc861_threestack_ch2_init[] = {
10289	/* set pin widget 1Ah (line in) for input */
10290	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10291	/* set pin widget 18h (mic1/2) for input, for mic also enable
10292	 * the vref
10293	 */
10294	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10295
10296	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10297#if 0
10298	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10299	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10300#endif
10301	{ } /* end */
10302};
10303/*
10304 * 6ch mode
10305 * need to set the codec line out and mic 1 pin widgets to outputs
10306 */
10307static struct hda_verb alc861_threestack_ch6_init[] = {
10308	/* set pin widget 1Ah (line in) for output (Back Surround)*/
10309	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10310	/* set pin widget 18h (mic1) for output (CLFE)*/
10311	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10312
10313	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10314	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10315
10316	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10317#if 0
10318	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10319	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10320#endif
10321	{ } /* end */
10322};
10323
10324static struct hda_channel_mode alc861_threestack_modes[2] = {
10325	{ 2, alc861_threestack_ch2_init },
10326	{ 6, alc861_threestack_ch6_init },
10327};
10328/* Set mic1 as input and unmute the mixer */
10329static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10330	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10331	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10332	{ } /* end */
10333};
10334/* Set mic1 as output and mute mixer */
10335static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10336	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10337	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10338	{ } /* end */
10339};
10340
10341static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10342	{ 2, alc861_uniwill_m31_ch2_init },
10343	{ 4, alc861_uniwill_m31_ch4_init },
10344};
10345
10346/* Set mic1 and line-in as input and unmute the mixer */
10347static struct hda_verb alc861_asus_ch2_init[] = {
10348	/* set pin widget 1Ah (line in) for input */
10349	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10350	/* set pin widget 18h (mic1/2) for input, for mic also enable
10351	 * the vref
10352	 */
10353	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10354
10355	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10356#if 0
10357	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10358	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10359#endif
10360	{ } /* end */
10361};
10362/* Set mic1 nad line-in as output and mute mixer */
10363static struct hda_verb alc861_asus_ch6_init[] = {
10364	/* set pin widget 1Ah (line in) for output (Back Surround)*/
10365	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10366	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10367	/* set pin widget 18h (mic1) for output (CLFE)*/
10368	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10369	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10370	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10371	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10372
10373	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10374#if 0
10375	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10376	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10377#endif
10378	{ } /* end */
10379};
10380
10381static struct hda_channel_mode alc861_asus_modes[2] = {
10382	{ 2, alc861_asus_ch2_init },
10383	{ 6, alc861_asus_ch6_init },
10384};
10385
10386/* patch-ALC861 */
10387
10388static struct snd_kcontrol_new alc861_base_mixer[] = {
10389        /* output mixer control */
10390	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10391	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10392	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10393	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10394	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10395
10396        /*Input mixer control */
10397	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10398	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10399	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10400	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10401	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10402	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10403	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10404	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10405	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10406	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10407
10408        /* Capture mixer control */
10409	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10410	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10411	{
10412		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10413		.name = "Capture Source",
10414		.count = 1,
10415		.info = alc_mux_enum_info,
10416		.get = alc_mux_enum_get,
10417		.put = alc_mux_enum_put,
10418	},
10419	{ } /* end */
10420};
10421
10422static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10423        /* output mixer control */
10424	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10425	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10426	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10427	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10428	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10429
10430	/* Input mixer control */
10431	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10432	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10433	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10434	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10435	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10436	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10437	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10438	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10439	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10440	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10441
10442	/* Capture mixer control */
10443	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10444	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10445	{
10446		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10447		.name = "Capture Source",
10448		.count = 1,
10449		.info = alc_mux_enum_info,
10450		.get = alc_mux_enum_get,
10451		.put = alc_mux_enum_put,
10452	},
10453	{
10454		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10455		.name = "Channel Mode",
10456		.info = alc_ch_mode_info,
10457		.get = alc_ch_mode_get,
10458		.put = alc_ch_mode_put,
10459                .private_value = ARRAY_SIZE(alc861_threestack_modes),
10460	},
10461	{ } /* end */
10462};
10463
10464static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
10465        /* output mixer control */
10466	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10467	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10468	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10469
10470        /*Capture mixer control */
10471	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10472	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10473	{
10474		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10475		.name = "Capture Source",
10476		.count = 1,
10477		.info = alc_mux_enum_info,
10478		.get = alc_mux_enum_get,
10479		.put = alc_mux_enum_put,
10480	},
10481
10482	{ } /* end */
10483};
10484
10485static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10486        /* output mixer control */
10487	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10488	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10489	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10490	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10491	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10492
10493	/* Input mixer control */
10494	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10495	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10496	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10497	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10498	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10499	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10500	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10501	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10502	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10503	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10504
10505	/* Capture mixer control */
10506	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10507	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10508	{
10509		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10510		.name = "Capture Source",
10511		.count = 1,
10512		.info = alc_mux_enum_info,
10513		.get = alc_mux_enum_get,
10514		.put = alc_mux_enum_put,
10515	},
10516	{
10517		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10518		.name = "Channel Mode",
10519		.info = alc_ch_mode_info,
10520		.get = alc_ch_mode_get,
10521		.put = alc_ch_mode_put,
10522                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10523	},
10524	{ } /* end */
10525};
10526
10527static struct snd_kcontrol_new alc861_asus_mixer[] = {
10528        /* output mixer control */
10529	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10530	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10531	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10532	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10533	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10534
10535	/* Input mixer control */
10536	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10537	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10538	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10539	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10540	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10541	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10542	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10543	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10544	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10545	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10546
10547	/* Capture mixer control */
10548	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10549	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10550	{
10551		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10552		.name = "Capture Source",
10553		.count = 1,
10554		.info = alc_mux_enum_info,
10555		.get = alc_mux_enum_get,
10556		.put = alc_mux_enum_put,
10557	},
10558	{
10559		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10560		.name = "Channel Mode",
10561		.info = alc_ch_mode_info,
10562		.get = alc_ch_mode_get,
10563		.put = alc_ch_mode_put,
10564                .private_value = ARRAY_SIZE(alc861_asus_modes),
10565	},
10566	{ }
10567};
10568
10569/* additional mixer */
10570static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
10571	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10572	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10573	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10574	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10575	{ }
10576};
10577
10578/*
10579 * generic initialization of ADC, input mixers and output mixers
10580 */
10581static struct hda_verb alc861_base_init_verbs[] = {
10582	/*
10583	 * Unmute ADC0 and set the default input to mic-in
10584	 */
10585	/* port-A for surround (rear panel) */
10586	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10587	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10588	/* port-B for mic-in (rear panel) with vref */
10589	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10590	/* port-C for line-in (rear panel) */
10591	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10592	/* port-D for Front */
10593	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10594	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10595	/* port-E for HP out (front panel) */
10596	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10597	/* route front PCM to HP */
10598	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10599	/* port-F for mic-in (front panel) with vref */
10600	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10601	/* port-G for CLFE (rear panel) */
10602	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10603	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10604	/* port-H for side (rear panel) */
10605	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10606	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10607	/* CD-in */
10608	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10609	/* route front mic to ADC1*/
10610	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10611	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10612
10613	/* Unmute DAC0~3 & spdif out*/
10614	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10615	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10616	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10617	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10618	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10619
10620	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10621	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10622        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10623	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10624        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10625
10626	/* Unmute Stereo Mixer 15 */
10627	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10628	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10629	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10630	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10631
10632	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10633	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10634	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10635	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10636	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10637	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10638	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10639	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10640	/* hp used DAC 3 (Front) */
10641	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10642        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10643
10644	{ }
10645};
10646
10647static struct hda_verb alc861_threestack_init_verbs[] = {
10648	/*
10649	 * Unmute ADC0 and set the default input to mic-in
10650	 */
10651	/* port-A for surround (rear panel) */
10652	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10653	/* port-B for mic-in (rear panel) with vref */
10654	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10655	/* port-C for line-in (rear panel) */
10656	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10657	/* port-D for Front */
10658	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10659	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10660	/* port-E for HP out (front panel) */
10661	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10662	/* route front PCM to HP */
10663	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10664	/* port-F for mic-in (front panel) with vref */
10665	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10666	/* port-G for CLFE (rear panel) */
10667	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10668	/* port-H for side (rear panel) */
10669	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10670	/* CD-in */
10671	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10672	/* route front mic to ADC1*/
10673	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10674	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10675	/* Unmute DAC0~3 & spdif out*/
10676	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10677	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10678	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10679	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10680	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10681
10682	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10683	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10684        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10685	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10686        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10687
10688	/* Unmute Stereo Mixer 15 */
10689	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10690	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10691	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10692	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10693
10694	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10695	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10696	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10697	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10698	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10699	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10700	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10701	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10702	/* hp used DAC 3 (Front) */
10703	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10704        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10705	{ }
10706};
10707
10708static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10709	/*
10710	 * Unmute ADC0 and set the default input to mic-in
10711	 */
10712	/* port-A for surround (rear panel) */
10713	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10714	/* port-B for mic-in (rear panel) with vref */
10715	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10716	/* port-C for line-in (rear panel) */
10717	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10718	/* port-D for Front */
10719	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10720	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10721	/* port-E for HP out (front panel) */
10722	/* this has to be set to VREF80 */
10723	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10724	/* route front PCM to HP */
10725	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10726	/* port-F for mic-in (front panel) with vref */
10727	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10728	/* port-G for CLFE (rear panel) */
10729	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10730	/* port-H for side (rear panel) */
10731	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10732	/* CD-in */
10733	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10734	/* route front mic to ADC1*/
10735	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10736	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10737	/* Unmute DAC0~3 & spdif out*/
10738	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10739	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10740	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10741	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10742	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10743
10744	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10745	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10746        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10747	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10748        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10749
10750	/* Unmute Stereo Mixer 15 */
10751	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10752	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10753	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10754	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10755
10756	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10757	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10758	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10759	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10760	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10761	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10762	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10763	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10764	/* hp used DAC 3 (Front) */
10765	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10766        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10767	{ }
10768};
10769
10770static struct hda_verb alc861_asus_init_verbs[] = {
10771	/*
10772	 * Unmute ADC0 and set the default input to mic-in
10773	 */
10774	/* port-A for surround (rear panel)
10775	 * according to codec#0 this is the HP jack
10776	 */
10777	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10778	/* route front PCM to HP */
10779	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10780	/* port-B for mic-in (rear panel) with vref */
10781	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10782	/* port-C for line-in (rear panel) */
10783	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10784	/* port-D for Front */
10785	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10786	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10787	/* port-E for HP out (front panel) */
10788	/* this has to be set to VREF80 */
10789	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10790	/* route front PCM to HP */
10791	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10792	/* port-F for mic-in (front panel) with vref */
10793	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10794	/* port-G for CLFE (rear panel) */
10795	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10796	/* port-H for side (rear panel) */
10797	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10798	/* CD-in */
10799	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10800	/* route front mic to ADC1*/
10801	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10802	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10803	/* Unmute DAC0~3 & spdif out*/
10804	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10805	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10806	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10807	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10808	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10809	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10810	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10811        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10812	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10813        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10814
10815	/* Unmute Stereo Mixer 15 */
10816	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10817	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10818	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10819	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
10820
10821	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10822	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10823	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10824	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10825	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10826	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10827	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10828	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10829	/* hp used DAC 3 (Front) */
10830	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10831	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10832	{ }
10833};
10834
10835/* additional init verbs for ASUS laptops */
10836static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10837	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10838	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10839	{ }
10840};
10841
10842/*
10843 * generic initialization of ADC, input mixers and output mixers
10844 */
10845static struct hda_verb alc861_auto_init_verbs[] = {
10846	/*
10847	 * Unmute ADC0 and set the default input to mic-in
10848	 */
10849	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
10850	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10851
10852	/* Unmute DAC0~3 & spdif out*/
10853	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10854	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10855	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10856	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10857	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10858
10859	/* Unmute Mixer 14 (mic) 1c (Line in)*/
10860	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10861	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10862	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10863	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10864
10865	/* Unmute Stereo Mixer 15 */
10866	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10867	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10868	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10869	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10870
10871	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10872	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10873	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10874	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10875	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10876	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10877	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10878	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10879
10880	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10881	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10882	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10883	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10884	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10885	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10886	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10887	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10888
10889	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
10890
10891	{ }
10892};
10893
10894static struct hda_verb alc861_toshiba_init_verbs[] = {
10895	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10896
10897	{ }
10898};
10899
10900/* toggle speaker-output according to the hp-jack state */
10901static void alc861_toshiba_automute(struct hda_codec *codec)
10902{
10903	unsigned int present;
10904
10905	present = snd_hda_codec_read(codec, 0x0f, 0,
10906				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10907	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10908				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10909	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10910				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10911}
10912
10913static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10914				       unsigned int res)
10915{
10916	if ((res >> 26) == ALC880_HP_EVENT)
10917		alc861_toshiba_automute(codec);
10918}
10919
10920/* pcm configuration: identiacal with ALC880 */
10921#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
10922#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
10923#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
10924#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
10925
10926
10927#define ALC861_DIGOUT_NID	0x07
10928
10929static struct hda_channel_mode alc861_8ch_modes[1] = {
10930	{ 8, NULL }
10931};
10932
10933static hda_nid_t alc861_dac_nids[4] = {
10934	/* front, surround, clfe, side */
10935	0x03, 0x06, 0x05, 0x04
10936};
10937
10938static hda_nid_t alc660_dac_nids[3] = {
10939	/* front, clfe, surround */
10940	0x03, 0x05, 0x06
10941};
10942
10943static hda_nid_t alc861_adc_nids[1] = {
10944	/* ADC0-2 */
10945	0x08,
10946};
10947
10948static struct hda_input_mux alc861_capture_source = {
10949	.num_items = 5,
10950	.items = {
10951		{ "Mic", 0x0 },
10952		{ "Front Mic", 0x3 },
10953		{ "Line", 0x1 },
10954		{ "CD", 0x4 },
10955		{ "Mixer", 0x5 },
10956	},
10957};
10958
10959/* fill in the dac_nids table from the parsed pin configuration */
10960static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10961				     const struct auto_pin_cfg *cfg)
10962{
10963	int i;
10964	hda_nid_t nid;
10965
10966	spec->multiout.dac_nids = spec->private_dac_nids;
10967	for (i = 0; i < cfg->line_outs; i++) {
10968		nid = cfg->line_out_pins[i];
10969		if (nid) {
10970			if (i >= ARRAY_SIZE(alc861_dac_nids))
10971				continue;
10972			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10973		}
10974	}
10975	spec->multiout.num_dacs = cfg->line_outs;
10976	return 0;
10977}
10978
10979/* add playback controls from the parsed DAC table */
10980static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10981					     const struct auto_pin_cfg *cfg)
10982{
10983	char name[32];
10984	static const char *chname[4] = {
10985		"Front", "Surround", NULL /*CLFE*/, "Side"
10986	};
10987	hda_nid_t nid;
10988	int i, idx, err;
10989
10990	for (i = 0; i < cfg->line_outs; i++) {
10991		nid = spec->multiout.dac_nids[i];
10992		if (!nid)
10993			continue;
10994		if (nid == 0x05) {
10995			/* Center/LFE */
10996			err = add_control(spec, ALC_CTL_BIND_MUTE,
10997					  "Center Playback Switch",
10998					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10999							      HDA_OUTPUT));
11000			if (err < 0)
11001				return err;
11002			err = add_control(spec, ALC_CTL_BIND_MUTE,
11003					  "LFE Playback Switch",
11004					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11005							      HDA_OUTPUT));
11006			if (err < 0)
11007				return err;
11008		} else {
11009			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11010			     idx++)
11011				if (nid == alc861_dac_nids[idx])
11012					break;
11013			sprintf(name, "%s Playback Switch", chname[idx]);
11014			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11015					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11016							      HDA_OUTPUT));
11017			if (err < 0)
11018				return err;
11019		}
11020	}
11021	return 0;
11022}
11023
11024static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11025{
11026	int err;
11027	hda_nid_t nid;
11028
11029	if (!pin)
11030		return 0;
11031
11032	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11033		nid = 0x03;
11034		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11035				  "Headphone Playback Switch",
11036				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11037		if (err < 0)
11038			return err;
11039		spec->multiout.hp_nid = nid;
11040	}
11041	return 0;
11042}
11043
11044/* create playback/capture controls for input pins */
11045static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11046						const struct auto_pin_cfg *cfg)
11047{
11048	struct hda_input_mux *imux = &spec->private_imux;
11049	int i, err, idx, idx1;
11050
11051	for (i = 0; i < AUTO_PIN_LAST; i++) {
11052		switch (cfg->input_pins[i]) {
11053		case 0x0c:
11054			idx1 = 1;
11055			idx = 2;	/* Line In */
11056			break;
11057		case 0x0f:
11058			idx1 = 2;
11059			idx = 2;	/* Line In */
11060			break;
11061		case 0x0d:
11062			idx1 = 0;
11063			idx = 1;	/* Mic In */
11064			break;
11065		case 0x10:
11066			idx1 = 3;
11067			idx = 1;	/* Mic In */
11068			break;
11069		case 0x11:
11070			idx1 = 4;
11071			idx = 0;	/* CD */
11072			break;
11073		default:
11074			continue;
11075		}
11076
11077		err = new_analog_input(spec, cfg->input_pins[i],
11078				       auto_pin_cfg_labels[i], idx, 0x15);
11079		if (err < 0)
11080			return err;
11081
11082		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11083		imux->items[imux->num_items].index = idx1;
11084		imux->num_items++;
11085	}
11086	return 0;
11087}
11088
11089static struct snd_kcontrol_new alc861_capture_mixer[] = {
11090	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11091	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11092
11093	{
11094		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11095		/* The multiple "Capture Source" controls confuse alsamixer
11096		 * So call somewhat different..
11097		 *FIXME: the controls appear in the "playback" view!
11098		 */
11099		/* .name = "Capture Source", */
11100		.name = "Input Source",
11101		.count = 1,
11102		.info = alc_mux_enum_info,
11103		.get = alc_mux_enum_get,
11104		.put = alc_mux_enum_put,
11105	},
11106	{ } /* end */
11107};
11108
11109static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11110					      hda_nid_t nid,
11111					      int pin_type, int dac_idx)
11112{
11113	/* set as output */
11114
11115	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11116			    pin_type);
11117	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11118			    AMP_OUT_UNMUTE);
11119
11120}
11121
11122static void alc861_auto_init_multi_out(struct hda_codec *codec)
11123{
11124	struct alc_spec *spec = codec->spec;
11125	int i;
11126
11127	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
11128	for (i = 0; i < spec->autocfg.line_outs; i++) {
11129		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11130		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11131		if (nid)
11132			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
11133							  spec->multiout.dac_nids[i]);
11134	}
11135}
11136
11137static void alc861_auto_init_hp_out(struct hda_codec *codec)
11138{
11139	struct alc_spec *spec = codec->spec;
11140	hda_nid_t pin;
11141
11142	pin = spec->autocfg.hp_pins[0];
11143	if (pin) /* connect to front */
11144		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11145						  spec->multiout.dac_nids[0]);
11146}
11147
11148static void alc861_auto_init_analog_input(struct hda_codec *codec)
11149{
11150	struct alc_spec *spec = codec->spec;
11151	int i;
11152
11153	for (i = 0; i < AUTO_PIN_LAST; i++) {
11154		hda_nid_t nid = spec->autocfg.input_pins[i];
11155		if (nid >= 0x0c && nid <= 0x11) {
11156			snd_hda_codec_write(codec, nid, 0,
11157					    AC_VERB_SET_PIN_WIDGET_CONTROL,
11158					    i <= AUTO_PIN_FRONT_MIC ?
11159					    PIN_VREF80 : PIN_IN);
11160		}
11161	}
11162}
11163
11164/* parse the BIOS configuration and set up the alc_spec */
11165/* return 1 if successful, 0 if the proper config is not found,
11166 * or a negative error code
11167 */
11168static int alc861_parse_auto_config(struct hda_codec *codec)
11169{
11170	struct alc_spec *spec = codec->spec;
11171	int err;
11172	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11173
11174	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11175					   alc861_ignore);
11176	if (err < 0)
11177		return err;
11178	if (!spec->autocfg.line_outs)
11179		return 0; /* can't find valid BIOS pin config */
11180
11181	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11182	if (err < 0)
11183		return err;
11184	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11185	if (err < 0)
11186		return err;
11187	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11188	if (err < 0)
11189		return err;
11190	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11191	if (err < 0)
11192		return err;
11193
11194	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11195
11196	if (spec->autocfg.dig_out_pin)
11197		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11198
11199	if (spec->kctl_alloc)
11200		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11201
11202	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11203
11204	spec->num_mux_defs = 1;
11205	spec->input_mux = &spec->private_imux;
11206
11207	spec->adc_nids = alc861_adc_nids;
11208	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11209	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11210	spec->num_mixers++;
11211
11212	return 1;
11213}
11214
11215/* additional initialization for auto-configuration model */
11216static void alc861_auto_init(struct hda_codec *codec)
11217{
11218	alc861_auto_init_multi_out(codec);
11219	alc861_auto_init_hp_out(codec);
11220	alc861_auto_init_analog_input(codec);
11221}
11222
11223#ifdef CONFIG_SND_HDA_POWER_SAVE
11224static struct hda_amp_list alc861_loopbacks[] = {
11225	{ 0x15, HDA_INPUT, 0 },
11226	{ 0x15, HDA_INPUT, 1 },
11227	{ 0x15, HDA_INPUT, 2 },
11228	{ 0x15, HDA_INPUT, 3 },
11229	{ } /* end */
11230};
11231#endif
11232
11233
11234/*
11235 * configuration and preset
11236 */
11237static const char *alc861_models[ALC861_MODEL_LAST] = {
11238	[ALC861_3ST]		= "3stack",
11239	[ALC660_3ST]		= "3stack-660",
11240	[ALC861_3ST_DIG]	= "3stack-dig",
11241	[ALC861_6ST_DIG]	= "6stack-dig",
11242	[ALC861_UNIWILL_M31]	= "uniwill-m31",
11243	[ALC861_TOSHIBA]	= "toshiba",
11244	[ALC861_ASUS]		= "asus",
11245	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
11246	[ALC861_AUTO]		= "auto",
11247};
11248
11249static struct snd_pci_quirk alc861_cfg_tbl[] = {
11250	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
11251	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11252	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11253	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
11254	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
11255	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
11256	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
11257	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11258	 *        Any other models that need this preset?
11259	 */
11260	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
11261	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11262	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
11263	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
11264	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11265	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11266	/* FIXME: the below seems conflict */
11267	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
11268	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
11269	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
11270	{}
11271};
11272
11273static struct alc_config_preset alc861_presets[] = {
11274	[ALC861_3ST] = {
11275		.mixers = { alc861_3ST_mixer },
11276		.init_verbs = { alc861_threestack_init_verbs },
11277		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
11278		.dac_nids = alc861_dac_nids,
11279		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11280		.channel_mode = alc861_threestack_modes,
11281		.need_dac_fix = 1,
11282		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11283		.adc_nids = alc861_adc_nids,
11284		.input_mux = &alc861_capture_source,
11285	},
11286	[ALC861_3ST_DIG] = {
11287		.mixers = { alc861_base_mixer },
11288		.init_verbs = { alc861_threestack_init_verbs },
11289		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
11290		.dac_nids = alc861_dac_nids,
11291		.dig_out_nid = ALC861_DIGOUT_NID,
11292		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11293		.channel_mode = alc861_threestack_modes,
11294		.need_dac_fix = 1,
11295		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11296		.adc_nids = alc861_adc_nids,
11297		.input_mux = &alc861_capture_source,
11298	},
11299	[ALC861_6ST_DIG] = {
11300		.mixers = { alc861_base_mixer },
11301		.init_verbs = { alc861_base_init_verbs },
11302		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
11303		.dac_nids = alc861_dac_nids,
11304		.dig_out_nid = ALC861_DIGOUT_NID,
11305		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11306		.channel_mode = alc861_8ch_modes,
11307		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11308		.adc_nids = alc861_adc_nids,
11309		.input_mux = &alc861_capture_source,
11310	},
11311	[ALC660_3ST] = {
11312		.mixers = { alc861_3ST_mixer },
11313		.init_verbs = { alc861_threestack_init_verbs },
11314		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
11315		.dac_nids = alc660_dac_nids,
11316		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11317		.channel_mode = alc861_threestack_modes,
11318		.need_dac_fix = 1,
11319		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11320		.adc_nids = alc861_adc_nids,
11321		.input_mux = &alc861_capture_source,
11322	},
11323	[ALC861_UNIWILL_M31] = {
11324		.mixers = { alc861_uniwill_m31_mixer },
11325		.init_verbs = { alc861_uniwill_m31_init_verbs },
11326		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
11327		.dac_nids = alc861_dac_nids,
11328		.dig_out_nid = ALC861_DIGOUT_NID,
11329		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11330		.channel_mode = alc861_uniwill_m31_modes,
11331		.need_dac_fix = 1,
11332		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11333		.adc_nids = alc861_adc_nids,
11334		.input_mux = &alc861_capture_source,
11335	},
11336	[ALC861_TOSHIBA] = {
11337		.mixers = { alc861_toshiba_mixer },
11338		.init_verbs = { alc861_base_init_verbs,
11339				alc861_toshiba_init_verbs },
11340		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
11341		.dac_nids = alc861_dac_nids,
11342		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11343		.channel_mode = alc883_3ST_2ch_modes,
11344		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11345		.adc_nids = alc861_adc_nids,
11346		.input_mux = &alc861_capture_source,
11347		.unsol_event = alc861_toshiba_unsol_event,
11348		.init_hook = alc861_toshiba_automute,
11349	},
11350	[ALC861_ASUS] = {
11351		.mixers = { alc861_asus_mixer },
11352		.init_verbs = { alc861_asus_init_verbs },
11353		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
11354		.dac_nids = alc861_dac_nids,
11355		.dig_out_nid = ALC861_DIGOUT_NID,
11356		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11357		.channel_mode = alc861_asus_modes,
11358		.need_dac_fix = 1,
11359		.hp_nid = 0x06,
11360		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11361		.adc_nids = alc861_adc_nids,
11362		.input_mux = &alc861_capture_source,
11363	},
11364	[ALC861_ASUS_LAPTOP] = {
11365		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11366		.init_verbs = { alc861_asus_init_verbs,
11367				alc861_asus_laptop_init_verbs },
11368		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
11369		.dac_nids = alc861_dac_nids,
11370		.dig_out_nid = ALC861_DIGOUT_NID,
11371		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11372		.channel_mode = alc883_3ST_2ch_modes,
11373		.need_dac_fix = 1,
11374		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11375		.adc_nids = alc861_adc_nids,
11376		.input_mux = &alc861_capture_source,
11377	},
11378};
11379
11380
11381static int patch_alc861(struct hda_codec *codec)
11382{
11383	struct alc_spec *spec;
11384	int board_config;
11385	int err;
11386
11387	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11388	if (spec == NULL)
11389		return -ENOMEM;
11390
11391	codec->spec = spec;
11392
11393        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11394						  alc861_models,
11395						  alc861_cfg_tbl);
11396
11397	if (board_config < 0) {
11398		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11399		       "trying auto-probe from BIOS...\n");
11400		board_config = ALC861_AUTO;
11401	}
11402
11403	if (board_config == ALC861_AUTO) {
11404		/* automatic parse from the BIOS config */
11405		err = alc861_parse_auto_config(codec);
11406		if (err < 0) {
11407			alc_free(codec);
11408			return err;
11409		} else if (!err) {
11410			printk(KERN_INFO
11411			       "hda_codec: Cannot set up configuration "
11412			       "from BIOS.  Using base mode...\n");
11413		   board_config = ALC861_3ST_DIG;
11414		}
11415	}
11416
11417	if (board_config != ALC861_AUTO)
11418		setup_preset(spec, &alc861_presets[board_config]);
11419
11420	spec->stream_name_analog = "ALC861 Analog";
11421	spec->stream_analog_playback = &alc861_pcm_analog_playback;
11422	spec->stream_analog_capture = &alc861_pcm_analog_capture;
11423
11424	spec->stream_name_digital = "ALC861 Digital";
11425	spec->stream_digital_playback = &alc861_pcm_digital_playback;
11426	spec->stream_digital_capture = &alc861_pcm_digital_capture;
11427
11428	spec->vmaster_nid = 0x03;
11429
11430	codec->patch_ops = alc_patch_ops;
11431	if (board_config == ALC861_AUTO)
11432		spec->init_hook = alc861_auto_init;
11433#ifdef CONFIG_SND_HDA_POWER_SAVE
11434	if (!spec->loopback.amplist)
11435		spec->loopback.amplist = alc861_loopbacks;
11436#endif
11437
11438	return 0;
11439}
11440
11441/*
11442 * ALC861-VD support
11443 *
11444 * Based on ALC882
11445 *
11446 * In addition, an independent DAC
11447 */
11448#define ALC861VD_DIGOUT_NID	0x06
11449
11450static hda_nid_t alc861vd_dac_nids[4] = {
11451	/* front, surr, clfe, side surr */
11452	0x02, 0x03, 0x04, 0x05
11453};
11454
11455/* dac_nids for ALC660vd are in a different order - according to
11456 * Realtek's driver.
11457 * This should probably tesult in a different mixer for 6stack models
11458 * of ALC660vd codecs, but for now there is only 3stack mixer
11459 * - and it is the same as in 861vd.
11460 * adc_nids in ALC660vd are (is) the same as in 861vd
11461 */
11462static hda_nid_t alc660vd_dac_nids[3] = {
11463	/* front, rear, clfe, rear_surr */
11464	0x02, 0x04, 0x03
11465};
11466
11467static hda_nid_t alc861vd_adc_nids[1] = {
11468	/* ADC0 */
11469	0x09,
11470};
11471
11472/* input MUX */
11473/* FIXME: should be a matrix-type input source selection */
11474static struct hda_input_mux alc861vd_capture_source = {
11475	.num_items = 4,
11476	.items = {
11477		{ "Mic", 0x0 },
11478		{ "Front Mic", 0x1 },
11479		{ "Line", 0x2 },
11480		{ "CD", 0x4 },
11481	},
11482};
11483
11484static struct hda_input_mux alc861vd_dallas_capture_source = {
11485	.num_items = 3,
11486	.items = {
11487		{ "Front Mic", 0x0 },
11488		{ "ATAPI Mic", 0x1 },
11489		{ "Line In", 0x5 },
11490	},
11491};
11492
11493static struct hda_input_mux alc861vd_hp_capture_source = {
11494	.num_items = 2,
11495	.items = {
11496		{ "Front Mic", 0x0 },
11497		{ "ATAPI Mic", 0x1 },
11498	},
11499};
11500
11501#define alc861vd_mux_enum_info alc_mux_enum_info
11502#define alc861vd_mux_enum_get alc_mux_enum_get
11503
11504static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11505				struct snd_ctl_elem_value *ucontrol)
11506{
11507	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11508	struct alc_spec *spec = codec->spec;
11509	const struct hda_input_mux *imux = spec->input_mux;
11510	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11511	static hda_nid_t capture_mixers[1] = { 0x22 };
11512	hda_nid_t nid = capture_mixers[adc_idx];
11513	unsigned int *cur_val = &spec->cur_mux[adc_idx];
11514	unsigned int i, idx;
11515
11516	idx = ucontrol->value.enumerated.item[0];
11517	if (idx >= imux->num_items)
11518		idx = imux->num_items - 1;
11519	if (*cur_val == idx)
11520		return 0;
11521	for (i = 0; i < imux->num_items; i++) {
11522		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11523		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11524					 imux->items[i].index,
11525					 HDA_AMP_MUTE, v);
11526	}
11527	*cur_val = idx;
11528	return 1;
11529}
11530
11531/*
11532 * 2ch mode
11533 */
11534static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11535	{ 2, NULL }
11536};
11537
11538/*
11539 * 6ch mode
11540 */
11541static struct hda_verb alc861vd_6stack_ch6_init[] = {
11542	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11543	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11544	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11545	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11546	{ } /* end */
11547};
11548
11549/*
11550 * 8ch mode
11551 */
11552static struct hda_verb alc861vd_6stack_ch8_init[] = {
11553	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11554	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11555	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11556	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11557	{ } /* end */
11558};
11559
11560static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11561	{ 6, alc861vd_6stack_ch6_init },
11562	{ 8, alc861vd_6stack_ch8_init },
11563};
11564
11565static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11566	{
11567		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11568		.name = "Channel Mode",
11569		.info = alc_ch_mode_info,
11570		.get = alc_ch_mode_get,
11571		.put = alc_ch_mode_put,
11572	},
11573	{ } /* end */
11574};
11575
11576static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11577	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11578	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11579
11580	{
11581		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11582		/* The multiple "Capture Source" controls confuse alsamixer
11583		 * So call somewhat different..
11584		 *FIXME: the controls appear in the "playback" view!
11585		 */
11586		/* .name = "Capture Source", */
11587		.name = "Input Source",
11588		.count = 1,
11589		.info = alc861vd_mux_enum_info,
11590		.get = alc861vd_mux_enum_get,
11591		.put = alc861vd_mux_enum_put,
11592	},
11593	{ } /* end */
11594};
11595
11596/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11597 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11598 */
11599static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11600	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11601	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11602
11603	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11604	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11605
11606	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11607				HDA_OUTPUT),
11608	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11609				HDA_OUTPUT),
11610	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11611	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11612
11613	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11614	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11615
11616	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11617
11618	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11619	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11620	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11621
11622	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11623	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11624	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11625
11626	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11627	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11628
11629	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11630	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11631
11632	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11633	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11634
11635	{ } /* end */
11636};
11637
11638static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11639	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11640	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11641
11642	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11643
11644	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11645	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11646	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11647
11648	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11649	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11650	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11651
11652	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11653	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11654
11655	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11656	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11657
11658	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11659	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11660
11661	{ } /* end */
11662};
11663
11664static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11665	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11666	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11667	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11668
11669	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11670
11671	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11672	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11673	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11674
11675	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11676	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11677	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11678
11679	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11680	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11681
11682	{ } /* end */
11683};
11684
11685/* Pin assignment: Front=0x14, HP = 0x15,
11686 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11687 */
11688static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11689	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11690	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11691	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11692	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11693	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11694	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11695	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11696	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11697	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
11698	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
11699	{ } /* end */
11700};
11701
11702/* Pin assignment: Speaker=0x14, Line-out = 0x15,
11703 *                 Front Mic=0x18, ATAPI Mic = 0x19,
11704 */
11705static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
11706	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11707	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11708	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11709	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11710	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11711	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11712	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11713	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11714
11715	{ } /* end */
11716};
11717
11718/*
11719 * generic initialization of ADC, input mixers and output mixers
11720 */
11721static struct hda_verb alc861vd_volume_init_verbs[] = {
11722	/*
11723	 * Unmute ADC0 and set the default input to mic-in
11724	 */
11725	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11726	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11727
11728	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11729	 * the analog-loopback mixer widget
11730	 */
11731	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11732	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11733	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11734	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11735	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11736	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11737
11738	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
11739	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11740	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11741	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11742	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11743
11744	/*
11745	 * Set up output mixers (0x02 - 0x05)
11746	 */
11747	/* set vol=0 to output mixers */
11748	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11749	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11750	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11751	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11752
11753	/* set up input amps for analog loopback */
11754	/* Amp Indices: DAC = 0, mixer = 1 */
11755	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11756	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11757	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11758	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11759	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11760	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11761	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11762	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11763
11764	{ }
11765};
11766
11767/*
11768 * 3-stack pin configuration:
11769 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11770 */
11771static struct hda_verb alc861vd_3stack_init_verbs[] = {
11772	/*
11773	 * Set pin mode and muting
11774	 */
11775	/* set front pin widgets 0x14 for output */
11776	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11777	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11778	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11779
11780	/* Mic (rear) pin: input vref at 80% */
11781	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11782	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11783	/* Front Mic pin: input vref at 80% */
11784	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11785	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11786	/* Line In pin: input */
11787	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11788	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11789	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11790	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11791	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11792	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11793	/* CD pin widget for input */
11794	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11795
11796	{ }
11797};
11798
11799/*
11800 * 6-stack pin configuration:
11801 */
11802static struct hda_verb alc861vd_6stack_init_verbs[] = {
11803	/*
11804	 * Set pin mode and muting
11805	 */
11806	/* set front pin widgets 0x14 for output */
11807	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11808	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11809	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11810
11811	/* Rear Pin: output 1 (0x0d) */
11812	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11813	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11814	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11815	/* CLFE Pin: output 2 (0x0e) */
11816	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11817	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11818	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11819	/* Side Pin: output 3 (0x0f) */
11820	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11821	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11822	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11823
11824	/* Mic (rear) pin: input vref at 80% */
11825	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11826	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11827	/* Front Mic pin: input vref at 80% */
11828	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11829	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11830	/* Line In pin: input */
11831	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11832	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11833	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11834	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11835	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11836	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11837	/* CD pin widget for input */
11838	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11839
11840	{ }
11841};
11842
11843static struct hda_verb alc861vd_eapd_verbs[] = {
11844	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11845	{ }
11846};
11847
11848static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11849	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11850	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11851	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11852	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11853	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11854	{}
11855};
11856
11857/* toggle speaker-output according to the hp-jack state */
11858static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11859{
11860	unsigned int present;
11861	unsigned char bits;
11862
11863	present = snd_hda_codec_read(codec, 0x1b, 0,
11864				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11865	bits = present ? HDA_AMP_MUTE : 0;
11866	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11867				 HDA_AMP_MUTE, bits);
11868}
11869
11870static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11871{
11872	unsigned int present;
11873	unsigned char bits;
11874
11875	present = snd_hda_codec_read(codec, 0x18, 0,
11876				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11877	bits = present ? HDA_AMP_MUTE : 0;
11878	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11879				 HDA_AMP_MUTE, bits);
11880}
11881
11882static void alc861vd_lenovo_automute(struct hda_codec *codec)
11883{
11884	alc861vd_lenovo_hp_automute(codec);
11885	alc861vd_lenovo_mic_automute(codec);
11886}
11887
11888static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11889					unsigned int res)
11890{
11891	switch (res >> 26) {
11892	case ALC880_HP_EVENT:
11893		alc861vd_lenovo_hp_automute(codec);
11894		break;
11895	case ALC880_MIC_EVENT:
11896		alc861vd_lenovo_mic_automute(codec);
11897		break;
11898	}
11899}
11900
11901static struct hda_verb alc861vd_dallas_verbs[] = {
11902	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11903	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11904	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11905	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11906
11907	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11908	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11909	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11910	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11911	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11912	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11913	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11914	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11915
11916	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11917	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11918	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11919	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11920	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11921	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11922	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11923	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11924
11925	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11926	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11927	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11928	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11929	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11930	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11931	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11932	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11933
11934	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11935	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11936	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11937	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11938
11939	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11940	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11941	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11942
11943	{ } /* end */
11944};
11945
11946/* toggle speaker-output according to the hp-jack state */
11947static void alc861vd_dallas_automute(struct hda_codec *codec)
11948{
11949	unsigned int present;
11950
11951	present = snd_hda_codec_read(codec, 0x15, 0,
11952				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11953	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11954				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11955}
11956
11957static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11958{
11959	if ((res >> 26) == ALC880_HP_EVENT)
11960		alc861vd_dallas_automute(codec);
11961}
11962
11963#ifdef CONFIG_SND_HDA_POWER_SAVE
11964#define alc861vd_loopbacks	alc880_loopbacks
11965#endif
11966
11967/* pcm configuration: identiacal with ALC880 */
11968#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
11969#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
11970#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
11971#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
11972
11973/*
11974 * configuration and preset
11975 */
11976static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11977	[ALC660VD_3ST]		= "3stack-660",
11978	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
11979	[ALC861VD_3ST]		= "3stack",
11980	[ALC861VD_3ST_DIG]	= "3stack-digout",
11981	[ALC861VD_6ST_DIG]	= "6stack-digout",
11982	[ALC861VD_LENOVO]	= "lenovo",
11983	[ALC861VD_DALLAS]	= "dallas",
11984	[ALC861VD_HP]		= "hp",
11985	[ALC861VD_AUTO]		= "auto",
11986};
11987
11988static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11989	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11990	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11991	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11992	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11993	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11994	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11995	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11996	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11997	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11998	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11999	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
12000	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12001	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
12002	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
12003	{}
12004};
12005
12006static struct alc_config_preset alc861vd_presets[] = {
12007	[ALC660VD_3ST] = {
12008		.mixers = { alc861vd_3st_mixer },
12009		.init_verbs = { alc861vd_volume_init_verbs,
12010				 alc861vd_3stack_init_verbs },
12011		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12012		.dac_nids = alc660vd_dac_nids,
12013		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12014		.adc_nids = alc861vd_adc_nids,
12015		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12016		.channel_mode = alc861vd_3stack_2ch_modes,
12017		.input_mux = &alc861vd_capture_source,
12018	},
12019	[ALC660VD_3ST_DIG] = {
12020		.mixers = { alc861vd_3st_mixer },
12021		.init_verbs = { alc861vd_volume_init_verbs,
12022				 alc861vd_3stack_init_verbs },
12023		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12024		.dac_nids = alc660vd_dac_nids,
12025		.dig_out_nid = ALC861VD_DIGOUT_NID,
12026		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12027		.adc_nids = alc861vd_adc_nids,
12028		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12029		.channel_mode = alc861vd_3stack_2ch_modes,
12030		.input_mux = &alc861vd_capture_source,
12031	},
12032	[ALC861VD_3ST] = {
12033		.mixers = { alc861vd_3st_mixer },
12034		.init_verbs = { alc861vd_volume_init_verbs,
12035				 alc861vd_3stack_init_verbs },
12036		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12037		.dac_nids = alc861vd_dac_nids,
12038		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12039		.channel_mode = alc861vd_3stack_2ch_modes,
12040		.input_mux = &alc861vd_capture_source,
12041	},
12042	[ALC861VD_3ST_DIG] = {
12043		.mixers = { alc861vd_3st_mixer },
12044		.init_verbs = { alc861vd_volume_init_verbs,
12045		 		 alc861vd_3stack_init_verbs },
12046		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12047		.dac_nids = alc861vd_dac_nids,
12048		.dig_out_nid = ALC861VD_DIGOUT_NID,
12049		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12050		.channel_mode = alc861vd_3stack_2ch_modes,
12051		.input_mux = &alc861vd_capture_source,
12052	},
12053	[ALC861VD_6ST_DIG] = {
12054		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12055		.init_verbs = { alc861vd_volume_init_verbs,
12056				alc861vd_6stack_init_verbs },
12057		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12058		.dac_nids = alc861vd_dac_nids,
12059		.dig_out_nid = ALC861VD_DIGOUT_NID,
12060		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12061		.channel_mode = alc861vd_6stack_modes,
12062		.input_mux = &alc861vd_capture_source,
12063	},
12064	[ALC861VD_LENOVO] = {
12065		.mixers = { alc861vd_lenovo_mixer },
12066		.init_verbs = { alc861vd_volume_init_verbs,
12067				alc861vd_3stack_init_verbs,
12068				alc861vd_eapd_verbs,
12069				alc861vd_lenovo_unsol_verbs },
12070		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12071		.dac_nids = alc660vd_dac_nids,
12072		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12073		.adc_nids = alc861vd_adc_nids,
12074		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12075		.channel_mode = alc861vd_3stack_2ch_modes,
12076		.input_mux = &alc861vd_capture_source,
12077		.unsol_event = alc861vd_lenovo_unsol_event,
12078		.init_hook = alc861vd_lenovo_automute,
12079	},
12080	[ALC861VD_DALLAS] = {
12081		.mixers = { alc861vd_dallas_mixer },
12082		.init_verbs = { alc861vd_dallas_verbs },
12083		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12084		.dac_nids = alc861vd_dac_nids,
12085		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12086		.adc_nids = alc861vd_adc_nids,
12087		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12088		.channel_mode = alc861vd_3stack_2ch_modes,
12089		.input_mux = &alc861vd_dallas_capture_source,
12090		.unsol_event = alc861vd_dallas_unsol_event,
12091		.init_hook = alc861vd_dallas_automute,
12092	},
12093	[ALC861VD_HP] = {
12094		.mixers = { alc861vd_hp_mixer },
12095		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12096		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12097		.dac_nids = alc861vd_dac_nids,
12098		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12099		.dig_out_nid = ALC861VD_DIGOUT_NID,
12100		.adc_nids = alc861vd_adc_nids,
12101		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12102		.channel_mode = alc861vd_3stack_2ch_modes,
12103		.input_mux = &alc861vd_hp_capture_source,
12104		.unsol_event = alc861vd_dallas_unsol_event,
12105		.init_hook = alc861vd_dallas_automute,
12106	},
12107};
12108
12109/*
12110 * BIOS auto configuration
12111 */
12112static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12113				hda_nid_t nid, int pin_type, int dac_idx)
12114{
12115	/* set as output */
12116	snd_hda_codec_write(codec, nid, 0,
12117				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12118	snd_hda_codec_write(codec, nid, 0,
12119				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12120}
12121
12122static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12123{
12124	struct alc_spec *spec = codec->spec;
12125	int i;
12126
12127	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
12128	for (i = 0; i <= HDA_SIDE; i++) {
12129		hda_nid_t nid = spec->autocfg.line_out_pins[i];
12130		int pin_type = get_pin_type(spec->autocfg.line_out_type);
12131		if (nid)
12132			alc861vd_auto_set_output_and_unmute(codec, nid,
12133							    pin_type, i);
12134	}
12135}
12136
12137
12138static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12139{
12140	struct alc_spec *spec = codec->spec;
12141	hda_nid_t pin;
12142
12143	pin = spec->autocfg.hp_pins[0];
12144	if (pin) /* connect to front and  use dac 0 */
12145		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12146}
12147
12148#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
12149#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
12150
12151static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12152{
12153	struct alc_spec *spec = codec->spec;
12154	int i;
12155
12156	for (i = 0; i < AUTO_PIN_LAST; i++) {
12157		hda_nid_t nid = spec->autocfg.input_pins[i];
12158		if (alc861vd_is_input_pin(nid)) {
12159			snd_hda_codec_write(codec, nid, 0,
12160					AC_VERB_SET_PIN_WIDGET_CONTROL,
12161					i <= AUTO_PIN_FRONT_MIC ?
12162							PIN_VREF80 : PIN_IN);
12163			if (nid != ALC861VD_PIN_CD_NID)
12164				snd_hda_codec_write(codec, nid, 0,
12165						AC_VERB_SET_AMP_GAIN_MUTE,
12166						AMP_OUT_MUTE);
12167		}
12168	}
12169}
12170
12171#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
12172#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
12173
12174/* add playback controls from the parsed DAC table */
12175/* Based on ALC880 version. But ALC861VD has separate,
12176 * different NIDs for mute/unmute switch and volume control */
12177static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12178					     const struct auto_pin_cfg *cfg)
12179{
12180	char name[32];
12181	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12182	hda_nid_t nid_v, nid_s;
12183	int i, err;
12184
12185	for (i = 0; i < cfg->line_outs; i++) {
12186		if (!spec->multiout.dac_nids[i])
12187			continue;
12188		nid_v = alc861vd_idx_to_mixer_vol(
12189				alc880_dac_to_idx(
12190					spec->multiout.dac_nids[i]));
12191		nid_s = alc861vd_idx_to_mixer_switch(
12192				alc880_dac_to_idx(
12193					spec->multiout.dac_nids[i]));
12194
12195		if (i == 2) {
12196			/* Center/LFE */
12197			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12198					  "Center Playback Volume",
12199					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12200							      HDA_OUTPUT));
12201			if (err < 0)
12202				return err;
12203			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12204					  "LFE Playback Volume",
12205					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12206							      HDA_OUTPUT));
12207			if (err < 0)
12208				return err;
12209			err = add_control(spec, ALC_CTL_BIND_MUTE,
12210					  "Center Playback Switch",
12211					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12212							      HDA_INPUT));
12213			if (err < 0)
12214				return err;
12215			err = add_control(spec, ALC_CTL_BIND_MUTE,
12216					  "LFE Playback Switch",
12217					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12218							      HDA_INPUT));
12219			if (err < 0)
12220				return err;
12221		} else {
12222			sprintf(name, "%s Playback Volume", chname[i]);
12223			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12224					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12225							      HDA_OUTPUT));
12226			if (err < 0)
12227				return err;
12228			sprintf(name, "%s Playback Switch", chname[i]);
12229			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12230					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
12231							      HDA_INPUT));
12232			if (err < 0)
12233				return err;
12234		}
12235	}
12236	return 0;
12237}
12238
12239/* add playback controls for speaker and HP outputs */
12240/* Based on ALC880 version. But ALC861VD has separate,
12241 * different NIDs for mute/unmute switch and volume control */
12242static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12243					hda_nid_t pin, const char *pfx)
12244{
12245	hda_nid_t nid_v, nid_s;
12246	int err;
12247	char name[32];
12248
12249	if (!pin)
12250		return 0;
12251
12252	if (alc880_is_fixed_pin(pin)) {
12253		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12254		/* specify the DAC as the extra output */
12255		if (!spec->multiout.hp_nid)
12256			spec->multiout.hp_nid = nid_v;
12257		else
12258			spec->multiout.extra_out_nid[0] = nid_v;
12259		/* control HP volume/switch on the output mixer amp */
12260		nid_v = alc861vd_idx_to_mixer_vol(
12261				alc880_fixed_pin_idx(pin));
12262		nid_s = alc861vd_idx_to_mixer_switch(
12263				alc880_fixed_pin_idx(pin));
12264
12265		sprintf(name, "%s Playback Volume", pfx);
12266		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12267				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12268		if (err < 0)
12269			return err;
12270		sprintf(name, "%s Playback Switch", pfx);
12271		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12272				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12273		if (err < 0)
12274			return err;
12275	} else if (alc880_is_multi_pin(pin)) {
12276		/* set manual connection */
12277		/* we have only a switch on HP-out PIN */
12278		sprintf(name, "%s Playback Switch", pfx);
12279		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12280				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12281		if (err < 0)
12282			return err;
12283	}
12284	return 0;
12285}
12286
12287/* parse the BIOS configuration and set up the alc_spec
12288 * return 1 if successful, 0 if the proper config is not found,
12289 * or a negative error code
12290 * Based on ALC880 version - had to change it to override
12291 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12292static int alc861vd_parse_auto_config(struct hda_codec *codec)
12293{
12294	struct alc_spec *spec = codec->spec;
12295	int err;
12296	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12297
12298	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12299					   alc861vd_ignore);
12300	if (err < 0)
12301		return err;
12302	if (!spec->autocfg.line_outs)
12303		return 0; /* can't find valid BIOS pin config */
12304
12305	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12306	if (err < 0)
12307		return err;
12308	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12309	if (err < 0)
12310		return err;
12311	err = alc861vd_auto_create_extra_out(spec,
12312					     spec->autocfg.speaker_pins[0],
12313					     "Speaker");
12314	if (err < 0)
12315		return err;
12316	err = alc861vd_auto_create_extra_out(spec,
12317					     spec->autocfg.hp_pins[0],
12318					     "Headphone");
12319	if (err < 0)
12320		return err;
12321	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12322	if (err < 0)
12323		return err;
12324
12325	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12326
12327	if (spec->autocfg.dig_out_pin)
12328		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12329
12330	if (spec->kctl_alloc)
12331		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12332
12333	spec->init_verbs[spec->num_init_verbs++]
12334		= alc861vd_volume_init_verbs;
12335
12336	spec->num_mux_defs = 1;
12337	spec->input_mux = &spec->private_imux;
12338
12339	err = alc_auto_add_mic_boost(codec);
12340	if (err < 0)
12341		return err;
12342
12343	return 1;
12344}
12345
12346/* additional initialization for auto-configuration model */
12347static void alc861vd_auto_init(struct hda_codec *codec)
12348{
12349	alc861vd_auto_init_multi_out(codec);
12350	alc861vd_auto_init_hp_out(codec);
12351	alc861vd_auto_init_analog_input(codec);
12352}
12353
12354static int patch_alc861vd(struct hda_codec *codec)
12355{
12356	struct alc_spec *spec;
12357	int err, board_config;
12358
12359	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12360	if (spec == NULL)
12361		return -ENOMEM;
12362
12363	codec->spec = spec;
12364
12365	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12366						  alc861vd_models,
12367						  alc861vd_cfg_tbl);
12368
12369	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12370		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12371			"ALC861VD, trying auto-probe from BIOS...\n");
12372		board_config = ALC861VD_AUTO;
12373	}
12374
12375	if (board_config == ALC861VD_AUTO) {
12376		/* automatic parse from the BIOS config */
12377		err = alc861vd_parse_auto_config(codec);
12378		if (err < 0) {
12379			alc_free(codec);
12380			return err;
12381		} else if (!err) {
12382			printk(KERN_INFO
12383			       "hda_codec: Cannot set up configuration "
12384			       "from BIOS.  Using base mode...\n");
12385			board_config = ALC861VD_3ST;
12386		}
12387	}
12388
12389	if (board_config != ALC861VD_AUTO)
12390		setup_preset(spec, &alc861vd_presets[board_config]);
12391
12392	spec->stream_name_analog = "ALC861VD Analog";
12393	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12394	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12395
12396	spec->stream_name_digital = "ALC861VD Digital";
12397	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12398	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12399
12400	spec->adc_nids = alc861vd_adc_nids;
12401	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12402
12403	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12404	spec->num_mixers++;
12405
12406	spec->vmaster_nid = 0x02;
12407
12408	codec->patch_ops = alc_patch_ops;
12409
12410	if (board_config == ALC861VD_AUTO)
12411		spec->init_hook = alc861vd_auto_init;
12412#ifdef CONFIG_SND_HDA_POWER_SAVE
12413	if (!spec->loopback.amplist)
12414		spec->loopback.amplist = alc861vd_loopbacks;
12415#endif
12416
12417	return 0;
12418}
12419
12420/*
12421 * ALC662 support
12422 *
12423 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12424 * configuration.  Each pin widget can choose any input DACs and a mixer.
12425 * Each ADC is connected from a mixer of all inputs.  This makes possible
12426 * 6-channel independent captures.
12427 *
12428 * In addition, an independent DAC for the multi-playback (not used in this
12429 * driver yet).
12430 */
12431#define ALC662_DIGOUT_NID	0x06
12432#define ALC662_DIGIN_NID	0x0a
12433
12434static hda_nid_t alc662_dac_nids[4] = {
12435	/* front, rear, clfe, rear_surr */
12436	0x02, 0x03, 0x04
12437};
12438
12439static hda_nid_t alc662_adc_nids[1] = {
12440	/* ADC1-2 */
12441	0x09,
12442};
12443/* input MUX */
12444/* FIXME: should be a matrix-type input source selection */
12445
12446static struct hda_input_mux alc662_capture_source = {
12447	.num_items = 4,
12448	.items = {
12449		{ "Mic", 0x0 },
12450		{ "Front Mic", 0x1 },
12451		{ "Line", 0x2 },
12452		{ "CD", 0x4 },
12453	},
12454};
12455
12456static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12457	.num_items = 2,
12458	.items = {
12459		{ "Mic", 0x1 },
12460		{ "Line", 0x2 },
12461	},
12462};
12463
12464static struct hda_input_mux alc662_eeepc_capture_source = {
12465	.num_items = 2,
12466	.items = {
12467		{ "i-Mic", 0x1 },
12468		{ "e-Mic", 0x0 },
12469	},
12470};
12471
12472#define alc662_mux_enum_info alc_mux_enum_info
12473#define alc662_mux_enum_get alc_mux_enum_get
12474
12475static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12476			       struct snd_ctl_elem_value *ucontrol)
12477{
12478	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12479	struct alc_spec *spec = codec->spec;
12480	const struct hda_input_mux *imux = spec->input_mux;
12481	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
12482	static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
12483	hda_nid_t nid = capture_mixers[adc_idx];
12484	unsigned int *cur_val = &spec->cur_mux[adc_idx];
12485	unsigned int i, idx;
12486
12487	idx = ucontrol->value.enumerated.item[0];
12488	if (idx >= imux->num_items)
12489		idx = imux->num_items - 1;
12490	if (*cur_val == idx)
12491		return 0;
12492	for (i = 0; i < imux->num_items; i++) {
12493		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12494		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12495					 imux->items[i].index,
12496					 HDA_AMP_MUTE, v);
12497	}
12498	*cur_val = idx;
12499	return 1;
12500}
12501/*
12502 * 2ch mode
12503 */
12504static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12505	{ 2, NULL }
12506};
12507
12508/*
12509 * 2ch mode
12510 */
12511static struct hda_verb alc662_3ST_ch2_init[] = {
12512	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12513	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12514	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12515	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12516	{ } /* end */
12517};
12518
12519/*
12520 * 6ch mode
12521 */
12522static struct hda_verb alc662_3ST_ch6_init[] = {
12523	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12524	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12525	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12526	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12527	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12528	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12529	{ } /* end */
12530};
12531
12532static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12533	{ 2, alc662_3ST_ch2_init },
12534	{ 6, alc662_3ST_ch6_init },
12535};
12536
12537/*
12538 * 2ch mode
12539 */
12540static struct hda_verb alc662_sixstack_ch6_init[] = {
12541	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12542	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12543	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12544	{ } /* end */
12545};
12546
12547/*
12548 * 6ch mode
12549 */
12550static struct hda_verb alc662_sixstack_ch8_init[] = {
12551	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12552	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12553	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12554	{ } /* end */
12555};
12556
12557static struct hda_channel_mode alc662_5stack_modes[2] = {
12558	{ 2, alc662_sixstack_ch6_init },
12559	{ 6, alc662_sixstack_ch8_init },
12560};
12561
12562/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12563 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12564 */
12565
12566static struct snd_kcontrol_new alc662_base_mixer[] = {
12567	/* output mixer control */
12568	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12569	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12570	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12571	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12572	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12573	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12574	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12575	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12576	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12577
12578	/*Input mixer control */
12579	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12580	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12581	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12582	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12583	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12584	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12585	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12586	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
12587	{ } /* end */
12588};
12589
12590static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12591	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12592	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12593	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12594	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12595	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12596	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12597	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12598	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12599	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12600	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12601	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12602	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12603	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12604	{ } /* end */
12605};
12606
12607static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12608	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12609	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12610	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12611	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12612	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12613	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12614	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12615	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12616	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12617	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12618	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12619	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12620	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12621	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12622	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12623	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12624	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12625	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12626	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12627	{ } /* end */
12628};
12629
12630static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12631	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12632	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12633	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12634	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
12635	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12636	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12637	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12638	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12639	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12640	{ } /* end */
12641};
12642
12643static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12644	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12645
12646	HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12647	HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12648
12649	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12650	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12651	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12652
12653	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12654	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12655	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12656	{ } /* end */
12657};
12658
12659static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
12660	HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12661	HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12662	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12663	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12664	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12665	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12666	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12667	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12668	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12669	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
12670	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12671	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12672	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12673	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12674	{ } /* end */
12675};
12676
12677static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12678	{
12679		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12680		.name = "Channel Mode",
12681		.info = alc_ch_mode_info,
12682		.get = alc_ch_mode_get,
12683		.put = alc_ch_mode_put,
12684	},
12685	{ } /* end */
12686};
12687
12688static struct hda_verb alc662_init_verbs[] = {
12689	/* ADC: mute amp left and right */
12690	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12691	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12692	/* Front mixer: unmute input/output amp left and right (volume = 0) */
12693
12694	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12695	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12696	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12697	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12698	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12699
12700	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12701	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12702	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12703	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12704	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12705	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12706
12707	/* Front Pin: output 0 (0x0c) */
12708	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12709	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12710
12711	/* Rear Pin: output 1 (0x0d) */
12712	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12713	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12714
12715	/* CLFE Pin: output 2 (0x0e) */
12716	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12717	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12718
12719	/* Mic (rear) pin: input vref at 80% */
12720	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12721	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12722	/* Front Mic pin: input vref at 80% */
12723	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12724	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12725	/* Line In pin: input */
12726	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12727	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12728	/* Line-2 In: Headphone output (output 0 - 0x0c) */
12729	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12730	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12731	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12732	/* CD pin widget for input */
12733	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12734
12735	/* FIXME: use matrix-type input source selection */
12736	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12737	/* Input mixer */
12738	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12740	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12741	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12742
12743	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12744	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12745	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12746	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12747	{ }
12748};
12749
12750static struct hda_verb alc662_sue_init_verbs[] = {
12751	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12752	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
12753	{}
12754};
12755
12756static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12757	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12758	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12759	{}
12760};
12761
12762/* Set Unsolicited Event*/
12763static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
12764	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12765	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12766	{}
12767};
12768
12769/*
12770 * generic initialization of ADC, input mixers and output mixers
12771 */
12772static struct hda_verb alc662_auto_init_verbs[] = {
12773	/*
12774	 * Unmute ADC and set the default input to mic-in
12775	 */
12776	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12777	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12778
12779	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12780	 * mixer widget
12781	 * Note: PASD motherboards uses the Line In 2 as the input for front
12782	 * panel mic (mic 2)
12783	 */
12784	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12785	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12786	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12787	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12788	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12789	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12790
12791	/*
12792	 * Set up output mixers (0x0c - 0x0f)
12793	 */
12794	/* set vol=0 to output mixers */
12795	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12796	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12797	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12798
12799	/* set up input amps for analog loopback */
12800	/* Amp Indices: DAC = 0, mixer = 1 */
12801	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12802	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12803	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12804	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12805	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12806	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12807
12808
12809	/* FIXME: use matrix-type input source selection */
12810	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12811	/* Input mixer */
12812	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12813	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12814	{ }
12815};
12816
12817/* capture mixer elements */
12818static struct snd_kcontrol_new alc662_capture_mixer[] = {
12819	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12820	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12821	{
12822		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12823		/* The multiple "Capture Source" controls confuse alsamixer
12824		 * So call somewhat different..
12825		 * FIXME: the controls appear in the "playback" view!
12826		 */
12827		/* .name = "Capture Source", */
12828		.name = "Input Source",
12829		.count = 1,
12830		.info = alc662_mux_enum_info,
12831		.get = alc662_mux_enum_get,
12832		.put = alc662_mux_enum_put,
12833	},
12834	{ } /* end */
12835};
12836
12837static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12838{
12839	unsigned int present;
12840	unsigned char bits;
12841
12842	present = snd_hda_codec_read(codec, 0x14, 0,
12843				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12844	bits = present ? HDA_AMP_MUTE : 0;
12845	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12846				 HDA_AMP_MUTE, bits);
12847}
12848
12849static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12850{
12851	unsigned int present;
12852	unsigned char bits;
12853
12854 	present = snd_hda_codec_read(codec, 0x1b, 0,
12855				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12856	bits = present ? HDA_AMP_MUTE : 0;
12857	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12858				 HDA_AMP_MUTE, bits);
12859	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12860				 HDA_AMP_MUTE, bits);
12861}
12862
12863static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12864					   unsigned int res)
12865{
12866	if ((res >> 26) == ALC880_HP_EVENT)
12867		alc662_lenovo_101e_all_automute(codec);
12868	if ((res >> 26) == ALC880_FRONT_EVENT)
12869		alc662_lenovo_101e_ispeaker_automute(codec);
12870}
12871
12872static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12873{
12874	unsigned int present;
12875
12876	present = snd_hda_codec_read(codec, 0x18, 0,
12877				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12878	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12879			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12880	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12881			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12882	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12883			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12884	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12885			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12886}
12887
12888/* unsolicited event for HP jack sensing */
12889static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12890				     unsigned int res)
12891{
12892	if ((res >> 26) == ALC880_HP_EVENT)
12893		alc262_hippo1_automute( codec );
12894
12895	if ((res >> 26) == ALC880_MIC_EVENT)
12896		alc662_eeepc_mic_automute(codec);
12897}
12898
12899static void alc662_eeepc_inithook(struct hda_codec *codec)
12900{
12901	alc262_hippo1_automute( codec );
12902	alc662_eeepc_mic_automute(codec);
12903}
12904
12905static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
12906{
12907	unsigned int mute;
12908	unsigned int present;
12909
12910	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
12911	present = snd_hda_codec_read(codec, 0x14, 0,
12912				     AC_VERB_GET_PIN_SENSE, 0);
12913	present = (present & 0x80000000) != 0;
12914	if (present) {
12915		/* mute internal speaker */
12916		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
12917					 HDA_AMP_MUTE, HDA_AMP_MUTE);
12918	} else {
12919		/* unmute internal speaker if necessary */
12920		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12921		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
12922					 HDA_AMP_MUTE, mute);
12923	}
12924}
12925
12926/* unsolicited event for HP jack sensing */
12927static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
12928					  unsigned int res)
12929{
12930	if ((res >> 26) == ALC880_HP_EVENT)
12931		alc662_eeepc_ep20_automute(codec);
12932}
12933
12934static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
12935{
12936	alc662_eeepc_ep20_automute(codec);
12937}
12938
12939#ifdef CONFIG_SND_HDA_POWER_SAVE
12940#define alc662_loopbacks	alc880_loopbacks
12941#endif
12942
12943
12944/* pcm configuration: identiacal with ALC880 */
12945#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
12946#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
12947#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
12948#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
12949
12950/*
12951 * configuration and preset
12952 */
12953static const char *alc662_models[ALC662_MODEL_LAST] = {
12954	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
12955	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
12956	[ALC662_3ST_6ch]	= "3stack-6ch",
12957	[ALC662_5ST_DIG]	= "6stack-dig",
12958	[ALC662_LENOVO_101E]	= "lenovo-101e",
12959	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12960	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
12961	[ALC662_AUTO]		= "auto",
12962};
12963
12964static struct snd_pci_quirk alc662_cfg_tbl[] = {
12965	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12966	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
12967	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12968	{}
12969};
12970
12971static struct alc_config_preset alc662_presets[] = {
12972	[ALC662_3ST_2ch_DIG] = {
12973		.mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12974		.init_verbs = { alc662_init_verbs },
12975		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12976		.dac_nids = alc662_dac_nids,
12977		.dig_out_nid = ALC662_DIGOUT_NID,
12978		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12979		.adc_nids = alc662_adc_nids,
12980		.dig_in_nid = ALC662_DIGIN_NID,
12981		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12982		.channel_mode = alc662_3ST_2ch_modes,
12983		.input_mux = &alc662_capture_source,
12984	},
12985	[ALC662_3ST_6ch_DIG] = {
12986		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12987			    alc662_capture_mixer },
12988		.init_verbs = { alc662_init_verbs },
12989		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
12990		.dac_nids = alc662_dac_nids,
12991		.dig_out_nid = ALC662_DIGOUT_NID,
12992		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12993		.adc_nids = alc662_adc_nids,
12994		.dig_in_nid = ALC662_DIGIN_NID,
12995		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12996		.channel_mode = alc662_3ST_6ch_modes,
12997		.need_dac_fix = 1,
12998		.input_mux = &alc662_capture_source,
12999	},
13000	[ALC662_3ST_6ch] = {
13001		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13002			    alc662_capture_mixer },
13003		.init_verbs = { alc662_init_verbs },
13004		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13005		.dac_nids = alc662_dac_nids,
13006		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13007		.adc_nids = alc662_adc_nids,
13008		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13009		.channel_mode = alc662_3ST_6ch_modes,
13010		.need_dac_fix = 1,
13011		.input_mux = &alc662_capture_source,
13012	},
13013	[ALC662_5ST_DIG] = {
13014		.mixers = { alc662_base_mixer, alc662_chmode_mixer,
13015			    alc662_capture_mixer },
13016		.init_verbs = { alc662_init_verbs },
13017		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13018		.dac_nids = alc662_dac_nids,
13019		.dig_out_nid = ALC662_DIGOUT_NID,
13020		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13021		.adc_nids = alc662_adc_nids,
13022		.dig_in_nid = ALC662_DIGIN_NID,
13023		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13024		.channel_mode = alc662_5stack_modes,
13025		.input_mux = &alc662_capture_source,
13026	},
13027	[ALC662_LENOVO_101E] = {
13028		.mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
13029		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13030		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13031		.dac_nids = alc662_dac_nids,
13032		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13033		.adc_nids = alc662_adc_nids,
13034		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13035		.channel_mode = alc662_3ST_2ch_modes,
13036		.input_mux = &alc662_lenovo_101e_capture_source,
13037		.unsol_event = alc662_lenovo_101e_unsol_event,
13038		.init_hook = alc662_lenovo_101e_all_automute,
13039	},
13040	[ALC662_ASUS_EEEPC_P701] = {
13041		.mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13042		.init_verbs = { alc662_init_verbs,
13043				alc662_eeepc_sue_init_verbs },
13044		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13045		.dac_nids = alc662_dac_nids,
13046		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
13047		.adc_nids = alc662_adc_nids,
13048		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13049		.channel_mode = alc662_3ST_2ch_modes,
13050		.input_mux = &alc662_eeepc_capture_source,
13051		.unsol_event = alc662_eeepc_unsol_event,
13052		.init_hook = alc662_eeepc_inithook,
13053	},
13054	[ALC662_ASUS_EEEPC_EP20] = {
13055		.mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13056			    alc662_chmode_mixer },
13057		.init_verbs = { alc662_init_verbs,
13058				alc662_eeepc_ep20_sue_init_verbs },
13059		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
13060		.dac_nids = alc662_dac_nids,
13061		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13062		.adc_nids = alc662_adc_nids,
13063		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13064		.channel_mode = alc662_3ST_6ch_modes,
13065		.input_mux = &alc662_lenovo_101e_capture_source,
13066		.unsol_event = alc662_eeepc_ep20_unsol_event,
13067		.init_hook = alc662_eeepc_ep20_inithook,
13068	},
13069
13070};
13071
13072
13073/*
13074 * BIOS auto configuration
13075 */
13076
13077/* add playback controls from the parsed DAC table */
13078static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13079					     const struct auto_pin_cfg *cfg)
13080{
13081	char name[32];
13082	static const char *chname[4] = {
13083		"Front", "Surround", NULL /*CLFE*/, "Side"
13084	};
13085	hda_nid_t nid;
13086	int i, err;
13087
13088	for (i = 0; i < cfg->line_outs; i++) {
13089		if (!spec->multiout.dac_nids[i])
13090			continue;
13091		nid = alc880_idx_to_dac(i);
13092		if (i == 2) {
13093			/* Center/LFE */
13094			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13095					  "Center Playback Volume",
13096					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13097							      HDA_OUTPUT));
13098			if (err < 0)
13099				return err;
13100			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13101					  "LFE Playback Volume",
13102					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13103							      HDA_OUTPUT));
13104			if (err < 0)
13105				return err;
13106			err = add_control(spec, ALC_CTL_BIND_MUTE,
13107					  "Center Playback Switch",
13108					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13109							      HDA_INPUT));
13110			if (err < 0)
13111				return err;
13112			err = add_control(spec, ALC_CTL_BIND_MUTE,
13113					  "LFE Playback Switch",
13114					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13115							      HDA_INPUT));
13116			if (err < 0)
13117				return err;
13118		} else {
13119			sprintf(name, "%s Playback Volume", chname[i]);
13120			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13121					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13122							      HDA_OUTPUT));
13123			if (err < 0)
13124				return err;
13125			sprintf(name, "%s Playback Switch", chname[i]);
13126			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13127					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13128							      HDA_INPUT));
13129			if (err < 0)
13130				return err;
13131		}
13132	}
13133	return 0;
13134}
13135
13136/* add playback controls for speaker and HP outputs */
13137static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13138					const char *pfx)
13139{
13140	hda_nid_t nid;
13141	int err;
13142	char name[32];
13143
13144	if (!pin)
13145		return 0;
13146
13147	if (alc880_is_fixed_pin(pin)) {
13148		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13149                /* printk("DAC nid=%x\n",nid); */
13150		/* specify the DAC as the extra output */
13151		if (!spec->multiout.hp_nid)
13152			spec->multiout.hp_nid = nid;
13153		else
13154			spec->multiout.extra_out_nid[0] = nid;
13155		/* control HP volume/switch on the output mixer amp */
13156		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13157		sprintf(name, "%s Playback Volume", pfx);
13158		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13159				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13160		if (err < 0)
13161			return err;
13162		sprintf(name, "%s Playback Switch", pfx);
13163		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13164				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13165		if (err < 0)
13166			return err;
13167	} else if (alc880_is_multi_pin(pin)) {
13168		/* set manual connection */
13169		/* we have only a switch on HP-out PIN */
13170		sprintf(name, "%s Playback Switch", pfx);
13171		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13172				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13173		if (err < 0)
13174			return err;
13175	}
13176	return 0;
13177}
13178
13179/* create playback/capture controls for input pins */
13180static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13181						const struct auto_pin_cfg *cfg)
13182{
13183	struct hda_input_mux *imux = &spec->private_imux;
13184	int i, err, idx;
13185
13186	for (i = 0; i < AUTO_PIN_LAST; i++) {
13187		if (alc880_is_input_pin(cfg->input_pins[i])) {
13188			idx = alc880_input_pin_idx(cfg->input_pins[i]);
13189			err = new_analog_input(spec, cfg->input_pins[i],
13190					       auto_pin_cfg_labels[i],
13191					       idx, 0x0b);
13192			if (err < 0)
13193				return err;
13194			imux->items[imux->num_items].label =
13195				auto_pin_cfg_labels[i];
13196			imux->items[imux->num_items].index =
13197				alc880_input_pin_idx(cfg->input_pins[i]);
13198			imux->num_items++;
13199		}
13200	}
13201	return 0;
13202}
13203
13204static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13205					      hda_nid_t nid, int pin_type,
13206					      int dac_idx)
13207{
13208	/* set as output */
13209	snd_hda_codec_write(codec, nid, 0,
13210			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
13211	snd_hda_codec_write(codec, nid, 0,
13212			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
13213	/* need the manual connection? */
13214	if (alc880_is_multi_pin(nid)) {
13215		struct alc_spec *spec = codec->spec;
13216		int idx = alc880_multi_pin_idx(nid);
13217		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13218				    AC_VERB_SET_CONNECT_SEL,
13219				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13220	}
13221}
13222
13223static void alc662_auto_init_multi_out(struct hda_codec *codec)
13224{
13225	struct alc_spec *spec = codec->spec;
13226	int i;
13227
13228	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13229	for (i = 0; i <= HDA_SIDE; i++) {
13230		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13231		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13232		if (nid)
13233			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
13234							  i);
13235	}
13236}
13237
13238static void alc662_auto_init_hp_out(struct hda_codec *codec)
13239{
13240	struct alc_spec *spec = codec->spec;
13241	hda_nid_t pin;
13242
13243	pin = spec->autocfg.hp_pins[0];
13244	if (pin) /* connect to front */
13245		/* use dac 0 */
13246		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13247}
13248
13249#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
13250#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
13251
13252static void alc662_auto_init_analog_input(struct hda_codec *codec)
13253{
13254	struct alc_spec *spec = codec->spec;
13255	int i;
13256
13257	for (i = 0; i < AUTO_PIN_LAST; i++) {
13258		hda_nid_t nid = spec->autocfg.input_pins[i];
13259		if (alc662_is_input_pin(nid)) {
13260			snd_hda_codec_write(codec, nid, 0,
13261					    AC_VERB_SET_PIN_WIDGET_CONTROL,
13262					    (i <= AUTO_PIN_FRONT_MIC ?
13263					     PIN_VREF80 : PIN_IN));
13264			if (nid != ALC662_PIN_CD_NID)
13265				snd_hda_codec_write(codec, nid, 0,
13266						    AC_VERB_SET_AMP_GAIN_MUTE,
13267						    AMP_OUT_MUTE);
13268		}
13269	}
13270}
13271
13272static int alc662_parse_auto_config(struct hda_codec *codec)
13273{
13274	struct alc_spec *spec = codec->spec;
13275	int err;
13276	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13277
13278	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13279					   alc662_ignore);
13280	if (err < 0)
13281		return err;
13282	if (!spec->autocfg.line_outs)
13283		return 0; /* can't find valid BIOS pin config */
13284
13285	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13286	if (err < 0)
13287		return err;
13288	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13289	if (err < 0)
13290		return err;
13291	err = alc662_auto_create_extra_out(spec,
13292					   spec->autocfg.speaker_pins[0],
13293					   "Speaker");
13294	if (err < 0)
13295		return err;
13296	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13297					   "Headphone");
13298	if (err < 0)
13299		return err;
13300	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13301	if (err < 0)
13302		return err;
13303
13304	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13305
13306	if (spec->autocfg.dig_out_pin)
13307		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13308
13309	if (spec->kctl_alloc)
13310		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13311
13312	spec->num_mux_defs = 1;
13313	spec->input_mux = &spec->private_imux;
13314
13315	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
13316	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13317	spec->num_mixers++;
13318	return 1;
13319}
13320
13321/* additional initialization for auto-configuration model */
13322static void alc662_auto_init(struct hda_codec *codec)
13323{
13324	alc662_auto_init_multi_out(codec);
13325	alc662_auto_init_hp_out(codec);
13326	alc662_auto_init_analog_input(codec);
13327}
13328
13329static int patch_alc662(struct hda_codec *codec)
13330{
13331	struct alc_spec *spec;
13332	int err, board_config;
13333
13334	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13335	if (!spec)
13336		return -ENOMEM;
13337
13338	codec->spec = spec;
13339
13340	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13341						  alc662_models,
13342			  	                  alc662_cfg_tbl);
13343	if (board_config < 0) {
13344		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13345		       "trying auto-probe from BIOS...\n");
13346		board_config = ALC662_AUTO;
13347	}
13348
13349	if (board_config == ALC662_AUTO) {
13350		/* automatic parse from the BIOS config */
13351		err = alc662_parse_auto_config(codec);
13352		if (err < 0) {
13353			alc_free(codec);
13354			return err;
13355		} else if (!err) {
13356			printk(KERN_INFO
13357			       "hda_codec: Cannot set up configuration "
13358			       "from BIOS.  Using base mode...\n");
13359			board_config = ALC662_3ST_2ch_DIG;
13360		}
13361	}
13362
13363	if (board_config != ALC662_AUTO)
13364		setup_preset(spec, &alc662_presets[board_config]);
13365
13366	spec->stream_name_analog = "ALC662 Analog";
13367	spec->stream_analog_playback = &alc662_pcm_analog_playback;
13368	spec->stream_analog_capture = &alc662_pcm_analog_capture;
13369
13370	spec->stream_name_digital = "ALC662 Digital";
13371	spec->stream_digital_playback = &alc662_pcm_digital_playback;
13372	spec->stream_digital_capture = &alc662_pcm_digital_capture;
13373
13374	if (!spec->adc_nids && spec->input_mux) {
13375		spec->adc_nids = alc662_adc_nids;
13376		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13377	}
13378
13379	spec->vmaster_nid = 0x02;
13380
13381	codec->patch_ops = alc_patch_ops;
13382	if (board_config == ALC662_AUTO)
13383		spec->init_hook = alc662_auto_init;
13384#ifdef CONFIG_SND_HDA_POWER_SAVE
13385	if (!spec->loopback.amplist)
13386		spec->loopback.amplist = alc662_loopbacks;
13387#endif
13388
13389	return 0;
13390}
13391
13392/*
13393 * patch entries
13394 */
13395struct hda_codec_preset snd_hda_preset_realtek[] = {
13396	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
13397	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
13398	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
13399	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
13400	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
13401	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
13402	  .patch = patch_alc861 },
13403	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13404	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13405	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
13406	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13407	  .patch = patch_alc883 },
13408	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13409	  .patch = patch_alc662 },
13410	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
13411	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
13412	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
13413	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
13414	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
13415	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
13416	{} /* terminator */
13417};
13418