patch_realtek.c revision dfed0ef9b3ff9e37903920b6938ed33344ad0b3d
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 *                    PeiSen Hou <pshou@realtek.com.tw>
8 *                    Takashi Iwai <tiwai@suse.de>
9 *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10 *
11 *  This driver is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This driver is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24 */
25
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
33#include "hda_beep.h"
34
35#define ALC880_FRONT_EVENT		0x01
36#define ALC880_DCVOL_EVENT		0x02
37#define ALC880_HP_EVENT			0x04
38#define ALC880_MIC_EVENT		0x08
39
40/* ALC880 board config type */
41enum {
42	ALC880_3ST,
43	ALC880_3ST_DIG,
44	ALC880_5ST,
45	ALC880_5ST_DIG,
46	ALC880_W810,
47	ALC880_Z71V,
48	ALC880_6ST,
49	ALC880_6ST_DIG,
50	ALC880_F1734,
51	ALC880_ASUS,
52	ALC880_ASUS_DIG,
53	ALC880_ASUS_W1V,
54	ALC880_ASUS_DIG2,
55	ALC880_FUJITSU,
56	ALC880_UNIWILL_DIG,
57	ALC880_UNIWILL,
58	ALC880_UNIWILL_P53,
59	ALC880_CLEVO,
60	ALC880_TCL_S700,
61	ALC880_LG,
62	ALC880_LG_LW,
63	ALC880_MEDION_RIM,
64#ifdef CONFIG_SND_DEBUG
65	ALC880_TEST,
66#endif
67	ALC880_AUTO,
68	ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73	ALC260_BASIC,
74	ALC260_HP,
75	ALC260_HP_DC7600,
76	ALC260_HP_3013,
77	ALC260_FUJITSU_S702X,
78	ALC260_ACER,
79	ALC260_WILL,
80	ALC260_REPLACER_672V,
81	ALC260_FAVORIT100,
82#ifdef CONFIG_SND_DEBUG
83	ALC260_TEST,
84#endif
85	ALC260_AUTO,
86	ALC260_MODEL_LAST /* last tag */
87};
88
89/* ALC262 models */
90enum {
91	ALC262_BASIC,
92	ALC262_HIPPO,
93	ALC262_HIPPO_1,
94	ALC262_FUJITSU,
95	ALC262_HP_BPC,
96	ALC262_HP_BPC_D7000_WL,
97	ALC262_HP_BPC_D7000_WF,
98	ALC262_HP_TC_T5735,
99	ALC262_HP_RP5700,
100	ALC262_BENQ_ED8,
101	ALC262_SONY_ASSAMD,
102	ALC262_BENQ_T31,
103	ALC262_ULTRA,
104	ALC262_LENOVO_3000,
105	ALC262_NEC,
106	ALC262_TOSHIBA_S06,
107	ALC262_TOSHIBA_RX1,
108	ALC262_TYAN,
109	ALC262_AUTO,
110	ALC262_MODEL_LAST /* last tag */
111};
112
113/* ALC268 models */
114enum {
115	ALC267_QUANTA_IL1,
116	ALC268_3ST,
117	ALC268_TOSHIBA,
118	ALC268_ACER,
119	ALC268_ACER_DMIC,
120	ALC268_ACER_ASPIRE_ONE,
121	ALC268_DELL,
122	ALC268_ZEPTO,
123#ifdef CONFIG_SND_DEBUG
124	ALC268_TEST,
125#endif
126	ALC268_AUTO,
127	ALC268_MODEL_LAST /* last tag */
128};
129
130/* ALC269 models */
131enum {
132	ALC269_BASIC,
133	ALC269_QUANTA_FL1,
134	ALC269_ASUS_EEEPC_P703,
135	ALC269_ASUS_EEEPC_P901,
136	ALC269_FUJITSU,
137	ALC269_LIFEBOOK,
138	ALC269_AUTO,
139	ALC269_MODEL_LAST /* last tag */
140};
141
142/* ALC861 models */
143enum {
144	ALC861_3ST,
145	ALC660_3ST,
146	ALC861_3ST_DIG,
147	ALC861_6ST_DIG,
148	ALC861_UNIWILL_M31,
149	ALC861_TOSHIBA,
150	ALC861_ASUS,
151	ALC861_ASUS_LAPTOP,
152	ALC861_AUTO,
153	ALC861_MODEL_LAST,
154};
155
156/* ALC861-VD models */
157enum {
158	ALC660VD_3ST,
159	ALC660VD_3ST_DIG,
160	ALC660VD_ASUS_V1S,
161	ALC861VD_3ST,
162	ALC861VD_3ST_DIG,
163	ALC861VD_6ST_DIG,
164	ALC861VD_LENOVO,
165	ALC861VD_DALLAS,
166	ALC861VD_HP,
167	ALC861VD_AUTO,
168	ALC861VD_MODEL_LAST,
169};
170
171/* ALC662 models */
172enum {
173	ALC662_3ST_2ch_DIG,
174	ALC662_3ST_6ch_DIG,
175	ALC662_3ST_6ch,
176	ALC662_5ST_DIG,
177	ALC662_LENOVO_101E,
178	ALC662_ASUS_EEEPC_P701,
179	ALC662_ASUS_EEEPC_EP20,
180	ALC663_ASUS_M51VA,
181	ALC663_ASUS_G71V,
182	ALC663_ASUS_H13,
183	ALC663_ASUS_G50V,
184	ALC662_ECS,
185	ALC663_ASUS_MODE1,
186	ALC662_ASUS_MODE2,
187	ALC663_ASUS_MODE3,
188	ALC663_ASUS_MODE4,
189	ALC663_ASUS_MODE5,
190	ALC663_ASUS_MODE6,
191	ALC272_DELL,
192	ALC272_DELL_ZM1,
193	ALC662_AUTO,
194	ALC662_MODEL_LAST,
195};
196
197/* ALC882 models */
198enum {
199	ALC882_3ST_DIG,
200	ALC882_6ST_DIG,
201	ALC882_ARIMA,
202	ALC882_W2JC,
203	ALC882_TARGA,
204	ALC882_ASUS_A7J,
205	ALC882_ASUS_A7M,
206	ALC885_MACPRO,
207	ALC885_MBP3,
208	ALC885_IMAC24,
209	ALC882_AUTO,
210	ALC882_MODEL_LAST,
211};
212
213/* ALC883 models */
214enum {
215	ALC883_3ST_2ch_DIG,
216	ALC883_3ST_6ch_DIG,
217	ALC883_3ST_6ch,
218	ALC883_6ST_DIG,
219	ALC883_TARGA_DIG,
220	ALC883_TARGA_2ch_DIG,
221	ALC883_ACER,
222	ALC883_ACER_ASPIRE,
223	ALC888_ACER_ASPIRE_4930G,
224	ALC883_MEDION,
225	ALC883_MEDION_MD2,
226	ALC883_LAPTOP_EAPD,
227	ALC883_LENOVO_101E_2ch,
228	ALC883_LENOVO_NB0763,
229	ALC888_LENOVO_MS7195_DIG,
230	ALC888_LENOVO_SKY,
231	ALC883_HAIER_W66,
232	ALC888_3ST_HP,
233	ALC888_6ST_DELL,
234	ALC883_MITAC,
235	ALC883_CLEVO_M720,
236	ALC883_FUJITSU_PI2515,
237	ALC888_FUJITSU_XA3530,
238	ALC883_3ST_6ch_INTEL,
239	ALC888_ASUS_M90V,
240	ALC888_ASUS_EEE1601,
241	ALC1200_ASUS_P5Q,
242	ALC883_AUTO,
243	ALC883_MODEL_LAST,
244};
245
246/* styles of capture selection */
247enum {
248	CAPT_MUX = 0,	/* only mux based */
249	CAPT_MIX,	/* only mixer based */
250	CAPT_1MUX_MIX,	/* first mux and other mixers */
251};
252
253/* for GPIO Poll */
254#define GPIO_MASK	0x03
255
256struct alc_spec {
257	/* codec parameterization */
258	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
259	unsigned int num_mixers;
260	struct snd_kcontrol_new *cap_mixer;	/* capture mixer */
261	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */
262
263	const struct hda_verb *init_verbs[5];	/* initialization verbs
264						 * don't forget NULL
265						 * termination!
266						 */
267	unsigned int num_init_verbs;
268
269	char *stream_name_analog;	/* analog PCM stream */
270	struct hda_pcm_stream *stream_analog_playback;
271	struct hda_pcm_stream *stream_analog_capture;
272	struct hda_pcm_stream *stream_analog_alt_playback;
273	struct hda_pcm_stream *stream_analog_alt_capture;
274
275	char *stream_name_digital;	/* digital PCM stream */
276	struct hda_pcm_stream *stream_digital_playback;
277	struct hda_pcm_stream *stream_digital_capture;
278
279	/* playback */
280	struct hda_multi_out multiout;	/* playback set-up
281					 * max_channels, dacs must be set
282					 * dig_out_nid and hp_nid are optional
283					 */
284	hda_nid_t alt_dac_nid;
285	hda_nid_t slave_dig_outs[3];	/* optional - for auto-parsing */
286	int dig_out_type;
287
288	/* capture */
289	unsigned int num_adc_nids;
290	hda_nid_t *adc_nids;
291	hda_nid_t *capsrc_nids;
292	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
293	int capture_style;		/* capture style (CAPT_*) */
294
295	/* capture source */
296	unsigned int num_mux_defs;
297	const struct hda_input_mux *input_mux;
298	unsigned int cur_mux[3];
299
300	/* channel model */
301	const struct hda_channel_mode *channel_mode;
302	int num_channel_mode;
303	int need_dac_fix;
304
305	/* PCM information */
306	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
307
308	/* dynamic controls, init_verbs and input_mux */
309	struct auto_pin_cfg autocfg;
310	struct snd_array kctls;
311	struct hda_input_mux private_imux[3];
312	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
313
314	/* hooks */
315	void (*init_hook)(struct hda_codec *codec);
316	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
317
318	/* for pin sensing */
319	unsigned int sense_updated: 1;
320	unsigned int jack_present: 1;
321	unsigned int master_sw: 1;
322
323	/* other flags */
324	unsigned int no_analog :1; /* digital I/O only */
325
326	/* for virtual master */
327	hda_nid_t vmaster_nid;
328#ifdef CONFIG_SND_HDA_POWER_SAVE
329	struct hda_loopback_check loopback;
330#endif
331
332	/* for PLL fix */
333	hda_nid_t pll_nid;
334	unsigned int pll_coef_idx, pll_coef_bit;
335};
336
337/*
338 * configuration template - to be copied to the spec instance
339 */
340struct alc_config_preset {
341	struct snd_kcontrol_new *mixers[5]; /* should be identical size
342					     * with spec
343					     */
344	struct snd_kcontrol_new *cap_mixer; /* capture mixer */
345	const struct hda_verb *init_verbs[5];
346	unsigned int num_dacs;
347	hda_nid_t *dac_nids;
348	hda_nid_t dig_out_nid;		/* optional */
349	hda_nid_t hp_nid;		/* optional */
350	hda_nid_t *slave_dig_outs;
351	unsigned int num_adc_nids;
352	hda_nid_t *adc_nids;
353	hda_nid_t *capsrc_nids;
354	hda_nid_t dig_in_nid;
355	unsigned int num_channel_mode;
356	const struct hda_channel_mode *channel_mode;
357	int need_dac_fix;
358	unsigned int num_mux_defs;
359	const struct hda_input_mux *input_mux;
360	void (*unsol_event)(struct hda_codec *, unsigned int);
361	void (*init_hook)(struct hda_codec *);
362#ifdef CONFIG_SND_HDA_POWER_SAVE
363	struct hda_amp_list *loopbacks;
364#endif
365};
366
367
368/*
369 * input MUX handling
370 */
371static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
372			     struct snd_ctl_elem_info *uinfo)
373{
374	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
375	struct alc_spec *spec = codec->spec;
376	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
377	if (mux_idx >= spec->num_mux_defs)
378		mux_idx = 0;
379	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
380}
381
382static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
383			    struct snd_ctl_elem_value *ucontrol)
384{
385	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386	struct alc_spec *spec = codec->spec;
387	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
388
389	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
390	return 0;
391}
392
393static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
394			    struct snd_ctl_elem_value *ucontrol)
395{
396	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397	struct alc_spec *spec = codec->spec;
398	const struct hda_input_mux *imux;
399	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
400	unsigned int mux_idx;
401	hda_nid_t nid = spec->capsrc_nids ?
402		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
403
404	mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
405	imux = &spec->input_mux[mux_idx];
406
407	if (spec->capture_style &&
408	    !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
409		/* Matrix-mixer style (e.g. ALC882) */
410		unsigned int *cur_val = &spec->cur_mux[adc_idx];
411		unsigned int i, idx;
412
413		idx = ucontrol->value.enumerated.item[0];
414		if (idx >= imux->num_items)
415			idx = imux->num_items - 1;
416		if (*cur_val == idx)
417			return 0;
418		for (i = 0; i < imux->num_items; i++) {
419			unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
420			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
421						 imux->items[i].index,
422						 HDA_AMP_MUTE, v);
423		}
424		*cur_val = idx;
425		return 1;
426	} else {
427		/* MUX style (e.g. ALC880) */
428		return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
429					     &spec->cur_mux[adc_idx]);
430	}
431}
432
433/*
434 * channel mode setting
435 */
436static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
437			    struct snd_ctl_elem_info *uinfo)
438{
439	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
440	struct alc_spec *spec = codec->spec;
441	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
442				    spec->num_channel_mode);
443}
444
445static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
446			   struct snd_ctl_elem_value *ucontrol)
447{
448	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449	struct alc_spec *spec = codec->spec;
450	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
451				   spec->num_channel_mode,
452				   spec->multiout.max_channels);
453}
454
455static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
456			   struct snd_ctl_elem_value *ucontrol)
457{
458	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
459	struct alc_spec *spec = codec->spec;
460	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
461				      spec->num_channel_mode,
462				      &spec->multiout.max_channels);
463	if (err >= 0 && spec->need_dac_fix)
464		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
465	return err;
466}
467
468/*
469 * Control the mode of pin widget settings via the mixer.  "pc" is used
470 * instead of "%" to avoid consequences of accidently treating the % as
471 * being part of a format specifier.  Maximum allowed length of a value is
472 * 63 characters plus NULL terminator.
473 *
474 * Note: some retasking pin complexes seem to ignore requests for input
475 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
476 * are requested.  Therefore order this list so that this behaviour will not
477 * cause problems when mixer clients move through the enum sequentially.
478 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
479 * March 2006.
480 */
481static char *alc_pin_mode_names[] = {
482	"Mic 50pc bias", "Mic 80pc bias",
483	"Line in", "Line out", "Headphone out",
484};
485static unsigned char alc_pin_mode_values[] = {
486	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
487};
488/* The control can present all 5 options, or it can limit the options based
489 * in the pin being assumed to be exclusively an input or an output pin.  In
490 * addition, "input" pins may or may not process the mic bias option
491 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
492 * accept requests for bias as of chip versions up to March 2006) and/or
493 * wiring in the computer.
494 */
495#define ALC_PIN_DIR_IN              0x00
496#define ALC_PIN_DIR_OUT             0x01
497#define ALC_PIN_DIR_INOUT           0x02
498#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
499#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
500
501/* Info about the pin modes supported by the different pin direction modes.
502 * For each direction the minimum and maximum values are given.
503 */
504static signed char alc_pin_mode_dir_info[5][2] = {
505	{ 0, 2 },    /* ALC_PIN_DIR_IN */
506	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
507	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
508	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
509	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
510};
511#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
512#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
513#define alc_pin_mode_n_items(_dir) \
514	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
515
516static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
517			     struct snd_ctl_elem_info *uinfo)
518{
519	unsigned int item_num = uinfo->value.enumerated.item;
520	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
521
522	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
523	uinfo->count = 1;
524	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
525
526	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
527		item_num = alc_pin_mode_min(dir);
528	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
529	return 0;
530}
531
532static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
533			    struct snd_ctl_elem_value *ucontrol)
534{
535	unsigned int i;
536	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
537	hda_nid_t nid = kcontrol->private_value & 0xffff;
538	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
539	long *valp = ucontrol->value.integer.value;
540	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
541						 AC_VERB_GET_PIN_WIDGET_CONTROL,
542						 0x00);
543
544	/* Find enumerated value for current pinctl setting */
545	i = alc_pin_mode_min(dir);
546	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
547		i++;
548	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
549	return 0;
550}
551
552static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
553			    struct snd_ctl_elem_value *ucontrol)
554{
555	signed int change;
556	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557	hda_nid_t nid = kcontrol->private_value & 0xffff;
558	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
559	long val = *ucontrol->value.integer.value;
560	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
561						 AC_VERB_GET_PIN_WIDGET_CONTROL,
562						 0x00);
563
564	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
565		val = alc_pin_mode_min(dir);
566
567	change = pinctl != alc_pin_mode_values[val];
568	if (change) {
569		/* Set pin mode to that requested */
570		snd_hda_codec_write_cache(codec, nid, 0,
571					  AC_VERB_SET_PIN_WIDGET_CONTROL,
572					  alc_pin_mode_values[val]);
573
574		/* Also enable the retasking pin's input/output as required
575		 * for the requested pin mode.  Enum values of 2 or less are
576		 * input modes.
577		 *
578		 * Dynamically switching the input/output buffers probably
579		 * reduces noise slightly (particularly on input) so we'll
580		 * do it.  However, having both input and output buffers
581		 * enabled simultaneously doesn't seem to be problematic if
582		 * this turns out to be necessary in the future.
583		 */
584		if (val <= 2) {
585			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
586						 HDA_AMP_MUTE, HDA_AMP_MUTE);
587			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
588						 HDA_AMP_MUTE, 0);
589		} else {
590			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
591						 HDA_AMP_MUTE, HDA_AMP_MUTE);
592			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
593						 HDA_AMP_MUTE, 0);
594		}
595	}
596	return change;
597}
598
599#define ALC_PIN_MODE(xname, nid, dir) \
600	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
601	  .info = alc_pin_mode_info, \
602	  .get = alc_pin_mode_get, \
603	  .put = alc_pin_mode_put, \
604	  .private_value = nid | (dir<<16) }
605
606/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
607 * together using a mask with more than one bit set.  This control is
608 * currently used only by the ALC260 test model.  At this stage they are not
609 * needed for any "production" models.
610 */
611#ifdef CONFIG_SND_DEBUG
612#define alc_gpio_data_info	snd_ctl_boolean_mono_info
613
614static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
615			     struct snd_ctl_elem_value *ucontrol)
616{
617	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618	hda_nid_t nid = kcontrol->private_value & 0xffff;
619	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
620	long *valp = ucontrol->value.integer.value;
621	unsigned int val = snd_hda_codec_read(codec, nid, 0,
622					      AC_VERB_GET_GPIO_DATA, 0x00);
623
624	*valp = (val & mask) != 0;
625	return 0;
626}
627static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
628			     struct snd_ctl_elem_value *ucontrol)
629{
630	signed int change;
631	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
632	hda_nid_t nid = kcontrol->private_value & 0xffff;
633	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
634	long val = *ucontrol->value.integer.value;
635	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
636						    AC_VERB_GET_GPIO_DATA,
637						    0x00);
638
639	/* Set/unset the masked GPIO bit(s) as needed */
640	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
641	if (val == 0)
642		gpio_data &= ~mask;
643	else
644		gpio_data |= mask;
645	snd_hda_codec_write_cache(codec, nid, 0,
646				  AC_VERB_SET_GPIO_DATA, gpio_data);
647
648	return change;
649}
650#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
651	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
652	  .info = alc_gpio_data_info, \
653	  .get = alc_gpio_data_get, \
654	  .put = alc_gpio_data_put, \
655	  .private_value = nid | (mask<<16) }
656#endif   /* CONFIG_SND_DEBUG */
657
658/* A switch control to allow the enabling of the digital IO pins on the
659 * ALC260.  This is incredibly simplistic; the intention of this control is
660 * to provide something in the test model allowing digital outputs to be
661 * identified if present.  If models are found which can utilise these
662 * outputs a more complete mixer control can be devised for those models if
663 * necessary.
664 */
665#ifdef CONFIG_SND_DEBUG
666#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
667
668static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
669			      struct snd_ctl_elem_value *ucontrol)
670{
671	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
672	hda_nid_t nid = kcontrol->private_value & 0xffff;
673	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
674	long *valp = ucontrol->value.integer.value;
675	unsigned int val = snd_hda_codec_read(codec, nid, 0,
676					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
677
678	*valp = (val & mask) != 0;
679	return 0;
680}
681static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
682			      struct snd_ctl_elem_value *ucontrol)
683{
684	signed int change;
685	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
686	hda_nid_t nid = kcontrol->private_value & 0xffff;
687	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
688	long val = *ucontrol->value.integer.value;
689	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
690						    AC_VERB_GET_DIGI_CONVERT_1,
691						    0x00);
692
693	/* Set/unset the masked control bit(s) as needed */
694	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
695	if (val==0)
696		ctrl_data &= ~mask;
697	else
698		ctrl_data |= mask;
699	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
700				  ctrl_data);
701
702	return change;
703}
704#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
705	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
706	  .info = alc_spdif_ctrl_info, \
707	  .get = alc_spdif_ctrl_get, \
708	  .put = alc_spdif_ctrl_put, \
709	  .private_value = nid | (mask<<16) }
710#endif   /* CONFIG_SND_DEBUG */
711
712/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
713 * Again, this is only used in the ALC26x test models to help identify when
714 * the EAPD line must be asserted for features to work.
715 */
716#ifdef CONFIG_SND_DEBUG
717#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
718
719static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
720			      struct snd_ctl_elem_value *ucontrol)
721{
722	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723	hda_nid_t nid = kcontrol->private_value & 0xffff;
724	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725	long *valp = ucontrol->value.integer.value;
726	unsigned int val = snd_hda_codec_read(codec, nid, 0,
727					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
728
729	*valp = (val & mask) != 0;
730	return 0;
731}
732
733static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
734			      struct snd_ctl_elem_value *ucontrol)
735{
736	int change;
737	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
738	hda_nid_t nid = kcontrol->private_value & 0xffff;
739	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
740	long val = *ucontrol->value.integer.value;
741	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
742						    AC_VERB_GET_EAPD_BTLENABLE,
743						    0x00);
744
745	/* Set/unset the masked control bit(s) as needed */
746	change = (!val ? 0 : mask) != (ctrl_data & mask);
747	if (!val)
748		ctrl_data &= ~mask;
749	else
750		ctrl_data |= mask;
751	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
752				  ctrl_data);
753
754	return change;
755}
756
757#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
758	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
759	  .info = alc_eapd_ctrl_info, \
760	  .get = alc_eapd_ctrl_get, \
761	  .put = alc_eapd_ctrl_put, \
762	  .private_value = nid | (mask<<16) }
763#endif   /* CONFIG_SND_DEBUG */
764
765/*
766 * set up the input pin config (depending on the given auto-pin type)
767 */
768static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
769			      int auto_pin_type)
770{
771	unsigned int val = PIN_IN;
772
773	if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
774		unsigned int pincap;
775		pincap = snd_hda_query_pin_caps(codec, nid);
776		pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
777		if (pincap & AC_PINCAP_VREF_80)
778			val = PIN_VREF80;
779	}
780	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
781}
782
783/*
784 */
785static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
786{
787	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
788		return;
789	spec->mixers[spec->num_mixers++] = mix;
790}
791
792static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
793{
794	if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
795		return;
796	spec->init_verbs[spec->num_init_verbs++] = verb;
797}
798
799#ifdef CONFIG_PROC_FS
800/*
801 * hook for proc
802 */
803static void print_realtek_coef(struct snd_info_buffer *buffer,
804			       struct hda_codec *codec, hda_nid_t nid)
805{
806	int coeff;
807
808	if (nid != 0x20)
809		return;
810	coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
811	snd_iprintf(buffer, "  Processing Coefficient: 0x%02x\n", coeff);
812	coeff = snd_hda_codec_read(codec, nid, 0,
813				   AC_VERB_GET_COEF_INDEX, 0);
814	snd_iprintf(buffer, "  Coefficient Index: 0x%02x\n", coeff);
815}
816#else
817#define print_realtek_coef	NULL
818#endif
819
820/*
821 * set up from the preset table
822 */
823static void setup_preset(struct alc_spec *spec,
824			 const struct alc_config_preset *preset)
825{
826	int i;
827
828	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
829		add_mixer(spec, preset->mixers[i]);
830	spec->cap_mixer = preset->cap_mixer;
831	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
832	     i++)
833		add_verb(spec, preset->init_verbs[i]);
834
835	spec->channel_mode = preset->channel_mode;
836	spec->num_channel_mode = preset->num_channel_mode;
837	spec->need_dac_fix = preset->need_dac_fix;
838
839	spec->multiout.max_channels = spec->channel_mode[0].channels;
840
841	spec->multiout.num_dacs = preset->num_dacs;
842	spec->multiout.dac_nids = preset->dac_nids;
843	spec->multiout.dig_out_nid = preset->dig_out_nid;
844	spec->multiout.slave_dig_outs = preset->slave_dig_outs;
845	spec->multiout.hp_nid = preset->hp_nid;
846
847	spec->num_mux_defs = preset->num_mux_defs;
848	if (!spec->num_mux_defs)
849		spec->num_mux_defs = 1;
850	spec->input_mux = preset->input_mux;
851
852	spec->num_adc_nids = preset->num_adc_nids;
853	spec->adc_nids = preset->adc_nids;
854	spec->capsrc_nids = preset->capsrc_nids;
855	spec->dig_in_nid = preset->dig_in_nid;
856
857	spec->unsol_event = preset->unsol_event;
858	spec->init_hook = preset->init_hook;
859#ifdef CONFIG_SND_HDA_POWER_SAVE
860	spec->loopback.amplist = preset->loopbacks;
861#endif
862}
863
864/* Enable GPIO mask and set output */
865static struct hda_verb alc_gpio1_init_verbs[] = {
866	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
867	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
868	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
869	{ }
870};
871
872static struct hda_verb alc_gpio2_init_verbs[] = {
873	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
874	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
875	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
876	{ }
877};
878
879static struct hda_verb alc_gpio3_init_verbs[] = {
880	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
881	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
882	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
883	{ }
884};
885
886/*
887 * Fix hardware PLL issue
888 * On some codecs, the analog PLL gating control must be off while
889 * the default value is 1.
890 */
891static void alc_fix_pll(struct hda_codec *codec)
892{
893	struct alc_spec *spec = codec->spec;
894	unsigned int val;
895
896	if (!spec->pll_nid)
897		return;
898	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
899			    spec->pll_coef_idx);
900	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
901				 AC_VERB_GET_PROC_COEF, 0);
902	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
903			    spec->pll_coef_idx);
904	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
905			    val & ~(1 << spec->pll_coef_bit));
906}
907
908static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
909			     unsigned int coef_idx, unsigned int coef_bit)
910{
911	struct alc_spec *spec = codec->spec;
912	spec->pll_nid = nid;
913	spec->pll_coef_idx = coef_idx;
914	spec->pll_coef_bit = coef_bit;
915	alc_fix_pll(codec);
916}
917
918static void alc_sku_automute(struct hda_codec *codec)
919{
920	struct alc_spec *spec = codec->spec;
921	unsigned int present;
922	unsigned int hp_nid = spec->autocfg.hp_pins[0];
923	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
924
925	/* need to execute and sync at first */
926	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
927	present = snd_hda_codec_read(codec, hp_nid, 0,
928				     AC_VERB_GET_PIN_SENSE, 0);
929	spec->jack_present = (present & 0x80000000) != 0;
930	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
931			    spec->jack_present ? 0 : PIN_OUT);
932}
933
934#if 0 /* it's broken in some acses -- temporarily disabled */
935static void alc_mic_automute(struct hda_codec *codec)
936{
937	struct alc_spec *spec = codec->spec;
938	unsigned int present;
939	unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
940	unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
941	unsigned int mix_nid = spec->capsrc_nids[0];
942	unsigned int capsrc_idx_mic, capsrc_idx_fmic;
943
944	capsrc_idx_mic = mic_nid - 0x18;
945	capsrc_idx_fmic = fmic_nid - 0x18;
946	present = snd_hda_codec_read(codec, mic_nid, 0,
947				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
948	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
949		    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
950	snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
951		    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
952	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
953			 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
954}
955#else
956#define alc_mic_automute(codec) do {} while(0) /* NOP */
957#endif /* disabled */
958
959/* unsolicited event for HP jack sensing */
960static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
961{
962	if (codec->vendor_id == 0x10ec0880)
963		res >>= 28;
964	else
965		res >>= 26;
966	if (res == ALC880_HP_EVENT)
967		alc_sku_automute(codec);
968
969	if (res == ALC880_MIC_EVENT)
970		alc_mic_automute(codec);
971}
972
973static void alc_inithook(struct hda_codec *codec)
974{
975	alc_sku_automute(codec);
976	alc_mic_automute(codec);
977}
978
979/* additional initialization for ALC888 variants */
980static void alc888_coef_init(struct hda_codec *codec)
981{
982	unsigned int tmp;
983
984	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
985	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
986	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
987	if ((tmp & 0xf0) == 0x20)
988		/* alc888S-VC */
989		snd_hda_codec_read(codec, 0x20, 0,
990				   AC_VERB_SET_PROC_COEF, 0x830);
991	 else
992		 /* alc888-VB */
993		 snd_hda_codec_read(codec, 0x20, 0,
994				    AC_VERB_SET_PROC_COEF, 0x3030);
995}
996
997/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
998 *	31 ~ 16 :	Manufacture ID
999 *	15 ~ 8	:	SKU ID
1000 *	7  ~ 0	:	Assembly ID
1001 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1002 */
1003static void alc_subsystem_id(struct hda_codec *codec,
1004			     unsigned int porta, unsigned int porte,
1005			     unsigned int portd)
1006{
1007	unsigned int ass, tmp, i;
1008	unsigned nid;
1009	struct alc_spec *spec = codec->spec;
1010
1011	ass = codec->subsystem_id & 0xffff;
1012	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1013		goto do_sku;
1014
1015	/*
1016	 * 31~30	: port conetcivity
1017	 * 29~21	: reserve
1018	 * 20		: PCBEEP input
1019	 * 19~16	: Check sum (15:1)
1020	 * 15~1		: Custom
1021	 * 0		: override
1022	*/
1023	nid = 0x1d;
1024	if (codec->vendor_id == 0x10ec0260)
1025		nid = 0x17;
1026	ass = snd_hda_codec_get_pincfg(codec, nid);
1027	snd_printd("realtek: No valid SSID, "
1028		   "checking pincfg 0x%08x for NID 0x%x\n",
1029		   ass, nid);
1030	if (!(ass & 1) && !(ass & 0x100000))
1031		return;
1032	if ((ass >> 30) != 1)	/* no physical connection */
1033		return;
1034
1035	/* check sum */
1036	tmp = 0;
1037	for (i = 1; i < 16; i++) {
1038		if ((ass >> i) & 1)
1039			tmp++;
1040	}
1041	if (((ass >> 16) & 0xf) != tmp)
1042		return;
1043do_sku:
1044	snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1045		   ass & 0xffff, codec->vendor_id);
1046	/*
1047	 * 0 : override
1048	 * 1 :	Swap Jack
1049	 * 2 : 0 --> Desktop, 1 --> Laptop
1050	 * 3~5 : External Amplifier control
1051	 * 7~6 : Reserved
1052	*/
1053	tmp = (ass & 0x38) >> 3;	/* external Amp control */
1054	switch (tmp) {
1055	case 1:
1056		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1057		break;
1058	case 3:
1059		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1060		break;
1061	case 7:
1062		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1063		break;
1064	case 5:	/* set EAPD output high */
1065		switch (codec->vendor_id) {
1066		case 0x10ec0260:
1067			snd_hda_codec_write(codec, 0x0f, 0,
1068					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1069			snd_hda_codec_write(codec, 0x10, 0,
1070					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1071			break;
1072		case 0x10ec0262:
1073		case 0x10ec0267:
1074		case 0x10ec0268:
1075		case 0x10ec0269:
1076		case 0x10ec0272:
1077		case 0x10ec0660:
1078		case 0x10ec0662:
1079		case 0x10ec0663:
1080		case 0x10ec0862:
1081		case 0x10ec0889:
1082			snd_hda_codec_write(codec, 0x14, 0,
1083					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1084			snd_hda_codec_write(codec, 0x15, 0,
1085					    AC_VERB_SET_EAPD_BTLENABLE, 2);
1086			break;
1087		}
1088		switch (codec->vendor_id) {
1089		case 0x10ec0260:
1090			snd_hda_codec_write(codec, 0x1a, 0,
1091					    AC_VERB_SET_COEF_INDEX, 7);
1092			tmp = snd_hda_codec_read(codec, 0x1a, 0,
1093						 AC_VERB_GET_PROC_COEF, 0);
1094			snd_hda_codec_write(codec, 0x1a, 0,
1095					    AC_VERB_SET_COEF_INDEX, 7);
1096			snd_hda_codec_write(codec, 0x1a, 0,
1097					    AC_VERB_SET_PROC_COEF,
1098					    tmp | 0x2010);
1099			break;
1100		case 0x10ec0262:
1101		case 0x10ec0880:
1102		case 0x10ec0882:
1103		case 0x10ec0883:
1104		case 0x10ec0885:
1105		case 0x10ec0887:
1106		case 0x10ec0889:
1107			snd_hda_codec_write(codec, 0x20, 0,
1108					    AC_VERB_SET_COEF_INDEX, 7);
1109			tmp = snd_hda_codec_read(codec, 0x20, 0,
1110						 AC_VERB_GET_PROC_COEF, 0);
1111			snd_hda_codec_write(codec, 0x20, 0,
1112					    AC_VERB_SET_COEF_INDEX, 7);
1113			snd_hda_codec_write(codec, 0x20, 0,
1114					    AC_VERB_SET_PROC_COEF,
1115					    tmp | 0x2010);
1116			break;
1117		case 0x10ec0888:
1118			/*alc888_coef_init(codec);*/ /* called in alc_init() */
1119			break;
1120		case 0x10ec0267:
1121		case 0x10ec0268:
1122			snd_hda_codec_write(codec, 0x20, 0,
1123					    AC_VERB_SET_COEF_INDEX, 7);
1124			tmp = snd_hda_codec_read(codec, 0x20, 0,
1125						 AC_VERB_GET_PROC_COEF, 0);
1126			snd_hda_codec_write(codec, 0x20, 0,
1127					    AC_VERB_SET_COEF_INDEX, 7);
1128			snd_hda_codec_write(codec, 0x20, 0,
1129					    AC_VERB_SET_PROC_COEF,
1130					    tmp | 0x3000);
1131			break;
1132		}
1133	default:
1134		break;
1135	}
1136
1137	/* is laptop or Desktop and enable the function "Mute internal speaker
1138	 * when the external headphone out jack is plugged"
1139	 */
1140	if (!(ass & 0x8000))
1141		return;
1142	/*
1143	 * 10~8 : Jack location
1144	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1145	 * 14~13: Resvered
1146	 * 15   : 1 --> enable the function "Mute internal speaker
1147	 *	        when the external headphone out jack is plugged"
1148	 */
1149	if (!spec->autocfg.speaker_pins[0]) {
1150		if (spec->autocfg.line_out_pins[0])
1151			spec->autocfg.speaker_pins[0] =
1152				spec->autocfg.line_out_pins[0];
1153		else
1154			return;
1155	}
1156
1157	if (!spec->autocfg.hp_pins[0]) {
1158		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
1159		if (tmp == 0)
1160			spec->autocfg.hp_pins[0] = porta;
1161		else if (tmp == 1)
1162			spec->autocfg.hp_pins[0] = porte;
1163		else if (tmp == 2)
1164			spec->autocfg.hp_pins[0] = portd;
1165		else
1166			return;
1167	}
1168	if (spec->autocfg.hp_pins[0])
1169		snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1170			AC_VERB_SET_UNSOLICITED_ENABLE,
1171			AC_USRSP_EN | ALC880_HP_EVENT);
1172
1173#if 0 /* it's broken in some acses -- temporarily disabled */
1174	if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1175		spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1176		snd_hda_codec_write(codec,
1177			spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1178			AC_VERB_SET_UNSOLICITED_ENABLE,
1179			AC_USRSP_EN | ALC880_MIC_EVENT);
1180#endif /* disabled */
1181
1182	spec->unsol_event = alc_sku_unsol_event;
1183}
1184
1185/*
1186 * Fix-up pin default configurations
1187 */
1188
1189struct alc_pincfg {
1190	hda_nid_t nid;
1191	u32 val;
1192};
1193
1194static void alc_fix_pincfg(struct hda_codec *codec,
1195			   const struct snd_pci_quirk *quirk,
1196			   const struct alc_pincfg **pinfix)
1197{
1198	const struct alc_pincfg *cfg;
1199
1200	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1201	if (!quirk)
1202		return;
1203
1204	cfg = pinfix[quirk->value];
1205	for (; cfg->nid; cfg++)
1206		snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1207}
1208
1209/*
1210 * ALC888
1211 */
1212
1213/*
1214 * 2ch mode
1215 */
1216static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1217/* Mic-in jack as mic in */
1218	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1219	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1220/* Line-in jack as Line in */
1221	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1222	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1223/* Line-Out as Front */
1224	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1225	{ } /* end */
1226};
1227
1228/*
1229 * 4ch mode
1230 */
1231static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1232/* Mic-in jack as mic in */
1233	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1234	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1235/* Line-in jack as Surround */
1236	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1237	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1238/* Line-Out as Front */
1239	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1240	{ } /* end */
1241};
1242
1243/*
1244 * 6ch mode
1245 */
1246static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1247/* Mic-in jack as CLFE */
1248	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1249	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1250/* Line-in jack as Surround */
1251	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1252	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1253/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1254	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1255	{ } /* end */
1256};
1257
1258/*
1259 * 8ch mode
1260 */
1261static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1262/* Mic-in jack as CLFE */
1263	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1264	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1265/* Line-in jack as Surround */
1266	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1267	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1268/* Line-Out as Side */
1269	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1270	{ } /* end */
1271};
1272
1273static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1274	{ 2, alc888_4ST_ch2_intel_init },
1275	{ 4, alc888_4ST_ch4_intel_init },
1276	{ 6, alc888_4ST_ch6_intel_init },
1277	{ 8, alc888_4ST_ch8_intel_init },
1278};
1279
1280/*
1281 * ALC888 Fujitsu Siemens Amillo xa3530
1282 */
1283
1284static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1285/* Front Mic: set to PIN_IN (empty by default) */
1286	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1287/* Connect Internal HP to Front */
1288	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1289	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1290	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1291/* Connect Bass HP to Front */
1292	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1293	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1294	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1295/* Connect Line-Out side jack (SPDIF) to Side */
1296	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1297	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1298	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1299/* Connect Mic jack to CLFE */
1300	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1301	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1302	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1303/* Connect Line-in jack to Surround */
1304	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1305	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1306	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1307/* Connect HP out jack to Front */
1308	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1309	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1310	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1311/* Enable unsolicited event for HP jack and Line-out jack */
1312	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1313	{0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1314	{}
1315};
1316
1317static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1318{
1319	unsigned int present;
1320	unsigned int bits;
1321	/* Line out presence */
1322	present = snd_hda_codec_read(codec, 0x17, 0,
1323				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1324	/* HP out presence */
1325	present = present || snd_hda_codec_read(codec, 0x1b, 0,
1326				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1327	bits = present ? HDA_AMP_MUTE : 0;
1328	/* Toggle internal speakers muting */
1329	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1330				 HDA_AMP_MUTE, bits);
1331	/* Toggle internal bass muting */
1332	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1333				 HDA_AMP_MUTE, bits);
1334}
1335
1336static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1337		unsigned int res)
1338{
1339	if (res >> 26 == ALC880_HP_EVENT)
1340		alc888_fujitsu_xa3530_automute(codec);
1341}
1342
1343
1344/*
1345 * ALC888 Acer Aspire 4930G model
1346 */
1347
1348static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1349/* Front Mic: set to PIN_IN (empty by default) */
1350	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1351/* Unselect Front Mic by default in input mixer 3 */
1352	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1353/* Enable unsolicited event for HP jack */
1354	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1355/* Connect Internal HP to front */
1356	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1357	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1358	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1359/* Connect HP out to front */
1360	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1361	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1363	{ }
1364};
1365
1366static struct hda_input_mux alc888_2_capture_sources[2] = {
1367	/* Front mic only available on one ADC */
1368	{
1369		.num_items = 4,
1370		.items = {
1371			{ "Mic", 0x0 },
1372			{ "Line", 0x2 },
1373			{ "CD", 0x4 },
1374			{ "Front Mic", 0xb },
1375		},
1376	},
1377	{
1378		.num_items = 3,
1379		.items = {
1380			{ "Mic", 0x0 },
1381			{ "Line", 0x2 },
1382			{ "CD", 0x4 },
1383		},
1384	}
1385};
1386
1387static struct snd_kcontrol_new alc888_base_mixer[] = {
1388	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1389	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1390	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1391	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1392	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1393		HDA_OUTPUT),
1394	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1395	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1396	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1397	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1398	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1399	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1400	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1401	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1402	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1403	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1404	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1405	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1406	{ } /* end */
1407};
1408
1409static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1410{
1411	unsigned int present;
1412	unsigned int bits;
1413	present = snd_hda_codec_read(codec, 0x15, 0,
1414				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1415	bits = present ? HDA_AMP_MUTE : 0;
1416	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1417				 HDA_AMP_MUTE, bits);
1418}
1419
1420static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1421		unsigned int res)
1422{
1423	if (res >> 26 == ALC880_HP_EVENT)
1424		alc888_acer_aspire_4930g_automute(codec);
1425}
1426
1427/*
1428 * ALC880 3-stack model
1429 *
1430 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1431 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1432 *                 F-Mic = 0x1b, HP = 0x19
1433 */
1434
1435static hda_nid_t alc880_dac_nids[4] = {
1436	/* front, rear, clfe, rear_surr */
1437	0x02, 0x05, 0x04, 0x03
1438};
1439
1440static hda_nid_t alc880_adc_nids[3] = {
1441	/* ADC0-2 */
1442	0x07, 0x08, 0x09,
1443};
1444
1445/* The datasheet says the node 0x07 is connected from inputs,
1446 * but it shows zero connection in the real implementation on some devices.
1447 * Note: this is a 915GAV bug, fixed on 915GLV
1448 */
1449static hda_nid_t alc880_adc_nids_alt[2] = {
1450	/* ADC1-2 */
1451	0x08, 0x09,
1452};
1453
1454#define ALC880_DIGOUT_NID	0x06
1455#define ALC880_DIGIN_NID	0x0a
1456
1457static struct hda_input_mux alc880_capture_source = {
1458	.num_items = 4,
1459	.items = {
1460		{ "Mic", 0x0 },
1461		{ "Front Mic", 0x3 },
1462		{ "Line", 0x2 },
1463		{ "CD", 0x4 },
1464	},
1465};
1466
1467/* channel source setting (2/6 channel selection for 3-stack) */
1468/* 2ch mode */
1469static struct hda_verb alc880_threestack_ch2_init[] = {
1470	/* set line-in to input, mute it */
1471	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1472	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1473	/* set mic-in to input vref 80%, mute it */
1474	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1475	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1476	{ } /* end */
1477};
1478
1479/* 6ch mode */
1480static struct hda_verb alc880_threestack_ch6_init[] = {
1481	/* set line-in to output, unmute it */
1482	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1483	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1484	/* set mic-in to output, unmute it */
1485	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1486	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1487	{ } /* end */
1488};
1489
1490static struct hda_channel_mode alc880_threestack_modes[2] = {
1491	{ 2, alc880_threestack_ch2_init },
1492	{ 6, alc880_threestack_ch6_init },
1493};
1494
1495static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1496	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1497	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1498	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1499	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1500	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1501	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1502	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1503	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1504	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1505	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1506	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1507	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1508	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1509	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1510	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1511	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1512	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1513	{
1514		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1515		.name = "Channel Mode",
1516		.info = alc_ch_mode_info,
1517		.get = alc_ch_mode_get,
1518		.put = alc_ch_mode_put,
1519	},
1520	{ } /* end */
1521};
1522
1523/* capture mixer elements */
1524static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1525			    struct snd_ctl_elem_info *uinfo)
1526{
1527	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1528	struct alc_spec *spec = codec->spec;
1529	int err;
1530
1531	mutex_lock(&codec->control_mutex);
1532	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1533						      HDA_INPUT);
1534	err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1535	mutex_unlock(&codec->control_mutex);
1536	return err;
1537}
1538
1539static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1540			   unsigned int size, unsigned int __user *tlv)
1541{
1542	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1543	struct alc_spec *spec = codec->spec;
1544	int err;
1545
1546	mutex_lock(&codec->control_mutex);
1547	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1548						      HDA_INPUT);
1549	err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1550	mutex_unlock(&codec->control_mutex);
1551	return err;
1552}
1553
1554typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1555			     struct snd_ctl_elem_value *ucontrol);
1556
1557static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1558				 struct snd_ctl_elem_value *ucontrol,
1559				 getput_call_t func)
1560{
1561	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562	struct alc_spec *spec = codec->spec;
1563	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1564	int err;
1565
1566	mutex_lock(&codec->control_mutex);
1567	kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1568						      3, 0, HDA_INPUT);
1569	err = func(kcontrol, ucontrol);
1570	mutex_unlock(&codec->control_mutex);
1571	return err;
1572}
1573
1574static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1575			   struct snd_ctl_elem_value *ucontrol)
1576{
1577	return alc_cap_getput_caller(kcontrol, ucontrol,
1578				     snd_hda_mixer_amp_volume_get);
1579}
1580
1581static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1582			   struct snd_ctl_elem_value *ucontrol)
1583{
1584	return alc_cap_getput_caller(kcontrol, ucontrol,
1585				     snd_hda_mixer_amp_volume_put);
1586}
1587
1588/* capture mixer elements */
1589#define alc_cap_sw_info		snd_ctl_boolean_stereo_info
1590
1591static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1592			  struct snd_ctl_elem_value *ucontrol)
1593{
1594	return alc_cap_getput_caller(kcontrol, ucontrol,
1595				     snd_hda_mixer_amp_switch_get);
1596}
1597
1598static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1599			  struct snd_ctl_elem_value *ucontrol)
1600{
1601	return alc_cap_getput_caller(kcontrol, ucontrol,
1602				     snd_hda_mixer_amp_switch_put);
1603}
1604
1605#define _DEFINE_CAPMIX(num) \
1606	{ \
1607		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1608		.name = "Capture Switch", \
1609		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1610		.count = num, \
1611		.info = alc_cap_sw_info, \
1612		.get = alc_cap_sw_get, \
1613		.put = alc_cap_sw_put, \
1614	}, \
1615	{ \
1616		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1617		.name = "Capture Volume", \
1618		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1619			   SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1620			   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1621		.count = num, \
1622		.info = alc_cap_vol_info, \
1623		.get = alc_cap_vol_get, \
1624		.put = alc_cap_vol_put, \
1625		.tlv = { .c = alc_cap_vol_tlv }, \
1626	}
1627
1628#define _DEFINE_CAPSRC(num) \
1629	{ \
1630		.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1631		/* .name = "Capture Source", */ \
1632		.name = "Input Source", \
1633		.count = num, \
1634		.info = alc_mux_enum_info, \
1635		.get = alc_mux_enum_get, \
1636		.put = alc_mux_enum_put, \
1637	}
1638
1639#define DEFINE_CAPMIX(num) \
1640static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1641	_DEFINE_CAPMIX(num),				      \
1642	_DEFINE_CAPSRC(num),				      \
1643	{ } /* end */					      \
1644}
1645
1646#define DEFINE_CAPMIX_NOSRC(num) \
1647static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1648	_DEFINE_CAPMIX(num),					    \
1649	{ } /* end */						    \
1650}
1651
1652/* up to three ADCs */
1653DEFINE_CAPMIX(1);
1654DEFINE_CAPMIX(2);
1655DEFINE_CAPMIX(3);
1656DEFINE_CAPMIX_NOSRC(1);
1657DEFINE_CAPMIX_NOSRC(2);
1658DEFINE_CAPMIX_NOSRC(3);
1659
1660/*
1661 * ALC880 5-stack model
1662 *
1663 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1664 *      Side = 0x02 (0xd)
1665 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1666 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1667 */
1668
1669/* additional mixers to alc880_three_stack_mixer */
1670static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1671	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1672	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1673	{ } /* end */
1674};
1675
1676/* channel source setting (6/8 channel selection for 5-stack) */
1677/* 6ch mode */
1678static struct hda_verb alc880_fivestack_ch6_init[] = {
1679	/* set line-in to input, mute it */
1680	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1681	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1682	{ } /* end */
1683};
1684
1685/* 8ch mode */
1686static struct hda_verb alc880_fivestack_ch8_init[] = {
1687	/* set line-in to output, unmute it */
1688	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1689	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1690	{ } /* end */
1691};
1692
1693static struct hda_channel_mode alc880_fivestack_modes[2] = {
1694	{ 6, alc880_fivestack_ch6_init },
1695	{ 8, alc880_fivestack_ch8_init },
1696};
1697
1698
1699/*
1700 * ALC880 6-stack model
1701 *
1702 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1703 *      Side = 0x05 (0x0f)
1704 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1705 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1706 */
1707
1708static hda_nid_t alc880_6st_dac_nids[4] = {
1709	/* front, rear, clfe, rear_surr */
1710	0x02, 0x03, 0x04, 0x05
1711};
1712
1713static struct hda_input_mux alc880_6stack_capture_source = {
1714	.num_items = 4,
1715	.items = {
1716		{ "Mic", 0x0 },
1717		{ "Front Mic", 0x1 },
1718		{ "Line", 0x2 },
1719		{ "CD", 0x4 },
1720	},
1721};
1722
1723/* fixed 8-channels */
1724static struct hda_channel_mode alc880_sixstack_modes[1] = {
1725	{ 8, NULL },
1726};
1727
1728static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1729	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1730	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1731	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1732	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1733	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1734	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1735	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1736	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1737	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1738	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1739	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1740	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1741	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1742	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1743	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1744	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1745	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1746	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1747	{
1748		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1749		.name = "Channel Mode",
1750		.info = alc_ch_mode_info,
1751		.get = alc_ch_mode_get,
1752		.put = alc_ch_mode_put,
1753	},
1754	{ } /* end */
1755};
1756
1757
1758/*
1759 * ALC880 W810 model
1760 *
1761 * W810 has rear IO for:
1762 * Front (DAC 02)
1763 * Surround (DAC 03)
1764 * Center/LFE (DAC 04)
1765 * Digital out (06)
1766 *
1767 * The system also has a pair of internal speakers, and a headphone jack.
1768 * These are both connected to Line2 on the codec, hence to DAC 02.
1769 *
1770 * There is a variable resistor to control the speaker or headphone
1771 * volume. This is a hardware-only device without a software API.
1772 *
1773 * Plugging headphones in will disable the internal speakers. This is
1774 * implemented in hardware, not via the driver using jack sense. In
1775 * a similar fashion, plugging into the rear socket marked "front" will
1776 * disable both the speakers and headphones.
1777 *
1778 * For input, there's a microphone jack, and an "audio in" jack.
1779 * These may not do anything useful with this driver yet, because I
1780 * haven't setup any initialization verbs for these yet...
1781 */
1782
1783static hda_nid_t alc880_w810_dac_nids[3] = {
1784	/* front, rear/surround, clfe */
1785	0x02, 0x03, 0x04
1786};
1787
1788/* fixed 6 channels */
1789static struct hda_channel_mode alc880_w810_modes[1] = {
1790	{ 6, NULL }
1791};
1792
1793/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1794static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1795	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1796	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1797	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1798	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1799	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1800	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1801	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1802	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1803	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1804	{ } /* end */
1805};
1806
1807
1808/*
1809 * Z710V model
1810 *
1811 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1812 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1813 *                 Line = 0x1a
1814 */
1815
1816static hda_nid_t alc880_z71v_dac_nids[1] = {
1817	0x02
1818};
1819#define ALC880_Z71V_HP_DAC	0x03
1820
1821/* fixed 2 channels */
1822static struct hda_channel_mode alc880_2_jack_modes[1] = {
1823	{ 2, NULL }
1824};
1825
1826static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1827	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1828	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1829	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1830	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1831	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1832	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1833	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1834	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1835	{ } /* end */
1836};
1837
1838
1839/*
1840 * ALC880 F1734 model
1841 *
1842 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1843 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1844 */
1845
1846static hda_nid_t alc880_f1734_dac_nids[1] = {
1847	0x03
1848};
1849#define ALC880_F1734_HP_DAC	0x02
1850
1851static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1852	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1853	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1854	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1855	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1856	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1857	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1858	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1859	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1860	{ } /* end */
1861};
1862
1863static struct hda_input_mux alc880_f1734_capture_source = {
1864	.num_items = 2,
1865	.items = {
1866		{ "Mic", 0x1 },
1867		{ "CD", 0x4 },
1868	},
1869};
1870
1871
1872/*
1873 * ALC880 ASUS model
1874 *
1875 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1876 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1877 *  Mic = 0x18, Line = 0x1a
1878 */
1879
1880#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1881#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1882
1883static struct snd_kcontrol_new alc880_asus_mixer[] = {
1884	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1885	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1886	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1887	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1888	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1889	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1890	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1891	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1892	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1893	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1894	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1895	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1896	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1897	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1898	{
1899		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1900		.name = "Channel Mode",
1901		.info = alc_ch_mode_info,
1902		.get = alc_ch_mode_get,
1903		.put = alc_ch_mode_put,
1904	},
1905	{ } /* end */
1906};
1907
1908/*
1909 * ALC880 ASUS W1V model
1910 *
1911 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1912 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1913 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1914 */
1915
1916/* additional mixers to alc880_asus_mixer */
1917static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1918	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1919	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1920	{ } /* end */
1921};
1922
1923/* TCL S700 */
1924static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1925	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1926	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1927	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1928	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1929	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1930	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1931	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1932	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1933	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1934	{ } /* end */
1935};
1936
1937/* Uniwill */
1938static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1939	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1940	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1941	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1942	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1943	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1944	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1945	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1946	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1947	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1948	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1949	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1950	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1951	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1952	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1953	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1954	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1955	{
1956		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1957		.name = "Channel Mode",
1958		.info = alc_ch_mode_info,
1959		.get = alc_ch_mode_get,
1960		.put = alc_ch_mode_put,
1961	},
1962	{ } /* end */
1963};
1964
1965static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1966	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1967	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1968	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1969	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1970	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1971	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1972	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1973	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1974	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1975	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1976	{ } /* end */
1977};
1978
1979static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1980	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1981	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1982	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1983	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1984	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1985	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1986	{ } /* end */
1987};
1988
1989/*
1990 * virtual master controls
1991 */
1992
1993/*
1994 * slave controls for virtual master
1995 */
1996static const char *alc_slave_vols[] = {
1997	"Front Playback Volume",
1998	"Surround Playback Volume",
1999	"Center Playback Volume",
2000	"LFE Playback Volume",
2001	"Side Playback Volume",
2002	"Headphone Playback Volume",
2003	"Speaker Playback Volume",
2004	"Mono Playback Volume",
2005	"Line-Out Playback Volume",
2006	"PCM Playback Volume",
2007	NULL,
2008};
2009
2010static const char *alc_slave_sws[] = {
2011	"Front Playback Switch",
2012	"Surround Playback Switch",
2013	"Center Playback Switch",
2014	"LFE Playback Switch",
2015	"Side Playback Switch",
2016	"Headphone Playback Switch",
2017	"Speaker Playback Switch",
2018	"Mono Playback Switch",
2019	"IEC958 Playback Switch",
2020	NULL,
2021};
2022
2023/*
2024 * build control elements
2025 */
2026
2027static void alc_free_kctls(struct hda_codec *codec);
2028
2029/* additional beep mixers; the actual parameters are overwritten at build */
2030static struct snd_kcontrol_new alc_beep_mixer[] = {
2031	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2032	HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2033	{ } /* end */
2034};
2035
2036static int alc_build_controls(struct hda_codec *codec)
2037{
2038	struct alc_spec *spec = codec->spec;
2039	int err;
2040	int i;
2041
2042	for (i = 0; i < spec->num_mixers; i++) {
2043		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2044		if (err < 0)
2045			return err;
2046	}
2047	if (spec->cap_mixer) {
2048		err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2049		if (err < 0)
2050			return err;
2051	}
2052	if (spec->multiout.dig_out_nid) {
2053		err = snd_hda_create_spdif_out_ctls(codec,
2054						    spec->multiout.dig_out_nid);
2055		if (err < 0)
2056			return err;
2057		if (!spec->no_analog) {
2058			err = snd_hda_create_spdif_share_sw(codec,
2059							    &spec->multiout);
2060			if (err < 0)
2061				return err;
2062			spec->multiout.share_spdif = 1;
2063		}
2064	}
2065	if (spec->dig_in_nid) {
2066		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2067		if (err < 0)
2068			return err;
2069	}
2070
2071	/* create beep controls if needed */
2072	if (spec->beep_amp) {
2073		struct snd_kcontrol_new *knew;
2074		for (knew = alc_beep_mixer; knew->name; knew++) {
2075			struct snd_kcontrol *kctl;
2076			kctl = snd_ctl_new1(knew, codec);
2077			if (!kctl)
2078				return -ENOMEM;
2079			kctl->private_value = spec->beep_amp;
2080			err = snd_hda_ctl_add(codec, kctl);
2081			if (err < 0)
2082				return err;
2083		}
2084	}
2085
2086	/* if we have no master control, let's create it */
2087	if (!spec->no_analog &&
2088	    !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2089		unsigned int vmaster_tlv[4];
2090		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2091					HDA_OUTPUT, vmaster_tlv);
2092		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2093					  vmaster_tlv, alc_slave_vols);
2094		if (err < 0)
2095			return err;
2096	}
2097	if (!spec->no_analog &&
2098	    !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2099		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2100					  NULL, alc_slave_sws);
2101		if (err < 0)
2102			return err;
2103	}
2104
2105	alc_free_kctls(codec); /* no longer needed */
2106	return 0;
2107}
2108
2109
2110/*
2111 * initialize the codec volumes, etc
2112 */
2113
2114/*
2115 * generic initialization of ADC, input mixers and output mixers
2116 */
2117static struct hda_verb alc880_volume_init_verbs[] = {
2118	/*
2119	 * Unmute ADC0-2 and set the default input to mic-in
2120	 */
2121	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2122	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2123	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2124	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2125	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2126	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2127
2128	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2129	 * mixer widget
2130	 * Note: PASD motherboards uses the Line In 2 as the input for front
2131	 * panel mic (mic 2)
2132	 */
2133	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2134	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2135	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2136	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2137	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2138	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2139	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2140	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2141
2142	/*
2143	 * Set up output mixers (0x0c - 0x0f)
2144	 */
2145	/* set vol=0 to output mixers */
2146	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2147	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2148	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2149	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2150	/* set up input amps for analog loopback */
2151	/* Amp Indices: DAC = 0, mixer = 1 */
2152	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2153	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2154	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2155	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2156	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2157	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2158	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2159	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2160
2161	{ }
2162};
2163
2164/*
2165 * 3-stack pin configuration:
2166 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2167 */
2168static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2169	/*
2170	 * preset connection lists of input pins
2171	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2172	 */
2173	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2174	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2175	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2176
2177	/*
2178	 * Set pin mode and muting
2179	 */
2180	/* set front pin widgets 0x14 for output */
2181	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2182	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2183	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2184	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2185	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2186	/* Mic2 (as headphone out) for HP output */
2187	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2188	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2189	/* Line In pin widget for input */
2190	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2191	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2192	/* Line2 (as front mic) pin widget for input and vref at 80% */
2193	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2194	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2195	/* CD pin widget for input */
2196	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2197
2198	{ }
2199};
2200
2201/*
2202 * 5-stack pin configuration:
2203 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2204 * line-in/side = 0x1a, f-mic = 0x1b
2205 */
2206static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2207	/*
2208	 * preset connection lists of input pins
2209	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2210	 */
2211	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2212	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2213
2214	/*
2215	 * Set pin mode and muting
2216	 */
2217	/* set pin widgets 0x14-0x17 for output */
2218	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2221	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222	/* unmute pins for output (no gain on this amp) */
2223	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2224	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227
2228	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2229	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2230	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2231	/* Mic2 (as headphone out) for HP output */
2232	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2233	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2234	/* Line In pin widget for input */
2235	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2236	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2237	/* Line2 (as front mic) pin widget for input and vref at 80% */
2238	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2239	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2240	/* CD pin widget for input */
2241	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2242
2243	{ }
2244};
2245
2246/*
2247 * W810 pin configuration:
2248 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2249 */
2250static struct hda_verb alc880_pin_w810_init_verbs[] = {
2251	/* hphone/speaker input selector: front DAC */
2252	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2253
2254	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2255	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2256	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2257	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2258	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2259	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2260
2261	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2262	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2263
2264	{ }
2265};
2266
2267/*
2268 * Z71V pin configuration:
2269 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2270 */
2271static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2272	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2273	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2274	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2275	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2276
2277	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2278	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2279	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2280	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2281
2282	{ }
2283};
2284
2285/*
2286 * 6-stack pin configuration:
2287 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2288 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2289 */
2290static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2291	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2292
2293	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2294	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2295	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2296	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2297	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2298	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2299	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2300	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2301
2302	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2303	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2304	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2305	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2306	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2307	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2308	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2309	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2311
2312	{ }
2313};
2314
2315/*
2316 * Uniwill pin configuration:
2317 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2318 * line = 0x1a
2319 */
2320static struct hda_verb alc880_uniwill_init_verbs[] = {
2321	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2322
2323	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2324	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2325	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2326	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2328	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2329	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2330	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2331	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2332	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2333	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2334	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2335	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2336	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2337
2338	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2339	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2340	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2341	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2342	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2343	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2344	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2345	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2346	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2347
2348	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2349	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2350
2351	{ }
2352};
2353
2354/*
2355* Uniwill P53
2356* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2357 */
2358static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2359	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2360
2361	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2362	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2363	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2364	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2366	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2368	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2369	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2370	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2371	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2372	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2373
2374	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2375	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2376	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2377	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2378	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2379	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2380
2381	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2382	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2383
2384	{ }
2385};
2386
2387static struct hda_verb alc880_beep_init_verbs[] = {
2388	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2389	{ }
2390};
2391
2392/* toggle speaker-output according to the hp-jack state */
2393static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2394{
2395 	unsigned int present;
2396	unsigned char bits;
2397
2398 	present = snd_hda_codec_read(codec, 0x14, 0,
2399				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2400	bits = present ? HDA_AMP_MUTE : 0;
2401	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2402				 HDA_AMP_MUTE, bits);
2403	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2404				 HDA_AMP_MUTE, bits);
2405}
2406
2407/* auto-toggle front mic */
2408static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2409{
2410 	unsigned int present;
2411	unsigned char bits;
2412
2413	present = snd_hda_codec_read(codec, 0x18, 0,
2414				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2415	bits = present ? HDA_AMP_MUTE : 0;
2416	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2417}
2418
2419static void alc880_uniwill_automute(struct hda_codec *codec)
2420{
2421	alc880_uniwill_hp_automute(codec);
2422	alc880_uniwill_mic_automute(codec);
2423}
2424
2425static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2426				       unsigned int res)
2427{
2428	/* Looks like the unsol event is incompatible with the standard
2429	 * definition.  4bit tag is placed at 28 bit!
2430	 */
2431	switch (res >> 28) {
2432	case ALC880_HP_EVENT:
2433		alc880_uniwill_hp_automute(codec);
2434		break;
2435	case ALC880_MIC_EVENT:
2436		alc880_uniwill_mic_automute(codec);
2437		break;
2438	}
2439}
2440
2441static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2442{
2443 	unsigned int present;
2444	unsigned char bits;
2445
2446 	present = snd_hda_codec_read(codec, 0x14, 0,
2447				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2448	bits = present ? HDA_AMP_MUTE : 0;
2449	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2450}
2451
2452static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2453{
2454	unsigned int present;
2455
2456	present = snd_hda_codec_read(codec, 0x21, 0,
2457				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2458	present &= HDA_AMP_VOLMASK;
2459	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2460				 HDA_AMP_VOLMASK, present);
2461	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2462				 HDA_AMP_VOLMASK, present);
2463}
2464
2465static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2466					   unsigned int res)
2467{
2468	/* Looks like the unsol event is incompatible with the standard
2469	 * definition.  4bit tag is placed at 28 bit!
2470	 */
2471	if ((res >> 28) == ALC880_HP_EVENT)
2472		alc880_uniwill_p53_hp_automute(codec);
2473	if ((res >> 28) == ALC880_DCVOL_EVENT)
2474		alc880_uniwill_p53_dcvol_automute(codec);
2475}
2476
2477/*
2478 * F1734 pin configuration:
2479 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2480 */
2481static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2482	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2483	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2484	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2485	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2486	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2487
2488	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2489	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2490	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2491	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2492
2493	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2494	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2495	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2496	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2497	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2498	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2499	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2500	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2501	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2502
2503	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2504	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2505
2506	{ }
2507};
2508
2509/*
2510 * ASUS pin configuration:
2511 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2512 */
2513static struct hda_verb alc880_pin_asus_init_verbs[] = {
2514	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2515	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2516	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2517	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2518
2519	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2520	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2522	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2524	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2525	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2526	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2527
2528	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2529	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2531	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2532	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2533	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2534	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2535	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2536	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2537
2538	{ }
2539};
2540
2541/* Enable GPIO mask and set output */
2542#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2543#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2544
2545/* Clevo m520g init */
2546static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2547	/* headphone output */
2548	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2549	/* line-out */
2550	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2551	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2552	/* Line-in */
2553	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2554	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555	/* CD */
2556	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2557	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2558	/* Mic1 (rear panel) */
2559	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2560	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2561	/* Mic2 (front panel) */
2562	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2563	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2564	/* headphone */
2565	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2566	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2567        /* change to EAPD mode */
2568	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2569	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2570
2571	{ }
2572};
2573
2574static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2575	/* change to EAPD mode */
2576	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2577	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2578
2579	/* Headphone output */
2580	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2581	/* Front output*/
2582	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2583	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2584
2585	/* Line In pin widget for input */
2586	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2587	/* CD pin widget for input */
2588	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2589	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2590	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2591
2592	/* change to EAPD mode */
2593	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2594	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2595
2596	{ }
2597};
2598
2599/*
2600 * LG m1 express dual
2601 *
2602 * Pin assignment:
2603 *   Rear Line-In/Out (blue): 0x14
2604 *   Build-in Mic-In: 0x15
2605 *   Speaker-out: 0x17
2606 *   HP-Out (green): 0x1b
2607 *   Mic-In/Out (red): 0x19
2608 *   SPDIF-Out: 0x1e
2609 */
2610
2611/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2612static hda_nid_t alc880_lg_dac_nids[3] = {
2613	0x05, 0x02, 0x03
2614};
2615
2616/* seems analog CD is not working */
2617static struct hda_input_mux alc880_lg_capture_source = {
2618	.num_items = 3,
2619	.items = {
2620		{ "Mic", 0x1 },
2621		{ "Line", 0x5 },
2622		{ "Internal Mic", 0x6 },
2623	},
2624};
2625
2626/* 2,4,6 channel modes */
2627static struct hda_verb alc880_lg_ch2_init[] = {
2628	/* set line-in and mic-in to input */
2629	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2630	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2631	{ }
2632};
2633
2634static struct hda_verb alc880_lg_ch4_init[] = {
2635	/* set line-in to out and mic-in to input */
2636	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2637	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2638	{ }
2639};
2640
2641static struct hda_verb alc880_lg_ch6_init[] = {
2642	/* set line-in and mic-in to output */
2643	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2644	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2645	{ }
2646};
2647
2648static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2649	{ 2, alc880_lg_ch2_init },
2650	{ 4, alc880_lg_ch4_init },
2651	{ 6, alc880_lg_ch6_init },
2652};
2653
2654static struct snd_kcontrol_new alc880_lg_mixer[] = {
2655	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2656	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2657	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2658	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2659	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2660	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2661	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2662	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2663	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2664	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2665	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2666	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2667	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2668	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2669	{
2670		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2671		.name = "Channel Mode",
2672		.info = alc_ch_mode_info,
2673		.get = alc_ch_mode_get,
2674		.put = alc_ch_mode_put,
2675	},
2676	{ } /* end */
2677};
2678
2679static struct hda_verb alc880_lg_init_verbs[] = {
2680	/* set capture source to mic-in */
2681	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2682	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2683	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2684	/* mute all amp mixer inputs */
2685	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2686	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2687	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2688	/* line-in to input */
2689	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2690	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2691	/* built-in mic */
2692	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2693	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2694	/* speaker-out */
2695	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2696	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2697	/* mic-in to input */
2698	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2699	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2700	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2701	/* HP-out */
2702	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2703	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2704	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2705	/* jack sense */
2706	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2707	{ }
2708};
2709
2710/* toggle speaker-output according to the hp-jack state */
2711static void alc880_lg_automute(struct hda_codec *codec)
2712{
2713	unsigned int present;
2714	unsigned char bits;
2715
2716	present = snd_hda_codec_read(codec, 0x1b, 0,
2717				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2718	bits = present ? HDA_AMP_MUTE : 0;
2719	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2720				 HDA_AMP_MUTE, bits);
2721}
2722
2723static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2724{
2725	/* Looks like the unsol event is incompatible with the standard
2726	 * definition.  4bit tag is placed at 28 bit!
2727	 */
2728	if ((res >> 28) == 0x01)
2729		alc880_lg_automute(codec);
2730}
2731
2732/*
2733 * LG LW20
2734 *
2735 * Pin assignment:
2736 *   Speaker-out: 0x14
2737 *   Mic-In: 0x18
2738 *   Built-in Mic-In: 0x19
2739 *   Line-In: 0x1b
2740 *   HP-Out: 0x1a
2741 *   SPDIF-Out: 0x1e
2742 */
2743
2744static struct hda_input_mux alc880_lg_lw_capture_source = {
2745	.num_items = 3,
2746	.items = {
2747		{ "Mic", 0x0 },
2748		{ "Internal Mic", 0x1 },
2749		{ "Line In", 0x2 },
2750	},
2751};
2752
2753#define alc880_lg_lw_modes alc880_threestack_modes
2754
2755static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2756	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2757	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2758	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2759	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2760	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2761	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2762	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2763	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2764	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2765	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2766	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2767	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2768	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2769	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2770	{
2771		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2772		.name = "Channel Mode",
2773		.info = alc_ch_mode_info,
2774		.get = alc_ch_mode_get,
2775		.put = alc_ch_mode_put,
2776	},
2777	{ } /* end */
2778};
2779
2780static struct hda_verb alc880_lg_lw_init_verbs[] = {
2781	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2782	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2783	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2784
2785	/* set capture source to mic-in */
2786	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2787	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2788	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2789	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2790	/* speaker-out */
2791	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2792	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2793	/* HP-out */
2794	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2795	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796	/* mic-in to input */
2797	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2798	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2799	/* built-in mic */
2800	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2801	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802	/* jack sense */
2803	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2804	{ }
2805};
2806
2807/* toggle speaker-output according to the hp-jack state */
2808static void alc880_lg_lw_automute(struct hda_codec *codec)
2809{
2810	unsigned int present;
2811	unsigned char bits;
2812
2813	present = snd_hda_codec_read(codec, 0x1b, 0,
2814				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2815	bits = present ? HDA_AMP_MUTE : 0;
2816	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2817				 HDA_AMP_MUTE, bits);
2818}
2819
2820static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2821{
2822	/* Looks like the unsol event is incompatible with the standard
2823	 * definition.  4bit tag is placed at 28 bit!
2824	 */
2825	if ((res >> 28) == 0x01)
2826		alc880_lg_lw_automute(codec);
2827}
2828
2829static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2830	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2831	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2832	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2833	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2834	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2835	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2836	{ } /* end */
2837};
2838
2839static struct hda_input_mux alc880_medion_rim_capture_source = {
2840	.num_items = 2,
2841	.items = {
2842		{ "Mic", 0x0 },
2843		{ "Internal Mic", 0x1 },
2844	},
2845};
2846
2847static struct hda_verb alc880_medion_rim_init_verbs[] = {
2848	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2849
2850	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2851	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2852
2853	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2854	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2855	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2856	/* Mic2 (as headphone out) for HP output */
2857	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2858	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2859	/* Internal Speaker */
2860	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2861	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2862
2863	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2864	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2865
2866	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2867	{ }
2868};
2869
2870/* toggle speaker-output according to the hp-jack state */
2871static void alc880_medion_rim_automute(struct hda_codec *codec)
2872{
2873	unsigned int present;
2874	unsigned char bits;
2875
2876	present = snd_hda_codec_read(codec, 0x14, 0,
2877				     AC_VERB_GET_PIN_SENSE, 0)
2878		& AC_PINSENSE_PRESENCE;
2879	bits = present ? HDA_AMP_MUTE : 0;
2880	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2881				 HDA_AMP_MUTE, bits);
2882	if (present)
2883		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2884	else
2885		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2886}
2887
2888static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2889					  unsigned int res)
2890{
2891	/* Looks like the unsol event is incompatible with the standard
2892	 * definition.  4bit tag is placed at 28 bit!
2893	 */
2894	if ((res >> 28) == ALC880_HP_EVENT)
2895		alc880_medion_rim_automute(codec);
2896}
2897
2898#ifdef CONFIG_SND_HDA_POWER_SAVE
2899static struct hda_amp_list alc880_loopbacks[] = {
2900	{ 0x0b, HDA_INPUT, 0 },
2901	{ 0x0b, HDA_INPUT, 1 },
2902	{ 0x0b, HDA_INPUT, 2 },
2903	{ 0x0b, HDA_INPUT, 3 },
2904	{ 0x0b, HDA_INPUT, 4 },
2905	{ } /* end */
2906};
2907
2908static struct hda_amp_list alc880_lg_loopbacks[] = {
2909	{ 0x0b, HDA_INPUT, 1 },
2910	{ 0x0b, HDA_INPUT, 6 },
2911	{ 0x0b, HDA_INPUT, 7 },
2912	{ } /* end */
2913};
2914#endif
2915
2916/*
2917 * Common callbacks
2918 */
2919
2920static int alc_init(struct hda_codec *codec)
2921{
2922	struct alc_spec *spec = codec->spec;
2923	unsigned int i;
2924
2925	alc_fix_pll(codec);
2926	if (codec->vendor_id == 0x10ec0888)
2927		alc888_coef_init(codec);
2928
2929	for (i = 0; i < spec->num_init_verbs; i++)
2930		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2931
2932	if (spec->init_hook)
2933		spec->init_hook(codec);
2934
2935	return 0;
2936}
2937
2938static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2939{
2940	struct alc_spec *spec = codec->spec;
2941
2942	if (spec->unsol_event)
2943		spec->unsol_event(codec, res);
2944}
2945
2946#ifdef CONFIG_SND_HDA_POWER_SAVE
2947static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2948{
2949	struct alc_spec *spec = codec->spec;
2950	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2951}
2952#endif
2953
2954/*
2955 * Analog playback callbacks
2956 */
2957static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2958				    struct hda_codec *codec,
2959				    struct snd_pcm_substream *substream)
2960{
2961	struct alc_spec *spec = codec->spec;
2962	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2963					     hinfo);
2964}
2965
2966static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2967				       struct hda_codec *codec,
2968				       unsigned int stream_tag,
2969				       unsigned int format,
2970				       struct snd_pcm_substream *substream)
2971{
2972	struct alc_spec *spec = codec->spec;
2973	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2974						stream_tag, format, substream);
2975}
2976
2977static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2978				       struct hda_codec *codec,
2979				       struct snd_pcm_substream *substream)
2980{
2981	struct alc_spec *spec = codec->spec;
2982	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2983}
2984
2985/*
2986 * Digital out
2987 */
2988static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2989					struct hda_codec *codec,
2990					struct snd_pcm_substream *substream)
2991{
2992	struct alc_spec *spec = codec->spec;
2993	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2994}
2995
2996static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2997					   struct hda_codec *codec,
2998					   unsigned int stream_tag,
2999					   unsigned int format,
3000					   struct snd_pcm_substream *substream)
3001{
3002	struct alc_spec *spec = codec->spec;
3003	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3004					     stream_tag, format, substream);
3005}
3006
3007static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3008					   struct hda_codec *codec,
3009					   struct snd_pcm_substream *substream)
3010{
3011	struct alc_spec *spec = codec->spec;
3012	return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3013}
3014
3015static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3016					 struct hda_codec *codec,
3017					 struct snd_pcm_substream *substream)
3018{
3019	struct alc_spec *spec = codec->spec;
3020	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3021}
3022
3023/*
3024 * Analog capture
3025 */
3026static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3027				      struct hda_codec *codec,
3028				      unsigned int stream_tag,
3029				      unsigned int format,
3030				      struct snd_pcm_substream *substream)
3031{
3032	struct alc_spec *spec = codec->spec;
3033
3034	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3035				   stream_tag, 0, format);
3036	return 0;
3037}
3038
3039static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3040				      struct hda_codec *codec,
3041				      struct snd_pcm_substream *substream)
3042{
3043	struct alc_spec *spec = codec->spec;
3044
3045	snd_hda_codec_cleanup_stream(codec,
3046				     spec->adc_nids[substream->number + 1]);
3047	return 0;
3048}
3049
3050
3051/*
3052 */
3053static struct hda_pcm_stream alc880_pcm_analog_playback = {
3054	.substreams = 1,
3055	.channels_min = 2,
3056	.channels_max = 8,
3057	/* NID is set in alc_build_pcms */
3058	.ops = {
3059		.open = alc880_playback_pcm_open,
3060		.prepare = alc880_playback_pcm_prepare,
3061		.cleanup = alc880_playback_pcm_cleanup
3062	},
3063};
3064
3065static struct hda_pcm_stream alc880_pcm_analog_capture = {
3066	.substreams = 1,
3067	.channels_min = 2,
3068	.channels_max = 2,
3069	/* NID is set in alc_build_pcms */
3070};
3071
3072static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3073	.substreams = 1,
3074	.channels_min = 2,
3075	.channels_max = 2,
3076	/* NID is set in alc_build_pcms */
3077};
3078
3079static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3080	.substreams = 2, /* can be overridden */
3081	.channels_min = 2,
3082	.channels_max = 2,
3083	/* NID is set in alc_build_pcms */
3084	.ops = {
3085		.prepare = alc880_alt_capture_pcm_prepare,
3086		.cleanup = alc880_alt_capture_pcm_cleanup
3087	},
3088};
3089
3090static struct hda_pcm_stream alc880_pcm_digital_playback = {
3091	.substreams = 1,
3092	.channels_min = 2,
3093	.channels_max = 2,
3094	/* NID is set in alc_build_pcms */
3095	.ops = {
3096		.open = alc880_dig_playback_pcm_open,
3097		.close = alc880_dig_playback_pcm_close,
3098		.prepare = alc880_dig_playback_pcm_prepare,
3099		.cleanup = alc880_dig_playback_pcm_cleanup
3100	},
3101};
3102
3103static struct hda_pcm_stream alc880_pcm_digital_capture = {
3104	.substreams = 1,
3105	.channels_min = 2,
3106	.channels_max = 2,
3107	/* NID is set in alc_build_pcms */
3108};
3109
3110/* Used by alc_build_pcms to flag that a PCM has no playback stream */
3111static struct hda_pcm_stream alc_pcm_null_stream = {
3112	.substreams = 0,
3113	.channels_min = 0,
3114	.channels_max = 0,
3115};
3116
3117static int alc_build_pcms(struct hda_codec *codec)
3118{
3119	struct alc_spec *spec = codec->spec;
3120	struct hda_pcm *info = spec->pcm_rec;
3121	int i;
3122
3123	codec->num_pcms = 1;
3124	codec->pcm_info = info;
3125
3126	if (spec->no_analog)
3127		goto skip_analog;
3128
3129	info->name = spec->stream_name_analog;
3130	if (spec->stream_analog_playback) {
3131		if (snd_BUG_ON(!spec->multiout.dac_nids))
3132			return -EINVAL;
3133		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3134		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3135	}
3136	if (spec->stream_analog_capture) {
3137		if (snd_BUG_ON(!spec->adc_nids))
3138			return -EINVAL;
3139		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3140		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3141	}
3142
3143	if (spec->channel_mode) {
3144		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3145		for (i = 0; i < spec->num_channel_mode; i++) {
3146			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3147				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3148			}
3149		}
3150	}
3151
3152 skip_analog:
3153	/* SPDIF for stream index #1 */
3154	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3155		codec->num_pcms = 2;
3156	        codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3157		info = spec->pcm_rec + 1;
3158		info->name = spec->stream_name_digital;
3159		if (spec->dig_out_type)
3160			info->pcm_type = spec->dig_out_type;
3161		else
3162			info->pcm_type = HDA_PCM_TYPE_SPDIF;
3163		if (spec->multiout.dig_out_nid &&
3164		    spec->stream_digital_playback) {
3165			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3166			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3167		}
3168		if (spec->dig_in_nid &&
3169		    spec->stream_digital_capture) {
3170			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3171			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3172		}
3173		/* FIXME: do we need this for all Realtek codec models? */
3174		codec->spdif_status_reset = 1;
3175	}
3176
3177	if (spec->no_analog)
3178		return 0;
3179
3180	/* If the use of more than one ADC is requested for the current
3181	 * model, configure a second analog capture-only PCM.
3182	 */
3183	/* Additional Analaog capture for index #2 */
3184	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3185	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3186		codec->num_pcms = 3;
3187		info = spec->pcm_rec + 2;
3188		info->name = spec->stream_name_analog;
3189		if (spec->alt_dac_nid) {
3190			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3191				*spec->stream_analog_alt_playback;
3192			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3193				spec->alt_dac_nid;
3194		} else {
3195			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3196				alc_pcm_null_stream;
3197			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3198		}
3199		if (spec->num_adc_nids > 1) {
3200			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3201				*spec->stream_analog_alt_capture;
3202			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3203				spec->adc_nids[1];
3204			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3205				spec->num_adc_nids - 1;
3206		} else {
3207			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3208				alc_pcm_null_stream;
3209			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3210		}
3211	}
3212
3213	return 0;
3214}
3215
3216static void alc_free_kctls(struct hda_codec *codec)
3217{
3218	struct alc_spec *spec = codec->spec;
3219
3220	if (spec->kctls.list) {
3221		struct snd_kcontrol_new *kctl = spec->kctls.list;
3222		int i;
3223		for (i = 0; i < spec->kctls.used; i++)
3224			kfree(kctl[i].name);
3225	}
3226	snd_array_free(&spec->kctls);
3227}
3228
3229static void alc_free(struct hda_codec *codec)
3230{
3231	struct alc_spec *spec = codec->spec;
3232
3233	if (!spec)
3234		return;
3235
3236	alc_free_kctls(codec);
3237	kfree(spec);
3238	snd_hda_detach_beep_device(codec);
3239}
3240
3241#ifdef SND_HDA_NEEDS_RESUME
3242static int alc_resume(struct hda_codec *codec)
3243{
3244	codec->patch_ops.init(codec);
3245	snd_hda_codec_resume_amp(codec);
3246	snd_hda_codec_resume_cache(codec);
3247	return 0;
3248}
3249#endif
3250
3251/*
3252 */
3253static struct hda_codec_ops alc_patch_ops = {
3254	.build_controls = alc_build_controls,
3255	.build_pcms = alc_build_pcms,
3256	.init = alc_init,
3257	.free = alc_free,
3258	.unsol_event = alc_unsol_event,
3259#ifdef SND_HDA_NEEDS_RESUME
3260	.resume = alc_resume,
3261#endif
3262#ifdef CONFIG_SND_HDA_POWER_SAVE
3263	.check_power_status = alc_check_power_status,
3264#endif
3265};
3266
3267
3268/*
3269 * Test configuration for debugging
3270 *
3271 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
3272 * enum controls.
3273 */
3274#ifdef CONFIG_SND_DEBUG
3275static hda_nid_t alc880_test_dac_nids[4] = {
3276	0x02, 0x03, 0x04, 0x05
3277};
3278
3279static struct hda_input_mux alc880_test_capture_source = {
3280	.num_items = 7,
3281	.items = {
3282		{ "In-1", 0x0 },
3283		{ "In-2", 0x1 },
3284		{ "In-3", 0x2 },
3285		{ "In-4", 0x3 },
3286		{ "CD", 0x4 },
3287		{ "Front", 0x5 },
3288		{ "Surround", 0x6 },
3289	},
3290};
3291
3292static struct hda_channel_mode alc880_test_modes[4] = {
3293	{ 2, NULL },
3294	{ 4, NULL },
3295	{ 6, NULL },
3296	{ 8, NULL },
3297};
3298
3299static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3300				 struct snd_ctl_elem_info *uinfo)
3301{
3302	static char *texts[] = {
3303		"N/A", "Line Out", "HP Out",
3304		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3305	};
3306	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3307	uinfo->count = 1;
3308	uinfo->value.enumerated.items = 8;
3309	if (uinfo->value.enumerated.item >= 8)
3310		uinfo->value.enumerated.item = 7;
3311	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3312	return 0;
3313}
3314
3315static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3316				struct snd_ctl_elem_value *ucontrol)
3317{
3318	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3319	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3320	unsigned int pin_ctl, item = 0;
3321
3322	pin_ctl = snd_hda_codec_read(codec, nid, 0,
3323				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3324	if (pin_ctl & AC_PINCTL_OUT_EN) {
3325		if (pin_ctl & AC_PINCTL_HP_EN)
3326			item = 2;
3327		else
3328			item = 1;
3329	} else if (pin_ctl & AC_PINCTL_IN_EN) {
3330		switch (pin_ctl & AC_PINCTL_VREFEN) {
3331		case AC_PINCTL_VREF_HIZ: item = 3; break;
3332		case AC_PINCTL_VREF_50:  item = 4; break;
3333		case AC_PINCTL_VREF_GRD: item = 5; break;
3334		case AC_PINCTL_VREF_80:  item = 6; break;
3335		case AC_PINCTL_VREF_100: item = 7; break;
3336		}
3337	}
3338	ucontrol->value.enumerated.item[0] = item;
3339	return 0;
3340}
3341
3342static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3343				struct snd_ctl_elem_value *ucontrol)
3344{
3345	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3346	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3347	static unsigned int ctls[] = {
3348		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3349		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3350		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3351		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3352		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3353		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3354	};
3355	unsigned int old_ctl, new_ctl;
3356
3357	old_ctl = snd_hda_codec_read(codec, nid, 0,
3358				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3359	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3360	if (old_ctl != new_ctl) {
3361		int val;
3362		snd_hda_codec_write_cache(codec, nid, 0,
3363					  AC_VERB_SET_PIN_WIDGET_CONTROL,
3364					  new_ctl);
3365		val = ucontrol->value.enumerated.item[0] >= 3 ?
3366			HDA_AMP_MUTE : 0;
3367		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3368					 HDA_AMP_MUTE, val);
3369		return 1;
3370	}
3371	return 0;
3372}
3373
3374static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3375				 struct snd_ctl_elem_info *uinfo)
3376{
3377	static char *texts[] = {
3378		"Front", "Surround", "CLFE", "Side"
3379	};
3380	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3381	uinfo->count = 1;
3382	uinfo->value.enumerated.items = 4;
3383	if (uinfo->value.enumerated.item >= 4)
3384		uinfo->value.enumerated.item = 3;
3385	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3386	return 0;
3387}
3388
3389static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3390				struct snd_ctl_elem_value *ucontrol)
3391{
3392	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3393	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3394	unsigned int sel;
3395
3396	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3397	ucontrol->value.enumerated.item[0] = sel & 3;
3398	return 0;
3399}
3400
3401static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3402				struct snd_ctl_elem_value *ucontrol)
3403{
3404	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3405	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3406	unsigned int sel;
3407
3408	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3409	if (ucontrol->value.enumerated.item[0] != sel) {
3410		sel = ucontrol->value.enumerated.item[0] & 3;
3411		snd_hda_codec_write_cache(codec, nid, 0,
3412					  AC_VERB_SET_CONNECT_SEL, sel);
3413		return 1;
3414	}
3415	return 0;
3416}
3417
3418#define PIN_CTL_TEST(xname,nid) {			\
3419		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3420			.name = xname,		       \
3421			.info = alc_test_pin_ctl_info, \
3422			.get = alc_test_pin_ctl_get,   \
3423			.put = alc_test_pin_ctl_put,   \
3424			.private_value = nid	       \
3425			}
3426
3427#define PIN_SRC_TEST(xname,nid) {			\
3428		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
3429			.name = xname,		       \
3430			.info = alc_test_pin_src_info, \
3431			.get = alc_test_pin_src_get,   \
3432			.put = alc_test_pin_src_put,   \
3433			.private_value = nid	       \
3434			}
3435
3436static struct snd_kcontrol_new alc880_test_mixer[] = {
3437	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3438	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3439	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3440	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3441	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3442	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3443	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3444	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3445	PIN_CTL_TEST("Front Pin Mode", 0x14),
3446	PIN_CTL_TEST("Surround Pin Mode", 0x15),
3447	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3448	PIN_CTL_TEST("Side Pin Mode", 0x17),
3449	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3450	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3451	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3452	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3453	PIN_SRC_TEST("In-1 Pin Source", 0x18),
3454	PIN_SRC_TEST("In-2 Pin Source", 0x19),
3455	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3456	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3457	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3458	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3459	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3460	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3461	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3462	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3463	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3464	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3465	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3466	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3467	{
3468		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3469		.name = "Channel Mode",
3470		.info = alc_ch_mode_info,
3471		.get = alc_ch_mode_get,
3472		.put = alc_ch_mode_put,
3473	},
3474	{ } /* end */
3475};
3476
3477static struct hda_verb alc880_test_init_verbs[] = {
3478	/* Unmute inputs of 0x0c - 0x0f */
3479	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3480	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3481	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3482	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3483	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3484	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3485	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3486	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3487	/* Vol output for 0x0c-0x0f */
3488	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3489	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3490	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3491	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3492	/* Set output pins 0x14-0x17 */
3493	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3494	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3495	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3496	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3497	/* Unmute output pins 0x14-0x17 */
3498	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3499	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3502	/* Set input pins 0x18-0x1c */
3503	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3504	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3505	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3506	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3507	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508	/* Mute input pins 0x18-0x1b */
3509	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3510	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3511	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3512	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3513	/* ADC set up */
3514	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3515	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3516	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3517	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3518	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3519	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3520	/* Analog input/passthru */
3521	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3522	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3523	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3524	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3525	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3526	{ }
3527};
3528#endif
3529
3530/*
3531 */
3532
3533static const char *alc880_models[ALC880_MODEL_LAST] = {
3534	[ALC880_3ST]		= "3stack",
3535	[ALC880_TCL_S700]	= "tcl",
3536	[ALC880_3ST_DIG]	= "3stack-digout",
3537	[ALC880_CLEVO]		= "clevo",
3538	[ALC880_5ST]		= "5stack",
3539	[ALC880_5ST_DIG]	= "5stack-digout",
3540	[ALC880_W810]		= "w810",
3541	[ALC880_Z71V]		= "z71v",
3542	[ALC880_6ST]		= "6stack",
3543	[ALC880_6ST_DIG]	= "6stack-digout",
3544	[ALC880_ASUS]		= "asus",
3545	[ALC880_ASUS_W1V]	= "asus-w1v",
3546	[ALC880_ASUS_DIG]	= "asus-dig",
3547	[ALC880_ASUS_DIG2]	= "asus-dig2",
3548	[ALC880_UNIWILL_DIG]	= "uniwill",
3549	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3550	[ALC880_FUJITSU]	= "fujitsu",
3551	[ALC880_F1734]		= "F1734",
3552	[ALC880_LG]		= "lg",
3553	[ALC880_LG_LW]		= "lg-lw",
3554	[ALC880_MEDION_RIM]	= "medion",
3555#ifdef CONFIG_SND_DEBUG
3556	[ALC880_TEST]		= "test",
3557#endif
3558	[ALC880_AUTO]		= "auto",
3559};
3560
3561static struct snd_pci_quirk alc880_cfg_tbl[] = {
3562	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3563	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3564	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3565	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3566	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3567	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3568	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3569	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3570	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3571	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3572	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3573	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3574	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3575	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3576	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3577	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3578	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3579	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3580	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3581	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3582	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3583	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3584	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3585	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3586	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3587	SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3588	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3589	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3590	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3591	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3592	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3593	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3594	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3595	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3596	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3597	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3598	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3599	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3600	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3601	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3602	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3603	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3604	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3605	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3606	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3607	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3608	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3609	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3610	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3611	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3612	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3613	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3614	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3615	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3616	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3617	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3618	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3619	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3620	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3621	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3622	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3623	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3624	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3625	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3626	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3627	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3628	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3629	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3630	/* default Intel */
3631	SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3632	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3633	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3634	{}
3635};
3636
3637/*
3638 * ALC880 codec presets
3639 */
3640static struct alc_config_preset alc880_presets[] = {
3641	[ALC880_3ST] = {
3642		.mixers = { alc880_three_stack_mixer },
3643		.init_verbs = { alc880_volume_init_verbs,
3644				alc880_pin_3stack_init_verbs },
3645		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3646		.dac_nids = alc880_dac_nids,
3647		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3648		.channel_mode = alc880_threestack_modes,
3649		.need_dac_fix = 1,
3650		.input_mux = &alc880_capture_source,
3651	},
3652	[ALC880_3ST_DIG] = {
3653		.mixers = { alc880_three_stack_mixer },
3654		.init_verbs = { alc880_volume_init_verbs,
3655				alc880_pin_3stack_init_verbs },
3656		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3657		.dac_nids = alc880_dac_nids,
3658		.dig_out_nid = ALC880_DIGOUT_NID,
3659		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3660		.channel_mode = alc880_threestack_modes,
3661		.need_dac_fix = 1,
3662		.input_mux = &alc880_capture_source,
3663	},
3664	[ALC880_TCL_S700] = {
3665		.mixers = { alc880_tcl_s700_mixer },
3666		.init_verbs = { alc880_volume_init_verbs,
3667				alc880_pin_tcl_S700_init_verbs,
3668				alc880_gpio2_init_verbs },
3669		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3670		.dac_nids = alc880_dac_nids,
3671		.adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3672		.num_adc_nids = 1, /* single ADC */
3673		.hp_nid = 0x03,
3674		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3675		.channel_mode = alc880_2_jack_modes,
3676		.input_mux = &alc880_capture_source,
3677	},
3678	[ALC880_5ST] = {
3679		.mixers = { alc880_three_stack_mixer,
3680			    alc880_five_stack_mixer},
3681		.init_verbs = { alc880_volume_init_verbs,
3682				alc880_pin_5stack_init_verbs },
3683		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3684		.dac_nids = alc880_dac_nids,
3685		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3686		.channel_mode = alc880_fivestack_modes,
3687		.input_mux = &alc880_capture_source,
3688	},
3689	[ALC880_5ST_DIG] = {
3690		.mixers = { alc880_three_stack_mixer,
3691			    alc880_five_stack_mixer },
3692		.init_verbs = { alc880_volume_init_verbs,
3693				alc880_pin_5stack_init_verbs },
3694		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3695		.dac_nids = alc880_dac_nids,
3696		.dig_out_nid = ALC880_DIGOUT_NID,
3697		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3698		.channel_mode = alc880_fivestack_modes,
3699		.input_mux = &alc880_capture_source,
3700	},
3701	[ALC880_6ST] = {
3702		.mixers = { alc880_six_stack_mixer },
3703		.init_verbs = { alc880_volume_init_verbs,
3704				alc880_pin_6stack_init_verbs },
3705		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3706		.dac_nids = alc880_6st_dac_nids,
3707		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3708		.channel_mode = alc880_sixstack_modes,
3709		.input_mux = &alc880_6stack_capture_source,
3710	},
3711	[ALC880_6ST_DIG] = {
3712		.mixers = { alc880_six_stack_mixer },
3713		.init_verbs = { alc880_volume_init_verbs,
3714				alc880_pin_6stack_init_verbs },
3715		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3716		.dac_nids = alc880_6st_dac_nids,
3717		.dig_out_nid = ALC880_DIGOUT_NID,
3718		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3719		.channel_mode = alc880_sixstack_modes,
3720		.input_mux = &alc880_6stack_capture_source,
3721	},
3722	[ALC880_W810] = {
3723		.mixers = { alc880_w810_base_mixer },
3724		.init_verbs = { alc880_volume_init_verbs,
3725				alc880_pin_w810_init_verbs,
3726				alc880_gpio2_init_verbs },
3727		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3728		.dac_nids = alc880_w810_dac_nids,
3729		.dig_out_nid = ALC880_DIGOUT_NID,
3730		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3731		.channel_mode = alc880_w810_modes,
3732		.input_mux = &alc880_capture_source,
3733	},
3734	[ALC880_Z71V] = {
3735		.mixers = { alc880_z71v_mixer },
3736		.init_verbs = { alc880_volume_init_verbs,
3737				alc880_pin_z71v_init_verbs },
3738		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3739		.dac_nids = alc880_z71v_dac_nids,
3740		.dig_out_nid = ALC880_DIGOUT_NID,
3741		.hp_nid = 0x03,
3742		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3743		.channel_mode = alc880_2_jack_modes,
3744		.input_mux = &alc880_capture_source,
3745	},
3746	[ALC880_F1734] = {
3747		.mixers = { alc880_f1734_mixer },
3748		.init_verbs = { alc880_volume_init_verbs,
3749				alc880_pin_f1734_init_verbs },
3750		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3751		.dac_nids = alc880_f1734_dac_nids,
3752		.hp_nid = 0x02,
3753		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3754		.channel_mode = alc880_2_jack_modes,
3755		.input_mux = &alc880_f1734_capture_source,
3756		.unsol_event = alc880_uniwill_p53_unsol_event,
3757		.init_hook = alc880_uniwill_p53_hp_automute,
3758	},
3759	[ALC880_ASUS] = {
3760		.mixers = { alc880_asus_mixer },
3761		.init_verbs = { alc880_volume_init_verbs,
3762				alc880_pin_asus_init_verbs,
3763				alc880_gpio1_init_verbs },
3764		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3765		.dac_nids = alc880_asus_dac_nids,
3766		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3767		.channel_mode = alc880_asus_modes,
3768		.need_dac_fix = 1,
3769		.input_mux = &alc880_capture_source,
3770	},
3771	[ALC880_ASUS_DIG] = {
3772		.mixers = { alc880_asus_mixer },
3773		.init_verbs = { alc880_volume_init_verbs,
3774				alc880_pin_asus_init_verbs,
3775				alc880_gpio1_init_verbs },
3776		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3777		.dac_nids = alc880_asus_dac_nids,
3778		.dig_out_nid = ALC880_DIGOUT_NID,
3779		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3780		.channel_mode = alc880_asus_modes,
3781		.need_dac_fix = 1,
3782		.input_mux = &alc880_capture_source,
3783	},
3784	[ALC880_ASUS_DIG2] = {
3785		.mixers = { alc880_asus_mixer },
3786		.init_verbs = { alc880_volume_init_verbs,
3787				alc880_pin_asus_init_verbs,
3788				alc880_gpio2_init_verbs }, /* use GPIO2 */
3789		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3790		.dac_nids = alc880_asus_dac_nids,
3791		.dig_out_nid = ALC880_DIGOUT_NID,
3792		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3793		.channel_mode = alc880_asus_modes,
3794		.need_dac_fix = 1,
3795		.input_mux = &alc880_capture_source,
3796	},
3797	[ALC880_ASUS_W1V] = {
3798		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3799		.init_verbs = { alc880_volume_init_verbs,
3800				alc880_pin_asus_init_verbs,
3801				alc880_gpio1_init_verbs },
3802		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3803		.dac_nids = alc880_asus_dac_nids,
3804		.dig_out_nid = ALC880_DIGOUT_NID,
3805		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3806		.channel_mode = alc880_asus_modes,
3807		.need_dac_fix = 1,
3808		.input_mux = &alc880_capture_source,
3809	},
3810	[ALC880_UNIWILL_DIG] = {
3811		.mixers = { alc880_asus_mixer },
3812		.init_verbs = { alc880_volume_init_verbs,
3813				alc880_pin_asus_init_verbs },
3814		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3815		.dac_nids = alc880_asus_dac_nids,
3816		.dig_out_nid = ALC880_DIGOUT_NID,
3817		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3818		.channel_mode = alc880_asus_modes,
3819		.need_dac_fix = 1,
3820		.input_mux = &alc880_capture_source,
3821	},
3822	[ALC880_UNIWILL] = {
3823		.mixers = { alc880_uniwill_mixer },
3824		.init_verbs = { alc880_volume_init_verbs,
3825				alc880_uniwill_init_verbs },
3826		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3827		.dac_nids = alc880_asus_dac_nids,
3828		.dig_out_nid = ALC880_DIGOUT_NID,
3829		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3830		.channel_mode = alc880_threestack_modes,
3831		.need_dac_fix = 1,
3832		.input_mux = &alc880_capture_source,
3833		.unsol_event = alc880_uniwill_unsol_event,
3834		.init_hook = alc880_uniwill_automute,
3835	},
3836	[ALC880_UNIWILL_P53] = {
3837		.mixers = { alc880_uniwill_p53_mixer },
3838		.init_verbs = { alc880_volume_init_verbs,
3839				alc880_uniwill_p53_init_verbs },
3840		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3841		.dac_nids = alc880_asus_dac_nids,
3842		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3843		.channel_mode = alc880_threestack_modes,
3844		.input_mux = &alc880_capture_source,
3845		.unsol_event = alc880_uniwill_p53_unsol_event,
3846		.init_hook = alc880_uniwill_p53_hp_automute,
3847	},
3848	[ALC880_FUJITSU] = {
3849		.mixers = { alc880_fujitsu_mixer },
3850		.init_verbs = { alc880_volume_init_verbs,
3851				alc880_uniwill_p53_init_verbs,
3852	       			alc880_beep_init_verbs },
3853		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3854		.dac_nids = alc880_dac_nids,
3855		.dig_out_nid = ALC880_DIGOUT_NID,
3856		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3857		.channel_mode = alc880_2_jack_modes,
3858		.input_mux = &alc880_capture_source,
3859		.unsol_event = alc880_uniwill_p53_unsol_event,
3860		.init_hook = alc880_uniwill_p53_hp_automute,
3861	},
3862	[ALC880_CLEVO] = {
3863		.mixers = { alc880_three_stack_mixer },
3864		.init_verbs = { alc880_volume_init_verbs,
3865				alc880_pin_clevo_init_verbs },
3866		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3867		.dac_nids = alc880_dac_nids,
3868		.hp_nid = 0x03,
3869		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3870		.channel_mode = alc880_threestack_modes,
3871		.need_dac_fix = 1,
3872		.input_mux = &alc880_capture_source,
3873	},
3874	[ALC880_LG] = {
3875		.mixers = { alc880_lg_mixer },
3876		.init_verbs = { alc880_volume_init_verbs,
3877				alc880_lg_init_verbs },
3878		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3879		.dac_nids = alc880_lg_dac_nids,
3880		.dig_out_nid = ALC880_DIGOUT_NID,
3881		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3882		.channel_mode = alc880_lg_ch_modes,
3883		.need_dac_fix = 1,
3884		.input_mux = &alc880_lg_capture_source,
3885		.unsol_event = alc880_lg_unsol_event,
3886		.init_hook = alc880_lg_automute,
3887#ifdef CONFIG_SND_HDA_POWER_SAVE
3888		.loopbacks = alc880_lg_loopbacks,
3889#endif
3890	},
3891	[ALC880_LG_LW] = {
3892		.mixers = { alc880_lg_lw_mixer },
3893		.init_verbs = { alc880_volume_init_verbs,
3894				alc880_lg_lw_init_verbs },
3895		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3896		.dac_nids = alc880_dac_nids,
3897		.dig_out_nid = ALC880_DIGOUT_NID,
3898		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3899		.channel_mode = alc880_lg_lw_modes,
3900		.input_mux = &alc880_lg_lw_capture_source,
3901		.unsol_event = alc880_lg_lw_unsol_event,
3902		.init_hook = alc880_lg_lw_automute,
3903	},
3904	[ALC880_MEDION_RIM] = {
3905		.mixers = { alc880_medion_rim_mixer },
3906		.init_verbs = { alc880_volume_init_verbs,
3907				alc880_medion_rim_init_verbs,
3908				alc_gpio2_init_verbs },
3909		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3910		.dac_nids = alc880_dac_nids,
3911		.dig_out_nid = ALC880_DIGOUT_NID,
3912		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3913		.channel_mode = alc880_2_jack_modes,
3914		.input_mux = &alc880_medion_rim_capture_source,
3915		.unsol_event = alc880_medion_rim_unsol_event,
3916		.init_hook = alc880_medion_rim_automute,
3917	},
3918#ifdef CONFIG_SND_DEBUG
3919	[ALC880_TEST] = {
3920		.mixers = { alc880_test_mixer },
3921		.init_verbs = { alc880_test_init_verbs },
3922		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3923		.dac_nids = alc880_test_dac_nids,
3924		.dig_out_nid = ALC880_DIGOUT_NID,
3925		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3926		.channel_mode = alc880_test_modes,
3927		.input_mux = &alc880_test_capture_source,
3928	},
3929#endif
3930};
3931
3932/*
3933 * Automatic parse of I/O pins from the BIOS configuration
3934 */
3935
3936enum {
3937	ALC_CTL_WIDGET_VOL,
3938	ALC_CTL_WIDGET_MUTE,
3939	ALC_CTL_BIND_MUTE,
3940};
3941static struct snd_kcontrol_new alc880_control_templates[] = {
3942	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3943	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3944	HDA_BIND_MUTE(NULL, 0, 0, 0),
3945};
3946
3947/* add dynamic controls */
3948static int add_control(struct alc_spec *spec, int type, const char *name,
3949		       unsigned long val)
3950{
3951	struct snd_kcontrol_new *knew;
3952
3953	snd_array_init(&spec->kctls, sizeof(*knew), 32);
3954	knew = snd_array_new(&spec->kctls);
3955	if (!knew)
3956		return -ENOMEM;
3957	*knew = alc880_control_templates[type];
3958	knew->name = kstrdup(name, GFP_KERNEL);
3959	if (!knew->name)
3960		return -ENOMEM;
3961	knew->private_value = val;
3962	return 0;
3963}
3964
3965#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3966#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3967#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3968#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3969#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3970#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3971#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3972#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3973#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3974#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3975#define ALC880_PIN_CD_NID		0x1c
3976
3977/* fill in the dac_nids table from the parsed pin configuration */
3978static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3979				     const struct auto_pin_cfg *cfg)
3980{
3981	hda_nid_t nid;
3982	int assigned[4];
3983	int i, j;
3984
3985	memset(assigned, 0, sizeof(assigned));
3986	spec->multiout.dac_nids = spec->private_dac_nids;
3987
3988	/* check the pins hardwired to audio widget */
3989	for (i = 0; i < cfg->line_outs; i++) {
3990		nid = cfg->line_out_pins[i];
3991		if (alc880_is_fixed_pin(nid)) {
3992			int idx = alc880_fixed_pin_idx(nid);
3993			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3994			assigned[idx] = 1;
3995		}
3996	}
3997	/* left pins can be connect to any audio widget */
3998	for (i = 0; i < cfg->line_outs; i++) {
3999		nid = cfg->line_out_pins[i];
4000		if (alc880_is_fixed_pin(nid))
4001			continue;
4002		/* search for an empty channel */
4003		for (j = 0; j < cfg->line_outs; j++) {
4004			if (!assigned[j]) {
4005				spec->multiout.dac_nids[i] =
4006					alc880_idx_to_dac(j);
4007				assigned[j] = 1;
4008				break;
4009			}
4010		}
4011	}
4012	spec->multiout.num_dacs = cfg->line_outs;
4013	return 0;
4014}
4015
4016/* add playback controls from the parsed DAC table */
4017static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4018					     const struct auto_pin_cfg *cfg)
4019{
4020	char name[32];
4021	static const char *chname[4] = {
4022		"Front", "Surround", NULL /*CLFE*/, "Side"
4023	};
4024	hda_nid_t nid;
4025	int i, err;
4026
4027	for (i = 0; i < cfg->line_outs; i++) {
4028		if (!spec->multiout.dac_nids[i])
4029			continue;
4030		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4031		if (i == 2) {
4032			/* Center/LFE */
4033			err = add_control(spec, ALC_CTL_WIDGET_VOL,
4034					  "Center Playback Volume",
4035					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4036							      HDA_OUTPUT));
4037			if (err < 0)
4038				return err;
4039			err = add_control(spec, ALC_CTL_WIDGET_VOL,
4040					  "LFE Playback Volume",
4041					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4042							      HDA_OUTPUT));
4043			if (err < 0)
4044				return err;
4045			err = add_control(spec, ALC_CTL_BIND_MUTE,
4046					  "Center Playback Switch",
4047					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4048							      HDA_INPUT));
4049			if (err < 0)
4050				return err;
4051			err = add_control(spec, ALC_CTL_BIND_MUTE,
4052					  "LFE Playback Switch",
4053					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4054							      HDA_INPUT));
4055			if (err < 0)
4056				return err;
4057		} else {
4058			sprintf(name, "%s Playback Volume", chname[i]);
4059			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4060					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4061							      HDA_OUTPUT));
4062			if (err < 0)
4063				return err;
4064			sprintf(name, "%s Playback Switch", chname[i]);
4065			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4066					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4067							      HDA_INPUT));
4068			if (err < 0)
4069				return err;
4070		}
4071	}
4072	return 0;
4073}
4074
4075/* add playback controls for speaker and HP outputs */
4076static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4077					const char *pfx)
4078{
4079	hda_nid_t nid;
4080	int err;
4081	char name[32];
4082
4083	if (!pin)
4084		return 0;
4085
4086	if (alc880_is_fixed_pin(pin)) {
4087		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4088		/* specify the DAC as the extra output */
4089		if (!spec->multiout.hp_nid)
4090			spec->multiout.hp_nid = nid;
4091		else
4092			spec->multiout.extra_out_nid[0] = nid;
4093		/* control HP volume/switch on the output mixer amp */
4094		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4095		sprintf(name, "%s Playback Volume", pfx);
4096		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4097				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4098		if (err < 0)
4099			return err;
4100		sprintf(name, "%s Playback Switch", pfx);
4101		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4102				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4103		if (err < 0)
4104			return err;
4105	} else if (alc880_is_multi_pin(pin)) {
4106		/* set manual connection */
4107		/* we have only a switch on HP-out PIN */
4108		sprintf(name, "%s Playback Switch", pfx);
4109		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4110				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4111		if (err < 0)
4112			return err;
4113	}
4114	return 0;
4115}
4116
4117/* create input playback/capture controls for the given pin */
4118static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4119			    const char *ctlname,
4120			    int idx, hda_nid_t mix_nid)
4121{
4122	char name[32];
4123	int err;
4124
4125	sprintf(name, "%s Playback Volume", ctlname);
4126	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4127			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4128	if (err < 0)
4129		return err;
4130	sprintf(name, "%s Playback Switch", ctlname);
4131	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4132			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4133	if (err < 0)
4134		return err;
4135	return 0;
4136}
4137
4138/* create playback/capture controls for input pins */
4139static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4140						const struct auto_pin_cfg *cfg)
4141{
4142	struct hda_input_mux *imux = &spec->private_imux[0];
4143	int i, err, idx;
4144
4145	for (i = 0; i < AUTO_PIN_LAST; i++) {
4146		if (alc880_is_input_pin(cfg->input_pins[i])) {
4147			idx = alc880_input_pin_idx(cfg->input_pins[i]);
4148			err = new_analog_input(spec, cfg->input_pins[i],
4149					       auto_pin_cfg_labels[i],
4150					       idx, 0x0b);
4151			if (err < 0)
4152				return err;
4153			imux->items[imux->num_items].label =
4154				auto_pin_cfg_labels[i];
4155			imux->items[imux->num_items].index =
4156				alc880_input_pin_idx(cfg->input_pins[i]);
4157			imux->num_items++;
4158		}
4159	}
4160	return 0;
4161}
4162
4163static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4164			       unsigned int pin_type)
4165{
4166	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4167			    pin_type);
4168	/* unmute pin */
4169	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4170			    AMP_OUT_UNMUTE);
4171}
4172
4173static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4174					      hda_nid_t nid, int pin_type,
4175					      int dac_idx)
4176{
4177	alc_set_pin_output(codec, nid, pin_type);
4178	/* need the manual connection? */
4179	if (alc880_is_multi_pin(nid)) {
4180		struct alc_spec *spec = codec->spec;
4181		int idx = alc880_multi_pin_idx(nid);
4182		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4183				    AC_VERB_SET_CONNECT_SEL,
4184				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4185	}
4186}
4187
4188static int get_pin_type(int line_out_type)
4189{
4190	if (line_out_type == AUTO_PIN_HP_OUT)
4191		return PIN_HP;
4192	else
4193		return PIN_OUT;
4194}
4195
4196static void alc880_auto_init_multi_out(struct hda_codec *codec)
4197{
4198	struct alc_spec *spec = codec->spec;
4199	int i;
4200
4201	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
4202	for (i = 0; i < spec->autocfg.line_outs; i++) {
4203		hda_nid_t nid = spec->autocfg.line_out_pins[i];
4204		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4205		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4206	}
4207}
4208
4209static void alc880_auto_init_extra_out(struct hda_codec *codec)
4210{
4211	struct alc_spec *spec = codec->spec;
4212	hda_nid_t pin;
4213
4214	pin = spec->autocfg.speaker_pins[0];
4215	if (pin) /* connect to front */
4216		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4217	pin = spec->autocfg.hp_pins[0];
4218	if (pin) /* connect to front */
4219		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4220}
4221
4222static void alc880_auto_init_analog_input(struct hda_codec *codec)
4223{
4224	struct alc_spec *spec = codec->spec;
4225	int i;
4226
4227	for (i = 0; i < AUTO_PIN_LAST; i++) {
4228		hda_nid_t nid = spec->autocfg.input_pins[i];
4229		if (alc880_is_input_pin(nid)) {
4230			alc_set_input_pin(codec, nid, i);
4231			if (nid != ALC880_PIN_CD_NID &&
4232			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4233				snd_hda_codec_write(codec, nid, 0,
4234						    AC_VERB_SET_AMP_GAIN_MUTE,
4235						    AMP_OUT_MUTE);
4236		}
4237	}
4238}
4239
4240/* parse the BIOS configuration and set up the alc_spec */
4241/* return 1 if successful, 0 if the proper config is not found,
4242 * or a negative error code
4243 */
4244static int alc880_parse_auto_config(struct hda_codec *codec)
4245{
4246	struct alc_spec *spec = codec->spec;
4247	int i, err;
4248	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4249
4250	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4251					   alc880_ignore);
4252	if (err < 0)
4253		return err;
4254	if (!spec->autocfg.line_outs)
4255		return 0; /* can't find valid BIOS pin config */
4256
4257	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4258	if (err < 0)
4259		return err;
4260	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4261	if (err < 0)
4262		return err;
4263	err = alc880_auto_create_extra_out(spec,
4264					   spec->autocfg.speaker_pins[0],
4265					   "Speaker");
4266	if (err < 0)
4267		return err;
4268	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4269					   "Headphone");
4270	if (err < 0)
4271		return err;
4272	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4273	if (err < 0)
4274		return err;
4275
4276	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4277
4278	/* check multiple SPDIF-out (for recent codecs) */
4279	for (i = 0; i < spec->autocfg.dig_outs; i++) {
4280		hda_nid_t dig_nid;
4281		err = snd_hda_get_connections(codec,
4282					      spec->autocfg.dig_out_pins[i],
4283					      &dig_nid, 1);
4284		if (err < 0)
4285			continue;
4286		if (!i)
4287			spec->multiout.dig_out_nid = dig_nid;
4288		else {
4289			spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4290			spec->slave_dig_outs[i - 1] = dig_nid;
4291			if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4292				break;
4293		}
4294	}
4295	if (spec->autocfg.dig_in_pin)
4296		spec->dig_in_nid = ALC880_DIGIN_NID;
4297
4298	if (spec->kctls.list)
4299		add_mixer(spec, spec->kctls.list);
4300
4301	add_verb(spec, alc880_volume_init_verbs);
4302
4303	spec->num_mux_defs = 1;
4304	spec->input_mux = &spec->private_imux[0];
4305
4306	return 1;
4307}
4308
4309/* additional initialization for auto-configuration model */
4310static void alc880_auto_init(struct hda_codec *codec)
4311{
4312	struct alc_spec *spec = codec->spec;
4313	alc880_auto_init_multi_out(codec);
4314	alc880_auto_init_extra_out(codec);
4315	alc880_auto_init_analog_input(codec);
4316	if (spec->unsol_event)
4317		alc_inithook(codec);
4318}
4319
4320static void set_capture_mixer(struct alc_spec *spec)
4321{
4322	static struct snd_kcontrol_new *caps[2][3] = {
4323		{ alc_capture_mixer_nosrc1,
4324		  alc_capture_mixer_nosrc2,
4325		  alc_capture_mixer_nosrc3 },
4326		{ alc_capture_mixer1,
4327		  alc_capture_mixer2,
4328		  alc_capture_mixer3 },
4329	};
4330	if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4331		int mux;
4332		if (spec->input_mux && spec->input_mux->num_items > 1)
4333			mux = 1;
4334		else
4335			mux = 0;
4336		spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4337	}
4338}
4339
4340#define set_beep_amp(spec, nid, idx, dir) \
4341	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4342
4343/*
4344 * OK, here we have finally the patch for ALC880
4345 */
4346
4347static int patch_alc880(struct hda_codec *codec)
4348{
4349	struct alc_spec *spec;
4350	int board_config;
4351	int err;
4352
4353	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4354	if (spec == NULL)
4355		return -ENOMEM;
4356
4357	codec->spec = spec;
4358
4359	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4360						  alc880_models,
4361						  alc880_cfg_tbl);
4362	if (board_config < 0) {
4363		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4364		       "trying auto-probe from BIOS...\n");
4365		board_config = ALC880_AUTO;
4366	}
4367
4368	if (board_config == ALC880_AUTO) {
4369		/* automatic parse from the BIOS config */
4370		err = alc880_parse_auto_config(codec);
4371		if (err < 0) {
4372			alc_free(codec);
4373			return err;
4374		} else if (!err) {
4375			printk(KERN_INFO
4376			       "hda_codec: Cannot set up configuration "
4377			       "from BIOS.  Using 3-stack mode...\n");
4378			board_config = ALC880_3ST;
4379		}
4380	}
4381
4382	err = snd_hda_attach_beep_device(codec, 0x1);
4383	if (err < 0) {
4384		alc_free(codec);
4385		return err;
4386	}
4387
4388	if (board_config != ALC880_AUTO)
4389		setup_preset(spec, &alc880_presets[board_config]);
4390
4391	spec->stream_name_analog = "ALC880 Analog";
4392	spec->stream_analog_playback = &alc880_pcm_analog_playback;
4393	spec->stream_analog_capture = &alc880_pcm_analog_capture;
4394	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4395
4396	spec->stream_name_digital = "ALC880 Digital";
4397	spec->stream_digital_playback = &alc880_pcm_digital_playback;
4398	spec->stream_digital_capture = &alc880_pcm_digital_capture;
4399
4400	if (!spec->adc_nids && spec->input_mux) {
4401		/* check whether NID 0x07 is valid */
4402		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4403		/* get type */
4404		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4405		if (wcap != AC_WID_AUD_IN) {
4406			spec->adc_nids = alc880_adc_nids_alt;
4407			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4408		} else {
4409			spec->adc_nids = alc880_adc_nids;
4410			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4411		}
4412	}
4413	set_capture_mixer(spec);
4414	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4415
4416	spec->vmaster_nid = 0x0c;
4417
4418	codec->patch_ops = alc_patch_ops;
4419	if (board_config == ALC880_AUTO)
4420		spec->init_hook = alc880_auto_init;
4421#ifdef CONFIG_SND_HDA_POWER_SAVE
4422	if (!spec->loopback.amplist)
4423		spec->loopback.amplist = alc880_loopbacks;
4424#endif
4425	codec->proc_widget_hook = print_realtek_coef;
4426
4427	return 0;
4428}
4429
4430
4431/*
4432 * ALC260 support
4433 */
4434
4435static hda_nid_t alc260_dac_nids[1] = {
4436	/* front */
4437	0x02,
4438};
4439
4440static hda_nid_t alc260_adc_nids[1] = {
4441	/* ADC0 */
4442	0x04,
4443};
4444
4445static hda_nid_t alc260_adc_nids_alt[1] = {
4446	/* ADC1 */
4447	0x05,
4448};
4449
4450/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
4451 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4452 */
4453static hda_nid_t alc260_dual_adc_nids[2] = {
4454	/* ADC0, ADC1 */
4455	0x04, 0x05
4456};
4457
4458#define ALC260_DIGOUT_NID	0x03
4459#define ALC260_DIGIN_NID	0x06
4460
4461static struct hda_input_mux alc260_capture_source = {
4462	.num_items = 4,
4463	.items = {
4464		{ "Mic", 0x0 },
4465		{ "Front Mic", 0x1 },
4466		{ "Line", 0x2 },
4467		{ "CD", 0x4 },
4468	},
4469};
4470
4471/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4472 * headphone jack and the internal CD lines since these are the only pins at
4473 * which audio can appear.  For flexibility, also allow the option of
4474 * recording the mixer output on the second ADC (ADC0 doesn't have a
4475 * connection to the mixer output).
4476 */
4477static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4478	{
4479		.num_items = 3,
4480		.items = {
4481			{ "Mic/Line", 0x0 },
4482			{ "CD", 0x4 },
4483			{ "Headphone", 0x2 },
4484		},
4485	},
4486	{
4487		.num_items = 4,
4488		.items = {
4489			{ "Mic/Line", 0x0 },
4490			{ "CD", 0x4 },
4491			{ "Headphone", 0x2 },
4492			{ "Mixer", 0x5 },
4493		},
4494	},
4495
4496};
4497
4498/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4499 * the Fujitsu S702x, but jacks are marked differently.
4500 */
4501static struct hda_input_mux alc260_acer_capture_sources[2] = {
4502	{
4503		.num_items = 4,
4504		.items = {
4505			{ "Mic", 0x0 },
4506			{ "Line", 0x2 },
4507			{ "CD", 0x4 },
4508			{ "Headphone", 0x5 },
4509		},
4510	},
4511	{
4512		.num_items = 5,
4513		.items = {
4514			{ "Mic", 0x0 },
4515			{ "Line", 0x2 },
4516			{ "CD", 0x4 },
4517			{ "Headphone", 0x6 },
4518			{ "Mixer", 0x5 },
4519		},
4520	},
4521};
4522
4523/* Maxdata Favorit 100XS */
4524static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4525	{
4526		.num_items = 2,
4527		.items = {
4528			{ "Line/Mic", 0x0 },
4529			{ "CD", 0x4 },
4530		},
4531	},
4532	{
4533		.num_items = 3,
4534		.items = {
4535			{ "Line/Mic", 0x0 },
4536			{ "CD", 0x4 },
4537			{ "Mixer", 0x5 },
4538		},
4539	},
4540};
4541
4542/*
4543 * This is just place-holder, so there's something for alc_build_pcms to look
4544 * at when it calculates the maximum number of channels. ALC260 has no mixer
4545 * element which allows changing the channel mode, so the verb list is
4546 * never used.
4547 */
4548static struct hda_channel_mode alc260_modes[1] = {
4549	{ 2, NULL },
4550};
4551
4552
4553/* Mixer combinations
4554 *
4555 * basic: base_output + input + pc_beep + capture
4556 * HP: base_output + input + capture_alt
4557 * HP_3013: hp_3013 + input + capture
4558 * fujitsu: fujitsu + capture
4559 * acer: acer + capture
4560 */
4561
4562static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4563	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4564	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4565	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4566	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4567	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4568	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4569	{ } /* end */
4570};
4571
4572static struct snd_kcontrol_new alc260_input_mixer[] = {
4573	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4574	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4575	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4576	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4577	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4578	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4579	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4580	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4581	{ } /* end */
4582};
4583
4584/* update HP, line and mono out pins according to the master switch */
4585static void alc260_hp_master_update(struct hda_codec *codec,
4586				    hda_nid_t hp, hda_nid_t line,
4587				    hda_nid_t mono)
4588{
4589	struct alc_spec *spec = codec->spec;
4590	unsigned int val = spec->master_sw ? PIN_HP : 0;
4591	/* change HP and line-out pins */
4592	snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4593			    val);
4594	snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4595			    val);
4596	/* mono (speaker) depending on the HP jack sense */
4597	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4598	snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4599			    val);
4600}
4601
4602static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4603				   struct snd_ctl_elem_value *ucontrol)
4604{
4605	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4606	struct alc_spec *spec = codec->spec;
4607	*ucontrol->value.integer.value = spec->master_sw;
4608	return 0;
4609}
4610
4611static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4612				   struct snd_ctl_elem_value *ucontrol)
4613{
4614	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4615	struct alc_spec *spec = codec->spec;
4616	int val = !!*ucontrol->value.integer.value;
4617	hda_nid_t hp, line, mono;
4618
4619	if (val == spec->master_sw)
4620		return 0;
4621	spec->master_sw = val;
4622	hp = (kcontrol->private_value >> 16) & 0xff;
4623	line = (kcontrol->private_value >> 8) & 0xff;
4624	mono = kcontrol->private_value & 0xff;
4625	alc260_hp_master_update(codec, hp, line, mono);
4626	return 1;
4627}
4628
4629static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4630	{
4631		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4632		.name = "Master Playback Switch",
4633		.info = snd_ctl_boolean_mono_info,
4634		.get = alc260_hp_master_sw_get,
4635		.put = alc260_hp_master_sw_put,
4636		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4637	},
4638	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4639	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4640	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4641	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4642	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4643			      HDA_OUTPUT),
4644	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4645	{ } /* end */
4646};
4647
4648static struct hda_verb alc260_hp_unsol_verbs[] = {
4649	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4650	{},
4651};
4652
4653static void alc260_hp_automute(struct hda_codec *codec)
4654{
4655	struct alc_spec *spec = codec->spec;
4656	unsigned int present;
4657
4658	present = snd_hda_codec_read(codec, 0x10, 0,
4659				     AC_VERB_GET_PIN_SENSE, 0);
4660	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4661	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4662}
4663
4664static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4665{
4666	if ((res >> 26) == ALC880_HP_EVENT)
4667		alc260_hp_automute(codec);
4668}
4669
4670static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4671	{
4672		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4673		.name = "Master Playback Switch",
4674		.info = snd_ctl_boolean_mono_info,
4675		.get = alc260_hp_master_sw_get,
4676		.put = alc260_hp_master_sw_put,
4677		.private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4678	},
4679	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4680	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4681	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4682	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4683	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4684	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4685	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4686	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4687	{ } /* end */
4688};
4689
4690static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4691	.ops = &snd_hda_bind_vol,
4692	.values = {
4693		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4694		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4695		HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4696		0
4697	},
4698};
4699
4700static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4701	.ops = &snd_hda_bind_sw,
4702	.values = {
4703		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4704		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4705		0
4706	},
4707};
4708
4709static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4710	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4711	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4712	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4713	HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4714	{ } /* end */
4715};
4716
4717static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4718	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4719	{},
4720};
4721
4722static void alc260_hp_3013_automute(struct hda_codec *codec)
4723{
4724	struct alc_spec *spec = codec->spec;
4725	unsigned int present;
4726
4727	present = snd_hda_codec_read(codec, 0x15, 0,
4728				     AC_VERB_GET_PIN_SENSE, 0);
4729	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4730	alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4731}
4732
4733static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4734				       unsigned int res)
4735{
4736	if ((res >> 26) == ALC880_HP_EVENT)
4737		alc260_hp_3013_automute(codec);
4738}
4739
4740static void alc260_hp_3012_automute(struct hda_codec *codec)
4741{
4742	unsigned int present, bits;
4743
4744	present = snd_hda_codec_read(codec, 0x10, 0,
4745			AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4746
4747	bits = present ? 0 : PIN_OUT;
4748	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4749			    bits);
4750	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4751			    bits);
4752	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4753			    bits);
4754}
4755
4756static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4757				       unsigned int res)
4758{
4759	if ((res >> 26) == ALC880_HP_EVENT)
4760		alc260_hp_3012_automute(codec);
4761}
4762
4763/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4764 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4765 */
4766static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4767	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4768	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4769	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4770	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4771	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4772	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4773	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4774	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4775	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4776	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4777	{ } /* end */
4778};
4779
4780/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4781 * versions of the ALC260 don't act on requests to enable mic bias from NID
4782 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4783 * datasheet doesn't mention this restriction.  At this stage it's not clear
4784 * whether this behaviour is intentional or is a hardware bug in chip
4785 * revisions available in early 2006.  Therefore for now allow the
4786 * "Headphone Jack Mode" control to span all choices, but if it turns out
4787 * that the lack of mic bias for this NID is intentional we could change the
4788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4789 *
4790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4791 * don't appear to make the mic bias available from the "line" jack, even
4792 * though the NID used for this jack (0x14) can supply it.  The theory is
4793 * that perhaps Acer have included blocking capacitors between the ALC260
4794 * and the output jack.  If this turns out to be the case for all such
4795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4796 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4797 *
4798 * The C20x Tablet series have a mono internal speaker which is controlled
4799 * via the chip's Mono sum widget and pin complex, so include the necessary
4800 * controls for such models.  On models without a "mono speaker" the control
4801 * won't do anything.
4802 */
4803static struct snd_kcontrol_new alc260_acer_mixer[] = {
4804	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4805	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4806	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4807	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4808			      HDA_OUTPUT),
4809	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4810			   HDA_INPUT),
4811	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4812	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4813	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4814	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4815	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4816	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4817	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4818	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4819	{ } /* end */
4820};
4821
4822/* Maxdata Favorit 100XS: one output and one input (0x12) jack
4823 */
4824static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4825	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4826	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4827	ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4828	HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4829	HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4830	ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4831	{ } /* end */
4832};
4833
4834/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4835 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4836 */
4837static struct snd_kcontrol_new alc260_will_mixer[] = {
4838	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4839	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4840	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4841	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4842	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4843	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4844	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4845	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4846	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4847	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4848	{ } /* end */
4849};
4850
4851/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4852 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4853 */
4854static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4855	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4856	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4857	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4858	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4859	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4860	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4861	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4862	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4863	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4864	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4865	{ } /* end */
4866};
4867
4868/*
4869 * initialization verbs
4870 */
4871static struct hda_verb alc260_init_verbs[] = {
4872	/* Line In pin widget for input */
4873	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4874	/* CD pin widget for input */
4875	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4876	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4877	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4878	/* Mic2 (front panel) pin widget for input and vref at 80% */
4879	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4880	/* LINE-2 is used for line-out in rear */
4881	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4882	/* select line-out */
4883	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4884	/* LINE-OUT pin */
4885	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4886	/* enable HP */
4887	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4888	/* enable Mono */
4889	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4890	/* mute capture amp left and right */
4891	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4892	/* set connection select to line in (default select for this ADC) */
4893	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4894	/* mute capture amp left and right */
4895	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4896	/* set connection select to line in (default select for this ADC) */
4897	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4898	/* set vol=0 Line-Out mixer amp left and right */
4899	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4900	/* unmute pin widget amp left and right (no gain on this amp) */
4901	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4902	/* set vol=0 HP mixer amp left and right */
4903	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4904	/* unmute pin widget amp left and right (no gain on this amp) */
4905	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4906	/* set vol=0 Mono mixer amp left and right */
4907	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4908	/* unmute pin widget amp left and right (no gain on this amp) */
4909	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4910	/* unmute LINE-2 out pin */
4911	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4912	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4913	 * Line In 2 = 0x03
4914	 */
4915	/* mute analog inputs */
4916	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4917	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4918	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4919	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4920	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4921	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4922	/* mute Front out path */
4923	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4924	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4925	/* mute Headphone out path */
4926	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4927	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4928	/* mute Mono out path */
4929	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4930	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4931	{ }
4932};
4933
4934#if 0 /* should be identical with alc260_init_verbs? */
4935static struct hda_verb alc260_hp_init_verbs[] = {
4936	/* Headphone and output */
4937	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4938	/* mono output */
4939	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4940	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4941	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4942	/* Mic2 (front panel) pin widget for input and vref at 80% */
4943	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4944	/* Line In pin widget for input */
4945	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4946	/* Line-2 pin widget for output */
4947	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4948	/* CD pin widget for input */
4949	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4950	/* unmute amp left and right */
4951	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4952	/* set connection select to line in (default select for this ADC) */
4953	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4954	/* unmute Line-Out mixer amp left and right (volume = 0) */
4955	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4956	/* mute pin widget amp left and right (no gain on this amp) */
4957	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4958	/* unmute HP mixer amp left and right (volume = 0) */
4959	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4960	/* mute pin widget amp left and right (no gain on this amp) */
4961	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4962	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4963	 * Line In 2 = 0x03
4964	 */
4965	/* mute analog inputs */
4966	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4967	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4968	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4969	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4970	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4971	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4972	/* Unmute Front out path */
4973	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4974	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4975	/* Unmute Headphone out path */
4976	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4977	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4978	/* Unmute Mono out path */
4979	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4980	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4981	{ }
4982};
4983#endif
4984
4985static struct hda_verb alc260_hp_3013_init_verbs[] = {
4986	/* Line out and output */
4987	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4988	/* mono output */
4989	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4990	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4991	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4992	/* Mic2 (front panel) pin widget for input and vref at 80% */
4993	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4994	/* Line In pin widget for input */
4995	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4996	/* Headphone pin widget for output */
4997	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4998	/* CD pin widget for input */
4999	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5000	/* unmute amp left and right */
5001	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5002	/* set connection select to line in (default select for this ADC) */
5003	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5004	/* unmute Line-Out mixer amp left and right (volume = 0) */
5005	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5006	/* mute pin widget amp left and right (no gain on this amp) */
5007	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5008	/* unmute HP mixer amp left and right (volume = 0) */
5009	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5010	/* mute pin widget amp left and right (no gain on this amp) */
5011	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5012	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5013	 * Line In 2 = 0x03
5014	 */
5015	/* mute analog inputs */
5016	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5017	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5018	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5019	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5020	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5021	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5022	/* Unmute Front out path */
5023	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5024	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5025	/* Unmute Headphone out path */
5026	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5027	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5028	/* Unmute Mono out path */
5029	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5030	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5031	{ }
5032};
5033
5034/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5035 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5036 * audio = 0x16, internal speaker = 0x10.
5037 */
5038static struct hda_verb alc260_fujitsu_init_verbs[] = {
5039	/* Disable all GPIOs */
5040	{0x01, AC_VERB_SET_GPIO_MASK, 0},
5041	/* Internal speaker is connected to headphone pin */
5042	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5043	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
5044	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5045	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5046	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5047	/* Ensure all other unused pins are disabled and muted. */
5048	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5049	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5050	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5051	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5052	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5053	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5054	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5055	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5056
5057	/* Disable digital (SPDIF) pins */
5058	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5059	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5060
5061	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5062	 * when acting as an output.
5063	 */
5064	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5065
5066	/* Start with output sum widgets muted and their output gains at min */
5067	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5068	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5069	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5070	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5071	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5072	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5073	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5074	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5075	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5076
5077	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5078	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5079	/* Unmute Line1 pin widget output buffer since it starts as an output.
5080	 * If the pin mode is changed by the user the pin mode control will
5081	 * take care of enabling the pin's input/output buffers as needed.
5082	 * Therefore there's no need to enable the input buffer at this
5083	 * stage.
5084	 */
5085	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5086	/* Unmute input buffer of pin widget used for Line-in (no equiv
5087	 * mixer ctrl)
5088	 */
5089	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5090
5091	/* Mute capture amp left and right */
5092	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5093	/* Set ADC connection select to match default mixer setting - line
5094	 * in (on mic1 pin)
5095	 */
5096	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5097
5098	/* Do the same for the second ADC: mute capture input amp and
5099	 * set ADC connection to line in (on mic1 pin)
5100	 */
5101	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5102	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5103
5104	/* Mute all inputs to mixer widget (even unconnected ones) */
5105	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5106	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5107	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5108	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5109	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5110	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5111	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5112	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5113
5114	{ }
5115};
5116
5117/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5118 * similar laptops (adapted from Fujitsu init verbs).
5119 */
5120static struct hda_verb alc260_acer_init_verbs[] = {
5121	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
5122	 * the headphone jack.  Turn this on and rely on the standard mute
5123	 * methods whenever the user wants to turn these outputs off.
5124	 */
5125	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5126	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5127	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5128	/* Internal speaker/Headphone jack is connected to Line-out pin */
5129	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5130	/* Internal microphone/Mic jack is connected to Mic1 pin */
5131	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5132	/* Line In jack is connected to Line1 pin */
5133	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5134	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5135	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5136	/* Ensure all other unused pins are disabled and muted. */
5137	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5138	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5139	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5140	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5141	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5142	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5143	/* Disable digital (SPDIF) pins */
5144	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5145	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5146
5147	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5148	 * bus when acting as outputs.
5149	 */
5150	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5151	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5152
5153	/* Start with output sum widgets muted and their output gains at min */
5154	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5155	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5156	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5157	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5158	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5159	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5160	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5161	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5162	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5163
5164	/* Unmute Line-out pin widget amp left and right
5165	 * (no equiv mixer ctrl)
5166	 */
5167	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5168	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5169	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5170	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
5171	 * inputs. If the pin mode is changed by the user the pin mode control
5172	 * will take care of enabling the pin's input/output buffers as needed.
5173	 * Therefore there's no need to enable the input buffer at this
5174	 * stage.
5175	 */
5176	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5177	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5178
5179	/* Mute capture amp left and right */
5180	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5181	/* Set ADC connection select to match default mixer setting - mic
5182	 * (on mic1 pin)
5183	 */
5184	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5185
5186	/* Do similar with the second ADC: mute capture input amp and
5187	 * set ADC connection to mic to match ALSA's default state.
5188	 */
5189	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5190	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5191
5192	/* Mute all inputs to mixer widget (even unconnected ones) */
5193	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5194	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5195	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5196	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5197	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5198	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5199	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5200	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5201
5202	{ }
5203};
5204
5205/* Initialisation sequence for Maxdata Favorit 100XS
5206 * (adapted from Acer init verbs).
5207 */
5208static struct hda_verb alc260_favorit100_init_verbs[] = {
5209	/* GPIO 0 enables the output jack.
5210	 * Turn this on and rely on the standard mute
5211	 * methods whenever the user wants to turn these outputs off.
5212	 */
5213	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5214	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5215	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5216	/* Line/Mic input jack is connected to Mic1 pin */
5217	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5218	/* Ensure all other unused pins are disabled and muted. */
5219	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5220	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5221	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5222	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5223	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5224	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5225	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5226	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5227	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5228	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5229	/* Disable digital (SPDIF) pins */
5230	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5231	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5232
5233	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5234	 * bus when acting as outputs.
5235	 */
5236	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5237	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5238
5239	/* Start with output sum widgets muted and their output gains at min */
5240	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5241	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5242	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5243	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5244	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5245	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5246	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5247	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5248	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5249
5250	/* Unmute Line-out pin widget amp left and right
5251	 * (no equiv mixer ctrl)
5252	 */
5253	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5254	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
5255	 * inputs. If the pin mode is changed by the user the pin mode control
5256	 * will take care of enabling the pin's input/output buffers as needed.
5257	 * Therefore there's no need to enable the input buffer at this
5258	 * stage.
5259	 */
5260	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5261
5262	/* Mute capture amp left and right */
5263	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5264	/* Set ADC connection select to match default mixer setting - mic
5265	 * (on mic1 pin)
5266	 */
5267	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5268
5269	/* Do similar with the second ADC: mute capture input amp and
5270	 * set ADC connection to mic to match ALSA's default state.
5271	 */
5272	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5273	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5274
5275	/* Mute all inputs to mixer widget (even unconnected ones) */
5276	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5277	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5278	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5279	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5280	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5281	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5282	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5283	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5284
5285	{ }
5286};
5287
5288static struct hda_verb alc260_will_verbs[] = {
5289	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5290	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5291	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5292	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5293	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5294	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5295	{}
5296};
5297
5298static struct hda_verb alc260_replacer_672v_verbs[] = {
5299	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5300	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5301	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5302
5303	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5304	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5305	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5306
5307	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5308	{}
5309};
5310
5311/* toggle speaker-output according to the hp-jack state */
5312static void alc260_replacer_672v_automute(struct hda_codec *codec)
5313{
5314        unsigned int present;
5315
5316	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5317        present = snd_hda_codec_read(codec, 0x0f, 0,
5318                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5319	if (present) {
5320		snd_hda_codec_write_cache(codec, 0x01, 0,
5321					  AC_VERB_SET_GPIO_DATA, 1);
5322		snd_hda_codec_write_cache(codec, 0x0f, 0,
5323					  AC_VERB_SET_PIN_WIDGET_CONTROL,
5324					  PIN_HP);
5325	} else {
5326		snd_hda_codec_write_cache(codec, 0x01, 0,
5327					  AC_VERB_SET_GPIO_DATA, 0);
5328		snd_hda_codec_write_cache(codec, 0x0f, 0,
5329					  AC_VERB_SET_PIN_WIDGET_CONTROL,
5330					  PIN_OUT);
5331	}
5332}
5333
5334static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5335                                       unsigned int res)
5336{
5337        if ((res >> 26) == ALC880_HP_EVENT)
5338                alc260_replacer_672v_automute(codec);
5339}
5340
5341static struct hda_verb alc260_hp_dc7600_verbs[] = {
5342	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5343	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5344	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5345	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5346	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5347	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5348	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5349	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5350	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5351	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5352	{}
5353};
5354
5355/* Test configuration for debugging, modelled after the ALC880 test
5356 * configuration.
5357 */
5358#ifdef CONFIG_SND_DEBUG
5359static hda_nid_t alc260_test_dac_nids[1] = {
5360	0x02,
5361};
5362static hda_nid_t alc260_test_adc_nids[2] = {
5363	0x04, 0x05,
5364};
5365/* For testing the ALC260, each input MUX needs its own definition since
5366 * the signal assignments are different.  This assumes that the first ADC
5367 * is NID 0x04.
5368 */
5369static struct hda_input_mux alc260_test_capture_sources[2] = {
5370	{
5371		.num_items = 7,
5372		.items = {
5373			{ "MIC1 pin", 0x0 },
5374			{ "MIC2 pin", 0x1 },
5375			{ "LINE1 pin", 0x2 },
5376			{ "LINE2 pin", 0x3 },
5377			{ "CD pin", 0x4 },
5378			{ "LINE-OUT pin", 0x5 },
5379			{ "HP-OUT pin", 0x6 },
5380		},
5381        },
5382	{
5383		.num_items = 8,
5384		.items = {
5385			{ "MIC1 pin", 0x0 },
5386			{ "MIC2 pin", 0x1 },
5387			{ "LINE1 pin", 0x2 },
5388			{ "LINE2 pin", 0x3 },
5389			{ "CD pin", 0x4 },
5390			{ "Mixer", 0x5 },
5391			{ "LINE-OUT pin", 0x6 },
5392			{ "HP-OUT pin", 0x7 },
5393		},
5394        },
5395};
5396static struct snd_kcontrol_new alc260_test_mixer[] = {
5397	/* Output driver widgets */
5398	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5399	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5400	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5401	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5402	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5403	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5404
5405	/* Modes for retasking pin widgets
5406	 * Note: the ALC260 doesn't seem to act on requests to enable mic
5407         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
5408         * mention this restriction.  At this stage it's not clear whether
5409         * this behaviour is intentional or is a hardware bug in chip
5410         * revisions available at least up until early 2006.  Therefore for
5411         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5412         * choices, but if it turns out that the lack of mic bias for these
5413         * NIDs is intentional we could change their modes from
5414         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5415	 */
5416	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5417	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5418	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5419	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5420	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5421	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5422
5423	/* Loopback mixer controls */
5424	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5425	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5426	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5427	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5428	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5429	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5430	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5431	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5432	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5433	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5434	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5435	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5436	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5437	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5438
5439	/* Controls for GPIO pins, assuming they are configured as outputs */
5440	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5441	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5442	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5443	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5444
5445	/* Switches to allow the digital IO pins to be enabled.  The datasheet
5446	 * is ambigious as to which NID is which; testing on laptops which
5447	 * make this output available should provide clarification.
5448	 */
5449	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5450	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5451
5452	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
5453	 * this output to turn on an external amplifier.
5454	 */
5455	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5456	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5457
5458	{ } /* end */
5459};
5460static struct hda_verb alc260_test_init_verbs[] = {
5461	/* Enable all GPIOs as outputs with an initial value of 0 */
5462	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5463	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5464	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5465
5466	/* Enable retasking pins as output, initially without power amp */
5467	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5468	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5469	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5470	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5471	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5472	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5473
5474	/* Disable digital (SPDIF) pins initially, but users can enable
5475	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
5476	 * payload also sets the generation to 0, output to be in "consumer"
5477	 * PCM format, copyright asserted, no pre-emphasis and no validity
5478	 * control.
5479	 */
5480	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5481	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5482
5483	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5484	 * OUT1 sum bus when acting as an output.
5485	 */
5486	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5487	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5488	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5489	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5490
5491	/* Start with output sum widgets muted and their output gains at min */
5492	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5493	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5494	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5495	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5496	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5497	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5498	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5499	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5500	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5501
5502	/* Unmute retasking pin widget output buffers since the default
5503	 * state appears to be output.  As the pin mode is changed by the
5504	 * user the pin mode control will take care of enabling the pin's
5505	 * input/output buffers as needed.
5506	 */
5507	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5508	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5509	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5510	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5511	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5512	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5513	/* Also unmute the mono-out pin widget */
5514	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5515
5516	/* Mute capture amp left and right */
5517	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5518	/* Set ADC connection select to match default mixer setting (mic1
5519	 * pin)
5520	 */
5521	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5522
5523	/* Do the same for the second ADC: mute capture input amp and
5524	 * set ADC connection to mic1 pin
5525	 */
5526	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5527	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5528
5529	/* Mute all inputs to mixer widget (even unconnected ones) */
5530	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5531	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5532	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5533	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5534	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5535	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5536	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5537	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5538
5539	{ }
5540};
5541#endif
5542
5543#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
5544#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
5545
5546#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
5547#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
5548
5549/*
5550 * for BIOS auto-configuration
5551 */
5552
5553static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5554					const char *pfx, int *vol_bits)
5555{
5556	hda_nid_t nid_vol;
5557	unsigned long vol_val, sw_val;
5558	char name[32];
5559	int err;
5560
5561	if (nid >= 0x0f && nid < 0x11) {
5562		nid_vol = nid - 0x7;
5563		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5564		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5565	} else if (nid == 0x11) {
5566		nid_vol = nid - 0x7;
5567		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5568		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5569	} else if (nid >= 0x12 && nid <= 0x15) {
5570		nid_vol = 0x08;
5571		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5572		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5573	} else
5574		return 0; /* N/A */
5575
5576	if (!(*vol_bits & (1 << nid_vol))) {
5577		/* first control for the volume widget */
5578		snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5579		err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5580		if (err < 0)
5581			return err;
5582		*vol_bits |= (1 << nid_vol);
5583	}
5584	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5585	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5586	if (err < 0)
5587		return err;
5588	return 1;
5589}
5590
5591/* add playback controls from the parsed DAC table */
5592static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5593					     const struct auto_pin_cfg *cfg)
5594{
5595	hda_nid_t nid;
5596	int err;
5597	int vols = 0;
5598
5599	spec->multiout.num_dacs = 1;
5600	spec->multiout.dac_nids = spec->private_dac_nids;
5601	spec->multiout.dac_nids[0] = 0x02;
5602
5603	nid = cfg->line_out_pins[0];
5604	if (nid) {
5605		err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5606		if (err < 0)
5607			return err;
5608	}
5609
5610	nid = cfg->speaker_pins[0];
5611	if (nid) {
5612		err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5613		if (err < 0)
5614			return err;
5615	}
5616
5617	nid = cfg->hp_pins[0];
5618	if (nid) {
5619		err = alc260_add_playback_controls(spec, nid, "Headphone",
5620						   &vols);
5621		if (err < 0)
5622			return err;
5623	}
5624	return 0;
5625}
5626
5627/* create playback/capture controls for input pins */
5628static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5629						const struct auto_pin_cfg *cfg)
5630{
5631	struct hda_input_mux *imux = &spec->private_imux[0];
5632	int i, err, idx;
5633
5634	for (i = 0; i < AUTO_PIN_LAST; i++) {
5635		if (cfg->input_pins[i] >= 0x12) {
5636			idx = cfg->input_pins[i] - 0x12;
5637			err = new_analog_input(spec, cfg->input_pins[i],
5638					       auto_pin_cfg_labels[i], idx,
5639					       0x07);
5640			if (err < 0)
5641				return err;
5642			imux->items[imux->num_items].label =
5643				auto_pin_cfg_labels[i];
5644			imux->items[imux->num_items].index = idx;
5645			imux->num_items++;
5646		}
5647		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5648			idx = cfg->input_pins[i] - 0x09;
5649			err = new_analog_input(spec, cfg->input_pins[i],
5650					       auto_pin_cfg_labels[i], idx,
5651					       0x07);
5652			if (err < 0)
5653				return err;
5654			imux->items[imux->num_items].label =
5655				auto_pin_cfg_labels[i];
5656			imux->items[imux->num_items].index = idx;
5657			imux->num_items++;
5658		}
5659	}
5660	return 0;
5661}
5662
5663static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5664					      hda_nid_t nid, int pin_type,
5665					      int sel_idx)
5666{
5667	alc_set_pin_output(codec, nid, pin_type);
5668	/* need the manual connection? */
5669	if (nid >= 0x12) {
5670		int idx = nid - 0x12;
5671		snd_hda_codec_write(codec, idx + 0x0b, 0,
5672				    AC_VERB_SET_CONNECT_SEL, sel_idx);
5673	}
5674}
5675
5676static void alc260_auto_init_multi_out(struct hda_codec *codec)
5677{
5678	struct alc_spec *spec = codec->spec;
5679	hda_nid_t nid;
5680
5681	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5682	nid = spec->autocfg.line_out_pins[0];
5683	if (nid) {
5684		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5685		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5686	}
5687
5688	nid = spec->autocfg.speaker_pins[0];
5689	if (nid)
5690		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5691
5692	nid = spec->autocfg.hp_pins[0];
5693	if (nid)
5694		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5695}
5696
5697#define ALC260_PIN_CD_NID		0x16
5698static void alc260_auto_init_analog_input(struct hda_codec *codec)
5699{
5700	struct alc_spec *spec = codec->spec;
5701	int i;
5702
5703	for (i = 0; i < AUTO_PIN_LAST; i++) {
5704		hda_nid_t nid = spec->autocfg.input_pins[i];
5705		if (nid >= 0x12) {
5706			alc_set_input_pin(codec, nid, i);
5707			if (nid != ALC260_PIN_CD_NID &&
5708			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5709				snd_hda_codec_write(codec, nid, 0,
5710						    AC_VERB_SET_AMP_GAIN_MUTE,
5711						    AMP_OUT_MUTE);
5712		}
5713	}
5714}
5715
5716/*
5717 * generic initialization of ADC, input mixers and output mixers
5718 */
5719static struct hda_verb alc260_volume_init_verbs[] = {
5720	/*
5721	 * Unmute ADC0-1 and set the default input to mic-in
5722	 */
5723	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5724	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5725	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5726	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5727
5728	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5729	 * mixer widget
5730	 * Note: PASD motherboards uses the Line In 2 as the input for
5731	 * front panel mic (mic 2)
5732	 */
5733	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5734	/* mute analog inputs */
5735	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5736	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5737	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5738	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5739	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5740
5741	/*
5742	 * Set up output mixers (0x08 - 0x0a)
5743	 */
5744	/* set vol=0 to output mixers */
5745	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5746	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5747	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5748	/* set up input amps for analog loopback */
5749	/* Amp Indices: DAC = 0, mixer = 1 */
5750	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5751	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5752	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5753	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5754	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5755	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5756
5757	{ }
5758};
5759
5760static int alc260_parse_auto_config(struct hda_codec *codec)
5761{
5762	struct alc_spec *spec = codec->spec;
5763	int err;
5764	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5765
5766	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5767					   alc260_ignore);
5768	if (err < 0)
5769		return err;
5770	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5771	if (err < 0)
5772		return err;
5773	if (!spec->kctls.list)
5774		return 0; /* can't find valid BIOS pin config */
5775	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5776	if (err < 0)
5777		return err;
5778
5779	spec->multiout.max_channels = 2;
5780
5781	if (spec->autocfg.dig_outs)
5782		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5783	if (spec->kctls.list)
5784		add_mixer(spec, spec->kctls.list);
5785
5786	add_verb(spec, alc260_volume_init_verbs);
5787
5788	spec->num_mux_defs = 1;
5789	spec->input_mux = &spec->private_imux[0];
5790
5791	return 1;
5792}
5793
5794/* additional initialization for auto-configuration model */
5795static void alc260_auto_init(struct hda_codec *codec)
5796{
5797	struct alc_spec *spec = codec->spec;
5798	alc260_auto_init_multi_out(codec);
5799	alc260_auto_init_analog_input(codec);
5800	if (spec->unsol_event)
5801		alc_inithook(codec);
5802}
5803
5804#ifdef CONFIG_SND_HDA_POWER_SAVE
5805static struct hda_amp_list alc260_loopbacks[] = {
5806	{ 0x07, HDA_INPUT, 0 },
5807	{ 0x07, HDA_INPUT, 1 },
5808	{ 0x07, HDA_INPUT, 2 },
5809	{ 0x07, HDA_INPUT, 3 },
5810	{ 0x07, HDA_INPUT, 4 },
5811	{ } /* end */
5812};
5813#endif
5814
5815/*
5816 * ALC260 configurations
5817 */
5818static const char *alc260_models[ALC260_MODEL_LAST] = {
5819	[ALC260_BASIC]		= "basic",
5820	[ALC260_HP]		= "hp",
5821	[ALC260_HP_3013]	= "hp-3013",
5822	[ALC260_HP_DC7600]	= "hp-dc7600",
5823	[ALC260_FUJITSU_S702X]	= "fujitsu",
5824	[ALC260_ACER]		= "acer",
5825	[ALC260_WILL]		= "will",
5826	[ALC260_REPLACER_672V]	= "replacer",
5827	[ALC260_FAVORIT100]	= "favorit100",
5828#ifdef CONFIG_SND_DEBUG
5829	[ALC260_TEST]		= "test",
5830#endif
5831	[ALC260_AUTO]		= "auto",
5832};
5833
5834static struct snd_pci_quirk alc260_cfg_tbl[] = {
5835	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5836	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5837	SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5838	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5839	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5840	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5841	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5842	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5843	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5844	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5845	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5846	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5847	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5848	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5849	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5850	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5851	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5852	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5853	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5854	{}
5855};
5856
5857static struct alc_config_preset alc260_presets[] = {
5858	[ALC260_BASIC] = {
5859		.mixers = { alc260_base_output_mixer,
5860			    alc260_input_mixer },
5861		.init_verbs = { alc260_init_verbs },
5862		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5863		.dac_nids = alc260_dac_nids,
5864		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5865		.adc_nids = alc260_adc_nids,
5866		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5867		.channel_mode = alc260_modes,
5868		.input_mux = &alc260_capture_source,
5869	},
5870	[ALC260_HP] = {
5871		.mixers = { alc260_hp_output_mixer,
5872			    alc260_input_mixer },
5873		.init_verbs = { alc260_init_verbs,
5874				alc260_hp_unsol_verbs },
5875		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5876		.dac_nids = alc260_dac_nids,
5877		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5878		.adc_nids = alc260_adc_nids_alt,
5879		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5880		.channel_mode = alc260_modes,
5881		.input_mux = &alc260_capture_source,
5882		.unsol_event = alc260_hp_unsol_event,
5883		.init_hook = alc260_hp_automute,
5884	},
5885	[ALC260_HP_DC7600] = {
5886		.mixers = { alc260_hp_dc7600_mixer,
5887			    alc260_input_mixer },
5888		.init_verbs = { alc260_init_verbs,
5889				alc260_hp_dc7600_verbs },
5890		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5891		.dac_nids = alc260_dac_nids,
5892		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5893		.adc_nids = alc260_adc_nids_alt,
5894		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5895		.channel_mode = alc260_modes,
5896		.input_mux = &alc260_capture_source,
5897		.unsol_event = alc260_hp_3012_unsol_event,
5898		.init_hook = alc260_hp_3012_automute,
5899	},
5900	[ALC260_HP_3013] = {
5901		.mixers = { alc260_hp_3013_mixer,
5902			    alc260_input_mixer },
5903		.init_verbs = { alc260_hp_3013_init_verbs,
5904				alc260_hp_3013_unsol_verbs },
5905		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5906		.dac_nids = alc260_dac_nids,
5907		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5908		.adc_nids = alc260_adc_nids_alt,
5909		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5910		.channel_mode = alc260_modes,
5911		.input_mux = &alc260_capture_source,
5912		.unsol_event = alc260_hp_3013_unsol_event,
5913		.init_hook = alc260_hp_3013_automute,
5914	},
5915	[ALC260_FUJITSU_S702X] = {
5916		.mixers = { alc260_fujitsu_mixer },
5917		.init_verbs = { alc260_fujitsu_init_verbs },
5918		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5919		.dac_nids = alc260_dac_nids,
5920		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5921		.adc_nids = alc260_dual_adc_nids,
5922		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5923		.channel_mode = alc260_modes,
5924		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5925		.input_mux = alc260_fujitsu_capture_sources,
5926	},
5927	[ALC260_ACER] = {
5928		.mixers = { alc260_acer_mixer },
5929		.init_verbs = { alc260_acer_init_verbs },
5930		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5931		.dac_nids = alc260_dac_nids,
5932		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5933		.adc_nids = alc260_dual_adc_nids,
5934		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5935		.channel_mode = alc260_modes,
5936		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5937		.input_mux = alc260_acer_capture_sources,
5938	},
5939	[ALC260_FAVORIT100] = {
5940		.mixers = { alc260_favorit100_mixer },
5941		.init_verbs = { alc260_favorit100_init_verbs },
5942		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5943		.dac_nids = alc260_dac_nids,
5944		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5945		.adc_nids = alc260_dual_adc_nids,
5946		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5947		.channel_mode = alc260_modes,
5948		.num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5949		.input_mux = alc260_favorit100_capture_sources,
5950	},
5951	[ALC260_WILL] = {
5952		.mixers = { alc260_will_mixer },
5953		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5954		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5955		.dac_nids = alc260_dac_nids,
5956		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5957		.adc_nids = alc260_adc_nids,
5958		.dig_out_nid = ALC260_DIGOUT_NID,
5959		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5960		.channel_mode = alc260_modes,
5961		.input_mux = &alc260_capture_source,
5962	},
5963	[ALC260_REPLACER_672V] = {
5964		.mixers = { alc260_replacer_672v_mixer },
5965		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5966		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5967		.dac_nids = alc260_dac_nids,
5968		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5969		.adc_nids = alc260_adc_nids,
5970		.dig_out_nid = ALC260_DIGOUT_NID,
5971		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5972		.channel_mode = alc260_modes,
5973		.input_mux = &alc260_capture_source,
5974		.unsol_event = alc260_replacer_672v_unsol_event,
5975		.init_hook = alc260_replacer_672v_automute,
5976	},
5977#ifdef CONFIG_SND_DEBUG
5978	[ALC260_TEST] = {
5979		.mixers = { alc260_test_mixer },
5980		.init_verbs = { alc260_test_init_verbs },
5981		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5982		.dac_nids = alc260_test_dac_nids,
5983		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5984		.adc_nids = alc260_test_adc_nids,
5985		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5986		.channel_mode = alc260_modes,
5987		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5988		.input_mux = alc260_test_capture_sources,
5989	},
5990#endif
5991};
5992
5993static int patch_alc260(struct hda_codec *codec)
5994{
5995	struct alc_spec *spec;
5996	int err, board_config;
5997
5998	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5999	if (spec == NULL)
6000		return -ENOMEM;
6001
6002	codec->spec = spec;
6003
6004	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6005						  alc260_models,
6006						  alc260_cfg_tbl);
6007	if (board_config < 0) {
6008		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6009			   "trying auto-probe from BIOS...\n");
6010		board_config = ALC260_AUTO;
6011	}
6012
6013	if (board_config == ALC260_AUTO) {
6014		/* automatic parse from the BIOS config */
6015		err = alc260_parse_auto_config(codec);
6016		if (err < 0) {
6017			alc_free(codec);
6018			return err;
6019		} else if (!err) {
6020			printk(KERN_INFO
6021			       "hda_codec: Cannot set up configuration "
6022			       "from BIOS.  Using base mode...\n");
6023			board_config = ALC260_BASIC;
6024		}
6025	}
6026
6027	err = snd_hda_attach_beep_device(codec, 0x1);
6028	if (err < 0) {
6029		alc_free(codec);
6030		return err;
6031	}
6032
6033	if (board_config != ALC260_AUTO)
6034		setup_preset(spec, &alc260_presets[board_config]);
6035
6036	spec->stream_name_analog = "ALC260 Analog";
6037	spec->stream_analog_playback = &alc260_pcm_analog_playback;
6038	spec->stream_analog_capture = &alc260_pcm_analog_capture;
6039
6040	spec->stream_name_digital = "ALC260 Digital";
6041	spec->stream_digital_playback = &alc260_pcm_digital_playback;
6042	spec->stream_digital_capture = &alc260_pcm_digital_capture;
6043
6044	if (!spec->adc_nids && spec->input_mux) {
6045		/* check whether NID 0x04 is valid */
6046		unsigned int wcap = get_wcaps(codec, 0x04);
6047		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6048		/* get type */
6049		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6050			spec->adc_nids = alc260_adc_nids_alt;
6051			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6052		} else {
6053			spec->adc_nids = alc260_adc_nids;
6054			spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6055		}
6056	}
6057	set_capture_mixer(spec);
6058	set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6059
6060	spec->vmaster_nid = 0x08;
6061
6062	codec->patch_ops = alc_patch_ops;
6063	if (board_config == ALC260_AUTO)
6064		spec->init_hook = alc260_auto_init;
6065#ifdef CONFIG_SND_HDA_POWER_SAVE
6066	if (!spec->loopback.amplist)
6067		spec->loopback.amplist = alc260_loopbacks;
6068#endif
6069	codec->proc_widget_hook = print_realtek_coef;
6070
6071	return 0;
6072}
6073
6074
6075/*
6076 * ALC882 support
6077 *
6078 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6079 * configuration.  Each pin widget can choose any input DACs and a mixer.
6080 * Each ADC is connected from a mixer of all inputs.  This makes possible
6081 * 6-channel independent captures.
6082 *
6083 * In addition, an independent DAC for the multi-playback (not used in this
6084 * driver yet).
6085 */
6086#define ALC882_DIGOUT_NID	0x06
6087#define ALC882_DIGIN_NID	0x0a
6088
6089static struct hda_channel_mode alc882_ch_modes[1] = {
6090	{ 8, NULL }
6091};
6092
6093static hda_nid_t alc882_dac_nids[4] = {
6094	/* front, rear, clfe, rear_surr */
6095	0x02, 0x03, 0x04, 0x05
6096};
6097
6098/* identical with ALC880 */
6099#define alc882_adc_nids		alc880_adc_nids
6100#define alc882_adc_nids_alt	alc880_adc_nids_alt
6101
6102static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6103static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6104
6105/* input MUX */
6106/* FIXME: should be a matrix-type input source selection */
6107
6108static struct hda_input_mux alc882_capture_source = {
6109	.num_items = 4,
6110	.items = {
6111		{ "Mic", 0x0 },
6112		{ "Front Mic", 0x1 },
6113		{ "Line", 0x2 },
6114		{ "CD", 0x4 },
6115	},
6116};
6117/*
6118 * 2ch mode
6119 */
6120static struct hda_verb alc882_3ST_ch2_init[] = {
6121	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6122	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6123	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6124	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6125	{ } /* end */
6126};
6127
6128/*
6129 * 6ch mode
6130 */
6131static struct hda_verb alc882_3ST_ch6_init[] = {
6132	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6133	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6134	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6135	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6136	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6137	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6138	{ } /* end */
6139};
6140
6141static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6142	{ 2, alc882_3ST_ch2_init },
6143	{ 6, alc882_3ST_ch6_init },
6144};
6145
6146/*
6147 * 6ch mode
6148 */
6149static struct hda_verb alc882_sixstack_ch6_init[] = {
6150	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6151	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6152	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6153	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6154	{ } /* end */
6155};
6156
6157/*
6158 * 8ch mode
6159 */
6160static struct hda_verb alc882_sixstack_ch8_init[] = {
6161	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6162	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6163	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6164	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6165	{ } /* end */
6166};
6167
6168static struct hda_channel_mode alc882_sixstack_modes[2] = {
6169	{ 6, alc882_sixstack_ch6_init },
6170	{ 8, alc882_sixstack_ch8_init },
6171};
6172
6173/*
6174 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6175 */
6176
6177/*
6178 * 2ch mode
6179 */
6180static struct hda_verb alc885_mbp_ch2_init[] = {
6181	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6182	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6183	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6184	{ } /* end */
6185};
6186
6187/*
6188 * 6ch mode
6189 */
6190static struct hda_verb alc885_mbp_ch6_init[] = {
6191	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6192	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6193	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6194	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6195	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6196	{ } /* end */
6197};
6198
6199static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6200	{ 2, alc885_mbp_ch2_init },
6201	{ 6, alc885_mbp_ch6_init },
6202};
6203
6204
6205/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6206 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6207 */
6208static struct snd_kcontrol_new alc882_base_mixer[] = {
6209	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6210	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6211	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6212	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6213	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6214	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6215	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6216	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6217	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6218	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6219	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6220	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6221	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6222	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6223	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6224	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6225	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6226	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6227	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6228	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6229	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6230	{ } /* end */
6231};
6232
6233static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6234	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6235	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6236	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6237	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6238	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6239	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6240	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6241	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6242	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6243	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6244	{ } /* end */
6245};
6246static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6247	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6248	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6249	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6250	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6251	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6252	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6253	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6254	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6255	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6256	{ } /* end */
6257};
6258
6259static struct snd_kcontrol_new alc882_targa_mixer[] = {
6260	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6261	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6262	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6263	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6264	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6265	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6266	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6267	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6268	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6269	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6270	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6271	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6272	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6273	{ } /* end */
6274};
6275
6276/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6277 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6278 */
6279static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6280	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6281	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6282	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6283	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6284	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6285	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6286	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6287	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6288	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6289	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6290	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6291	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6292	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6293	{ } /* end */
6294};
6295
6296static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6297	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6298	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6299	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6300	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6301	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6302	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6303	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6304	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6305	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6306	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6307	{ } /* end */
6308};
6309
6310static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6311	{
6312		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6313		.name = "Channel Mode",
6314		.info = alc_ch_mode_info,
6315		.get = alc_ch_mode_get,
6316		.put = alc_ch_mode_put,
6317	},
6318	{ } /* end */
6319};
6320
6321static struct hda_verb alc882_init_verbs[] = {
6322	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6324	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6325	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6326	/* Rear mixer */
6327	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6328	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6329	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6330	/* CLFE mixer */
6331	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6332	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6333	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6334	/* Side mixer */
6335	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6336	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6337	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6338
6339	/* Front Pin: output 0 (0x0c) */
6340	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6341	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6342	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6343	/* Rear Pin: output 1 (0x0d) */
6344	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6345	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6346	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6347	/* CLFE Pin: output 2 (0x0e) */
6348	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6349	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6350	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6351	/* Side Pin: output 3 (0x0f) */
6352	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6353	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6354	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6355	/* Mic (rear) pin: input vref at 80% */
6356	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6357	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6358	/* Front Mic pin: input vref at 80% */
6359	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6360	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6361	/* Line In pin: input */
6362	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6363	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6364	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6365	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6366	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6367	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6368	/* CD pin widget for input */
6369	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6370
6371	/* FIXME: use matrix-type input source selection */
6372	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6373	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6374	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6375	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6376	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6377	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6378	/* Input mixer2 */
6379	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6380	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6381	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6382	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6383	/* Input mixer3 */
6384	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6385	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6386	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6387	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6388	/* ADC1: mute amp left and right */
6389	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6390	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6391	/* ADC2: mute amp left and right */
6392	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6394	/* ADC3: mute amp left and right */
6395	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6396	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6397
6398	{ }
6399};
6400
6401static struct hda_verb alc882_eapd_verbs[] = {
6402	/* change to EAPD mode */
6403	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6404	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6405	{ }
6406};
6407
6408/* Mac Pro test */
6409static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6410	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6411	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6412	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6413	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6414	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6415	/* FIXME: this looks suspicious...
6416	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6417	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6418	*/
6419	{ } /* end */
6420};
6421
6422static struct hda_verb alc882_macpro_init_verbs[] = {
6423	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6424	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6425	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6426	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6427	/* Front Pin: output 0 (0x0c) */
6428	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6429	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6430	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6431	/* Front Mic pin: input vref at 80% */
6432	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6433	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6434	/* Speaker:  output */
6435	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6436	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6437	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6438	/* Headphone output (output 0 - 0x0c) */
6439	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6440	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6441	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6442
6443	/* FIXME: use matrix-type input source selection */
6444	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6445	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6446	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6447	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6448	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6449	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6450	/* Input mixer2 */
6451	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6452	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6453	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6454	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6455	/* Input mixer3 */
6456	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6457	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6458	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6459	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6460	/* ADC1: mute amp left and right */
6461	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6462	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6463	/* ADC2: mute amp left and right */
6464	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6466	/* ADC3: mute amp left and right */
6467	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6468	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6469
6470	{ }
6471};
6472
6473/* Macbook Pro rev3 */
6474static struct hda_verb alc885_mbp3_init_verbs[] = {
6475	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6476	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6477	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6479	/* Rear mixer */
6480	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6481	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6482	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6483	/* Front Pin: output 0 (0x0c) */
6484	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6485	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6486	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6487	/* HP Pin: output 0 (0x0d) */
6488	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6489	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6490	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6491	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6492	/* Mic (rear) pin: input vref at 80% */
6493	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6494	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6495	/* Front Mic pin: input vref at 80% */
6496	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6497	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6498	/* Line In pin: use output 1 when in LineOut mode */
6499	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6500	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6501	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6502
6503	/* FIXME: use matrix-type input source selection */
6504	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6505	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6506	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6507	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6508	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6509	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6510	/* Input mixer2 */
6511	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6512	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6513	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6514	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6515	/* Input mixer3 */
6516	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6517	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6518	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6519	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6520	/* ADC1: mute amp left and right */
6521	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6522	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6523	/* ADC2: mute amp left and right */
6524	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6525	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6526	/* ADC3: mute amp left and right */
6527	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6528	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6529
6530	{ }
6531};
6532
6533/* iMac 24 mixer. */
6534static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6535	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6536	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6537	{ } /* end */
6538};
6539
6540/* iMac 24 init verbs. */
6541static struct hda_verb alc885_imac24_init_verbs[] = {
6542	/* Internal speakers: output 0 (0x0c) */
6543	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6544	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6545	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6546	/* Internal speakers: output 0 (0x0c) */
6547	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6548	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6549	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6550	/* Headphone: output 0 (0x0c) */
6551	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6552	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6553	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6554	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6555	/* Front Mic: input vref at 80% */
6556	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6557	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6558	{ }
6559};
6560
6561/* Toggle speaker-output according to the hp-jack state */
6562static void alc885_imac24_automute(struct hda_codec *codec)
6563{
6564 	unsigned int present;
6565
6566 	present = snd_hda_codec_read(codec, 0x14, 0,
6567				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6568	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6569				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6570	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6571				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6572}
6573
6574/* Processes unsolicited events. */
6575static void alc885_imac24_unsol_event(struct hda_codec *codec,
6576				      unsigned int res)
6577{
6578	/* Headphone insertion or removal. */
6579	if ((res >> 26) == ALC880_HP_EVENT)
6580		alc885_imac24_automute(codec);
6581}
6582
6583static void alc885_mbp3_automute(struct hda_codec *codec)
6584{
6585 	unsigned int present;
6586
6587 	present = snd_hda_codec_read(codec, 0x15, 0,
6588				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6589	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
6590				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6591	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6592				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6593
6594}
6595static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6596				    unsigned int res)
6597{
6598	/* Headphone insertion or removal. */
6599	if ((res >> 26) == ALC880_HP_EVENT)
6600		alc885_mbp3_automute(codec);
6601}
6602
6603
6604static struct hda_verb alc882_targa_verbs[] = {
6605	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6606	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6607
6608	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6609	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6610
6611	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6612	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6613	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6614
6615	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6616	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6617	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6618	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6619	{ } /* end */
6620};
6621
6622/* toggle speaker-output according to the hp-jack state */
6623static void alc882_targa_automute(struct hda_codec *codec)
6624{
6625 	unsigned int present;
6626
6627 	present = snd_hda_codec_read(codec, 0x14, 0,
6628				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6629	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6630				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6631	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6632				  present ? 1 : 3);
6633}
6634
6635static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6636{
6637	/* Looks like the unsol event is incompatible with the standard
6638	 * definition.  4bit tag is placed at 26 bit!
6639	 */
6640	if (((res >> 26) == ALC880_HP_EVENT)) {
6641		alc882_targa_automute(codec);
6642	}
6643}
6644
6645static struct hda_verb alc882_asus_a7j_verbs[] = {
6646	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6647	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6648
6649	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6650	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6651	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6652
6653	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6654	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6655	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6656
6657	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6658	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6659	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6660	{ } /* end */
6661};
6662
6663static struct hda_verb alc882_asus_a7m_verbs[] = {
6664	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6665	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6666
6667	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6668	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6669	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6670
6671	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6672	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6673	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6674
6675	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6676	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6677	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6678 	{ } /* end */
6679};
6680
6681static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6682{
6683	unsigned int gpiostate, gpiomask, gpiodir;
6684
6685	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6686				       AC_VERB_GET_GPIO_DATA, 0);
6687
6688	if (!muted)
6689		gpiostate |= (1 << pin);
6690	else
6691		gpiostate &= ~(1 << pin);
6692
6693	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6694				      AC_VERB_GET_GPIO_MASK, 0);
6695	gpiomask |= (1 << pin);
6696
6697	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6698				     AC_VERB_GET_GPIO_DIRECTION, 0);
6699	gpiodir |= (1 << pin);
6700
6701
6702	snd_hda_codec_write(codec, codec->afg, 0,
6703			    AC_VERB_SET_GPIO_MASK, gpiomask);
6704	snd_hda_codec_write(codec, codec->afg, 0,
6705			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6706
6707	msleep(1);
6708
6709	snd_hda_codec_write(codec, codec->afg, 0,
6710			    AC_VERB_SET_GPIO_DATA, gpiostate);
6711}
6712
6713/* set up GPIO at initialization */
6714static void alc885_macpro_init_hook(struct hda_codec *codec)
6715{
6716	alc882_gpio_mute(codec, 0, 0);
6717	alc882_gpio_mute(codec, 1, 0);
6718}
6719
6720/* set up GPIO and update auto-muting at initialization */
6721static void alc885_imac24_init_hook(struct hda_codec *codec)
6722{
6723	alc885_macpro_init_hook(codec);
6724	alc885_imac24_automute(codec);
6725}
6726
6727/*
6728 * generic initialization of ADC, input mixers and output mixers
6729 */
6730static struct hda_verb alc882_auto_init_verbs[] = {
6731	/*
6732	 * Unmute ADC0-2 and set the default input to mic-in
6733	 */
6734	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6735	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6736	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6737	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6738	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6739	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6740
6741	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6742	 * mixer widget
6743	 * Note: PASD motherboards uses the Line In 2 as the input for
6744	 * front panel mic (mic 2)
6745	 */
6746	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6747	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6748	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6749	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6750	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6751	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6752
6753	/*
6754	 * Set up output mixers (0x0c - 0x0f)
6755	 */
6756	/* set vol=0 to output mixers */
6757	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6758	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6759	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6761	/* set up input amps for analog loopback */
6762	/* Amp Indices: DAC = 0, mixer = 1 */
6763	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6764	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6765	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6766	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6767	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6768	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6769	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6770	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6771	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6773
6774	/* FIXME: use matrix-type input source selection */
6775	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6776	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6777	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6778	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6779	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6780	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6781	/* Input mixer2 */
6782	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6783	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6784	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6785	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6786	/* Input mixer3 */
6787	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6788	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6789	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6790	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6791
6792	{ }
6793};
6794
6795#ifdef CONFIG_SND_HDA_POWER_SAVE
6796#define alc882_loopbacks	alc880_loopbacks
6797#endif
6798
6799/* pcm configuration: identiacal with ALC880 */
6800#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6801#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6802#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6803#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6804
6805/*
6806 * configuration and preset
6807 */
6808static const char *alc882_models[ALC882_MODEL_LAST] = {
6809	[ALC882_3ST_DIG]	= "3stack-dig",
6810	[ALC882_6ST_DIG]	= "6stack-dig",
6811	[ALC882_ARIMA]		= "arima",
6812	[ALC882_W2JC]		= "w2jc",
6813	[ALC882_TARGA]		= "targa",
6814	[ALC882_ASUS_A7J]	= "asus-a7j",
6815	[ALC882_ASUS_A7M]	= "asus-a7m",
6816	[ALC885_MACPRO]		= "macpro",
6817	[ALC885_MBP3]		= "mbp3",
6818	[ALC885_IMAC24]		= "imac24",
6819	[ALC882_AUTO]		= "auto",
6820};
6821
6822static struct snd_pci_quirk alc882_cfg_tbl[] = {
6823	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6824	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6825	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6826	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6827	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6828	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6829	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6830	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6831	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6832	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6833	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6834	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6835	{}
6836};
6837
6838static struct alc_config_preset alc882_presets[] = {
6839	[ALC882_3ST_DIG] = {
6840		.mixers = { alc882_base_mixer },
6841		.init_verbs = { alc882_init_verbs },
6842		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6843		.dac_nids = alc882_dac_nids,
6844		.dig_out_nid = ALC882_DIGOUT_NID,
6845		.dig_in_nid = ALC882_DIGIN_NID,
6846		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6847		.channel_mode = alc882_ch_modes,
6848		.need_dac_fix = 1,
6849		.input_mux = &alc882_capture_source,
6850	},
6851	[ALC882_6ST_DIG] = {
6852		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6853		.init_verbs = { alc882_init_verbs },
6854		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6855		.dac_nids = alc882_dac_nids,
6856		.dig_out_nid = ALC882_DIGOUT_NID,
6857		.dig_in_nid = ALC882_DIGIN_NID,
6858		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6859		.channel_mode = alc882_sixstack_modes,
6860		.input_mux = &alc882_capture_source,
6861	},
6862	[ALC882_ARIMA] = {
6863		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6864		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6865		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6866		.dac_nids = alc882_dac_nids,
6867		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6868		.channel_mode = alc882_sixstack_modes,
6869		.input_mux = &alc882_capture_source,
6870	},
6871	[ALC882_W2JC] = {
6872		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6873		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6874				alc880_gpio1_init_verbs },
6875		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6876		.dac_nids = alc882_dac_nids,
6877		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6878		.channel_mode = alc880_threestack_modes,
6879		.need_dac_fix = 1,
6880		.input_mux = &alc882_capture_source,
6881		.dig_out_nid = ALC882_DIGOUT_NID,
6882	},
6883	[ALC885_MBP3] = {
6884		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6885		.init_verbs = { alc885_mbp3_init_verbs,
6886				alc880_gpio1_init_verbs },
6887		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6888		.dac_nids = alc882_dac_nids,
6889		.channel_mode = alc885_mbp_6ch_modes,
6890		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6891		.input_mux = &alc882_capture_source,
6892		.dig_out_nid = ALC882_DIGOUT_NID,
6893		.dig_in_nid = ALC882_DIGIN_NID,
6894		.unsol_event = alc885_mbp3_unsol_event,
6895		.init_hook = alc885_mbp3_automute,
6896	},
6897	[ALC885_MACPRO] = {
6898		.mixers = { alc882_macpro_mixer },
6899		.init_verbs = { alc882_macpro_init_verbs },
6900		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6901		.dac_nids = alc882_dac_nids,
6902		.dig_out_nid = ALC882_DIGOUT_NID,
6903		.dig_in_nid = ALC882_DIGIN_NID,
6904		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6905		.channel_mode = alc882_ch_modes,
6906		.input_mux = &alc882_capture_source,
6907		.init_hook = alc885_macpro_init_hook,
6908	},
6909	[ALC885_IMAC24] = {
6910		.mixers = { alc885_imac24_mixer },
6911		.init_verbs = { alc885_imac24_init_verbs },
6912		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6913		.dac_nids = alc882_dac_nids,
6914		.dig_out_nid = ALC882_DIGOUT_NID,
6915		.dig_in_nid = ALC882_DIGIN_NID,
6916		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6917		.channel_mode = alc882_ch_modes,
6918		.input_mux = &alc882_capture_source,
6919		.unsol_event = alc885_imac24_unsol_event,
6920		.init_hook = alc885_imac24_init_hook,
6921	},
6922	[ALC882_TARGA] = {
6923		.mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6924		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6925		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6926		.dac_nids = alc882_dac_nids,
6927		.dig_out_nid = ALC882_DIGOUT_NID,
6928		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6929		.adc_nids = alc882_adc_nids,
6930		.capsrc_nids = alc882_capsrc_nids,
6931		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6932		.channel_mode = alc882_3ST_6ch_modes,
6933		.need_dac_fix = 1,
6934		.input_mux = &alc882_capture_source,
6935		.unsol_event = alc882_targa_unsol_event,
6936		.init_hook = alc882_targa_automute,
6937	},
6938	[ALC882_ASUS_A7J] = {
6939		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6940		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6941		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6942		.dac_nids = alc882_dac_nids,
6943		.dig_out_nid = ALC882_DIGOUT_NID,
6944		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6945		.adc_nids = alc882_adc_nids,
6946		.capsrc_nids = alc882_capsrc_nids,
6947		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6948		.channel_mode = alc882_3ST_6ch_modes,
6949		.need_dac_fix = 1,
6950		.input_mux = &alc882_capture_source,
6951	},
6952	[ALC882_ASUS_A7M] = {
6953		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6954		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6955				alc880_gpio1_init_verbs,
6956				alc882_asus_a7m_verbs },
6957		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6958		.dac_nids = alc882_dac_nids,
6959		.dig_out_nid = ALC882_DIGOUT_NID,
6960		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6961		.channel_mode = alc880_threestack_modes,
6962		.need_dac_fix = 1,
6963		.input_mux = &alc882_capture_source,
6964	},
6965};
6966
6967
6968/*
6969 * Pin config fixes
6970 */
6971enum {
6972	PINFIX_ABIT_AW9D_MAX
6973};
6974
6975static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6976	{ 0x15, 0x01080104 }, /* side */
6977	{ 0x16, 0x01011012 }, /* rear */
6978	{ 0x17, 0x01016011 }, /* clfe */
6979	{ }
6980};
6981
6982static const struct alc_pincfg *alc882_pin_fixes[] = {
6983	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6984};
6985
6986static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6987	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6988	{}
6989};
6990
6991/*
6992 * BIOS auto configuration
6993 */
6994static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6995					      hda_nid_t nid, int pin_type,
6996					      int dac_idx)
6997{
6998	/* set as output */
6999	struct alc_spec *spec = codec->spec;
7000	int idx;
7001
7002	alc_set_pin_output(codec, nid, pin_type);
7003	if (spec->multiout.dac_nids[dac_idx] == 0x25)
7004		idx = 4;
7005	else
7006		idx = spec->multiout.dac_nids[dac_idx] - 2;
7007	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7008
7009}
7010
7011static void alc882_auto_init_multi_out(struct hda_codec *codec)
7012{
7013	struct alc_spec *spec = codec->spec;
7014	int i;
7015
7016	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7017	for (i = 0; i <= HDA_SIDE; i++) {
7018		hda_nid_t nid = spec->autocfg.line_out_pins[i];
7019		int pin_type = get_pin_type(spec->autocfg.line_out_type);
7020		if (nid)
7021			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7022							  i);
7023	}
7024}
7025
7026static void alc882_auto_init_hp_out(struct hda_codec *codec)
7027{
7028	struct alc_spec *spec = codec->spec;
7029	hda_nid_t pin;
7030
7031	pin = spec->autocfg.hp_pins[0];
7032	if (pin) /* connect to front */
7033		/* use dac 0 */
7034		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7035	pin = spec->autocfg.speaker_pins[0];
7036	if (pin)
7037		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7038}
7039
7040#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
7041#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
7042
7043static void alc882_auto_init_analog_input(struct hda_codec *codec)
7044{
7045	struct alc_spec *spec = codec->spec;
7046	int i;
7047
7048	for (i = 0; i < AUTO_PIN_LAST; i++) {
7049		hda_nid_t nid = spec->autocfg.input_pins[i];
7050		if (!nid)
7051			continue;
7052		alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7053		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7054			snd_hda_codec_write(codec, nid, 0,
7055					    AC_VERB_SET_AMP_GAIN_MUTE,
7056					    AMP_OUT_MUTE);
7057	}
7058}
7059
7060static void alc882_auto_init_input_src(struct hda_codec *codec)
7061{
7062	struct alc_spec *spec = codec->spec;
7063	int c;
7064
7065	for (c = 0; c < spec->num_adc_nids; c++) {
7066		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7067		hda_nid_t nid = spec->capsrc_nids[c];
7068		unsigned int mux_idx;
7069		const struct hda_input_mux *imux;
7070		int conns, mute, idx, item;
7071
7072		conns = snd_hda_get_connections(codec, nid, conn_list,
7073						ARRAY_SIZE(conn_list));
7074		if (conns < 0)
7075			continue;
7076		mux_idx = c >= spec->num_mux_defs ? 0 : c;
7077		imux = &spec->input_mux[mux_idx];
7078		for (idx = 0; idx < conns; idx++) {
7079			/* if the current connection is the selected one,
7080			 * unmute it as default - otherwise mute it
7081			 */
7082			mute = AMP_IN_MUTE(idx);
7083			for (item = 0; item < imux->num_items; item++) {
7084				if (imux->items[item].index == idx) {
7085					if (spec->cur_mux[c] == item)
7086						mute = AMP_IN_UNMUTE(idx);
7087					break;
7088				}
7089			}
7090			/* check if we have a selector or mixer
7091			 * we could check for the widget type instead, but
7092			 * just check for Amp-In presence (in case of mixer
7093			 * without amp-in there is something wrong, this
7094			 * function shouldn't be used or capsrc nid is wrong)
7095			 */
7096			if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7097				snd_hda_codec_write(codec, nid, 0,
7098						    AC_VERB_SET_AMP_GAIN_MUTE,
7099						    mute);
7100			else if (mute != AMP_IN_MUTE(idx))
7101				snd_hda_codec_write(codec, nid, 0,
7102						    AC_VERB_SET_CONNECT_SEL,
7103						    idx);
7104		}
7105	}
7106}
7107
7108/* add mic boosts if needed */
7109static int alc_auto_add_mic_boost(struct hda_codec *codec)
7110{
7111	struct alc_spec *spec = codec->spec;
7112	int err;
7113	hda_nid_t nid;
7114
7115	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7116	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7117		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7118				  "Mic Boost",
7119				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7120		if (err < 0)
7121			return err;
7122	}
7123	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7124	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7125		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7126				  "Front Mic Boost",
7127				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7128		if (err < 0)
7129			return err;
7130	}
7131	return 0;
7132}
7133
7134/* almost identical with ALC880 parser... */
7135static int alc882_parse_auto_config(struct hda_codec *codec)
7136{
7137	struct alc_spec *spec = codec->spec;
7138	int err = alc880_parse_auto_config(codec);
7139
7140	if (err < 0)
7141		return err;
7142	else if (!err)
7143		return 0; /* no config found */
7144
7145	err = alc_auto_add_mic_boost(codec);
7146	if (err < 0)
7147		return err;
7148
7149	/* hack - override the init verbs */
7150	spec->init_verbs[0] = alc882_auto_init_verbs;
7151
7152	return 1; /* config found */
7153}
7154
7155/* additional initialization for auto-configuration model */
7156static void alc882_auto_init(struct hda_codec *codec)
7157{
7158	struct alc_spec *spec = codec->spec;
7159	alc882_auto_init_multi_out(codec);
7160	alc882_auto_init_hp_out(codec);
7161	alc882_auto_init_analog_input(codec);
7162	alc882_auto_init_input_src(codec);
7163	if (spec->unsol_event)
7164		alc_inithook(codec);
7165}
7166
7167static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7168
7169static int patch_alc882(struct hda_codec *codec)
7170{
7171	struct alc_spec *spec;
7172	int err, board_config;
7173
7174	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7175	if (spec == NULL)
7176		return -ENOMEM;
7177
7178	codec->spec = spec;
7179
7180	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7181						  alc882_models,
7182						  alc882_cfg_tbl);
7183
7184	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7185		/* Pick up systems that don't supply PCI SSID */
7186		switch (codec->subsystem_id) {
7187		case 0x106b0c00: /* Mac Pro */
7188			board_config = ALC885_MACPRO;
7189			break;
7190		case 0x106b1000: /* iMac 24 */
7191		case 0x106b2800: /* AppleTV */
7192		case 0x106b3e00: /* iMac 24 Aluminium */
7193			board_config = ALC885_IMAC24;
7194			break;
7195		case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7196		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7197		case 0x106b00a4: /* MacbookPro4,1 */
7198		case 0x106b2c00: /* Macbook Pro rev3 */
7199		case 0x106b3600: /* Macbook 3.1 */
7200		case 0x106b3800: /* MacbookPro4,1 - latter revision */
7201			board_config = ALC885_MBP3;
7202			break;
7203		default:
7204			/* ALC889A is handled better as ALC888-compatible */
7205			if (codec->revision_id == 0x100101 ||
7206			    codec->revision_id == 0x100103) {
7207				alc_free(codec);
7208				return patch_alc883(codec);
7209			}
7210			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7211		       			 "trying auto-probe from BIOS...\n");
7212			board_config = ALC882_AUTO;
7213		}
7214	}
7215
7216	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7217
7218	if (board_config == ALC882_AUTO) {
7219		/* automatic parse from the BIOS config */
7220		err = alc882_parse_auto_config(codec);
7221		if (err < 0) {
7222			alc_free(codec);
7223			return err;
7224		} else if (!err) {
7225			printk(KERN_INFO
7226			       "hda_codec: Cannot set up configuration "
7227			       "from BIOS.  Using base mode...\n");
7228			board_config = ALC882_3ST_DIG;
7229		}
7230	}
7231
7232	err = snd_hda_attach_beep_device(codec, 0x1);
7233	if (err < 0) {
7234		alc_free(codec);
7235		return err;
7236	}
7237
7238	if (board_config != ALC882_AUTO)
7239		setup_preset(spec, &alc882_presets[board_config]);
7240
7241	if (codec->vendor_id == 0x10ec0885) {
7242		spec->stream_name_analog = "ALC885 Analog";
7243		spec->stream_name_digital = "ALC885 Digital";
7244	} else {
7245		spec->stream_name_analog = "ALC882 Analog";
7246		spec->stream_name_digital = "ALC882 Digital";
7247	}
7248
7249	spec->stream_analog_playback = &alc882_pcm_analog_playback;
7250	spec->stream_analog_capture = &alc882_pcm_analog_capture;
7251	/* FIXME: setup DAC5 */
7252	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7253	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7254
7255	spec->stream_digital_playback = &alc882_pcm_digital_playback;
7256	spec->stream_digital_capture = &alc882_pcm_digital_capture;
7257
7258	spec->capture_style = CAPT_MIX; /* matrix-style capture */
7259	if (!spec->adc_nids && spec->input_mux) {
7260		/* check whether NID 0x07 is valid */
7261		unsigned int wcap = get_wcaps(codec, 0x07);
7262		/* get type */
7263		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7264		if (wcap != AC_WID_AUD_IN) {
7265			spec->adc_nids = alc882_adc_nids_alt;
7266			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7267			spec->capsrc_nids = alc882_capsrc_nids_alt;
7268		} else {
7269			spec->adc_nids = alc882_adc_nids;
7270			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7271			spec->capsrc_nids = alc882_capsrc_nids;
7272		}
7273	}
7274	set_capture_mixer(spec);
7275	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7276
7277	spec->vmaster_nid = 0x0c;
7278
7279	codec->patch_ops = alc_patch_ops;
7280	if (board_config == ALC882_AUTO)
7281		spec->init_hook = alc882_auto_init;
7282#ifdef CONFIG_SND_HDA_POWER_SAVE
7283	if (!spec->loopback.amplist)
7284		spec->loopback.amplist = alc882_loopbacks;
7285#endif
7286	codec->proc_widget_hook = print_realtek_coef;
7287
7288	return 0;
7289}
7290
7291/*
7292 * ALC883 support
7293 *
7294 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7295 * configuration.  Each pin widget can choose any input DACs and a mixer.
7296 * Each ADC is connected from a mixer of all inputs.  This makes possible
7297 * 6-channel independent captures.
7298 *
7299 * In addition, an independent DAC for the multi-playback (not used in this
7300 * driver yet).
7301 */
7302#define ALC883_DIGOUT_NID	0x06
7303#define ALC883_DIGIN_NID	0x0a
7304
7305#define ALC1200_DIGOUT_NID	0x10
7306
7307static hda_nid_t alc883_dac_nids[4] = {
7308	/* front, rear, clfe, rear_surr */
7309	0x02, 0x03, 0x04, 0x05
7310};
7311
7312static hda_nid_t alc883_adc_nids[2] = {
7313	/* ADC1-2 */
7314	0x08, 0x09,
7315};
7316
7317static hda_nid_t alc883_adc_nids_alt[1] = {
7318	/* ADC1 */
7319	0x08,
7320};
7321
7322static hda_nid_t alc883_adc_nids_rev[2] = {
7323	/* ADC2-1 */
7324	0x09, 0x08
7325};
7326
7327#define alc889_adc_nids		alc880_adc_nids
7328
7329static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7330
7331static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7332
7333#define alc889_capsrc_nids	alc882_capsrc_nids
7334
7335/* input MUX */
7336/* FIXME: should be a matrix-type input source selection */
7337
7338static struct hda_input_mux alc883_capture_source = {
7339	.num_items = 4,
7340	.items = {
7341		{ "Mic", 0x0 },
7342		{ "Front Mic", 0x1 },
7343		{ "Line", 0x2 },
7344		{ "CD", 0x4 },
7345	},
7346};
7347
7348static struct hda_input_mux alc883_3stack_6ch_intel = {
7349	.num_items = 4,
7350	.items = {
7351		{ "Mic", 0x1 },
7352		{ "Front Mic", 0x0 },
7353		{ "Line", 0x2 },
7354		{ "CD", 0x4 },
7355	},
7356};
7357
7358static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7359	.num_items = 2,
7360	.items = {
7361		{ "Mic", 0x1 },
7362		{ "Line", 0x2 },
7363	},
7364};
7365
7366static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7367	.num_items = 4,
7368	.items = {
7369		{ "Mic", 0x0 },
7370		{ "iMic", 0x1 },
7371		{ "Line", 0x2 },
7372		{ "CD", 0x4 },
7373	},
7374};
7375
7376static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7377	.num_items = 2,
7378	.items = {
7379		{ "Mic", 0x0 },
7380		{ "Int Mic", 0x1 },
7381	},
7382};
7383
7384static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7385	.num_items = 3,
7386	.items = {
7387		{ "Mic", 0x0 },
7388		{ "Front Mic", 0x1 },
7389		{ "Line", 0x4 },
7390	},
7391};
7392
7393static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7394	.num_items = 2,
7395	.items = {
7396		{ "Mic", 0x0 },
7397		{ "Line", 0x2 },
7398	},
7399};
7400
7401/*
7402 * 2ch mode
7403 */
7404static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7405	{ 2, NULL }
7406};
7407
7408/*
7409 * 2ch mode
7410 */
7411static struct hda_verb alc883_3ST_ch2_init[] = {
7412	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7413	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7414	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7415	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7416	{ } /* end */
7417};
7418
7419/*
7420 * 4ch mode
7421 */
7422static struct hda_verb alc883_3ST_ch4_init[] = {
7423	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7424	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7425	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7426	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7427	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7428	{ } /* end */
7429};
7430
7431/*
7432 * 6ch mode
7433 */
7434static struct hda_verb alc883_3ST_ch6_init[] = {
7435	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7436	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7437	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7438	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7439	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7440	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7441	{ } /* end */
7442};
7443
7444static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7445	{ 2, alc883_3ST_ch2_init },
7446	{ 4, alc883_3ST_ch4_init },
7447	{ 6, alc883_3ST_ch6_init },
7448};
7449
7450/*
7451 * 2ch mode
7452 */
7453static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7454	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7455	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7456	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7457	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7458	{ } /* end */
7459};
7460
7461/*
7462 * 4ch mode
7463 */
7464static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7465	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7466	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7467	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7468	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7469	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7470	{ } /* end */
7471};
7472
7473/*
7474 * 6ch mode
7475 */
7476static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7477	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7478	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7479	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7480	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7481	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7482	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7483	{ } /* end */
7484};
7485
7486static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7487	{ 2, alc883_3ST_ch2_intel_init },
7488	{ 4, alc883_3ST_ch4_intel_init },
7489	{ 6, alc883_3ST_ch6_intel_init },
7490};
7491
7492/*
7493 * 6ch mode
7494 */
7495static struct hda_verb alc883_sixstack_ch6_init[] = {
7496	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7497	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7498	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7499	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7500	{ } /* end */
7501};
7502
7503/*
7504 * 8ch mode
7505 */
7506static struct hda_verb alc883_sixstack_ch8_init[] = {
7507	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7508	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7509	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7510	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7511	{ } /* end */
7512};
7513
7514static struct hda_channel_mode alc883_sixstack_modes[2] = {
7515	{ 6, alc883_sixstack_ch6_init },
7516	{ 8, alc883_sixstack_ch8_init },
7517};
7518
7519static struct hda_verb alc883_medion_eapd_verbs[] = {
7520        /* eanable EAPD on medion laptop */
7521	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7522	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7523	{ }
7524};
7525
7526/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7527 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7528 */
7529
7530static struct snd_kcontrol_new alc883_base_mixer[] = {
7531	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7532	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7533	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7534	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7535	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7536	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7537	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7538	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7539	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7540	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7541	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7542	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7543	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7544	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7545	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7546	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7547	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7548	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7549	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7550	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7551	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7552	{ } /* end */
7553};
7554
7555static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7556	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7557	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7558	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7559	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7560	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7561	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7562	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7563	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7564	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7565	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7566	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7567	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7568	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7569	{ } /* end */
7570};
7571
7572static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7573	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7574	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7575	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7576	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7577	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7578	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7579	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7580	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7581	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7582	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7583	{ } /* end */
7584};
7585
7586static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7587	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7588	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7589	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7590	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7591	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7592	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7593	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7594	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7595	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7596	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7597	{ } /* end */
7598};
7599
7600static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7601	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7602	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7603	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7604	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7605	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7606	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7607	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7608	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7609	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7610	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7611	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7612	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7613	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7614	{ } /* end */
7615};
7616
7617static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7618	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7619	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7620	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7621	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7622	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7623	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7624	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7625	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7626	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7627	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7628	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7629	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7630	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7631	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7632	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7633	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7634	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7635	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7636	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7637	{ } /* end */
7638};
7639
7640static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7641	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7642	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7643	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7644	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7645	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7646			      HDA_OUTPUT),
7647	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7648	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7649	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7650	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7651	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7652	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7653	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7654	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7655	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7656	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7657	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7658	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7659	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7660	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7661	{ } /* end */
7662};
7663
7664static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7665	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7666	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7667	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7668	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7669	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7670	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7671	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7672	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7673	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7674	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7675	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7676	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7677	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7678	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7679	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7680	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7681	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7682	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7683	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7684	{ } /* end */
7685};
7686
7687static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7688	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7689	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7690	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7691	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7692	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7693	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7694	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7695	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7696	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7697	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7698	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7699	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7700	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7701	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7702	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7703	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7704	{ } /* end */
7705};
7706
7707static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7708	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7709	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7710	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7711	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7712	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7713	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7714	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7715	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7716	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7717	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7718	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7719	{ } /* end */
7720};
7721
7722static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7723	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7724	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7725	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7726	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7727	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7728	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7729	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7730	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7731	{ } /* end */
7732};
7733
7734static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7735	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7736	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7737	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7738	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7739	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7740	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7741	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7742	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7743	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7744	{ } /* end */
7745};
7746
7747static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7748	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7749	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7750	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7751	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7752	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7753	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7754	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7755	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7756	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7757	{ } /* end */
7758};
7759
7760static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7761	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7762	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7763	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7764	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7765	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7766	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7767	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7768	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7769	{ } /* end */
7770};
7771
7772static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7773	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7774	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7775	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7776	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7777	HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7778						0x0d, 1, 0x0, HDA_OUTPUT),
7779	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7780	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7781	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7782	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7783	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7784	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7785	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7786	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7787	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7788	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7789	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7790	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7791	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7792	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7793	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7794	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7795	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7796	{ } /* end */
7797};
7798
7799static struct hda_bind_ctls alc883_bind_cap_vol = {
7800	.ops = &snd_hda_bind_vol,
7801	.values = {
7802		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7803		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7804		0
7805	},
7806};
7807
7808static struct hda_bind_ctls alc883_bind_cap_switch = {
7809	.ops = &snd_hda_bind_sw,
7810	.values = {
7811		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7812		HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7813		0
7814	},
7815};
7816
7817static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7818	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7819	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7820	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7821	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7822	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7823	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7824	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7825	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7826	{ } /* end */
7827};
7828
7829static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7830	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7831	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7832	{
7833		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7834		/* .name = "Capture Source", */
7835		.name = "Input Source",
7836		.count = 1,
7837		.info = alc_mux_enum_info,
7838		.get = alc_mux_enum_get,
7839		.put = alc_mux_enum_put,
7840	},
7841	{ } /* end */
7842};
7843
7844static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7845	{
7846		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7847		.name = "Channel Mode",
7848		.info = alc_ch_mode_info,
7849		.get = alc_ch_mode_get,
7850		.put = alc_ch_mode_put,
7851	},
7852	{ } /* end */
7853};
7854
7855static struct hda_verb alc883_init_verbs[] = {
7856	/* ADC1: mute amp left and right */
7857	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7858	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7859	/* ADC2: mute amp left and right */
7860	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7861	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7862	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7863	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7864	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7865	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7866	/* Rear mixer */
7867	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7868	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7869	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7870	/* CLFE mixer */
7871	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7872	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7873	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7874	/* Side mixer */
7875	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7876	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7877	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7878
7879	/* mute analog input loopbacks */
7880	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7881	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7882	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7883	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7884	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7885
7886	/* Front Pin: output 0 (0x0c) */
7887	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7888	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7889	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7890	/* Rear Pin: output 1 (0x0d) */
7891	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7892	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7893	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7894	/* CLFE Pin: output 2 (0x0e) */
7895	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7896	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7897	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7898	/* Side Pin: output 3 (0x0f) */
7899	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7900	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7901	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7902	/* Mic (rear) pin: input vref at 80% */
7903	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7904	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7905	/* Front Mic pin: input vref at 80% */
7906	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7907	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7908	/* Line In pin: input */
7909	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7910	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7911	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7912	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7913	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7914	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7915	/* CD pin widget for input */
7916	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7917
7918	/* FIXME: use matrix-type input source selection */
7919	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7920	/* Input mixer2 */
7921	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7922	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7923	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7924	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7925	/* Input mixer3 */
7926	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7927	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7928	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7929	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7930	{ }
7931};
7932
7933/* toggle speaker-output according to the hp-jack state */
7934static void alc883_mitac_hp_automute(struct hda_codec *codec)
7935{
7936	unsigned int present;
7937
7938	present = snd_hda_codec_read(codec, 0x15, 0,
7939				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7940	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7941				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7942	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7943				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7944}
7945
7946/* auto-toggle front mic */
7947/*
7948static void alc883_mitac_mic_automute(struct hda_codec *codec)
7949{
7950	unsigned int present;
7951	unsigned char bits;
7952
7953	present = snd_hda_codec_read(codec, 0x18, 0,
7954				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7955	bits = present ? HDA_AMP_MUTE : 0;
7956	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7957}
7958*/
7959
7960static void alc883_mitac_automute(struct hda_codec *codec)
7961{
7962	alc883_mitac_hp_automute(codec);
7963	/* alc883_mitac_mic_automute(codec); */
7964}
7965
7966static void alc883_mitac_unsol_event(struct hda_codec *codec,
7967					   unsigned int res)
7968{
7969	switch (res >> 26) {
7970	case ALC880_HP_EVENT:
7971		alc883_mitac_hp_automute(codec);
7972		break;
7973	case ALC880_MIC_EVENT:
7974		/* alc883_mitac_mic_automute(codec); */
7975		break;
7976	}
7977}
7978
7979static struct hda_verb alc883_mitac_verbs[] = {
7980	/* HP */
7981	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7982	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7983	/* Subwoofer */
7984	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7985	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7986
7987	/* enable unsolicited event */
7988	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7989	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7990
7991	{ } /* end */
7992};
7993
7994static struct hda_verb alc883_clevo_m720_verbs[] = {
7995	/* HP */
7996	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7997	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7998	/* Int speaker */
7999	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8000	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8001
8002	/* enable unsolicited event */
8003	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8004	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8005
8006	{ } /* end */
8007};
8008
8009static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8010	/* HP */
8011	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8012	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8013	/* Subwoofer */
8014	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8015	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8016
8017	/* enable unsolicited event */
8018	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8019
8020	{ } /* end */
8021};
8022
8023static struct hda_verb alc883_tagra_verbs[] = {
8024	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8026
8027	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8028	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8029
8030	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8031	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8032	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8033
8034	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8035	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8036	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8037	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8038
8039	{ } /* end */
8040};
8041
8042static struct hda_verb alc883_lenovo_101e_verbs[] = {
8043	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8044	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8045        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8046	{ } /* end */
8047};
8048
8049static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8050        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8051	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8052        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8053        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8054	{ } /* end */
8055};
8056
8057static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8058	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8059	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8060	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8061	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8062	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
8063	{ } /* end */
8064};
8065
8066static struct hda_verb alc883_haier_w66_verbs[] = {
8067	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8068	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8069
8070	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8071
8072	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8073	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8074	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8075	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8076	{ } /* end */
8077};
8078
8079static struct hda_verb alc888_lenovo_sky_verbs[] = {
8080	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8081	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8082	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8083	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8084	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8085	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8086	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8087	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8088	{ } /* end */
8089};
8090
8091static struct hda_verb alc888_6st_dell_verbs[] = {
8092	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8093	{ }
8094};
8095
8096static void alc888_3st_hp_front_automute(struct hda_codec *codec)
8097{
8098	unsigned int present, bits;
8099
8100	present = snd_hda_codec_read(codec, 0x1b, 0,
8101			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8102	bits = present ? HDA_AMP_MUTE : 0;
8103	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8104				 HDA_AMP_MUTE, bits);
8105	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8106				 HDA_AMP_MUTE, bits);
8107	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
8108				 HDA_AMP_MUTE, bits);
8109}
8110
8111static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
8112				      unsigned int res)
8113{
8114	switch (res >> 26) {
8115	case ALC880_HP_EVENT:
8116		alc888_3st_hp_front_automute(codec);
8117		break;
8118	}
8119}
8120
8121static struct hda_verb alc888_3st_hp_verbs[] = {
8122	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
8123	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
8124	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
8125	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8126	{ } /* end */
8127};
8128
8129/*
8130 * 2ch mode
8131 */
8132static struct hda_verb alc888_3st_hp_2ch_init[] = {
8133	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8134	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8135	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8137	{ } /* end */
8138};
8139
8140/*
8141 * 4ch mode
8142 */
8143static struct hda_verb alc888_3st_hp_4ch_init[] = {
8144	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8145	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8146	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8147	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8148	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8149	{ } /* end */
8150};
8151
8152/*
8153 * 6ch mode
8154 */
8155static struct hda_verb alc888_3st_hp_6ch_init[] = {
8156	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8157	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8158	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8159	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8160	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8161	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8162	{ } /* end */
8163};
8164
8165static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8166	{ 2, alc888_3st_hp_2ch_init },
8167	{ 4, alc888_3st_hp_4ch_init },
8168	{ 6, alc888_3st_hp_6ch_init },
8169};
8170
8171/* toggle front-jack and RCA according to the hp-jack state */
8172static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8173{
8174 	unsigned int present;
8175
8176 	present = snd_hda_codec_read(codec, 0x1b, 0,
8177				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8178	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8179				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8180	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8181				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8182}
8183
8184/* toggle RCA according to the front-jack state */
8185static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8186{
8187 	unsigned int present;
8188
8189 	present = snd_hda_codec_read(codec, 0x14, 0,
8190				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8191	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8192				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8193}
8194
8195static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8196					     unsigned int res)
8197{
8198	if ((res >> 26) == ALC880_HP_EVENT)
8199		alc888_lenovo_ms7195_front_automute(codec);
8200	if ((res >> 26) == ALC880_FRONT_EVENT)
8201		alc888_lenovo_ms7195_rca_automute(codec);
8202}
8203
8204static struct hda_verb alc883_medion_md2_verbs[] = {
8205	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8206	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8207
8208	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8209
8210	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8211	{ } /* end */
8212};
8213
8214/* toggle speaker-output according to the hp-jack state */
8215static void alc883_medion_md2_automute(struct hda_codec *codec)
8216{
8217 	unsigned int present;
8218
8219 	present = snd_hda_codec_read(codec, 0x14, 0,
8220				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8221	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8222				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8223}
8224
8225static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8226					  unsigned int res)
8227{
8228	if ((res >> 26) == ALC880_HP_EVENT)
8229		alc883_medion_md2_automute(codec);
8230}
8231
8232/* toggle speaker-output according to the hp-jack state */
8233static void alc883_tagra_automute(struct hda_codec *codec)
8234{
8235 	unsigned int present;
8236	unsigned char bits;
8237
8238 	present = snd_hda_codec_read(codec, 0x14, 0,
8239				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8240	bits = present ? HDA_AMP_MUTE : 0;
8241	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8242				 HDA_AMP_MUTE, bits);
8243	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8244				  present ? 1 : 3);
8245}
8246
8247static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8248{
8249	if ((res >> 26) == ALC880_HP_EVENT)
8250		alc883_tagra_automute(codec);
8251}
8252
8253/* toggle speaker-output according to the hp-jack state */
8254static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
8255{
8256	unsigned int present;
8257	unsigned char bits;
8258
8259	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8260		& AC_PINSENSE_PRESENCE;
8261	bits = present ? HDA_AMP_MUTE : 0;
8262	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8263				 HDA_AMP_MUTE, bits);
8264}
8265
8266static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8267{
8268	unsigned int present;
8269
8270	present = snd_hda_codec_read(codec, 0x18, 0,
8271				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8272	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8273				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8274}
8275
8276static void alc883_clevo_m720_automute(struct hda_codec *codec)
8277{
8278	alc883_clevo_m720_hp_automute(codec);
8279	alc883_clevo_m720_mic_automute(codec);
8280}
8281
8282static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8283					   unsigned int res)
8284{
8285	switch (res >> 26) {
8286	case ALC880_HP_EVENT:
8287		alc883_clevo_m720_hp_automute(codec);
8288		break;
8289	case ALC880_MIC_EVENT:
8290		alc883_clevo_m720_mic_automute(codec);
8291		break;
8292	}
8293}
8294
8295/* toggle speaker-output according to the hp-jack state */
8296static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8297{
8298 	unsigned int present;
8299	unsigned char bits;
8300
8301 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8302		& AC_PINSENSE_PRESENCE;
8303	bits = present ? HDA_AMP_MUTE : 0;
8304	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8305				 HDA_AMP_MUTE, bits);
8306}
8307
8308static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8309						  unsigned int res)
8310{
8311	if ((res >> 26) == ALC880_HP_EVENT)
8312		alc883_2ch_fujitsu_pi2515_automute(codec);
8313}
8314
8315static void alc883_haier_w66_automute(struct hda_codec *codec)
8316{
8317	unsigned int present;
8318	unsigned char bits;
8319
8320	present = snd_hda_codec_read(codec, 0x1b, 0,
8321				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8322	bits = present ? 0x80 : 0;
8323	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8324				 0x80, bits);
8325}
8326
8327static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8328					 unsigned int res)
8329{
8330	if ((res >> 26) == ALC880_HP_EVENT)
8331		alc883_haier_w66_automute(codec);
8332}
8333
8334static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8335{
8336 	unsigned int present;
8337	unsigned char bits;
8338
8339 	present = snd_hda_codec_read(codec, 0x14, 0,
8340				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8341	bits = present ? HDA_AMP_MUTE : 0;
8342	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8343				 HDA_AMP_MUTE, bits);
8344}
8345
8346static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8347{
8348 	unsigned int present;
8349	unsigned char bits;
8350
8351 	present = snd_hda_codec_read(codec, 0x1b, 0,
8352				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8353	bits = present ? HDA_AMP_MUTE : 0;
8354	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8355				 HDA_AMP_MUTE, bits);
8356	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8357				 HDA_AMP_MUTE, bits);
8358}
8359
8360static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8361					   unsigned int res)
8362{
8363	if ((res >> 26) == ALC880_HP_EVENT)
8364		alc883_lenovo_101e_all_automute(codec);
8365	if ((res >> 26) == ALC880_FRONT_EVENT)
8366		alc883_lenovo_101e_ispeaker_automute(codec);
8367}
8368
8369/* toggle speaker-output according to the hp-jack state */
8370static void alc883_acer_aspire_automute(struct hda_codec *codec)
8371{
8372 	unsigned int present;
8373
8374 	present = snd_hda_codec_read(codec, 0x14, 0,
8375				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8376	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8377				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8378	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8379				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8380}
8381
8382static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8383					   unsigned int res)
8384{
8385	if ((res >> 26) == ALC880_HP_EVENT)
8386		alc883_acer_aspire_automute(codec);
8387}
8388
8389static struct hda_verb alc883_acer_eapd_verbs[] = {
8390	/* HP Pin: output 0 (0x0c) */
8391	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8392	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8394	/* Front Pin: output 0 (0x0c) */
8395	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8396	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8397	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8398	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8399        /* eanable EAPD on medion laptop */
8400	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8401	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8402	/* enable unsolicited event */
8403	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8404	{ }
8405};
8406
8407static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8408{
8409 	unsigned int present;
8410
8411 	present = snd_hda_codec_read(codec, 0x1b, 0,
8412				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8413	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8414				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8415	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8416				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8417	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8418				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8419	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8420				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8421}
8422
8423static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8424					     unsigned int res)
8425{
8426	switch (res >> 26) {
8427	case ALC880_HP_EVENT:
8428		/* printk(KERN_DEBUG "hp_event\n"); */
8429		alc888_6st_dell_front_automute(codec);
8430		break;
8431	}
8432}
8433
8434static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8435{
8436	unsigned int mute;
8437	unsigned int present;
8438
8439	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8440	present = snd_hda_codec_read(codec, 0x1b, 0,
8441				     AC_VERB_GET_PIN_SENSE, 0);
8442	present = (present & 0x80000000) != 0;
8443	if (present) {
8444		/* mute internal speaker */
8445		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8446					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8447		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8448					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8449		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8450					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8451		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8452					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8453		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8454					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8455	} else {
8456		/* unmute internal speaker if necessary */
8457		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8458		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8459					 HDA_AMP_MUTE, mute);
8460		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8461					 HDA_AMP_MUTE, mute);
8462		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8463					 HDA_AMP_MUTE, mute);
8464		snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8465					 HDA_AMP_MUTE, mute);
8466		snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8467					 HDA_AMP_MUTE, mute);
8468	}
8469}
8470
8471static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8472					     unsigned int res)
8473{
8474	if ((res >> 26) == ALC880_HP_EVENT)
8475		alc888_lenovo_sky_front_automute(codec);
8476}
8477
8478/*
8479 * generic initialization of ADC, input mixers and output mixers
8480 */
8481static struct hda_verb alc883_auto_init_verbs[] = {
8482	/*
8483	 * Unmute ADC0-2 and set the default input to mic-in
8484	 */
8485	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8486	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8487	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8488	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8489
8490	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8491	 * mixer widget
8492	 * Note: PASD motherboards uses the Line In 2 as the input for
8493	 * front panel mic (mic 2)
8494	 */
8495	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8496	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8497	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8498	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8499	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8500	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8501
8502	/*
8503	 * Set up output mixers (0x0c - 0x0f)
8504	 */
8505	/* set vol=0 to output mixers */
8506	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8510	/* set up input amps for analog loopback */
8511	/* Amp Indices: DAC = 0, mixer = 1 */
8512	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8513	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8514	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8515	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8516	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8517	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8518	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8519	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8520	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8522
8523	/* FIXME: use matrix-type input source selection */
8524	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8525	/* Input mixer1 */
8526	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8527	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8528	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8529	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8530	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8531	/* Input mixer2 */
8532	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8533	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8534	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8535	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8536	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8537
8538	{ }
8539};
8540
8541static struct hda_verb alc888_asus_m90v_verbs[] = {
8542	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8543	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8545	/* enable unsolicited event */
8546	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8547	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8548	{ } /* end */
8549};
8550
8551static void alc883_nb_mic_automute(struct hda_codec *codec)
8552{
8553	unsigned int present;
8554
8555	present = snd_hda_codec_read(codec, 0x18, 0,
8556				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8557	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8558			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8559	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8560			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8561}
8562
8563static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8564{
8565	unsigned int present;
8566	unsigned char bits;
8567
8568	present = snd_hda_codec_read(codec, 0x1b, 0,
8569				     AC_VERB_GET_PIN_SENSE, 0)
8570		& AC_PINSENSE_PRESENCE;
8571	bits = present ? 0 : PIN_OUT;
8572	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8573			    bits);
8574	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8575			    bits);
8576	snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8577			    bits);
8578}
8579
8580static void alc883_mode2_unsol_event(struct hda_codec *codec,
8581					   unsigned int res)
8582{
8583	switch (res >> 26) {
8584	case ALC880_HP_EVENT:
8585		alc883_M90V_speaker_automute(codec);
8586		break;
8587	case ALC880_MIC_EVENT:
8588		alc883_nb_mic_automute(codec);
8589		break;
8590	}
8591}
8592
8593static void alc883_mode2_inithook(struct hda_codec *codec)
8594{
8595	alc883_M90V_speaker_automute(codec);
8596	alc883_nb_mic_automute(codec);
8597}
8598
8599static struct hda_verb alc888_asus_eee1601_verbs[] = {
8600	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8601	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8602	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8603	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8604	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8605	{0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8606	{0x20, AC_VERB_SET_PROC_COEF,  0x0838},
8607	/* enable unsolicited event */
8608	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8609	{ } /* end */
8610};
8611
8612static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8613{
8614	unsigned int present;
8615	unsigned char bits;
8616
8617	present = snd_hda_codec_read(codec, 0x14, 0,
8618				     AC_VERB_GET_PIN_SENSE, 0)
8619		& AC_PINSENSE_PRESENCE;
8620	bits = present ? 0 : PIN_OUT;
8621	snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8622			    bits);
8623}
8624
8625static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8626					   unsigned int res)
8627{
8628	switch (res >> 26) {
8629	case ALC880_HP_EVENT:
8630		alc883_eee1601_speaker_automute(codec);
8631		break;
8632	}
8633}
8634
8635static void alc883_eee1601_inithook(struct hda_codec *codec)
8636{
8637	alc883_eee1601_speaker_automute(codec);
8638}
8639
8640#ifdef CONFIG_SND_HDA_POWER_SAVE
8641#define alc883_loopbacks	alc880_loopbacks
8642#endif
8643
8644/* pcm configuration: identiacal with ALC880 */
8645#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
8646#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
8647#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
8648#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
8649#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
8650
8651/*
8652 * configuration and preset
8653 */
8654static const char *alc883_models[ALC883_MODEL_LAST] = {
8655	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
8656	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
8657	[ALC883_3ST_6ch]	= "3stack-6ch",
8658	[ALC883_6ST_DIG]	= "6stack-dig",
8659	[ALC883_TARGA_DIG]	= "targa-dig",
8660	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
8661	[ALC883_ACER]		= "acer",
8662	[ALC883_ACER_ASPIRE]	= "acer-aspire",
8663	[ALC888_ACER_ASPIRE_4930G]	= "acer-aspire-4930g",
8664	[ALC883_MEDION]		= "medion",
8665	[ALC883_MEDION_MD2]	= "medion-md2",
8666	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
8667	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8668	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
8669	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8670	[ALC888_LENOVO_SKY] = "lenovo-sky",
8671	[ALC883_HAIER_W66] 	= "haier-w66",
8672	[ALC888_3ST_HP]		= "3stack-hp",
8673	[ALC888_6ST_DELL]	= "6stack-dell",
8674	[ALC883_MITAC]		= "mitac",
8675	[ALC883_CLEVO_M720]	= "clevo-m720",
8676	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8677	[ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8678	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
8679	[ALC1200_ASUS_P5Q]	= "asus-p5q",
8680	[ALC883_AUTO]		= "auto",
8681};
8682
8683static struct snd_pci_quirk alc883_cfg_tbl[] = {
8684	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8685	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8686	SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8687	SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8688	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8689	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8690	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8691	SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8692		ALC888_ACER_ASPIRE_4930G),
8693	SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8694		ALC888_ACER_ASPIRE_4930G),
8695	SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8696	SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8697	SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8698		ALC888_ACER_ASPIRE_4930G),
8699	SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8700		ALC888_ACER_ASPIRE_4930G),
8701	/* default Acer */
8702	SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
8703	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8704	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8705	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8706	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8707	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8708	SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8709	SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8710	SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8711	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8712	SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8713	SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8714	SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8715	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8716	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8717	SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8718	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8719	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8720	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8721	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8722	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8723	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8724	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8725	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8726	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8727	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8728	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8729	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8730	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8731	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8732	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8733	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8734	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8735	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8736	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8737	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8738	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8739	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8740	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8741	SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8742	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8743	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8744	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8745	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8746	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8747	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8748	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8749	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8750	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8751	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8752	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8753		      ALC883_FUJITSU_PI2515),
8754	SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8755		ALC888_FUJITSU_XA3530),
8756	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8757	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8758	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8759	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8760	SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8761	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8762	SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8763	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8764	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8765	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8766	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8767	SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8768	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8769	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8770	{}
8771};
8772
8773static hda_nid_t alc883_slave_dig_outs[] = {
8774	ALC1200_DIGOUT_NID, 0,
8775};
8776
8777static hda_nid_t alc1200_slave_dig_outs[] = {
8778	ALC883_DIGOUT_NID, 0,
8779};
8780
8781static struct alc_config_preset alc883_presets[] = {
8782	[ALC883_3ST_2ch_DIG] = {
8783		.mixers = { alc883_3ST_2ch_mixer },
8784		.init_verbs = { alc883_init_verbs },
8785		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8786		.dac_nids = alc883_dac_nids,
8787		.dig_out_nid = ALC883_DIGOUT_NID,
8788		.dig_in_nid = ALC883_DIGIN_NID,
8789		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8790		.channel_mode = alc883_3ST_2ch_modes,
8791		.input_mux = &alc883_capture_source,
8792	},
8793	[ALC883_3ST_6ch_DIG] = {
8794		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8795		.init_verbs = { alc883_init_verbs },
8796		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8797		.dac_nids = alc883_dac_nids,
8798		.dig_out_nid = ALC883_DIGOUT_NID,
8799		.dig_in_nid = ALC883_DIGIN_NID,
8800		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8801		.channel_mode = alc883_3ST_6ch_modes,
8802		.need_dac_fix = 1,
8803		.input_mux = &alc883_capture_source,
8804	},
8805	[ALC883_3ST_6ch] = {
8806		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8807		.init_verbs = { alc883_init_verbs },
8808		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8809		.dac_nids = alc883_dac_nids,
8810		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8811		.channel_mode = alc883_3ST_6ch_modes,
8812		.need_dac_fix = 1,
8813		.input_mux = &alc883_capture_source,
8814	},
8815	[ALC883_3ST_6ch_INTEL] = {
8816		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8817		.init_verbs = { alc883_init_verbs },
8818		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8819		.dac_nids = alc883_dac_nids,
8820		.dig_out_nid = ALC883_DIGOUT_NID,
8821		.dig_in_nid = ALC883_DIGIN_NID,
8822		.slave_dig_outs = alc883_slave_dig_outs,
8823		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8824		.channel_mode = alc883_3ST_6ch_intel_modes,
8825		.need_dac_fix = 1,
8826		.input_mux = &alc883_3stack_6ch_intel,
8827	},
8828	[ALC883_6ST_DIG] = {
8829		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8830		.init_verbs = { alc883_init_verbs },
8831		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8832		.dac_nids = alc883_dac_nids,
8833		.dig_out_nid = ALC883_DIGOUT_NID,
8834		.dig_in_nid = ALC883_DIGIN_NID,
8835		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8836		.channel_mode = alc883_sixstack_modes,
8837		.input_mux = &alc883_capture_source,
8838	},
8839	[ALC883_TARGA_DIG] = {
8840		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8841		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8842		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8843		.dac_nids = alc883_dac_nids,
8844		.dig_out_nid = ALC883_DIGOUT_NID,
8845		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8846		.channel_mode = alc883_3ST_6ch_modes,
8847		.need_dac_fix = 1,
8848		.input_mux = &alc883_capture_source,
8849		.unsol_event = alc883_tagra_unsol_event,
8850		.init_hook = alc883_tagra_automute,
8851	},
8852	[ALC883_TARGA_2ch_DIG] = {
8853		.mixers = { alc883_tagra_2ch_mixer},
8854		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8855		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8856		.dac_nids = alc883_dac_nids,
8857		.adc_nids = alc883_adc_nids_alt,
8858		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8859		.dig_out_nid = ALC883_DIGOUT_NID,
8860		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8861		.channel_mode = alc883_3ST_2ch_modes,
8862		.input_mux = &alc883_capture_source,
8863		.unsol_event = alc883_tagra_unsol_event,
8864		.init_hook = alc883_tagra_automute,
8865	},
8866	[ALC883_ACER] = {
8867		.mixers = { alc883_base_mixer },
8868		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8869		 * and the headphone jack.  Turn this on and rely on the
8870		 * standard mute methods whenever the user wants to turn
8871		 * these outputs off.
8872		 */
8873		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8874		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8875		.dac_nids = alc883_dac_nids,
8876		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8877		.channel_mode = alc883_3ST_2ch_modes,
8878		.input_mux = &alc883_capture_source,
8879	},
8880	[ALC883_ACER_ASPIRE] = {
8881		.mixers = { alc883_acer_aspire_mixer },
8882		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8883		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8884		.dac_nids = alc883_dac_nids,
8885		.dig_out_nid = ALC883_DIGOUT_NID,
8886		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8887		.channel_mode = alc883_3ST_2ch_modes,
8888		.input_mux = &alc883_capture_source,
8889		.unsol_event = alc883_acer_aspire_unsol_event,
8890		.init_hook = alc883_acer_aspire_automute,
8891	},
8892	[ALC888_ACER_ASPIRE_4930G] = {
8893		.mixers = { alc888_base_mixer,
8894				alc883_chmode_mixer },
8895		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8896				alc888_acer_aspire_4930g_verbs },
8897		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8898		.dac_nids = alc883_dac_nids,
8899		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8900		.adc_nids = alc883_adc_nids_rev,
8901		.capsrc_nids = alc883_capsrc_nids_rev,
8902		.dig_out_nid = ALC883_DIGOUT_NID,
8903		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8904		.channel_mode = alc883_3ST_6ch_modes,
8905		.need_dac_fix = 1,
8906		.num_mux_defs =
8907			ARRAY_SIZE(alc888_2_capture_sources),
8908		.input_mux = alc888_2_capture_sources,
8909		.unsol_event = alc888_acer_aspire_4930g_unsol_event,
8910		.init_hook = alc888_acer_aspire_4930g_automute,
8911	},
8912	[ALC883_MEDION] = {
8913		.mixers = { alc883_fivestack_mixer,
8914			    alc883_chmode_mixer },
8915		.init_verbs = { alc883_init_verbs,
8916				alc883_medion_eapd_verbs },
8917		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8918		.dac_nids = alc883_dac_nids,
8919		.adc_nids = alc883_adc_nids_alt,
8920		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8921		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8922		.channel_mode = alc883_sixstack_modes,
8923		.input_mux = &alc883_capture_source,
8924	},
8925	[ALC883_MEDION_MD2] = {
8926		.mixers = { alc883_medion_md2_mixer},
8927		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8928		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8929		.dac_nids = alc883_dac_nids,
8930		.dig_out_nid = ALC883_DIGOUT_NID,
8931		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8932		.channel_mode = alc883_3ST_2ch_modes,
8933		.input_mux = &alc883_capture_source,
8934		.unsol_event = alc883_medion_md2_unsol_event,
8935		.init_hook = alc883_medion_md2_automute,
8936	},
8937	[ALC883_LAPTOP_EAPD] = {
8938		.mixers = { alc883_base_mixer },
8939		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8940		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8941		.dac_nids = alc883_dac_nids,
8942		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8943		.channel_mode = alc883_3ST_2ch_modes,
8944		.input_mux = &alc883_capture_source,
8945	},
8946	[ALC883_CLEVO_M720] = {
8947		.mixers = { alc883_clevo_m720_mixer },
8948		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8949		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8950		.dac_nids = alc883_dac_nids,
8951		.dig_out_nid = ALC883_DIGOUT_NID,
8952		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8953		.channel_mode = alc883_3ST_2ch_modes,
8954		.input_mux = &alc883_capture_source,
8955		.unsol_event = alc883_clevo_m720_unsol_event,
8956		.init_hook = alc883_clevo_m720_automute,
8957	},
8958	[ALC883_LENOVO_101E_2ch] = {
8959		.mixers = { alc883_lenovo_101e_2ch_mixer},
8960		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8961		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8962		.dac_nids = alc883_dac_nids,
8963		.adc_nids = alc883_adc_nids_alt,
8964		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8965		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8966		.channel_mode = alc883_3ST_2ch_modes,
8967		.input_mux = &alc883_lenovo_101e_capture_source,
8968		.unsol_event = alc883_lenovo_101e_unsol_event,
8969		.init_hook = alc883_lenovo_101e_all_automute,
8970	},
8971	[ALC883_LENOVO_NB0763] = {
8972		.mixers = { alc883_lenovo_nb0763_mixer },
8973		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8974		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8975		.dac_nids = alc883_dac_nids,
8976		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8977		.channel_mode = alc883_3ST_2ch_modes,
8978		.need_dac_fix = 1,
8979		.input_mux = &alc883_lenovo_nb0763_capture_source,
8980		.unsol_event = alc883_medion_md2_unsol_event,
8981		.init_hook = alc883_medion_md2_automute,
8982	},
8983	[ALC888_LENOVO_MS7195_DIG] = {
8984		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8985		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8986		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8987		.dac_nids = alc883_dac_nids,
8988		.dig_out_nid = ALC883_DIGOUT_NID,
8989		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8990		.channel_mode = alc883_3ST_6ch_modes,
8991		.need_dac_fix = 1,
8992		.input_mux = &alc883_capture_source,
8993		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8994		.init_hook = alc888_lenovo_ms7195_front_automute,
8995	},
8996	[ALC883_HAIER_W66] = {
8997		.mixers = { alc883_tagra_2ch_mixer},
8998		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8999		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9000		.dac_nids = alc883_dac_nids,
9001		.dig_out_nid = ALC883_DIGOUT_NID,
9002		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9003		.channel_mode = alc883_3ST_2ch_modes,
9004		.input_mux = &alc883_capture_source,
9005		.unsol_event = alc883_haier_w66_unsol_event,
9006		.init_hook = alc883_haier_w66_automute,
9007	},
9008	[ALC888_3ST_HP] = {
9009		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9010		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9011		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9012		.dac_nids = alc883_dac_nids,
9013		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9014		.channel_mode = alc888_3st_hp_modes,
9015		.need_dac_fix = 1,
9016		.input_mux = &alc883_capture_source,
9017		.unsol_event = alc888_3st_hp_unsol_event,
9018		.init_hook = alc888_3st_hp_front_automute,
9019	},
9020	[ALC888_6ST_DELL] = {
9021		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
9022		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9023		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9024		.dac_nids = alc883_dac_nids,
9025		.dig_out_nid = ALC883_DIGOUT_NID,
9026		.dig_in_nid = ALC883_DIGIN_NID,
9027		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9028		.channel_mode = alc883_sixstack_modes,
9029		.input_mux = &alc883_capture_source,
9030		.unsol_event = alc888_6st_dell_unsol_event,
9031		.init_hook = alc888_6st_dell_front_automute,
9032	},
9033	[ALC883_MITAC] = {
9034		.mixers = { alc883_mitac_mixer },
9035		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9036		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9037		.dac_nids = alc883_dac_nids,
9038		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9039		.channel_mode = alc883_3ST_2ch_modes,
9040		.input_mux = &alc883_capture_source,
9041		.unsol_event = alc883_mitac_unsol_event,
9042		.init_hook = alc883_mitac_automute,
9043	},
9044	[ALC883_FUJITSU_PI2515] = {
9045		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9046		.init_verbs = { alc883_init_verbs,
9047				alc883_2ch_fujitsu_pi2515_verbs},
9048		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9049		.dac_nids = alc883_dac_nids,
9050		.dig_out_nid = ALC883_DIGOUT_NID,
9051		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9052		.channel_mode = alc883_3ST_2ch_modes,
9053		.input_mux = &alc883_fujitsu_pi2515_capture_source,
9054		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
9055		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
9056	},
9057	[ALC888_FUJITSU_XA3530] = {
9058		.mixers = { alc888_base_mixer, alc883_chmode_mixer },
9059		.init_verbs = { alc883_init_verbs,
9060			alc888_fujitsu_xa3530_verbs },
9061		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9062		.dac_nids = alc883_dac_nids,
9063		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9064		.adc_nids = alc883_adc_nids_rev,
9065		.capsrc_nids = alc883_capsrc_nids_rev,
9066		.dig_out_nid = ALC883_DIGOUT_NID,
9067		.num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9068		.channel_mode = alc888_4ST_8ch_intel_modes,
9069		.num_mux_defs =
9070			ARRAY_SIZE(alc888_2_capture_sources),
9071		.input_mux = alc888_2_capture_sources,
9072		.unsol_event = alc888_fujitsu_xa3530_unsol_event,
9073		.init_hook = alc888_fujitsu_xa3530_automute,
9074	},
9075	[ALC888_LENOVO_SKY] = {
9076		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9077		.init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9078		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9079		.dac_nids = alc883_dac_nids,
9080		.dig_out_nid = ALC883_DIGOUT_NID,
9081		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9082		.channel_mode = alc883_sixstack_modes,
9083		.need_dac_fix = 1,
9084		.input_mux = &alc883_lenovo_sky_capture_source,
9085		.unsol_event = alc883_lenovo_sky_unsol_event,
9086		.init_hook = alc888_lenovo_sky_front_automute,
9087	},
9088	[ALC888_ASUS_M90V] = {
9089		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9090		.init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9091		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9092		.dac_nids = alc883_dac_nids,
9093		.dig_out_nid = ALC883_DIGOUT_NID,
9094		.dig_in_nid = ALC883_DIGIN_NID,
9095		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9096		.channel_mode = alc883_3ST_6ch_modes,
9097		.need_dac_fix = 1,
9098		.input_mux = &alc883_fujitsu_pi2515_capture_source,
9099		.unsol_event = alc883_mode2_unsol_event,
9100		.init_hook = alc883_mode2_inithook,
9101	},
9102	[ALC888_ASUS_EEE1601] = {
9103		.mixers = { alc883_asus_eee1601_mixer },
9104		.cap_mixer = alc883_asus_eee1601_cap_mixer,
9105		.init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9106		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9107		.dac_nids = alc883_dac_nids,
9108		.dig_out_nid = ALC883_DIGOUT_NID,
9109		.dig_in_nid = ALC883_DIGIN_NID,
9110		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9111		.channel_mode = alc883_3ST_2ch_modes,
9112		.need_dac_fix = 1,
9113		.input_mux = &alc883_asus_eee1601_capture_source,
9114		.unsol_event = alc883_eee1601_unsol_event,
9115		.init_hook = alc883_eee1601_inithook,
9116	},
9117	[ALC1200_ASUS_P5Q] = {
9118		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
9119		.init_verbs = { alc883_init_verbs },
9120		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
9121		.dac_nids = alc883_dac_nids,
9122		.dig_out_nid = ALC1200_DIGOUT_NID,
9123		.dig_in_nid = ALC883_DIGIN_NID,
9124		.slave_dig_outs = alc1200_slave_dig_outs,
9125		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9126		.channel_mode = alc883_sixstack_modes,
9127		.input_mux = &alc883_capture_source,
9128	},
9129};
9130
9131
9132/*
9133 * BIOS auto configuration
9134 */
9135static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9136					      hda_nid_t nid, int pin_type,
9137					      int dac_idx)
9138{
9139	/* set as output */
9140	struct alc_spec *spec = codec->spec;
9141	int idx;
9142
9143	alc_set_pin_output(codec, nid, pin_type);
9144	if (spec->multiout.dac_nids[dac_idx] == 0x25)
9145		idx = 4;
9146	else
9147		idx = spec->multiout.dac_nids[dac_idx] - 2;
9148	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9149
9150}
9151
9152static void alc883_auto_init_multi_out(struct hda_codec *codec)
9153{
9154	struct alc_spec *spec = codec->spec;
9155	int i;
9156
9157	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9158	for (i = 0; i <= HDA_SIDE; i++) {
9159		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9160		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9161		if (nid)
9162			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9163							  i);
9164	}
9165}
9166
9167static void alc883_auto_init_hp_out(struct hda_codec *codec)
9168{
9169	struct alc_spec *spec = codec->spec;
9170	hda_nid_t pin;
9171
9172	pin = spec->autocfg.hp_pins[0];
9173	if (pin) /* connect to front */
9174		/* use dac 0 */
9175		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9176	pin = spec->autocfg.speaker_pins[0];
9177	if (pin)
9178		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9179}
9180
9181#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
9182#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
9183
9184static void alc883_auto_init_analog_input(struct hda_codec *codec)
9185{
9186	struct alc_spec *spec = codec->spec;
9187	int i;
9188
9189	for (i = 0; i < AUTO_PIN_LAST; i++) {
9190		hda_nid_t nid = spec->autocfg.input_pins[i];
9191		if (alc883_is_input_pin(nid)) {
9192			alc_set_input_pin(codec, nid, i);
9193			if (nid != ALC883_PIN_CD_NID &&
9194			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9195				snd_hda_codec_write(codec, nid, 0,
9196						    AC_VERB_SET_AMP_GAIN_MUTE,
9197						    AMP_OUT_MUTE);
9198		}
9199	}
9200}
9201
9202#define alc883_auto_init_input_src	alc882_auto_init_input_src
9203
9204/* almost identical with ALC880 parser... */
9205static int alc883_parse_auto_config(struct hda_codec *codec)
9206{
9207	struct alc_spec *spec = codec->spec;
9208	int err = alc880_parse_auto_config(codec);
9209	struct auto_pin_cfg *cfg = &spec->autocfg;
9210	int i;
9211
9212	if (err < 0)
9213		return err;
9214	else if (!err)
9215		return 0; /* no config found */
9216
9217	err = alc_auto_add_mic_boost(codec);
9218	if (err < 0)
9219		return err;
9220
9221	/* hack - override the init verbs */
9222	spec->init_verbs[0] = alc883_auto_init_verbs;
9223
9224	/* setup input_mux for ALC889 */
9225	if (codec->vendor_id == 0x10ec0889) {
9226		/* digital-mic input pin is excluded in alc880_auto_create..()
9227		 * because it's under 0x18
9228		 */
9229		if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9230		    cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9231			struct hda_input_mux *imux = &spec->private_imux[0];
9232			for (i = 1; i < 3; i++)
9233				memcpy(&spec->private_imux[i],
9234				       &spec->private_imux[0],
9235				       sizeof(spec->private_imux[0]));
9236			imux->items[imux->num_items].label = "Int DMic";
9237			imux->items[imux->num_items].index = 0x0b;
9238			imux->num_items++;
9239			spec->num_mux_defs = 3;
9240			spec->input_mux = spec->private_imux;
9241		}
9242	}
9243
9244	return 1; /* config found */
9245}
9246
9247/* additional initialization for auto-configuration model */
9248static void alc883_auto_init(struct hda_codec *codec)
9249{
9250	struct alc_spec *spec = codec->spec;
9251	alc883_auto_init_multi_out(codec);
9252	alc883_auto_init_hp_out(codec);
9253	alc883_auto_init_analog_input(codec);
9254	alc883_auto_init_input_src(codec);
9255	if (spec->unsol_event)
9256		alc_inithook(codec);
9257}
9258
9259static int patch_alc883(struct hda_codec *codec)
9260{
9261	struct alc_spec *spec;
9262	int err, board_config;
9263
9264	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9265	if (spec == NULL)
9266		return -ENOMEM;
9267
9268	codec->spec = spec;
9269
9270	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9271
9272	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9273						  alc883_models,
9274						  alc883_cfg_tbl);
9275	if (board_config < 0) {
9276		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9277		       "trying auto-probe from BIOS...\n");
9278		board_config = ALC883_AUTO;
9279	}
9280
9281	if (board_config == ALC883_AUTO) {
9282		/* automatic parse from the BIOS config */
9283		err = alc883_parse_auto_config(codec);
9284		if (err < 0) {
9285			alc_free(codec);
9286			return err;
9287		} else if (!err) {
9288			printk(KERN_INFO
9289			       "hda_codec: Cannot set up configuration "
9290			       "from BIOS.  Using base mode...\n");
9291			board_config = ALC883_3ST_2ch_DIG;
9292		}
9293	}
9294
9295	err = snd_hda_attach_beep_device(codec, 0x1);
9296	if (err < 0) {
9297		alc_free(codec);
9298		return err;
9299	}
9300
9301	if (board_config != ALC883_AUTO)
9302		setup_preset(spec, &alc883_presets[board_config]);
9303
9304	switch (codec->vendor_id) {
9305	case 0x10ec0888:
9306		if (codec->revision_id == 0x100101) {
9307			spec->stream_name_analog = "ALC1200 Analog";
9308			spec->stream_name_digital = "ALC1200 Digital";
9309		} else {
9310			spec->stream_name_analog = "ALC888 Analog";
9311			spec->stream_name_digital = "ALC888 Digital";
9312		}
9313		if (!spec->num_adc_nids) {
9314			spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9315			spec->adc_nids = alc883_adc_nids;
9316		}
9317		if (!spec->capsrc_nids)
9318			spec->capsrc_nids = alc883_capsrc_nids;
9319		spec->capture_style = CAPT_MIX; /* matrix-style capture */
9320		break;
9321	case 0x10ec0889:
9322		spec->stream_name_analog = "ALC889 Analog";
9323		spec->stream_name_digital = "ALC889 Digital";
9324		if (!spec->num_adc_nids) {
9325			spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9326			spec->adc_nids = alc889_adc_nids;
9327		}
9328		if (!spec->capsrc_nids)
9329			spec->capsrc_nids = alc889_capsrc_nids;
9330		spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9331							capture */
9332		break;
9333	default:
9334		spec->stream_name_analog = "ALC883 Analog";
9335		spec->stream_name_digital = "ALC883 Digital";
9336		if (!spec->num_adc_nids) {
9337			spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9338			spec->adc_nids = alc883_adc_nids;
9339		}
9340		if (!spec->capsrc_nids)
9341			spec->capsrc_nids = alc883_capsrc_nids;
9342		spec->capture_style = CAPT_MIX; /* matrix-style capture */
9343		break;
9344	}
9345
9346	spec->stream_analog_playback = &alc883_pcm_analog_playback;
9347	spec->stream_analog_capture = &alc883_pcm_analog_capture;
9348	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9349
9350	spec->stream_digital_playback = &alc883_pcm_digital_playback;
9351	spec->stream_digital_capture = &alc883_pcm_digital_capture;
9352
9353	if (!spec->cap_mixer)
9354		set_capture_mixer(spec);
9355	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9356
9357	spec->vmaster_nid = 0x0c;
9358
9359	codec->patch_ops = alc_patch_ops;
9360	if (board_config == ALC883_AUTO)
9361		spec->init_hook = alc883_auto_init;
9362
9363#ifdef CONFIG_SND_HDA_POWER_SAVE
9364	if (!spec->loopback.amplist)
9365		spec->loopback.amplist = alc883_loopbacks;
9366#endif
9367	codec->proc_widget_hook = print_realtek_coef;
9368
9369	return 0;
9370}
9371
9372/*
9373 * ALC262 support
9374 */
9375
9376#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
9377#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
9378
9379#define alc262_dac_nids		alc260_dac_nids
9380#define alc262_adc_nids		alc882_adc_nids
9381#define alc262_adc_nids_alt	alc882_adc_nids_alt
9382#define alc262_capsrc_nids	alc882_capsrc_nids
9383#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
9384
9385#define alc262_modes		alc260_modes
9386#define alc262_capture_source	alc882_capture_source
9387
9388static hda_nid_t alc262_dmic_adc_nids[1] = {
9389	/* ADC0 */
9390	0x09
9391};
9392
9393static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9394
9395static struct snd_kcontrol_new alc262_base_mixer[] = {
9396	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9397	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9398	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9399	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9400	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9401	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9402	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9403	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9404	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9405	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9406	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9407	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9408	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9409	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9410	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9411	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9412	{ } /* end */
9413};
9414
9415static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9416	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9417	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9418	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9419	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9420	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9421	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9422	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9423	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9424	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9425	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9426	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9427	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9428	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9429	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9430	{ } /* end */
9431};
9432
9433/* update HP, line and mono-out pins according to the master switch */
9434static void alc262_hp_master_update(struct hda_codec *codec)
9435{
9436	struct alc_spec *spec = codec->spec;
9437	int val = spec->master_sw;
9438
9439	/* HP & line-out */
9440	snd_hda_codec_write_cache(codec, 0x1b, 0,
9441				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9442				  val ? PIN_HP : 0);
9443	snd_hda_codec_write_cache(codec, 0x15, 0,
9444				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9445				  val ? PIN_HP : 0);
9446	/* mono (speaker) depending on the HP jack sense */
9447	val = val && !spec->jack_present;
9448	snd_hda_codec_write_cache(codec, 0x16, 0,
9449				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9450				  val ? PIN_OUT : 0);
9451}
9452
9453static void alc262_hp_bpc_automute(struct hda_codec *codec)
9454{
9455	struct alc_spec *spec = codec->spec;
9456	unsigned int presence;
9457	presence = snd_hda_codec_read(codec, 0x1b, 0,
9458				      AC_VERB_GET_PIN_SENSE, 0);
9459	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9460	alc262_hp_master_update(codec);
9461}
9462
9463static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9464{
9465	if ((res >> 26) != ALC880_HP_EVENT)
9466		return;
9467	alc262_hp_bpc_automute(codec);
9468}
9469
9470static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9471{
9472	struct alc_spec *spec = codec->spec;
9473	unsigned int presence;
9474	presence = snd_hda_codec_read(codec, 0x15, 0,
9475				      AC_VERB_GET_PIN_SENSE, 0);
9476	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9477	alc262_hp_master_update(codec);
9478}
9479
9480static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9481					   unsigned int res)
9482{
9483	if ((res >> 26) != ALC880_HP_EVENT)
9484		return;
9485	alc262_hp_wildwest_automute(codec);
9486}
9487
9488static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9489				   struct snd_ctl_elem_value *ucontrol)
9490{
9491	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9492	struct alc_spec *spec = codec->spec;
9493	*ucontrol->value.integer.value = spec->master_sw;
9494	return 0;
9495}
9496
9497static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9498				   struct snd_ctl_elem_value *ucontrol)
9499{
9500	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9501	struct alc_spec *spec = codec->spec;
9502	int val = !!*ucontrol->value.integer.value;
9503
9504	if (val == spec->master_sw)
9505		return 0;
9506	spec->master_sw = val;
9507	alc262_hp_master_update(codec);
9508	return 1;
9509}
9510
9511static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9512	{
9513		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9514		.name = "Master Playback Switch",
9515		.info = snd_ctl_boolean_mono_info,
9516		.get = alc262_hp_master_sw_get,
9517		.put = alc262_hp_master_sw_put,
9518	},
9519	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9520	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9521	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9522	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9523			      HDA_OUTPUT),
9524	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9525			    HDA_OUTPUT),
9526	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9527	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9528	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9529	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9530	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9531	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9532	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9533	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9534	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9535	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9536	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9537	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9538	{ } /* end */
9539};
9540
9541static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9542	{
9543		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9544		.name = "Master Playback Switch",
9545		.info = snd_ctl_boolean_mono_info,
9546		.get = alc262_hp_master_sw_get,
9547		.put = alc262_hp_master_sw_put,
9548	},
9549	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9550	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9551	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9552	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9553	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9554			      HDA_OUTPUT),
9555	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9556			    HDA_OUTPUT),
9557	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9558	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9559	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9560	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9561	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9562	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9563	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9564	{ } /* end */
9565};
9566
9567static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9568	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9569	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9570	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9571	{ } /* end */
9572};
9573
9574/* mute/unmute internal speaker according to the hp jack and mute state */
9575static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9576{
9577	struct alc_spec *spec = codec->spec;
9578
9579	if (force || !spec->sense_updated) {
9580		unsigned int present;
9581		present = snd_hda_codec_read(codec, 0x15, 0,
9582					     AC_VERB_GET_PIN_SENSE, 0);
9583		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9584		spec->sense_updated = 1;
9585	}
9586	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9587				 spec->jack_present ? HDA_AMP_MUTE : 0);
9588}
9589
9590static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9591					unsigned int res)
9592{
9593	if ((res >> 26) != ALC880_HP_EVENT)
9594		return;
9595	alc262_hp_t5735_automute(codec, 1);
9596}
9597
9598static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9599{
9600	alc262_hp_t5735_automute(codec, 1);
9601}
9602
9603static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9604	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9605	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9606	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9607	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9608	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9609	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9610	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9611	{ } /* end */
9612};
9613
9614static struct hda_verb alc262_hp_t5735_verbs[] = {
9615	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9616	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9617
9618	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9619	{ }
9620};
9621
9622static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9623	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9624	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9625	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9626	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9627	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9628	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9629	{ } /* end */
9630};
9631
9632static struct hda_verb alc262_hp_rp5700_verbs[] = {
9633	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9634	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9635	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9636	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9637	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9638	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9639	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9640	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9641	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9642	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9643	{}
9644};
9645
9646static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9647	.num_items = 1,
9648	.items = {
9649		{ "Line", 0x1 },
9650	},
9651};
9652
9653/* bind hp and internal speaker mute (with plug check) */
9654static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9655				     struct snd_ctl_elem_value *ucontrol)
9656{
9657	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9658	long *valp = ucontrol->value.integer.value;
9659	int change;
9660
9661	/* change hp mute */
9662	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9663					  HDA_AMP_MUTE,
9664					  valp[0] ? 0 : HDA_AMP_MUTE);
9665	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9666					   HDA_AMP_MUTE,
9667					   valp[1] ? 0 : HDA_AMP_MUTE);
9668	if (change) {
9669		/* change speaker according to HP jack state */
9670		struct alc_spec *spec = codec->spec;
9671		unsigned int mute;
9672		if (spec->jack_present)
9673			mute = HDA_AMP_MUTE;
9674		else
9675			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9676						      HDA_OUTPUT, 0);
9677		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9678					 HDA_AMP_MUTE, mute);
9679	}
9680	return change;
9681}
9682
9683static struct snd_kcontrol_new alc262_sony_mixer[] = {
9684	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9685	{
9686		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9687		.name = "Master Playback Switch",
9688		.info = snd_hda_mixer_amp_switch_info,
9689		.get = snd_hda_mixer_amp_switch_get,
9690		.put = alc262_sony_master_sw_put,
9691		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9692	},
9693	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9694	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9695	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9696	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9697	{ } /* end */
9698};
9699
9700static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9701	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9702	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9703	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9704	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9705	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9706	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9707	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9708	{ } /* end */
9709};
9710
9711static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9712	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9713	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9714	HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9715	HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9716	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9717	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9718	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9719	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9720	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9721	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9722	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9723	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9724	{ } /* end */
9725};
9726
9727static struct hda_verb alc262_tyan_verbs[] = {
9728	/* Headphone automute */
9729	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9730	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9731	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9732
9733	/* P11 AUX_IN, white 4-pin connector */
9734	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9735	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9736	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9737	{0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9738
9739	{}
9740};
9741
9742/* unsolicited event for HP jack sensing */
9743static void alc262_tyan_automute(struct hda_codec *codec)
9744{
9745	unsigned int mute;
9746	unsigned int present;
9747
9748	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9749	present = snd_hda_codec_read(codec, 0x1b, 0,
9750				     AC_VERB_GET_PIN_SENSE, 0);
9751	present = (present & 0x80000000) != 0;
9752	if (present) {
9753		/* mute line output on ATX panel */
9754		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9755					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9756	} else {
9757		/* unmute line output if necessary */
9758		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9759		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9760					 HDA_AMP_MUTE, mute);
9761	}
9762}
9763
9764static void alc262_tyan_unsol_event(struct hda_codec *codec,
9765				       unsigned int res)
9766{
9767	if ((res >> 26) != ALC880_HP_EVENT)
9768		return;
9769	alc262_tyan_automute(codec);
9770}
9771
9772#define alc262_capture_mixer		alc882_capture_mixer
9773#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
9774
9775/*
9776 * generic initialization of ADC, input mixers and output mixers
9777 */
9778static struct hda_verb alc262_init_verbs[] = {
9779	/*
9780	 * Unmute ADC0-2 and set the default input to mic-in
9781	 */
9782	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9783	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9784	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9785	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9786	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9787	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9788
9789	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9790	 * mixer widget
9791	 * Note: PASD motherboards uses the Line In 2 as the input for
9792	 * front panel mic (mic 2)
9793	 */
9794	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9795	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9796	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9797	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9798	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9799	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9800
9801	/*
9802	 * Set up output mixers (0x0c - 0x0e)
9803	 */
9804	/* set vol=0 to output mixers */
9805	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9806	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9807	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9808	/* set up input amps for analog loopback */
9809	/* Amp Indices: DAC = 0, mixer = 1 */
9810	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9811	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9812	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9813	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9814	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9815	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9816
9817	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9818	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9819	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9820	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9821	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9822	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9823
9824	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9825	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9826	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9827	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9828	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9829
9830	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9831	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9832
9833	/* FIXME: use matrix-type input source selection */
9834	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9835	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9836	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9837	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9838	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9839	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9840	/* Input mixer2 */
9841	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9842	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9843	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9844	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9845	/* Input mixer3 */
9846	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9847	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9848	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9849	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9850
9851	{ }
9852};
9853
9854static struct hda_verb alc262_eapd_verbs[] = {
9855	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9856	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9857	{ }
9858};
9859
9860static struct hda_verb alc262_hippo_unsol_verbs[] = {
9861	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9862	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9863	{}
9864};
9865
9866static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9867	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9868	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9869	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9870
9871	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9872	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9873	{}
9874};
9875
9876static struct hda_verb alc262_sony_unsol_verbs[] = {
9877	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9878	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9879	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
9880
9881	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9882	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9883	{}
9884};
9885
9886static struct hda_input_mux alc262_dmic_capture_source = {
9887	.num_items = 2,
9888	.items = {
9889		{ "Int DMic", 0x9 },
9890		{ "Mic", 0x0 },
9891	},
9892};
9893
9894static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9895	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9896	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9897	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9898	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9899	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9900	{ } /* end */
9901};
9902
9903static struct hda_verb alc262_toshiba_s06_verbs[] = {
9904	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9905	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9906	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9907	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9908	{0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9909	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9910	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9911	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9912	{}
9913};
9914
9915static void alc262_dmic_automute(struct hda_codec *codec)
9916{
9917	unsigned int present;
9918
9919	present = snd_hda_codec_read(codec, 0x18, 0,
9920					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9921	snd_hda_codec_write(codec, 0x22, 0,
9922				AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9923}
9924
9925/* toggle speaker-output according to the hp-jack state */
9926static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9927{
9928	unsigned int present;
9929	unsigned char bits;
9930
9931	present = snd_hda_codec_read(codec, 0x15, 0,
9932					AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9933	bits = present ? 0 : PIN_OUT;
9934	snd_hda_codec_write(codec, 0x14, 0,
9935					AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9936}
9937
9938
9939
9940/* unsolicited event for HP jack sensing */
9941static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9942				       unsigned int res)
9943{
9944	if ((res >> 26) == ALC880_HP_EVENT)
9945		alc262_toshiba_s06_speaker_automute(codec);
9946	if ((res >> 26) == ALC880_MIC_EVENT)
9947		alc262_dmic_automute(codec);
9948
9949}
9950
9951static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9952{
9953	alc262_toshiba_s06_speaker_automute(codec);
9954	alc262_dmic_automute(codec);
9955}
9956
9957/* mute/unmute internal speaker according to the hp jack and mute state */
9958static void alc262_hippo_automute(struct hda_codec *codec)
9959{
9960	struct alc_spec *spec = codec->spec;
9961	unsigned int mute;
9962	unsigned int present;
9963
9964	/* need to execute and sync at first */
9965	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9966	present = snd_hda_codec_read(codec, 0x15, 0,
9967				     AC_VERB_GET_PIN_SENSE, 0);
9968	spec->jack_present = (present & 0x80000000) != 0;
9969	if (spec->jack_present) {
9970		/* mute internal speaker */
9971		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9972					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9973	} else {
9974		/* unmute internal speaker if necessary */
9975		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9976		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9977					 HDA_AMP_MUTE, mute);
9978	}
9979}
9980
9981/* unsolicited event for HP jack sensing */
9982static void alc262_hippo_unsol_event(struct hda_codec *codec,
9983				       unsigned int res)
9984{
9985	if ((res >> 26) != ALC880_HP_EVENT)
9986		return;
9987	alc262_hippo_automute(codec);
9988}
9989
9990static void alc262_hippo1_automute(struct hda_codec *codec)
9991{
9992	unsigned int mute;
9993	unsigned int present;
9994
9995	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9996	present = snd_hda_codec_read(codec, 0x1b, 0,
9997				     AC_VERB_GET_PIN_SENSE, 0);
9998	present = (present & 0x80000000) != 0;
9999	if (present) {
10000		/* mute internal speaker */
10001		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10002					 HDA_AMP_MUTE, HDA_AMP_MUTE);
10003	} else {
10004		/* unmute internal speaker if necessary */
10005		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10006		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10007					 HDA_AMP_MUTE, mute);
10008	}
10009}
10010
10011/* unsolicited event for HP jack sensing */
10012static void alc262_hippo1_unsol_event(struct hda_codec *codec,
10013				       unsigned int res)
10014{
10015	if ((res >> 26) != ALC880_HP_EVENT)
10016		return;
10017	alc262_hippo1_automute(codec);
10018}
10019
10020/*
10021 * nec model
10022 *  0x15 = headphone
10023 *  0x16 = internal speaker
10024 *  0x18 = external mic
10025 */
10026
10027static struct snd_kcontrol_new alc262_nec_mixer[] = {
10028	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10029	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10030
10031	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10032	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10033	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10034
10035	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10036	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10037	{ } /* end */
10038};
10039
10040static struct hda_verb alc262_nec_verbs[] = {
10041	/* Unmute Speaker */
10042	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10043
10044	/* Headphone */
10045	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10046	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10047
10048	/* External mic to headphone */
10049	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10050	/* External mic to speaker */
10051	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10052	{}
10053};
10054
10055/*
10056 * fujitsu model
10057 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
10058 *  0x1b = port replicator headphone out
10059 */
10060
10061#define ALC_HP_EVENT	0x37
10062
10063static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10064	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10065	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10066	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10067	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10068	{}
10069};
10070
10071static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10072	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10073	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10074	{}
10075};
10076
10077static struct hda_input_mux alc262_fujitsu_capture_source = {
10078	.num_items = 3,
10079	.items = {
10080		{ "Mic", 0x0 },
10081		{ "Int Mic", 0x1 },
10082		{ "CD", 0x4 },
10083	},
10084};
10085
10086static struct hda_input_mux alc262_HP_capture_source = {
10087	.num_items = 5,
10088	.items = {
10089		{ "Mic", 0x0 },
10090		{ "Front Mic", 0x1 },
10091		{ "Line", 0x2 },
10092		{ "CD", 0x4 },
10093		{ "AUX IN", 0x6 },
10094	},
10095};
10096
10097static struct hda_input_mux alc262_HP_D7000_capture_source = {
10098	.num_items = 4,
10099	.items = {
10100		{ "Mic", 0x0 },
10101		{ "Front Mic", 0x2 },
10102		{ "Line", 0x1 },
10103		{ "CD", 0x4 },
10104	},
10105};
10106
10107/* mute/unmute internal speaker according to the hp jacks and mute state */
10108static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10109{
10110	struct alc_spec *spec = codec->spec;
10111	unsigned int mute;
10112
10113	if (force || !spec->sense_updated) {
10114		unsigned int present;
10115		/* need to execute and sync at first */
10116		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10117		/* check laptop HP jack */
10118		present = snd_hda_codec_read(codec, 0x14, 0,
10119					     AC_VERB_GET_PIN_SENSE, 0);
10120		/* need to execute and sync at first */
10121		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10122		/* check docking HP jack */
10123		present |= snd_hda_codec_read(codec, 0x1b, 0,
10124					      AC_VERB_GET_PIN_SENSE, 0);
10125		if (present & AC_PINSENSE_PRESENCE)
10126			spec->jack_present = 1;
10127		else
10128			spec->jack_present = 0;
10129		spec->sense_updated = 1;
10130	}
10131	/* unmute internal speaker only if both HPs are unplugged and
10132	 * master switch is on
10133	 */
10134	if (spec->jack_present)
10135		mute = HDA_AMP_MUTE;
10136	else
10137		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10138	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10139				 HDA_AMP_MUTE, mute);
10140}
10141
10142/* unsolicited event for HP jack sensing */
10143static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10144				       unsigned int res)
10145{
10146	if ((res >> 26) != ALC_HP_EVENT)
10147		return;
10148	alc262_fujitsu_automute(codec, 1);
10149}
10150
10151static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10152{
10153	alc262_fujitsu_automute(codec, 1);
10154}
10155
10156/* bind volumes of both NID 0x0c and 0x0d */
10157static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10158	.ops = &snd_hda_bind_vol,
10159	.values = {
10160		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10161		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10162		0
10163	},
10164};
10165
10166/* mute/unmute internal speaker according to the hp jack and mute state */
10167static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10168{
10169	struct alc_spec *spec = codec->spec;
10170	unsigned int mute;
10171
10172	if (force || !spec->sense_updated) {
10173		unsigned int present_int_hp;
10174		/* need to execute and sync at first */
10175		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10176		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10177					AC_VERB_GET_PIN_SENSE, 0);
10178		spec->jack_present = (present_int_hp & 0x80000000) != 0;
10179		spec->sense_updated = 1;
10180	}
10181	if (spec->jack_present) {
10182		/* mute internal speaker */
10183		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10184					 HDA_AMP_MUTE, HDA_AMP_MUTE);
10185		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10186					 HDA_AMP_MUTE, HDA_AMP_MUTE);
10187	} else {
10188		/* unmute internal speaker if necessary */
10189		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10190		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10191					 HDA_AMP_MUTE, mute);
10192		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10193					 HDA_AMP_MUTE, mute);
10194	}
10195}
10196
10197/* unsolicited event for HP jack sensing */
10198static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10199				       unsigned int res)
10200{
10201	if ((res >> 26) != ALC_HP_EVENT)
10202		return;
10203	alc262_lenovo_3000_automute(codec, 1);
10204}
10205
10206/* bind hp and internal speaker mute (with plug check) */
10207static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10208					 struct snd_ctl_elem_value *ucontrol)
10209{
10210	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10211	long *valp = ucontrol->value.integer.value;
10212	int change;
10213
10214	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10215						 HDA_AMP_MUTE,
10216						 valp ? 0 : HDA_AMP_MUTE);
10217	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10218						 HDA_AMP_MUTE,
10219						 valp ? 0 : HDA_AMP_MUTE);
10220
10221	if (change)
10222		alc262_fujitsu_automute(codec, 0);
10223	return change;
10224}
10225
10226static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10227	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10228	{
10229		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10230		.name = "Master Playback Switch",
10231		.info = snd_hda_mixer_amp_switch_info,
10232		.get = snd_hda_mixer_amp_switch_get,
10233		.put = alc262_fujitsu_master_sw_put,
10234		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10235	},
10236	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10237	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10238	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10239	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10240	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10241	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10242	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10243	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10244	{ } /* end */
10245};
10246
10247/* bind hp and internal speaker mute (with plug check) */
10248static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10249					 struct snd_ctl_elem_value *ucontrol)
10250{
10251	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10252	long *valp = ucontrol->value.integer.value;
10253	int change;
10254
10255	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10256						 HDA_AMP_MUTE,
10257						 valp ? 0 : HDA_AMP_MUTE);
10258
10259	if (change)
10260		alc262_lenovo_3000_automute(codec, 0);
10261	return change;
10262}
10263
10264static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10265	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10266	{
10267		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10268		.name = "Master Playback Switch",
10269		.info = snd_hda_mixer_amp_switch_info,
10270		.get = snd_hda_mixer_amp_switch_get,
10271		.put = alc262_lenovo_3000_master_sw_put,
10272		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10273	},
10274	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10275	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10276	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10277	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10278	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10279	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10280	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10281	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10282	{ } /* end */
10283};
10284
10285static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10286	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10287	{
10288		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10289		.name = "Master Playback Switch",
10290		.info = snd_hda_mixer_amp_switch_info,
10291		.get = snd_hda_mixer_amp_switch_get,
10292		.put = alc262_sony_master_sw_put,
10293		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10294	},
10295	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10296	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10297	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10298	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10299	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10300	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10301	{ } /* end */
10302};
10303
10304/* additional init verbs for Benq laptops */
10305static struct hda_verb alc262_EAPD_verbs[] = {
10306	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10307	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
10308	{}
10309};
10310
10311static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10312	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10313	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10314
10315	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10316	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
10317	{}
10318};
10319
10320/* Samsung Q1 Ultra Vista model setup */
10321static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10322	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10323	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10324	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10325	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10326	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10327	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10328	{ } /* end */
10329};
10330
10331static struct hda_verb alc262_ultra_verbs[] = {
10332	/* output mixer */
10333	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10334	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10335	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10336	/* speaker */
10337	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10338	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10339	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10340	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10341	/* HP */
10342	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10343	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10344	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10345	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10346	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10347	/* internal mic */
10348	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10349	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10350	/* ADC, choose mic */
10351	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10352	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10353	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10354	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10355	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10356	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10357	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10358	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10359	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10360	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10361	{}
10362};
10363
10364/* mute/unmute internal speaker according to the hp jack and mute state */
10365static void alc262_ultra_automute(struct hda_codec *codec)
10366{
10367	struct alc_spec *spec = codec->spec;
10368	unsigned int mute;
10369
10370	mute = 0;
10371	/* auto-mute only when HP is used as HP */
10372	if (!spec->cur_mux[0]) {
10373		unsigned int present;
10374		/* need to execute and sync at first */
10375		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10376		present = snd_hda_codec_read(codec, 0x15, 0,
10377					     AC_VERB_GET_PIN_SENSE, 0);
10378		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10379		if (spec->jack_present)
10380			mute = HDA_AMP_MUTE;
10381	}
10382	/* mute/unmute internal speaker */
10383	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10384				 HDA_AMP_MUTE, mute);
10385	/* mute/unmute HP */
10386	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10387				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10388}
10389
10390/* unsolicited event for HP jack sensing */
10391static void alc262_ultra_unsol_event(struct hda_codec *codec,
10392				       unsigned int res)
10393{
10394	if ((res >> 26) != ALC880_HP_EVENT)
10395		return;
10396	alc262_ultra_automute(codec);
10397}
10398
10399static struct hda_input_mux alc262_ultra_capture_source = {
10400	.num_items = 2,
10401	.items = {
10402		{ "Mic", 0x1 },
10403		{ "Headphone", 0x7 },
10404	},
10405};
10406
10407static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10408				     struct snd_ctl_elem_value *ucontrol)
10409{
10410	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10411	struct alc_spec *spec = codec->spec;
10412	int ret;
10413
10414	ret = alc_mux_enum_put(kcontrol, ucontrol);
10415	if (!ret)
10416		return 0;
10417	/* reprogram the HP pin as mic or HP according to the input source */
10418	snd_hda_codec_write_cache(codec, 0x15, 0,
10419				  AC_VERB_SET_PIN_WIDGET_CONTROL,
10420				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10421	alc262_ultra_automute(codec); /* mute/unmute HP */
10422	return ret;
10423}
10424
10425static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10426	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10427	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10428	{
10429		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10430		.name = "Capture Source",
10431		.info = alc_mux_enum_info,
10432		.get = alc_mux_enum_get,
10433		.put = alc262_ultra_mux_enum_put,
10434	},
10435	{ } /* end */
10436};
10437
10438/* add playback controls from the parsed DAC table */
10439static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10440					     const struct auto_pin_cfg *cfg)
10441{
10442	hda_nid_t nid;
10443	int err;
10444
10445	spec->multiout.num_dacs = 1;	/* only use one dac */
10446	spec->multiout.dac_nids = spec->private_dac_nids;
10447	spec->multiout.dac_nids[0] = 2;
10448
10449	nid = cfg->line_out_pins[0];
10450	if (nid) {
10451		err = add_control(spec, ALC_CTL_WIDGET_VOL,
10452				  "Front Playback Volume",
10453				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10454		if (err < 0)
10455			return err;
10456		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10457				  "Front Playback Switch",
10458				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10459		if (err < 0)
10460			return err;
10461	}
10462
10463	nid = cfg->speaker_pins[0];
10464	if (nid) {
10465		if (nid == 0x16) {
10466			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10467					  "Speaker Playback Volume",
10468					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10469							      HDA_OUTPUT));
10470			if (err < 0)
10471				return err;
10472			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10473					  "Speaker Playback Switch",
10474					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10475							      HDA_OUTPUT));
10476			if (err < 0)
10477				return err;
10478		} else {
10479			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10480					  "Speaker Playback Switch",
10481					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10482							      HDA_OUTPUT));
10483			if (err < 0)
10484				return err;
10485		}
10486	}
10487	nid = cfg->hp_pins[0];
10488	if (nid) {
10489		/* spec->multiout.hp_nid = 2; */
10490		if (nid == 0x16) {
10491			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10492					  "Headphone Playback Volume",
10493					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10494							      HDA_OUTPUT));
10495			if (err < 0)
10496				return err;
10497			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10498					  "Headphone Playback Switch",
10499					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10500							      HDA_OUTPUT));
10501			if (err < 0)
10502				return err;
10503		} else {
10504			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10505					  "Headphone Playback Switch",
10506					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10507							      HDA_OUTPUT));
10508			if (err < 0)
10509				return err;
10510		}
10511	}
10512	return 0;
10513}
10514
10515/* identical with ALC880 */
10516#define alc262_auto_create_analog_input_ctls \
10517	alc880_auto_create_analog_input_ctls
10518
10519/*
10520 * generic initialization of ADC, input mixers and output mixers
10521 */
10522static struct hda_verb alc262_volume_init_verbs[] = {
10523	/*
10524	 * Unmute ADC0-2 and set the default input to mic-in
10525	 */
10526	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10527	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10528	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10529	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10530	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10531	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10532
10533	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10534	 * mixer widget
10535	 * Note: PASD motherboards uses the Line In 2 as the input for
10536	 * front panel mic (mic 2)
10537	 */
10538	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10539	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10540	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10541	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10542	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10543	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10544
10545	/*
10546	 * Set up output mixers (0x0c - 0x0f)
10547	 */
10548	/* set vol=0 to output mixers */
10549	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10550	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10551	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10552
10553	/* set up input amps for analog loopback */
10554	/* Amp Indices: DAC = 0, mixer = 1 */
10555	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10556	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10558	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10559	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10560	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10561
10562	/* FIXME: use matrix-type input source selection */
10563	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10564	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10565	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10566	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10567	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10568	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10569	/* Input mixer2 */
10570	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10571	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10572	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10573	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10574	/* Input mixer3 */
10575	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10576	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10577	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10578	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10579
10580	{ }
10581};
10582
10583static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10584	/*
10585	 * Unmute ADC0-2 and set the default input to mic-in
10586	 */
10587	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10588	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10589	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10590	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10591	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10592	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10593
10594	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10595	 * mixer widget
10596	 * Note: PASD motherboards uses the Line In 2 as the input for
10597	 * front panel mic (mic 2)
10598	 */
10599	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10600	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10601	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10602	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10603	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10604	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10605	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10606        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10607
10608	/*
10609	 * Set up output mixers (0x0c - 0x0e)
10610	 */
10611	/* set vol=0 to output mixers */
10612	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10613	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10614	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10615
10616	/* set up input amps for analog loopback */
10617	/* Amp Indices: DAC = 0, mixer = 1 */
10618	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10619	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10620	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10621	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10622	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10623	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10624
10625	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10626	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10627	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10628
10629	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10630	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10631
10632	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10633	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10634
10635	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10636	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10637        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10638	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10639	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10640
10641	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10642	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10643        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10644	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10645	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10646	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10647
10648
10649	/* FIXME: use matrix-type input source selection */
10650	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10651	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10652	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10653	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10654	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10655	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10656	/* Input mixer2 */
10657	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10658	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10659	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10660	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10661	/* Input mixer3 */
10662	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10663	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10664	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10665	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10666
10667	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10668
10669	{ }
10670};
10671
10672static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10673	/*
10674	 * Unmute ADC0-2 and set the default input to mic-in
10675	 */
10676	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10677	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10678	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10679	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10680	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10681	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10682
10683	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10684	 * mixer widget
10685	 * Note: PASD motherboards uses the Line In 2 as the input for front
10686	 * panel mic (mic 2)
10687	 */
10688	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10689	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10690	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10691	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10692	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10693	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10694	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10695	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10696	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10697	/*
10698	 * Set up output mixers (0x0c - 0x0e)
10699	 */
10700	/* set vol=0 to output mixers */
10701	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10702	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10703	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10704
10705	/* set up input amps for analog loopback */
10706	/* Amp Indices: DAC = 0, mixer = 1 */
10707	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10708	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10709	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10710	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10711	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10712	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10713
10714
10715	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
10716	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
10717	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
10718	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
10719	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10720	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
10721	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
10722
10723	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10724	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10725
10726	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10727	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10728
10729	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10730	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10731	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10732	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10733	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10734	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10735
10736	/* FIXME: use matrix-type input source selection */
10737	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10738	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10739	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10740	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10741	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10742	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10743	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10744        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10745	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10746	/* Input mixer2 */
10747	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10748	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10749	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10750	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10751	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10752        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10753	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10754	/* Input mixer3 */
10755	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10756	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10757	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10758	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10759	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10760        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10761	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10762
10763	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10764
10765	{ }
10766};
10767
10768static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10769
10770	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */
10771	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10772	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10773
10774	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* MIC jack */
10775	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
10776	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10777	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10778
10779	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP  jack */
10780	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10781	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10782	{}
10783};
10784
10785
10786#ifdef CONFIG_SND_HDA_POWER_SAVE
10787#define alc262_loopbacks	alc880_loopbacks
10788#endif
10789
10790/* pcm configuration: identiacal with ALC880 */
10791#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
10792#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
10793#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
10794#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
10795
10796/*
10797 * BIOS auto configuration
10798 */
10799static int alc262_parse_auto_config(struct hda_codec *codec)
10800{
10801	struct alc_spec *spec = codec->spec;
10802	int err;
10803	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10804
10805	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10806					   alc262_ignore);
10807	if (err < 0)
10808		return err;
10809	if (!spec->autocfg.line_outs) {
10810		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10811			spec->multiout.max_channels = 2;
10812			spec->no_analog = 1;
10813			goto dig_only;
10814		}
10815		return 0; /* can't find valid BIOS pin config */
10816	}
10817	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10818	if (err < 0)
10819		return err;
10820	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10821	if (err < 0)
10822		return err;
10823
10824	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10825
10826 dig_only:
10827	if (spec->autocfg.dig_outs) {
10828		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10829		spec->dig_out_type = spec->autocfg.dig_out_type[0];
10830	}
10831	if (spec->autocfg.dig_in_pin)
10832		spec->dig_in_nid = ALC262_DIGIN_NID;
10833
10834	if (spec->kctls.list)
10835		add_mixer(spec, spec->kctls.list);
10836
10837	add_verb(spec, alc262_volume_init_verbs);
10838	spec->num_mux_defs = 1;
10839	spec->input_mux = &spec->private_imux[0];
10840
10841	err = alc_auto_add_mic_boost(codec);
10842	if (err < 0)
10843		return err;
10844
10845	return 1;
10846}
10847
10848#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
10849#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
10850#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
10851#define alc262_auto_init_input_src	alc882_auto_init_input_src
10852
10853
10854/* init callback for auto-configuration model -- overriding the default init */
10855static void alc262_auto_init(struct hda_codec *codec)
10856{
10857	struct alc_spec *spec = codec->spec;
10858	alc262_auto_init_multi_out(codec);
10859	alc262_auto_init_hp_out(codec);
10860	alc262_auto_init_analog_input(codec);
10861	alc262_auto_init_input_src(codec);
10862	if (spec->unsol_event)
10863		alc_inithook(codec);
10864}
10865
10866/*
10867 * configuration and preset
10868 */
10869static const char *alc262_models[ALC262_MODEL_LAST] = {
10870	[ALC262_BASIC]		= "basic",
10871	[ALC262_HIPPO]		= "hippo",
10872	[ALC262_HIPPO_1]	= "hippo_1",
10873	[ALC262_FUJITSU]	= "fujitsu",
10874	[ALC262_HP_BPC]		= "hp-bpc",
10875	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10876	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
10877	[ALC262_HP_RP5700]	= "hp-rp5700",
10878	[ALC262_BENQ_ED8]	= "benq",
10879	[ALC262_BENQ_T31]	= "benq-t31",
10880	[ALC262_SONY_ASSAMD]	= "sony-assamd",
10881	[ALC262_TOSHIBA_S06]	= "toshiba-s06",
10882	[ALC262_TOSHIBA_RX1]	= "toshiba-rx1",
10883	[ALC262_ULTRA]		= "ultra",
10884	[ALC262_LENOVO_3000]	= "lenovo-3000",
10885	[ALC262_NEC]		= "nec",
10886	[ALC262_TYAN]		= "tyan",
10887	[ALC262_AUTO]		= "auto",
10888};
10889
10890static struct snd_pci_quirk alc262_cfg_tbl[] = {
10891	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10892	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10893	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10894			   ALC262_HP_BPC),
10895	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10896			   ALC262_HP_BPC),
10897	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10898			   ALC262_HP_BPC),
10899	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10900	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10901	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10902	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10903	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10904	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10905	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10906	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10907	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10908	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10909	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10910	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10911		      ALC262_HP_TC_T5735),
10912	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10913	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10914	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10915	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10916	SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10917	SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10918			   ALC262_SONY_ASSAMD),
10919	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10920		      ALC262_TOSHIBA_RX1),
10921	SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10922	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10923	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10924	SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10925	SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10926			   ALC262_ULTRA),
10927	SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10928	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10929	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10930	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10931	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10932	{}
10933};
10934
10935static struct alc_config_preset alc262_presets[] = {
10936	[ALC262_BASIC] = {
10937		.mixers = { alc262_base_mixer },
10938		.init_verbs = { alc262_init_verbs },
10939		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10940		.dac_nids = alc262_dac_nids,
10941		.hp_nid = 0x03,
10942		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10943		.channel_mode = alc262_modes,
10944		.input_mux = &alc262_capture_source,
10945	},
10946	[ALC262_HIPPO] = {
10947		.mixers = { alc262_base_mixer },
10948		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10949		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10950		.dac_nids = alc262_dac_nids,
10951		.hp_nid = 0x03,
10952		.dig_out_nid = ALC262_DIGOUT_NID,
10953		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10954		.channel_mode = alc262_modes,
10955		.input_mux = &alc262_capture_source,
10956		.unsol_event = alc262_hippo_unsol_event,
10957		.init_hook = alc262_hippo_automute,
10958	},
10959	[ALC262_HIPPO_1] = {
10960		.mixers = { alc262_hippo1_mixer },
10961		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10962		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10963		.dac_nids = alc262_dac_nids,
10964		.hp_nid = 0x02,
10965		.dig_out_nid = ALC262_DIGOUT_NID,
10966		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10967		.channel_mode = alc262_modes,
10968		.input_mux = &alc262_capture_source,
10969		.unsol_event = alc262_hippo1_unsol_event,
10970		.init_hook = alc262_hippo1_automute,
10971	},
10972	[ALC262_FUJITSU] = {
10973		.mixers = { alc262_fujitsu_mixer },
10974		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10975				alc262_fujitsu_unsol_verbs },
10976		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10977		.dac_nids = alc262_dac_nids,
10978		.hp_nid = 0x03,
10979		.dig_out_nid = ALC262_DIGOUT_NID,
10980		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10981		.channel_mode = alc262_modes,
10982		.input_mux = &alc262_fujitsu_capture_source,
10983		.unsol_event = alc262_fujitsu_unsol_event,
10984		.init_hook = alc262_fujitsu_init_hook,
10985	},
10986	[ALC262_HP_BPC] = {
10987		.mixers = { alc262_HP_BPC_mixer },
10988		.init_verbs = { alc262_HP_BPC_init_verbs },
10989		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
10990		.dac_nids = alc262_dac_nids,
10991		.hp_nid = 0x03,
10992		.num_channel_mode = ARRAY_SIZE(alc262_modes),
10993		.channel_mode = alc262_modes,
10994		.input_mux = &alc262_HP_capture_source,
10995		.unsol_event = alc262_hp_bpc_unsol_event,
10996		.init_hook = alc262_hp_bpc_automute,
10997	},
10998	[ALC262_HP_BPC_D7000_WF] = {
10999		.mixers = { alc262_HP_BPC_WildWest_mixer },
11000		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11001		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11002		.dac_nids = alc262_dac_nids,
11003		.hp_nid = 0x03,
11004		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11005		.channel_mode = alc262_modes,
11006		.input_mux = &alc262_HP_D7000_capture_source,
11007		.unsol_event = alc262_hp_wildwest_unsol_event,
11008		.init_hook = alc262_hp_wildwest_automute,
11009	},
11010	[ALC262_HP_BPC_D7000_WL] = {
11011		.mixers = { alc262_HP_BPC_WildWest_mixer,
11012			    alc262_HP_BPC_WildWest_option_mixer },
11013		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11014		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11015		.dac_nids = alc262_dac_nids,
11016		.hp_nid = 0x03,
11017		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11018		.channel_mode = alc262_modes,
11019		.input_mux = &alc262_HP_D7000_capture_source,
11020		.unsol_event = alc262_hp_wildwest_unsol_event,
11021		.init_hook = alc262_hp_wildwest_automute,
11022	},
11023	[ALC262_HP_TC_T5735] = {
11024		.mixers = { alc262_hp_t5735_mixer },
11025		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11026		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11027		.dac_nids = alc262_dac_nids,
11028		.hp_nid = 0x03,
11029		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11030		.channel_mode = alc262_modes,
11031		.input_mux = &alc262_capture_source,
11032		.unsol_event = alc262_hp_t5735_unsol_event,
11033		.init_hook = alc262_hp_t5735_init_hook,
11034	},
11035	[ALC262_HP_RP5700] = {
11036		.mixers = { alc262_hp_rp5700_mixer },
11037		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11038		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11039		.dac_nids = alc262_dac_nids,
11040		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11041		.channel_mode = alc262_modes,
11042		.input_mux = &alc262_hp_rp5700_capture_source,
11043        },
11044	[ALC262_BENQ_ED8] = {
11045		.mixers = { alc262_base_mixer },
11046		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11047		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11048		.dac_nids = alc262_dac_nids,
11049		.hp_nid = 0x03,
11050		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11051		.channel_mode = alc262_modes,
11052		.input_mux = &alc262_capture_source,
11053	},
11054	[ALC262_SONY_ASSAMD] = {
11055		.mixers = { alc262_sony_mixer },
11056		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11057		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11058		.dac_nids = alc262_dac_nids,
11059		.hp_nid = 0x02,
11060		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11061		.channel_mode = alc262_modes,
11062		.input_mux = &alc262_capture_source,
11063		.unsol_event = alc262_hippo_unsol_event,
11064		.init_hook = alc262_hippo_automute,
11065	},
11066	[ALC262_BENQ_T31] = {
11067		.mixers = { alc262_benq_t31_mixer },
11068		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11069		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11070		.dac_nids = alc262_dac_nids,
11071		.hp_nid = 0x03,
11072		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11073		.channel_mode = alc262_modes,
11074		.input_mux = &alc262_capture_source,
11075		.unsol_event = alc262_hippo_unsol_event,
11076		.init_hook = alc262_hippo_automute,
11077	},
11078	[ALC262_ULTRA] = {
11079		.mixers = { alc262_ultra_mixer },
11080		.cap_mixer = alc262_ultra_capture_mixer,
11081		.init_verbs = { alc262_ultra_verbs },
11082		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11083		.dac_nids = alc262_dac_nids,
11084		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11085		.channel_mode = alc262_modes,
11086		.input_mux = &alc262_ultra_capture_source,
11087		.adc_nids = alc262_adc_nids, /* ADC0 */
11088		.capsrc_nids = alc262_capsrc_nids,
11089		.num_adc_nids = 1, /* single ADC */
11090		.unsol_event = alc262_ultra_unsol_event,
11091		.init_hook = alc262_ultra_automute,
11092	},
11093	[ALC262_LENOVO_3000] = {
11094		.mixers = { alc262_lenovo_3000_mixer },
11095		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11096				alc262_lenovo_3000_unsol_verbs },
11097		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11098		.dac_nids = alc262_dac_nids,
11099		.hp_nid = 0x03,
11100		.dig_out_nid = ALC262_DIGOUT_NID,
11101		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11102		.channel_mode = alc262_modes,
11103		.input_mux = &alc262_fujitsu_capture_source,
11104		.unsol_event = alc262_lenovo_3000_unsol_event,
11105	},
11106	[ALC262_NEC] = {
11107		.mixers = { alc262_nec_mixer },
11108		.init_verbs = { alc262_nec_verbs },
11109		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11110		.dac_nids = alc262_dac_nids,
11111		.hp_nid = 0x03,
11112		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11113		.channel_mode = alc262_modes,
11114		.input_mux = &alc262_capture_source,
11115	},
11116	[ALC262_TOSHIBA_S06] = {
11117		.mixers = { alc262_toshiba_s06_mixer },
11118		.init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11119							alc262_eapd_verbs },
11120		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11121		.capsrc_nids = alc262_dmic_capsrc_nids,
11122		.dac_nids = alc262_dac_nids,
11123		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11124		.dig_out_nid = ALC262_DIGOUT_NID,
11125		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11126		.channel_mode = alc262_modes,
11127		.input_mux = &alc262_dmic_capture_source,
11128		.unsol_event = alc262_toshiba_s06_unsol_event,
11129		.init_hook = alc262_toshiba_s06_init_hook,
11130	},
11131	[ALC262_TOSHIBA_RX1] = {
11132		.mixers = { alc262_toshiba_rx1_mixer },
11133		.init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11134		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11135		.dac_nids = alc262_dac_nids,
11136		.hp_nid = 0x03,
11137		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11138		.channel_mode = alc262_modes,
11139		.input_mux = &alc262_capture_source,
11140		.unsol_event = alc262_hippo_unsol_event,
11141		.init_hook = alc262_hippo_automute,
11142	},
11143	[ALC262_TYAN] = {
11144		.mixers = { alc262_tyan_mixer },
11145		.init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11146		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
11147		.dac_nids = alc262_dac_nids,
11148		.hp_nid = 0x02,
11149		.dig_out_nid = ALC262_DIGOUT_NID,
11150		.num_channel_mode = ARRAY_SIZE(alc262_modes),
11151		.channel_mode = alc262_modes,
11152		.input_mux = &alc262_capture_source,
11153		.unsol_event = alc262_tyan_unsol_event,
11154		.init_hook = alc262_tyan_automute,
11155	},
11156};
11157
11158static int patch_alc262(struct hda_codec *codec)
11159{
11160	struct alc_spec *spec;
11161	int board_config;
11162	int err;
11163
11164	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11165	if (spec == NULL)
11166		return -ENOMEM;
11167
11168	codec->spec = spec;
11169#if 0
11170	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
11171	 * under-run
11172	 */
11173	{
11174	int tmp;
11175	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11176	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11177	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11178	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11179	}
11180#endif
11181
11182	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11183
11184	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11185						  alc262_models,
11186						  alc262_cfg_tbl);
11187
11188	if (board_config < 0) {
11189		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11190		       "trying auto-probe from BIOS...\n");
11191		board_config = ALC262_AUTO;
11192	}
11193
11194	if (board_config == ALC262_AUTO) {
11195		/* automatic parse from the BIOS config */
11196		err = alc262_parse_auto_config(codec);
11197		if (err < 0) {
11198			alc_free(codec);
11199			return err;
11200		} else if (!err) {
11201			printk(KERN_INFO
11202			       "hda_codec: Cannot set up configuration "
11203			       "from BIOS.  Using base mode...\n");
11204			board_config = ALC262_BASIC;
11205		}
11206	}
11207
11208	if (!spec->no_analog) {
11209		err = snd_hda_attach_beep_device(codec, 0x1);
11210		if (err < 0) {
11211			alc_free(codec);
11212			return err;
11213		}
11214	}
11215
11216	if (board_config != ALC262_AUTO)
11217		setup_preset(spec, &alc262_presets[board_config]);
11218
11219	spec->stream_name_analog = "ALC262 Analog";
11220	spec->stream_analog_playback = &alc262_pcm_analog_playback;
11221	spec->stream_analog_capture = &alc262_pcm_analog_capture;
11222
11223	spec->stream_name_digital = "ALC262 Digital";
11224	spec->stream_digital_playback = &alc262_pcm_digital_playback;
11225	spec->stream_digital_capture = &alc262_pcm_digital_capture;
11226
11227	spec->capture_style = CAPT_MIX;
11228	if (!spec->adc_nids && spec->input_mux) {
11229		/* check whether NID 0x07 is valid */
11230		unsigned int wcap = get_wcaps(codec, 0x07);
11231
11232		/* get type */
11233		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11234		if (wcap != AC_WID_AUD_IN) {
11235			spec->adc_nids = alc262_adc_nids_alt;
11236			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11237			spec->capsrc_nids = alc262_capsrc_nids_alt;
11238		} else {
11239			spec->adc_nids = alc262_adc_nids;
11240			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11241			spec->capsrc_nids = alc262_capsrc_nids;
11242		}
11243	}
11244	if (!spec->cap_mixer && !spec->no_analog)
11245		set_capture_mixer(spec);
11246	if (!spec->no_analog)
11247		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11248
11249	spec->vmaster_nid = 0x0c;
11250
11251	codec->patch_ops = alc_patch_ops;
11252	if (board_config == ALC262_AUTO)
11253		spec->init_hook = alc262_auto_init;
11254#ifdef CONFIG_SND_HDA_POWER_SAVE
11255	if (!spec->loopback.amplist)
11256		spec->loopback.amplist = alc262_loopbacks;
11257#endif
11258	codec->proc_widget_hook = print_realtek_coef;
11259
11260	return 0;
11261}
11262
11263/*
11264 *  ALC268 channel source setting (2 channel)
11265 */
11266#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
11267#define alc268_modes		alc260_modes
11268
11269static hda_nid_t alc268_dac_nids[2] = {
11270	/* front, hp */
11271	0x02, 0x03
11272};
11273
11274static hda_nid_t alc268_adc_nids[2] = {
11275	/* ADC0-1 */
11276	0x08, 0x07
11277};
11278
11279static hda_nid_t alc268_adc_nids_alt[1] = {
11280	/* ADC0 */
11281	0x08
11282};
11283
11284static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11285
11286static struct snd_kcontrol_new alc268_base_mixer[] = {
11287	/* output mixer control */
11288	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11289	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11290	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11291	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11292	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11293	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11294	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11295	{ }
11296};
11297
11298/* bind Beep switches of both NID 0x0f and 0x10 */
11299static struct hda_bind_ctls alc268_bind_beep_sw = {
11300	.ops = &snd_hda_bind_sw,
11301	.values = {
11302		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11303		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11304		0
11305	},
11306};
11307
11308static struct snd_kcontrol_new alc268_beep_mixer[] = {
11309	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11310	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11311	{ }
11312};
11313
11314static struct hda_verb alc268_eapd_verbs[] = {
11315	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11316	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11317	{ }
11318};
11319
11320/* Toshiba specific */
11321#define alc268_toshiba_automute	alc262_hippo_automute
11322
11323static struct hda_verb alc268_toshiba_verbs[] = {
11324	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11325	{ } /* end */
11326};
11327
11328static struct hda_input_mux alc268_acer_lc_capture_source = {
11329	.num_items = 2,
11330	.items = {
11331		{ "i-Mic", 0x6 },
11332		{ "E-Mic", 0x0 },
11333	},
11334};
11335
11336/* Acer specific */
11337/* bind volumes of both NID 0x02 and 0x03 */
11338static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11339	.ops = &snd_hda_bind_vol,
11340	.values = {
11341		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11342		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11343		0
11344	},
11345};
11346
11347/* mute/unmute internal speaker according to the hp jack and mute state */
11348static void alc268_acer_automute(struct hda_codec *codec, int force)
11349{
11350	struct alc_spec *spec = codec->spec;
11351	unsigned int mute;
11352
11353	if (force || !spec->sense_updated) {
11354		unsigned int present;
11355		present = snd_hda_codec_read(codec, 0x14, 0,
11356				    	 AC_VERB_GET_PIN_SENSE, 0);
11357		spec->jack_present = (present & 0x80000000) != 0;
11358		spec->sense_updated = 1;
11359	}
11360	if (spec->jack_present)
11361		mute = HDA_AMP_MUTE; /* mute internal speaker */
11362	else /* unmute internal speaker if necessary */
11363		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11364	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11365				 HDA_AMP_MUTE, mute);
11366}
11367
11368
11369/* bind hp and internal speaker mute (with plug check) */
11370static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11371				     struct snd_ctl_elem_value *ucontrol)
11372{
11373	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11374	long *valp = ucontrol->value.integer.value;
11375	int change;
11376
11377	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11378					  HDA_AMP_MUTE,
11379					  valp[0] ? 0 : HDA_AMP_MUTE);
11380	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11381					   HDA_AMP_MUTE,
11382					   valp[1] ? 0 : HDA_AMP_MUTE);
11383	if (change)
11384		alc268_acer_automute(codec, 0);
11385	return change;
11386}
11387
11388static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11389	/* output mixer control */
11390	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11391	{
11392		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11393		.name = "Master Playback Switch",
11394		.info = snd_hda_mixer_amp_switch_info,
11395		.get = snd_hda_mixer_amp_switch_get,
11396		.put = alc268_acer_master_sw_put,
11397		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11398	},
11399	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11400	{ }
11401};
11402
11403static struct snd_kcontrol_new alc268_acer_mixer[] = {
11404	/* output mixer control */
11405	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11406	{
11407		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11408		.name = "Master Playback Switch",
11409		.info = snd_hda_mixer_amp_switch_info,
11410		.get = snd_hda_mixer_amp_switch_get,
11411		.put = alc268_acer_master_sw_put,
11412		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11413	},
11414	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11415	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11416	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11417	{ }
11418};
11419
11420static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11421	/* output mixer control */
11422	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11423	{
11424		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11425		.name = "Master Playback Switch",
11426		.info = snd_hda_mixer_amp_switch_info,
11427		.get = snd_hda_mixer_amp_switch_get,
11428		.put = alc268_acer_master_sw_put,
11429		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11430	},
11431	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11432	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11433	{ }
11434};
11435
11436static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11437	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11438	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11439	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11440	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11441	{0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11442	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11443	{ }
11444};
11445
11446static struct hda_verb alc268_acer_verbs[] = {
11447	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11448	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11449	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11450	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11451	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11452	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11453	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11454	{ }
11455};
11456
11457/* unsolicited event for HP jack sensing */
11458static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11459				       unsigned int res)
11460{
11461	if ((res >> 26) != ALC880_HP_EVENT)
11462		return;
11463	alc268_toshiba_automute(codec);
11464}
11465
11466static void alc268_acer_unsol_event(struct hda_codec *codec,
11467				       unsigned int res)
11468{
11469	if ((res >> 26) != ALC880_HP_EVENT)
11470		return;
11471	alc268_acer_automute(codec, 1);
11472}
11473
11474static void alc268_acer_init_hook(struct hda_codec *codec)
11475{
11476	alc268_acer_automute(codec, 1);
11477}
11478
11479/* toggle speaker-output according to the hp-jack state */
11480static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11481{
11482	unsigned int present;
11483	unsigned char bits;
11484
11485	present = snd_hda_codec_read(codec, 0x15, 0,
11486				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11487	bits = present ? AMP_IN_MUTE(0) : 0;
11488	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11489				AMP_IN_MUTE(0), bits);
11490	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11491				AMP_IN_MUTE(0), bits);
11492}
11493
11494
11495static void alc268_acer_mic_automute(struct hda_codec *codec)
11496{
11497	unsigned int present;
11498
11499	present = snd_hda_codec_read(codec, 0x18, 0,
11500				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11501	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11502			    present ? 0x0 : 0x6);
11503}
11504
11505static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11506				    unsigned int res)
11507{
11508	if ((res >> 26) == ALC880_HP_EVENT)
11509		alc268_aspire_one_speaker_automute(codec);
11510	if ((res >> 26) == ALC880_MIC_EVENT)
11511		alc268_acer_mic_automute(codec);
11512}
11513
11514static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11515{
11516	alc268_aspire_one_speaker_automute(codec);
11517	alc268_acer_mic_automute(codec);
11518}
11519
11520static struct snd_kcontrol_new alc268_dell_mixer[] = {
11521	/* output mixer control */
11522	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11523	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11524	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11525	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11526	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11527	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11528	{ }
11529};
11530
11531static struct hda_verb alc268_dell_verbs[] = {
11532	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11533	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11534	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11535	{ }
11536};
11537
11538/* mute/unmute internal speaker according to the hp jack and mute state */
11539static void alc268_dell_automute(struct hda_codec *codec)
11540{
11541	unsigned int present;
11542	unsigned int mute;
11543
11544	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11545	if (present & 0x80000000)
11546		mute = HDA_AMP_MUTE;
11547	else
11548		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11549	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11550				 HDA_AMP_MUTE, mute);
11551}
11552
11553static void alc268_dell_unsol_event(struct hda_codec *codec,
11554				    unsigned int res)
11555{
11556	if ((res >> 26) != ALC880_HP_EVENT)
11557		return;
11558	alc268_dell_automute(codec);
11559}
11560
11561#define alc268_dell_init_hook	alc268_dell_automute
11562
11563static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11564	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11565	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11566	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11567	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11568	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11569	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11570	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11571	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11572	{ }
11573};
11574
11575static struct hda_verb alc267_quanta_il1_verbs[] = {
11576	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11577	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11578	{ }
11579};
11580
11581static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11582{
11583	unsigned int present;
11584
11585	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11586		& AC_PINSENSE_PRESENCE;
11587	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11588			    present ? 0 : PIN_OUT);
11589}
11590
11591static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11592{
11593	unsigned int present;
11594
11595	present = snd_hda_codec_read(codec, 0x18, 0,
11596				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11597	snd_hda_codec_write(codec, 0x23, 0,
11598			    AC_VERB_SET_CONNECT_SEL,
11599			    present ? 0x00 : 0x01);
11600}
11601
11602static void alc267_quanta_il1_automute(struct hda_codec *codec)
11603{
11604	alc267_quanta_il1_hp_automute(codec);
11605	alc267_quanta_il1_mic_automute(codec);
11606}
11607
11608static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11609					   unsigned int res)
11610{
11611	switch (res >> 26) {
11612	case ALC880_HP_EVENT:
11613		alc267_quanta_il1_hp_automute(codec);
11614		break;
11615	case ALC880_MIC_EVENT:
11616		alc267_quanta_il1_mic_automute(codec);
11617		break;
11618	}
11619}
11620
11621/*
11622 * generic initialization of ADC, input mixers and output mixers
11623 */
11624static struct hda_verb alc268_base_init_verbs[] = {
11625	/* Unmute DAC0-1 and set vol = 0 */
11626	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11627	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11628
11629	/*
11630	 * Set up output mixers (0x0c - 0x0e)
11631	 */
11632	/* set vol=0 to output mixers */
11633	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11634        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11635
11636	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11637	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11638
11639	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11640	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11641	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11642	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11643	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11644	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11645	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11646	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11647
11648	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11649	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11650	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11651	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11652	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11653
11654	/* set PCBEEP vol = 0, mute connections */
11655	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11656	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11657	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11658
11659	/* Unmute Selector 23h,24h and set the default input to mic-in */
11660
11661	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11662	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11663	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11664	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11665
11666	{ }
11667};
11668
11669/*
11670 * generic initialization of ADC, input mixers and output mixers
11671 */
11672static struct hda_verb alc268_volume_init_verbs[] = {
11673	/* set output DAC */
11674	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11675	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11676
11677	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11678	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11679	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11680	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11681	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11682
11683	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11684	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11686
11687	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11688	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11689
11690	/* set PCBEEP vol = 0, mute connections */
11691	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11692	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11693	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11694
11695	{ }
11696};
11697
11698static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11699	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11700	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11701	{
11702		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11703		/* The multiple "Capture Source" controls confuse alsamixer
11704		 * So call somewhat different..
11705		 */
11706		/* .name = "Capture Source", */
11707		.name = "Input Source",
11708		.count = 1,
11709		.info = alc_mux_enum_info,
11710		.get = alc_mux_enum_get,
11711		.put = alc_mux_enum_put,
11712	},
11713	{ } /* end */
11714};
11715
11716static struct snd_kcontrol_new alc268_capture_mixer[] = {
11717	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11718	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11719	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11720	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11721	{
11722		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11723		/* The multiple "Capture Source" controls confuse alsamixer
11724		 * So call somewhat different..
11725		 */
11726		/* .name = "Capture Source", */
11727		.name = "Input Source",
11728		.count = 2,
11729		.info = alc_mux_enum_info,
11730		.get = alc_mux_enum_get,
11731		.put = alc_mux_enum_put,
11732	},
11733	{ } /* end */
11734};
11735
11736static struct hda_input_mux alc268_capture_source = {
11737	.num_items = 4,
11738	.items = {
11739		{ "Mic", 0x0 },
11740		{ "Front Mic", 0x1 },
11741		{ "Line", 0x2 },
11742		{ "CD", 0x3 },
11743	},
11744};
11745
11746static struct hda_input_mux alc268_acer_capture_source = {
11747	.num_items = 3,
11748	.items = {
11749		{ "Mic", 0x0 },
11750		{ "Internal Mic", 0x1 },
11751		{ "Line", 0x2 },
11752	},
11753};
11754
11755static struct hda_input_mux alc268_acer_dmic_capture_source = {
11756	.num_items = 3,
11757	.items = {
11758		{ "Mic", 0x0 },
11759		{ "Internal Mic", 0x6 },
11760		{ "Line", 0x2 },
11761	},
11762};
11763
11764#ifdef CONFIG_SND_DEBUG
11765static struct snd_kcontrol_new alc268_test_mixer[] = {
11766	/* Volume widgets */
11767	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11768	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11769	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11770	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11771	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11772	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11773	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11774	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11775	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11776	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11777	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11778	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11779	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11780	/* The below appears problematic on some hardwares */
11781	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11782	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11783	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11784	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11785	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11786
11787	/* Modes for retasking pin widgets */
11788	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11789	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11790	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11791	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11792
11793	/* Controls for GPIO pins, assuming they are configured as outputs */
11794	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11795	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11796	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11797	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11798
11799	/* Switches to allow the digital SPDIF output pin to be enabled.
11800	 * The ALC268 does not have an SPDIF input.
11801	 */
11802	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11803
11804	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
11805	 * this output to turn on an external amplifier.
11806	 */
11807	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11808	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11809
11810	{ } /* end */
11811};
11812#endif
11813
11814/* create input playback/capture controls for the given pin */
11815static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11816				    const char *ctlname, int idx)
11817{
11818	char name[32];
11819	int err;
11820
11821	sprintf(name, "%s Playback Volume", ctlname);
11822	if (nid == 0x14) {
11823		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11824				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11825						      HDA_OUTPUT));
11826		if (err < 0)
11827			return err;
11828	} else if (nid == 0x15) {
11829		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11830				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11831						      HDA_OUTPUT));
11832		if (err < 0)
11833			return err;
11834	} else
11835		return -1;
11836	sprintf(name, "%s Playback Switch", ctlname);
11837	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11838			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11839	if (err < 0)
11840		return err;
11841	return 0;
11842}
11843
11844/* add playback controls from the parsed DAC table */
11845static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11846					     const struct auto_pin_cfg *cfg)
11847{
11848	hda_nid_t nid;
11849	int err;
11850
11851	spec->multiout.num_dacs = 2;	/* only use one dac */
11852	spec->multiout.dac_nids = spec->private_dac_nids;
11853	spec->multiout.dac_nids[0] = 2;
11854	spec->multiout.dac_nids[1] = 3;
11855
11856	nid = cfg->line_out_pins[0];
11857	if (nid)
11858		alc268_new_analog_output(spec, nid, "Front", 0);
11859
11860	nid = cfg->speaker_pins[0];
11861	if (nid == 0x1d) {
11862		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11863				  "Speaker Playback Volume",
11864				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11865		if (err < 0)
11866			return err;
11867	}
11868	nid = cfg->hp_pins[0];
11869	if (nid)
11870		alc268_new_analog_output(spec, nid, "Headphone", 0);
11871
11872	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11873	if (nid == 0x16) {
11874		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11875				  "Mono Playback Switch",
11876				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11877		if (err < 0)
11878			return err;
11879	}
11880	return 0;
11881}
11882
11883/* create playback/capture controls for input pins */
11884static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11885						const struct auto_pin_cfg *cfg)
11886{
11887	struct hda_input_mux *imux = &spec->private_imux[0];
11888	int i, idx1;
11889
11890	for (i = 0; i < AUTO_PIN_LAST; i++) {
11891		switch(cfg->input_pins[i]) {
11892		case 0x18:
11893			idx1 = 0;	/* Mic 1 */
11894			break;
11895		case 0x19:
11896			idx1 = 1;	/* Mic 2 */
11897			break;
11898		case 0x1a:
11899			idx1 = 2;	/* Line In */
11900			break;
11901		case 0x1c:
11902			idx1 = 3;	/* CD */
11903			break;
11904		case 0x12:
11905		case 0x13:
11906			idx1 = 6;	/* digital mics */
11907			break;
11908		default:
11909			continue;
11910		}
11911		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11912		imux->items[imux->num_items].index = idx1;
11913		imux->num_items++;
11914	}
11915	return 0;
11916}
11917
11918static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11919{
11920	struct alc_spec *spec = codec->spec;
11921	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11922	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11923	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11924	unsigned int	dac_vol1, dac_vol2;
11925
11926	if (speaker_nid) {
11927		snd_hda_codec_write(codec, speaker_nid, 0,
11928				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11929		snd_hda_codec_write(codec, 0x0f, 0,
11930				    AC_VERB_SET_AMP_GAIN_MUTE,
11931				    AMP_IN_UNMUTE(1));
11932		snd_hda_codec_write(codec, 0x10, 0,
11933				    AC_VERB_SET_AMP_GAIN_MUTE,
11934				    AMP_IN_UNMUTE(1));
11935	} else {
11936		snd_hda_codec_write(codec, 0x0f, 0,
11937				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11938		snd_hda_codec_write(codec, 0x10, 0,
11939				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11940	}
11941
11942	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
11943	if (line_nid == 0x14)
11944		dac_vol2 = AMP_OUT_ZERO;
11945	else if (line_nid == 0x15)
11946		dac_vol1 = AMP_OUT_ZERO;
11947	if (hp_nid == 0x14)
11948		dac_vol2 = AMP_OUT_ZERO;
11949	else if (hp_nid == 0x15)
11950		dac_vol1 = AMP_OUT_ZERO;
11951	if (line_nid != 0x16 || hp_nid != 0x16 ||
11952	    spec->autocfg.line_out_pins[1] != 0x16 ||
11953	    spec->autocfg.line_out_pins[2] != 0x16)
11954		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11955
11956	snd_hda_codec_write(codec, 0x02, 0,
11957			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11958	snd_hda_codec_write(codec, 0x03, 0,
11959			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11960}
11961
11962/* pcm configuration: identiacal with ALC880 */
11963#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
11964#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
11965#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
11966#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
11967
11968/*
11969 * BIOS auto configuration
11970 */
11971static int alc268_parse_auto_config(struct hda_codec *codec)
11972{
11973	struct alc_spec *spec = codec->spec;
11974	int err;
11975	static hda_nid_t alc268_ignore[] = { 0 };
11976
11977	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11978					   alc268_ignore);
11979	if (err < 0)
11980		return err;
11981	if (!spec->autocfg.line_outs) {
11982		if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11983			spec->multiout.max_channels = 2;
11984			spec->no_analog = 1;
11985			goto dig_only;
11986		}
11987		return 0; /* can't find valid BIOS pin config */
11988	}
11989	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11990	if (err < 0)
11991		return err;
11992	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11993	if (err < 0)
11994		return err;
11995
11996	spec->multiout.max_channels = 2;
11997
11998 dig_only:
11999	/* digital only support output */
12000	if (spec->autocfg.dig_outs) {
12001		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12002		spec->dig_out_type = spec->autocfg.dig_out_type[0];
12003	}
12004	if (spec->kctls.list)
12005		add_mixer(spec, spec->kctls.list);
12006
12007	if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12008		add_mixer(spec, alc268_beep_mixer);
12009
12010	add_verb(spec, alc268_volume_init_verbs);
12011	spec->num_mux_defs = 1;
12012	spec->input_mux = &spec->private_imux[0];
12013
12014	err = alc_auto_add_mic_boost(codec);
12015	if (err < 0)
12016		return err;
12017
12018	return 1;
12019}
12020
12021#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
12022#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
12023#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
12024
12025/* init callback for auto-configuration model -- overriding the default init */
12026static void alc268_auto_init(struct hda_codec *codec)
12027{
12028	struct alc_spec *spec = codec->spec;
12029	alc268_auto_init_multi_out(codec);
12030	alc268_auto_init_hp_out(codec);
12031	alc268_auto_init_mono_speaker_out(codec);
12032	alc268_auto_init_analog_input(codec);
12033	if (spec->unsol_event)
12034		alc_inithook(codec);
12035}
12036
12037/*
12038 * configuration and preset
12039 */
12040static const char *alc268_models[ALC268_MODEL_LAST] = {
12041	[ALC267_QUANTA_IL1]	= "quanta-il1",
12042	[ALC268_3ST]		= "3stack",
12043	[ALC268_TOSHIBA]	= "toshiba",
12044	[ALC268_ACER]		= "acer",
12045	[ALC268_ACER_DMIC]	= "acer-dmic",
12046	[ALC268_ACER_ASPIRE_ONE]	= "acer-aspire",
12047	[ALC268_DELL]		= "dell",
12048	[ALC268_ZEPTO]		= "zepto",
12049#ifdef CONFIG_SND_DEBUG
12050	[ALC268_TEST]		= "test",
12051#endif
12052	[ALC268_AUTO]		= "auto",
12053};
12054
12055static struct snd_pci_quirk alc268_cfg_tbl[] = {
12056	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12057	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12058	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12059	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12060	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12061	SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12062						ALC268_ACER_ASPIRE_ONE),
12063	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12064	SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12065	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12066	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12067	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12068	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12069	SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12070	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12071	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12072	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12073	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12074	{}
12075};
12076
12077static struct alc_config_preset alc268_presets[] = {
12078	[ALC267_QUANTA_IL1] = {
12079		.mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12080		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12081				alc267_quanta_il1_verbs },
12082		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12083		.dac_nids = alc268_dac_nids,
12084		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12085		.adc_nids = alc268_adc_nids_alt,
12086		.hp_nid = 0x03,
12087		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12088		.channel_mode = alc268_modes,
12089		.input_mux = &alc268_capture_source,
12090		.unsol_event = alc267_quanta_il1_unsol_event,
12091		.init_hook = alc267_quanta_il1_automute,
12092	},
12093	[ALC268_3ST] = {
12094		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12095			    alc268_beep_mixer },
12096		.init_verbs = { alc268_base_init_verbs },
12097		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12098		.dac_nids = alc268_dac_nids,
12099                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12100                .adc_nids = alc268_adc_nids_alt,
12101		.capsrc_nids = alc268_capsrc_nids,
12102		.hp_nid = 0x03,
12103		.dig_out_nid = ALC268_DIGOUT_NID,
12104		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12105		.channel_mode = alc268_modes,
12106		.input_mux = &alc268_capture_source,
12107	},
12108	[ALC268_TOSHIBA] = {
12109		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12110			    alc268_beep_mixer },
12111		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12112				alc268_toshiba_verbs },
12113		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12114		.dac_nids = alc268_dac_nids,
12115		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12116		.adc_nids = alc268_adc_nids_alt,
12117		.capsrc_nids = alc268_capsrc_nids,
12118		.hp_nid = 0x03,
12119		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12120		.channel_mode = alc268_modes,
12121		.input_mux = &alc268_capture_source,
12122		.unsol_event = alc268_toshiba_unsol_event,
12123		.init_hook = alc268_toshiba_automute,
12124	},
12125	[ALC268_ACER] = {
12126		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12127			    alc268_beep_mixer },
12128		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12129				alc268_acer_verbs },
12130		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12131		.dac_nids = alc268_dac_nids,
12132		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12133		.adc_nids = alc268_adc_nids_alt,
12134		.capsrc_nids = alc268_capsrc_nids,
12135		.hp_nid = 0x02,
12136		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12137		.channel_mode = alc268_modes,
12138		.input_mux = &alc268_acer_capture_source,
12139		.unsol_event = alc268_acer_unsol_event,
12140		.init_hook = alc268_acer_init_hook,
12141	},
12142	[ALC268_ACER_DMIC] = {
12143		.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12144			    alc268_beep_mixer },
12145		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12146				alc268_acer_verbs },
12147		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12148		.dac_nids = alc268_dac_nids,
12149		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12150		.adc_nids = alc268_adc_nids_alt,
12151		.capsrc_nids = alc268_capsrc_nids,
12152		.hp_nid = 0x02,
12153		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12154		.channel_mode = alc268_modes,
12155		.input_mux = &alc268_acer_dmic_capture_source,
12156		.unsol_event = alc268_acer_unsol_event,
12157		.init_hook = alc268_acer_init_hook,
12158	},
12159	[ALC268_ACER_ASPIRE_ONE] = {
12160		.mixers = { alc268_acer_aspire_one_mixer,
12161			    alc268_beep_mixer,
12162			    alc268_capture_alt_mixer },
12163		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12164				alc268_acer_aspire_one_verbs },
12165		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12166		.dac_nids = alc268_dac_nids,
12167		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12168		.adc_nids = alc268_adc_nids_alt,
12169		.capsrc_nids = alc268_capsrc_nids,
12170		.hp_nid = 0x03,
12171		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12172		.channel_mode = alc268_modes,
12173		.input_mux = &alc268_acer_lc_capture_source,
12174		.unsol_event = alc268_acer_lc_unsol_event,
12175		.init_hook = alc268_acer_lc_init_hook,
12176	},
12177	[ALC268_DELL] = {
12178		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
12179		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12180				alc268_dell_verbs },
12181		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12182		.dac_nids = alc268_dac_nids,
12183		.hp_nid = 0x02,
12184		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12185		.channel_mode = alc268_modes,
12186		.unsol_event = alc268_dell_unsol_event,
12187		.init_hook = alc268_dell_init_hook,
12188		.input_mux = &alc268_capture_source,
12189	},
12190	[ALC268_ZEPTO] = {
12191		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12192			    alc268_beep_mixer },
12193		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12194				alc268_toshiba_verbs },
12195		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12196		.dac_nids = alc268_dac_nids,
12197		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12198		.adc_nids = alc268_adc_nids_alt,
12199		.capsrc_nids = alc268_capsrc_nids,
12200		.hp_nid = 0x03,
12201		.dig_out_nid = ALC268_DIGOUT_NID,
12202		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12203		.channel_mode = alc268_modes,
12204		.input_mux = &alc268_capture_source,
12205		.unsol_event = alc268_toshiba_unsol_event,
12206		.init_hook = alc268_toshiba_automute
12207	},
12208#ifdef CONFIG_SND_DEBUG
12209	[ALC268_TEST] = {
12210		.mixers = { alc268_test_mixer, alc268_capture_mixer },
12211		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12212				alc268_volume_init_verbs },
12213		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
12214		.dac_nids = alc268_dac_nids,
12215		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12216		.adc_nids = alc268_adc_nids_alt,
12217		.capsrc_nids = alc268_capsrc_nids,
12218		.hp_nid = 0x03,
12219		.dig_out_nid = ALC268_DIGOUT_NID,
12220		.num_channel_mode = ARRAY_SIZE(alc268_modes),
12221		.channel_mode = alc268_modes,
12222		.input_mux = &alc268_capture_source,
12223	},
12224#endif
12225};
12226
12227static int patch_alc268(struct hda_codec *codec)
12228{
12229	struct alc_spec *spec;
12230	int board_config;
12231	int i, has_beep, err;
12232
12233	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12234	if (spec == NULL)
12235		return -ENOMEM;
12236
12237	codec->spec = spec;
12238
12239	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12240						  alc268_models,
12241						  alc268_cfg_tbl);
12242
12243	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12244		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12245		       "trying auto-probe from BIOS...\n");
12246		board_config = ALC268_AUTO;
12247	}
12248
12249	if (board_config == ALC268_AUTO) {
12250		/* automatic parse from the BIOS config */
12251		err = alc268_parse_auto_config(codec);
12252		if (err < 0) {
12253			alc_free(codec);
12254			return err;
12255		} else if (!err) {
12256			printk(KERN_INFO
12257			       "hda_codec: Cannot set up configuration "
12258			       "from BIOS.  Using base mode...\n");
12259			board_config = ALC268_3ST;
12260		}
12261	}
12262
12263	if (board_config != ALC268_AUTO)
12264		setup_preset(spec, &alc268_presets[board_config]);
12265
12266	if (codec->vendor_id == 0x10ec0267) {
12267		spec->stream_name_analog = "ALC267 Analog";
12268		spec->stream_name_digital = "ALC267 Digital";
12269	} else {
12270		spec->stream_name_analog = "ALC268 Analog";
12271		spec->stream_name_digital = "ALC268 Digital";
12272	}
12273
12274	spec->stream_analog_playback = &alc268_pcm_analog_playback;
12275	spec->stream_analog_capture = &alc268_pcm_analog_capture;
12276	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12277
12278	spec->stream_digital_playback = &alc268_pcm_digital_playback;
12279
12280	has_beep = 0;
12281	for (i = 0; i < spec->num_mixers; i++) {
12282		if (spec->mixers[i] == alc268_beep_mixer) {
12283			has_beep = 1;
12284			break;
12285		}
12286	}
12287
12288	if (has_beep) {
12289		err = snd_hda_attach_beep_device(codec, 0x1);
12290		if (err < 0) {
12291			alc_free(codec);
12292			return err;
12293		}
12294		if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12295			/* override the amp caps for beep generator */
12296			snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12297					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12298					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12299					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12300					  (0 << AC_AMPCAP_MUTE_SHIFT));
12301	}
12302
12303	if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12304		/* check whether NID 0x07 is valid */
12305		unsigned int wcap = get_wcaps(codec, 0x07);
12306		int i;
12307
12308		/* get type */
12309		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12310		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12311			spec->adc_nids = alc268_adc_nids_alt;
12312			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12313			add_mixer(spec, alc268_capture_alt_mixer);
12314		} else {
12315			spec->adc_nids = alc268_adc_nids;
12316			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12317			add_mixer(spec, alc268_capture_mixer);
12318		}
12319		spec->capsrc_nids = alc268_capsrc_nids;
12320		/* set default input source */
12321		for (i = 0; i < spec->num_adc_nids; i++)
12322			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12323				0, AC_VERB_SET_CONNECT_SEL,
12324				spec->input_mux->items[0].index);
12325	}
12326
12327	spec->vmaster_nid = 0x02;
12328
12329	codec->patch_ops = alc_patch_ops;
12330	if (board_config == ALC268_AUTO)
12331		spec->init_hook = alc268_auto_init;
12332
12333	codec->proc_widget_hook = print_realtek_coef;
12334
12335	return 0;
12336}
12337
12338/*
12339 *  ALC269 channel source setting (2 channel)
12340 */
12341#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
12342
12343#define alc269_dac_nids		alc260_dac_nids
12344
12345static hda_nid_t alc269_adc_nids[1] = {
12346	/* ADC1 */
12347	0x08,
12348};
12349
12350static hda_nid_t alc269_capsrc_nids[1] = {
12351	0x23,
12352};
12353
12354/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12355 *       not a mux!
12356 */
12357
12358static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12359	.num_items = 2,
12360	.items = {
12361		{ "i-Mic", 0x5 },
12362		{ "e-Mic", 0x0 },
12363	},
12364};
12365
12366static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12367	.num_items = 2,
12368	.items = {
12369		{ "i-Mic", 0x1 },
12370		{ "e-Mic", 0x0 },
12371	},
12372};
12373
12374#define alc269_modes		alc260_modes
12375#define alc269_capture_source	alc880_lg_lw_capture_source
12376
12377static struct snd_kcontrol_new alc269_base_mixer[] = {
12378	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12379	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12380	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12381	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12382	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12383	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12384	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12385	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12386	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12387	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12388	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12389	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12390	{ } /* end */
12391};
12392
12393static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12394	/* output mixer control */
12395	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12396	{
12397		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12398		.name = "Master Playback Switch",
12399		.info = snd_hda_mixer_amp_switch_info,
12400		.get = snd_hda_mixer_amp_switch_get,
12401		.put = alc268_acer_master_sw_put,
12402		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12403	},
12404	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12405	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12406	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12407	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12408	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12409	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12410	{ }
12411};
12412
12413static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12414	/* output mixer control */
12415	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12416	{
12417		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12418		.name = "Master Playback Switch",
12419		.info = snd_hda_mixer_amp_switch_info,
12420		.get = snd_hda_mixer_amp_switch_get,
12421		.put = alc268_acer_master_sw_put,
12422		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12423	},
12424	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12425	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12426	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12427	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12428	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12429	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12430	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12431	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12432	HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12433	{ }
12434};
12435
12436/* bind volumes of both NID 0x0c and 0x0d */
12437static struct hda_bind_ctls alc269_epc_bind_vol = {
12438	.ops = &snd_hda_bind_vol,
12439	.values = {
12440		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12441		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12442		0
12443	},
12444};
12445
12446static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12447	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12448	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12449	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12450	{ } /* end */
12451};
12452
12453/* capture mixer elements */
12454static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12455	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12456	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12457	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12458	{ } /* end */
12459};
12460
12461/* FSC amilo */
12462static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12463	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12464	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12465	HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12466	{ } /* end */
12467};
12468
12469static struct hda_verb alc269_quanta_fl1_verbs[] = {
12470	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12471	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12472	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12473	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12474	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12475	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12476	{ }
12477};
12478
12479static struct hda_verb alc269_lifebook_verbs[] = {
12480	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12481	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12482	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12483	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12484	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12485	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12486	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12487	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12488	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12489	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12490	{ }
12491};
12492
12493/* toggle speaker-output according to the hp-jack state */
12494static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12495{
12496	unsigned int present;
12497	unsigned char bits;
12498
12499	present = snd_hda_codec_read(codec, 0x15, 0,
12500			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12501	bits = present ? AMP_IN_MUTE(0) : 0;
12502	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12503			AMP_IN_MUTE(0), bits);
12504	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12505			AMP_IN_MUTE(0), bits);
12506
12507	snd_hda_codec_write(codec, 0x20, 0,
12508			AC_VERB_SET_COEF_INDEX, 0x0c);
12509	snd_hda_codec_write(codec, 0x20, 0,
12510			AC_VERB_SET_PROC_COEF, 0x680);
12511
12512	snd_hda_codec_write(codec, 0x20, 0,
12513			AC_VERB_SET_COEF_INDEX, 0x0c);
12514	snd_hda_codec_write(codec, 0x20, 0,
12515			AC_VERB_SET_PROC_COEF, 0x480);
12516}
12517
12518/* toggle speaker-output according to the hp-jacks state */
12519static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12520{
12521	unsigned int present;
12522	unsigned char bits;
12523
12524	/* Check laptop headphone socket */
12525	present = snd_hda_codec_read(codec, 0x15, 0,
12526			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12527
12528	/* Check port replicator headphone socket */
12529	present |= snd_hda_codec_read(codec, 0x1a, 0,
12530			AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12531
12532	bits = present ? AMP_IN_MUTE(0) : 0;
12533	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12534			AMP_IN_MUTE(0), bits);
12535	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12536			AMP_IN_MUTE(0), bits);
12537
12538	snd_hda_codec_write(codec, 0x20, 0,
12539			AC_VERB_SET_COEF_INDEX, 0x0c);
12540	snd_hda_codec_write(codec, 0x20, 0,
12541			AC_VERB_SET_PROC_COEF, 0x680);
12542
12543	snd_hda_codec_write(codec, 0x20, 0,
12544			AC_VERB_SET_COEF_INDEX, 0x0c);
12545	snd_hda_codec_write(codec, 0x20, 0,
12546			AC_VERB_SET_PROC_COEF, 0x480);
12547}
12548
12549static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12550{
12551	unsigned int present;
12552
12553	present = snd_hda_codec_read(codec, 0x18, 0,
12554				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12555	snd_hda_codec_write(codec, 0x23, 0,
12556			    AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12557}
12558
12559static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12560{
12561	unsigned int present_laptop;
12562	unsigned int present_dock;
12563
12564	present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12565				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12566
12567	present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12568				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12569
12570	/* Laptop mic port overrides dock mic port, design decision */
12571	if (present_dock)
12572		snd_hda_codec_write(codec, 0x23, 0,
12573				AC_VERB_SET_CONNECT_SEL, 0x3);
12574	if (present_laptop)
12575		snd_hda_codec_write(codec, 0x23, 0,
12576				AC_VERB_SET_CONNECT_SEL, 0x0);
12577	if (!present_dock && !present_laptop)
12578		snd_hda_codec_write(codec, 0x23, 0,
12579				AC_VERB_SET_CONNECT_SEL, 0x1);
12580}
12581
12582static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12583				    unsigned int res)
12584{
12585	if ((res >> 26) == ALC880_HP_EVENT)
12586		alc269_quanta_fl1_speaker_automute(codec);
12587	if ((res >> 26) == ALC880_MIC_EVENT)
12588		alc269_quanta_fl1_mic_automute(codec);
12589}
12590
12591static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12592					unsigned int res)
12593{
12594	if ((res >> 26) == ALC880_HP_EVENT)
12595		alc269_lifebook_speaker_automute(codec);
12596	if ((res >> 26) == ALC880_MIC_EVENT)
12597		alc269_lifebook_mic_autoswitch(codec);
12598}
12599
12600static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12601{
12602	alc269_quanta_fl1_speaker_automute(codec);
12603	alc269_quanta_fl1_mic_automute(codec);
12604}
12605
12606static void alc269_lifebook_init_hook(struct hda_codec *codec)
12607{
12608	alc269_lifebook_speaker_automute(codec);
12609	alc269_lifebook_mic_autoswitch(codec);
12610}
12611
12612static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12613	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12614	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12615	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12616	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12617	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12618	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12619	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12620	{}
12621};
12622
12623static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12624	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12625	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12626	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12627	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12628	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12629	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12630	{}
12631};
12632
12633/* toggle speaker-output according to the hp-jack state */
12634static void alc269_speaker_automute(struct hda_codec *codec)
12635{
12636	unsigned int present;
12637	unsigned char bits;
12638
12639	present = snd_hda_codec_read(codec, 0x15, 0,
12640				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12641	bits = present ? AMP_IN_MUTE(0) : 0;
12642	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12643				AMP_IN_MUTE(0), bits);
12644	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12645				AMP_IN_MUTE(0), bits);
12646}
12647
12648static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12649{
12650	unsigned int present;
12651
12652	present = snd_hda_codec_read(codec, 0x18, 0,
12653				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12654	snd_hda_codec_write(codec, 0x23, 0,
12655				AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
12656}
12657
12658static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12659{
12660	unsigned int present;
12661
12662	present = snd_hda_codec_read(codec, 0x18, 0,
12663				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12664	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12665				0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12666	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12667				0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12668}
12669
12670/* unsolicited event for HP jack sensing */
12671static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12672				     unsigned int res)
12673{
12674	if ((res >> 26) == ALC880_HP_EVENT)
12675		alc269_speaker_automute(codec);
12676
12677	if ((res >> 26) == ALC880_MIC_EVENT)
12678		alc269_eeepc_dmic_automute(codec);
12679}
12680
12681static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12682{
12683	alc269_speaker_automute(codec);
12684	alc269_eeepc_dmic_automute(codec);
12685}
12686
12687/* unsolicited event for HP jack sensing */
12688static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12689				     unsigned int res)
12690{
12691	if ((res >> 26) == ALC880_HP_EVENT)
12692		alc269_speaker_automute(codec);
12693
12694	if ((res >> 26) == ALC880_MIC_EVENT)
12695		alc269_eeepc_amic_automute(codec);
12696}
12697
12698static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12699{
12700	alc269_speaker_automute(codec);
12701	alc269_eeepc_amic_automute(codec);
12702}
12703
12704/*
12705 * generic initialization of ADC, input mixers and output mixers
12706 */
12707static struct hda_verb alc269_init_verbs[] = {
12708	/*
12709	 * Unmute ADC0 and set the default input to mic-in
12710	 */
12711	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12712
12713	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12714	 * analog-loopback mixer widget
12715	 * Note: PASD motherboards uses the Line In 2 as the input for
12716	 * front panel mic (mic 2)
12717	 */
12718	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12719	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12720	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12721	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12722	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12723	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12724
12725	/*
12726	 * Set up output mixers (0x0c - 0x0e)
12727	 */
12728	/* set vol=0 to output mixers */
12729	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12730	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12731
12732	/* set up input amps for analog loopback */
12733	/* Amp Indices: DAC = 0, mixer = 1 */
12734	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12736	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12737	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12738	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12740
12741	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12742	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12743	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12744	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12745	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12746	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12747	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12748
12749	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12750	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12751	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12752	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12753	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12754	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12755	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12756
12757	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12758	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12759
12760	/* FIXME: use matrix-type input source selection */
12761	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12762	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12763	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12764	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12765	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12766	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12767
12768	/* set EAPD */
12769	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12770	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12771	{ }
12772};
12773
12774/* add playback controls from the parsed DAC table */
12775static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12776					     const struct auto_pin_cfg *cfg)
12777{
12778	hda_nid_t nid;
12779	int err;
12780
12781	spec->multiout.num_dacs = 1;	/* only use one dac */
12782	spec->multiout.dac_nids = spec->private_dac_nids;
12783	spec->multiout.dac_nids[0] = 2;
12784
12785	nid = cfg->line_out_pins[0];
12786	if (nid) {
12787		err = add_control(spec, ALC_CTL_WIDGET_VOL,
12788				  "Front Playback Volume",
12789				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12790		if (err < 0)
12791			return err;
12792		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12793				  "Front Playback Switch",
12794				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12795		if (err < 0)
12796			return err;
12797	}
12798
12799	nid = cfg->speaker_pins[0];
12800	if (nid) {
12801		if (!cfg->line_out_pins[0]) {
12802			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12803					  "Speaker Playback Volume",
12804					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12805							      HDA_OUTPUT));
12806			if (err < 0)
12807				return err;
12808		}
12809		if (nid == 0x16) {
12810			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12811					  "Speaker Playback Switch",
12812					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12813							      HDA_OUTPUT));
12814			if (err < 0)
12815				return err;
12816		} else {
12817			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12818					  "Speaker Playback Switch",
12819					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12820							      HDA_OUTPUT));
12821			if (err < 0)
12822				return err;
12823		}
12824	}
12825	nid = cfg->hp_pins[0];
12826	if (nid) {
12827		/* spec->multiout.hp_nid = 2; */
12828		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12829			err = add_control(spec, ALC_CTL_WIDGET_VOL,
12830					  "Headphone Playback Volume",
12831					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12832							      HDA_OUTPUT));
12833			if (err < 0)
12834				return err;
12835		}
12836		if (nid == 0x16) {
12837			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12838					  "Headphone Playback Switch",
12839					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12840							      HDA_OUTPUT));
12841			if (err < 0)
12842				return err;
12843		} else {
12844			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12845					  "Headphone Playback Switch",
12846					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12847							      HDA_OUTPUT));
12848			if (err < 0)
12849				return err;
12850		}
12851	}
12852	return 0;
12853}
12854
12855static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12856						const struct auto_pin_cfg *cfg)
12857{
12858	int err;
12859
12860	err = alc880_auto_create_analog_input_ctls(spec, cfg);
12861	if (err < 0)
12862		return err;
12863	/* digital-mic input pin is excluded in alc880_auto_create..()
12864	 * because it's under 0x18
12865	 */
12866	if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12867	    cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12868		struct hda_input_mux *imux = &spec->private_imux[0];
12869		imux->items[imux->num_items].label = "Int Mic";
12870		imux->items[imux->num_items].index = 0x05;
12871		imux->num_items++;
12872	}
12873	return 0;
12874}
12875
12876#ifdef CONFIG_SND_HDA_POWER_SAVE
12877#define alc269_loopbacks	alc880_loopbacks
12878#endif
12879
12880/* pcm configuration: identiacal with ALC880 */
12881#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
12882#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
12883#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
12884#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
12885
12886static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12887	.substreams = 1,
12888	.channels_min = 2,
12889	.channels_max = 8,
12890	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12891	/* NID is set in alc_build_pcms */
12892	.ops = {
12893		.open = alc880_playback_pcm_open,
12894		.prepare = alc880_playback_pcm_prepare,
12895		.cleanup = alc880_playback_pcm_cleanup
12896	},
12897};
12898
12899static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12900	.substreams = 1,
12901	.channels_min = 2,
12902	.channels_max = 2,
12903	.rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12904	/* NID is set in alc_build_pcms */
12905};
12906
12907/*
12908 * BIOS auto configuration
12909 */
12910static int alc269_parse_auto_config(struct hda_codec *codec)
12911{
12912	struct alc_spec *spec = codec->spec;
12913	int err;
12914	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12915
12916	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12917					   alc269_ignore);
12918	if (err < 0)
12919		return err;
12920
12921	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12922	if (err < 0)
12923		return err;
12924	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12925	if (err < 0)
12926		return err;
12927
12928	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12929
12930	if (spec->autocfg.dig_outs)
12931		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12932
12933	if (spec->kctls.list)
12934		add_mixer(spec, spec->kctls.list);
12935
12936	add_verb(spec, alc269_init_verbs);
12937	spec->num_mux_defs = 1;
12938	spec->input_mux = &spec->private_imux[0];
12939	/* set default input source */
12940	snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12941				  0, AC_VERB_SET_CONNECT_SEL,
12942				  spec->input_mux->items[0].index);
12943
12944	err = alc_auto_add_mic_boost(codec);
12945	if (err < 0)
12946		return err;
12947
12948	if (!spec->cap_mixer && !spec->no_analog)
12949		set_capture_mixer(spec);
12950
12951	return 1;
12952}
12953
12954#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
12955#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
12956#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
12957
12958
12959/* init callback for auto-configuration model -- overriding the default init */
12960static void alc269_auto_init(struct hda_codec *codec)
12961{
12962	struct alc_spec *spec = codec->spec;
12963	alc269_auto_init_multi_out(codec);
12964	alc269_auto_init_hp_out(codec);
12965	alc269_auto_init_analog_input(codec);
12966	if (spec->unsol_event)
12967		alc_inithook(codec);
12968}
12969
12970/*
12971 * configuration and preset
12972 */
12973static const char *alc269_models[ALC269_MODEL_LAST] = {
12974	[ALC269_BASIC]			= "basic",
12975	[ALC269_QUANTA_FL1]		= "quanta",
12976	[ALC269_ASUS_EEEPC_P703]	= "eeepc-p703",
12977	[ALC269_ASUS_EEEPC_P901]	= "eeepc-p901",
12978	[ALC269_FUJITSU]		= "fujitsu",
12979	[ALC269_LIFEBOOK]		= "lifebook"
12980};
12981
12982static struct snd_pci_quirk alc269_cfg_tbl[] = {
12983	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12984	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12985		      ALC269_ASUS_EEEPC_P703),
12986        SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12987        SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12988        SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12989        SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12990        SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12991        SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12992	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12993		      ALC269_ASUS_EEEPC_P901),
12994	SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12995		      ALC269_ASUS_EEEPC_P901),
12996        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12997	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12998	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12999	{}
13000};
13001
13002static struct alc_config_preset alc269_presets[] = {
13003	[ALC269_BASIC] = {
13004		.mixers = { alc269_base_mixer },
13005		.init_verbs = { alc269_init_verbs },
13006		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13007		.dac_nids = alc269_dac_nids,
13008		.hp_nid = 0x03,
13009		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13010		.channel_mode = alc269_modes,
13011		.input_mux = &alc269_capture_source,
13012	},
13013	[ALC269_QUANTA_FL1] = {
13014		.mixers = { alc269_quanta_fl1_mixer },
13015		.init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13016		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13017		.dac_nids = alc269_dac_nids,
13018		.hp_nid = 0x03,
13019		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13020		.channel_mode = alc269_modes,
13021		.input_mux = &alc269_capture_source,
13022		.unsol_event = alc269_quanta_fl1_unsol_event,
13023		.init_hook = alc269_quanta_fl1_init_hook,
13024	},
13025	[ALC269_ASUS_EEEPC_P703] = {
13026		.mixers = { alc269_eeepc_mixer },
13027		.cap_mixer = alc269_epc_capture_mixer,
13028		.init_verbs = { alc269_init_verbs,
13029				alc269_eeepc_amic_init_verbs },
13030		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13031		.dac_nids = alc269_dac_nids,
13032		.hp_nid = 0x03,
13033		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13034		.channel_mode = alc269_modes,
13035		.input_mux = &alc269_eeepc_amic_capture_source,
13036		.unsol_event = alc269_eeepc_amic_unsol_event,
13037		.init_hook = alc269_eeepc_amic_inithook,
13038	},
13039	[ALC269_ASUS_EEEPC_P901] = {
13040		.mixers = { alc269_eeepc_mixer },
13041		.cap_mixer = alc269_epc_capture_mixer,
13042		.init_verbs = { alc269_init_verbs,
13043				alc269_eeepc_dmic_init_verbs },
13044		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13045		.dac_nids = alc269_dac_nids,
13046		.hp_nid = 0x03,
13047		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13048		.channel_mode = alc269_modes,
13049		.input_mux = &alc269_eeepc_dmic_capture_source,
13050		.unsol_event = alc269_eeepc_dmic_unsol_event,
13051		.init_hook = alc269_eeepc_dmic_inithook,
13052	},
13053	[ALC269_FUJITSU] = {
13054		.mixers = { alc269_fujitsu_mixer },
13055		.cap_mixer = alc269_epc_capture_mixer,
13056		.init_verbs = { alc269_init_verbs,
13057				alc269_eeepc_dmic_init_verbs },
13058		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13059		.dac_nids = alc269_dac_nids,
13060		.hp_nid = 0x03,
13061		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13062		.channel_mode = alc269_modes,
13063		.input_mux = &alc269_eeepc_dmic_capture_source,
13064		.unsol_event = alc269_eeepc_dmic_unsol_event,
13065		.init_hook = alc269_eeepc_dmic_inithook,
13066	},
13067	[ALC269_LIFEBOOK] = {
13068		.mixers = { alc269_lifebook_mixer },
13069		.init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13070		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
13071		.dac_nids = alc269_dac_nids,
13072		.hp_nid = 0x03,
13073		.num_channel_mode = ARRAY_SIZE(alc269_modes),
13074		.channel_mode = alc269_modes,
13075		.input_mux = &alc269_capture_source,
13076		.unsol_event = alc269_lifebook_unsol_event,
13077		.init_hook = alc269_lifebook_init_hook,
13078	},
13079};
13080
13081static int patch_alc269(struct hda_codec *codec)
13082{
13083	struct alc_spec *spec;
13084	int board_config;
13085	int err;
13086
13087	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13088	if (spec == NULL)
13089		return -ENOMEM;
13090
13091	codec->spec = spec;
13092
13093	alc_fix_pll_init(codec, 0x20, 0x04, 15);
13094
13095	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13096						  alc269_models,
13097						  alc269_cfg_tbl);
13098
13099	if (board_config < 0) {
13100		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
13101		       "trying auto-probe from BIOS...\n");
13102		board_config = ALC269_AUTO;
13103	}
13104
13105	if (board_config == ALC269_AUTO) {
13106		/* automatic parse from the BIOS config */
13107		err = alc269_parse_auto_config(codec);
13108		if (err < 0) {
13109			alc_free(codec);
13110			return err;
13111		} else if (!err) {
13112			printk(KERN_INFO
13113			       "hda_codec: Cannot set up configuration "
13114			       "from BIOS.  Using base mode...\n");
13115			board_config = ALC269_BASIC;
13116		}
13117	}
13118
13119	err = snd_hda_attach_beep_device(codec, 0x1);
13120	if (err < 0) {
13121		alc_free(codec);
13122		return err;
13123	}
13124
13125	if (board_config != ALC269_AUTO)
13126		setup_preset(spec, &alc269_presets[board_config]);
13127
13128	spec->stream_name_analog = "ALC269 Analog";
13129	if (codec->subsystem_id == 0x17aa3bf8) {
13130		/* Due to a hardware problem on Lenovo Ideadpad, we need to
13131		 * fix the sample rate of analog I/O to 44.1kHz
13132		 */
13133		spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13134		spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13135	} else {
13136		spec->stream_analog_playback = &alc269_pcm_analog_playback;
13137		spec->stream_analog_capture = &alc269_pcm_analog_capture;
13138	}
13139	spec->stream_name_digital = "ALC269 Digital";
13140	spec->stream_digital_playback = &alc269_pcm_digital_playback;
13141	spec->stream_digital_capture = &alc269_pcm_digital_capture;
13142
13143	spec->adc_nids = alc269_adc_nids;
13144	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13145	spec->capsrc_nids = alc269_capsrc_nids;
13146	if (!spec->cap_mixer)
13147		set_capture_mixer(spec);
13148	set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13149
13150	codec->patch_ops = alc_patch_ops;
13151	if (board_config == ALC269_AUTO)
13152		spec->init_hook = alc269_auto_init;
13153#ifdef CONFIG_SND_HDA_POWER_SAVE
13154	if (!spec->loopback.amplist)
13155		spec->loopback.amplist = alc269_loopbacks;
13156#endif
13157	codec->proc_widget_hook = print_realtek_coef;
13158
13159	return 0;
13160}
13161
13162/*
13163 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
13164 */
13165
13166/*
13167 * set the path ways for 2 channel output
13168 * need to set the codec line out and mic 1 pin widgets to inputs
13169 */
13170static struct hda_verb alc861_threestack_ch2_init[] = {
13171	/* set pin widget 1Ah (line in) for input */
13172	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13173	/* set pin widget 18h (mic1/2) for input, for mic also enable
13174	 * the vref
13175	 */
13176	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13177
13178	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13179#if 0
13180	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13181	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13182#endif
13183	{ } /* end */
13184};
13185/*
13186 * 6ch mode
13187 * need to set the codec line out and mic 1 pin widgets to outputs
13188 */
13189static struct hda_verb alc861_threestack_ch6_init[] = {
13190	/* set pin widget 1Ah (line in) for output (Back Surround)*/
13191	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13192	/* set pin widget 18h (mic1) for output (CLFE)*/
13193	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13194
13195	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13196	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13197
13198	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13199#if 0
13200	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13201	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13202#endif
13203	{ } /* end */
13204};
13205
13206static struct hda_channel_mode alc861_threestack_modes[2] = {
13207	{ 2, alc861_threestack_ch2_init },
13208	{ 6, alc861_threestack_ch6_init },
13209};
13210/* Set mic1 as input and unmute the mixer */
13211static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13212	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13213	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13214	{ } /* end */
13215};
13216/* Set mic1 as output and mute mixer */
13217static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13218	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13219	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13220	{ } /* end */
13221};
13222
13223static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13224	{ 2, alc861_uniwill_m31_ch2_init },
13225	{ 4, alc861_uniwill_m31_ch4_init },
13226};
13227
13228/* Set mic1 and line-in as input and unmute the mixer */
13229static struct hda_verb alc861_asus_ch2_init[] = {
13230	/* set pin widget 1Ah (line in) for input */
13231	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13232	/* set pin widget 18h (mic1/2) for input, for mic also enable
13233	 * the vref
13234	 */
13235	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13236
13237	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13238#if 0
13239	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13240	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13241#endif
13242	{ } /* end */
13243};
13244/* Set mic1 nad line-in as output and mute mixer */
13245static struct hda_verb alc861_asus_ch6_init[] = {
13246	/* set pin widget 1Ah (line in) for output (Back Surround)*/
13247	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13248	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13249	/* set pin widget 18h (mic1) for output (CLFE)*/
13250	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13251	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13252	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13253	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13254
13255	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13256#if 0
13257	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13258	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13259#endif
13260	{ } /* end */
13261};
13262
13263static struct hda_channel_mode alc861_asus_modes[2] = {
13264	{ 2, alc861_asus_ch2_init },
13265	{ 6, alc861_asus_ch6_init },
13266};
13267
13268/* patch-ALC861 */
13269
13270static struct snd_kcontrol_new alc861_base_mixer[] = {
13271        /* output mixer control */
13272	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13273	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13274	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13275	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13276	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13277
13278        /*Input mixer control */
13279	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13280	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13281	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13282	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13283	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13284	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13285	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13286	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13287	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13288	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13289
13290	{ } /* end */
13291};
13292
13293static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13294        /* output mixer control */
13295	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13296	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13297	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13298	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13299	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13300
13301	/* Input mixer control */
13302	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13303	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13304	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13305	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13306	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13307	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13308	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13309	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13310	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13311	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13312
13313	{
13314		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13315		.name = "Channel Mode",
13316		.info = alc_ch_mode_info,
13317		.get = alc_ch_mode_get,
13318		.put = alc_ch_mode_put,
13319                .private_value = ARRAY_SIZE(alc861_threestack_modes),
13320	},
13321	{ } /* end */
13322};
13323
13324static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13325        /* output mixer control */
13326	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13327	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13328	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13329
13330	{ } /* end */
13331};
13332
13333static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13334        /* output mixer control */
13335	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13336	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13337	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13338	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13339	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13340
13341	/* Input mixer control */
13342	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13343	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13344	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13345	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13346	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13347	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13348	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13349	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13350	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13351	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13352
13353	{
13354		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13355		.name = "Channel Mode",
13356		.info = alc_ch_mode_info,
13357		.get = alc_ch_mode_get,
13358		.put = alc_ch_mode_put,
13359                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13360	},
13361	{ } /* end */
13362};
13363
13364static struct snd_kcontrol_new alc861_asus_mixer[] = {
13365        /* output mixer control */
13366	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13367	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13368	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13369	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13370	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13371
13372	/* Input mixer control */
13373	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13374	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13375	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13376	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13377	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13378	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13379	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13380	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13381	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13382	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13383
13384	{
13385		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13386		.name = "Channel Mode",
13387		.info = alc_ch_mode_info,
13388		.get = alc_ch_mode_get,
13389		.put = alc_ch_mode_put,
13390                .private_value = ARRAY_SIZE(alc861_asus_modes),
13391	},
13392	{ }
13393};
13394
13395/* additional mixer */
13396static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13397	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13398	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13399	{ }
13400};
13401
13402/*
13403 * generic initialization of ADC, input mixers and output mixers
13404 */
13405static struct hda_verb alc861_base_init_verbs[] = {
13406	/*
13407	 * Unmute ADC0 and set the default input to mic-in
13408	 */
13409	/* port-A for surround (rear panel) */
13410	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13411	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13412	/* port-B for mic-in (rear panel) with vref */
13413	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13414	/* port-C for line-in (rear panel) */
13415	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13416	/* port-D for Front */
13417	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13418	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13419	/* port-E for HP out (front panel) */
13420	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13421	/* route front PCM to HP */
13422	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13423	/* port-F for mic-in (front panel) with vref */
13424	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13425	/* port-G for CLFE (rear panel) */
13426	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13427	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13428	/* port-H for side (rear panel) */
13429	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13430	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13431	/* CD-in */
13432	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13433	/* route front mic to ADC1*/
13434	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13435	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13436
13437	/* Unmute DAC0~3 & spdif out*/
13438	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13439	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13440	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13441	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13442	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13443
13444	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13445	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13446        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13447	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13448        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13449
13450	/* Unmute Stereo Mixer 15 */
13451	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13452	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13453	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13454	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13455
13456	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13458	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13460	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13461	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13462	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13463	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13464	/* hp used DAC 3 (Front) */
13465	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13466        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13467
13468	{ }
13469};
13470
13471static struct hda_verb alc861_threestack_init_verbs[] = {
13472	/*
13473	 * Unmute ADC0 and set the default input to mic-in
13474	 */
13475	/* port-A for surround (rear panel) */
13476	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13477	/* port-B for mic-in (rear panel) with vref */
13478	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13479	/* port-C for line-in (rear panel) */
13480	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13481	/* port-D for Front */
13482	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13483	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13484	/* port-E for HP out (front panel) */
13485	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13486	/* route front PCM to HP */
13487	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13488	/* port-F for mic-in (front panel) with vref */
13489	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13490	/* port-G for CLFE (rear panel) */
13491	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13492	/* port-H for side (rear panel) */
13493	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13494	/* CD-in */
13495	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13496	/* route front mic to ADC1*/
13497	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13498	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13499	/* Unmute DAC0~3 & spdif out*/
13500	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13501	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13502	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13503	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13504	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13505
13506	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13507	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13508        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13509	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13510        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13511
13512	/* Unmute Stereo Mixer 15 */
13513	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13514	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13515	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13516	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13517
13518	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13519	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13520	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13521	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13522	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13523	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13524	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13525	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13526	/* hp used DAC 3 (Front) */
13527	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13528        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13529	{ }
13530};
13531
13532static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13533	/*
13534	 * Unmute ADC0 and set the default input to mic-in
13535	 */
13536	/* port-A for surround (rear panel) */
13537	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13538	/* port-B for mic-in (rear panel) with vref */
13539	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13540	/* port-C for line-in (rear panel) */
13541	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13542	/* port-D for Front */
13543	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13544	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13545	/* port-E for HP out (front panel) */
13546	/* this has to be set to VREF80 */
13547	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13548	/* route front PCM to HP */
13549	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13550	/* port-F for mic-in (front panel) with vref */
13551	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13552	/* port-G for CLFE (rear panel) */
13553	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13554	/* port-H for side (rear panel) */
13555	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13556	/* CD-in */
13557	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13558	/* route front mic to ADC1*/
13559	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13560	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13561	/* Unmute DAC0~3 & spdif out*/
13562	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13563	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13564	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13565	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13566	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13567
13568	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13569	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13570        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13571	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13572        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13573
13574	/* Unmute Stereo Mixer 15 */
13575	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13576	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13577	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13578	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13579
13580	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13581	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13582	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13583	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13584	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13585	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13586	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13587	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13588	/* hp used DAC 3 (Front) */
13589	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13590        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13591	{ }
13592};
13593
13594static struct hda_verb alc861_asus_init_verbs[] = {
13595	/*
13596	 * Unmute ADC0 and set the default input to mic-in
13597	 */
13598	/* port-A for surround (rear panel)
13599	 * according to codec#0 this is the HP jack
13600	 */
13601	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13602	/* route front PCM to HP */
13603	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13604	/* port-B for mic-in (rear panel) with vref */
13605	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13606	/* port-C for line-in (rear panel) */
13607	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13608	/* port-D for Front */
13609	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13610	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13611	/* port-E for HP out (front panel) */
13612	/* this has to be set to VREF80 */
13613	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13614	/* route front PCM to HP */
13615	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13616	/* port-F for mic-in (front panel) with vref */
13617	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13618	/* port-G for CLFE (rear panel) */
13619	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13620	/* port-H for side (rear panel) */
13621	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13622	/* CD-in */
13623	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13624	/* route front mic to ADC1*/
13625	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13626	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13627	/* Unmute DAC0~3 & spdif out*/
13628	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13629	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13630	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13631	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13632	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13633	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13634	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13635        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13636	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13637        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13638
13639	/* Unmute Stereo Mixer 15 */
13640	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13641	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13642	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13643	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13644
13645	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13646	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13647	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13648	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13649	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13650	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13651	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13652	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13653	/* hp used DAC 3 (Front) */
13654	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13655	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13656	{ }
13657};
13658
13659/* additional init verbs for ASUS laptops */
13660static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13661	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13662	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13663	{ }
13664};
13665
13666/*
13667 * generic initialization of ADC, input mixers and output mixers
13668 */
13669static struct hda_verb alc861_auto_init_verbs[] = {
13670	/*
13671	 * Unmute ADC0 and set the default input to mic-in
13672	 */
13673	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13674	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13675
13676	/* Unmute DAC0~3 & spdif out*/
13677	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13678	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13679	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13680	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13681	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13682
13683	/* Unmute Mixer 14 (mic) 1c (Line in)*/
13684	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13685	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13686	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13687	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13688
13689	/* Unmute Stereo Mixer 15 */
13690	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13691	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13692	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13693	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13694
13695	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13696	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13697	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13698	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13699	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13700	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13701	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13702	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13703
13704	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13705	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13706	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13707	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13708	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13709	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13710	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13711	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13712
13713	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
13714
13715	{ }
13716};
13717
13718static struct hda_verb alc861_toshiba_init_verbs[] = {
13719	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13720
13721	{ }
13722};
13723
13724/* toggle speaker-output according to the hp-jack state */
13725static void alc861_toshiba_automute(struct hda_codec *codec)
13726{
13727	unsigned int present;
13728
13729	present = snd_hda_codec_read(codec, 0x0f, 0,
13730				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13731	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13732				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13733	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13734				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13735}
13736
13737static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13738				       unsigned int res)
13739{
13740	if ((res >> 26) == ALC880_HP_EVENT)
13741		alc861_toshiba_automute(codec);
13742}
13743
13744/* pcm configuration: identiacal with ALC880 */
13745#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
13746#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
13747#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
13748#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
13749
13750
13751#define ALC861_DIGOUT_NID	0x07
13752
13753static struct hda_channel_mode alc861_8ch_modes[1] = {
13754	{ 8, NULL }
13755};
13756
13757static hda_nid_t alc861_dac_nids[4] = {
13758	/* front, surround, clfe, side */
13759	0x03, 0x06, 0x05, 0x04
13760};
13761
13762static hda_nid_t alc660_dac_nids[3] = {
13763	/* front, clfe, surround */
13764	0x03, 0x05, 0x06
13765};
13766
13767static hda_nid_t alc861_adc_nids[1] = {
13768	/* ADC0-2 */
13769	0x08,
13770};
13771
13772static struct hda_input_mux alc861_capture_source = {
13773	.num_items = 5,
13774	.items = {
13775		{ "Mic", 0x0 },
13776		{ "Front Mic", 0x3 },
13777		{ "Line", 0x1 },
13778		{ "CD", 0x4 },
13779		{ "Mixer", 0x5 },
13780	},
13781};
13782
13783/* fill in the dac_nids table from the parsed pin configuration */
13784static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13785				     const struct auto_pin_cfg *cfg)
13786{
13787	int i;
13788	hda_nid_t nid;
13789
13790	spec->multiout.dac_nids = spec->private_dac_nids;
13791	for (i = 0; i < cfg->line_outs; i++) {
13792		nid = cfg->line_out_pins[i];
13793		if (nid) {
13794			if (i >= ARRAY_SIZE(alc861_dac_nids))
13795				continue;
13796			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13797		}
13798	}
13799	spec->multiout.num_dacs = cfg->line_outs;
13800	return 0;
13801}
13802
13803/* add playback controls from the parsed DAC table */
13804static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13805					     const struct auto_pin_cfg *cfg)
13806{
13807	char name[32];
13808	static const char *chname[4] = {
13809		"Front", "Surround", NULL /*CLFE*/, "Side"
13810	};
13811	hda_nid_t nid;
13812	int i, idx, err;
13813
13814	for (i = 0; i < cfg->line_outs; i++) {
13815		nid = spec->multiout.dac_nids[i];
13816		if (!nid)
13817			continue;
13818		if (nid == 0x05) {
13819			/* Center/LFE */
13820			err = add_control(spec, ALC_CTL_BIND_MUTE,
13821					  "Center Playback Switch",
13822					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13823							      HDA_OUTPUT));
13824			if (err < 0)
13825				return err;
13826			err = add_control(spec, ALC_CTL_BIND_MUTE,
13827					  "LFE Playback Switch",
13828					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13829							      HDA_OUTPUT));
13830			if (err < 0)
13831				return err;
13832		} else {
13833			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13834			     idx++)
13835				if (nid == alc861_dac_nids[idx])
13836					break;
13837			sprintf(name, "%s Playback Switch", chname[idx]);
13838			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13839					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13840							      HDA_OUTPUT));
13841			if (err < 0)
13842				return err;
13843		}
13844	}
13845	return 0;
13846}
13847
13848static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13849{
13850	int err;
13851	hda_nid_t nid;
13852
13853	if (!pin)
13854		return 0;
13855
13856	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13857		nid = 0x03;
13858		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13859				  "Headphone Playback Switch",
13860				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13861		if (err < 0)
13862			return err;
13863		spec->multiout.hp_nid = nid;
13864	}
13865	return 0;
13866}
13867
13868/* create playback/capture controls for input pins */
13869static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13870						const struct auto_pin_cfg *cfg)
13871{
13872	struct hda_input_mux *imux = &spec->private_imux[0];
13873	int i, err, idx, idx1;
13874
13875	for (i = 0; i < AUTO_PIN_LAST; i++) {
13876		switch (cfg->input_pins[i]) {
13877		case 0x0c:
13878			idx1 = 1;
13879			idx = 2;	/* Line In */
13880			break;
13881		case 0x0f:
13882			idx1 = 2;
13883			idx = 2;	/* Line In */
13884			break;
13885		case 0x0d:
13886			idx1 = 0;
13887			idx = 1;	/* Mic In */
13888			break;
13889		case 0x10:
13890			idx1 = 3;
13891			idx = 1;	/* Mic In */
13892			break;
13893		case 0x11:
13894			idx1 = 4;
13895			idx = 0;	/* CD */
13896			break;
13897		default:
13898			continue;
13899		}
13900
13901		err = new_analog_input(spec, cfg->input_pins[i],
13902				       auto_pin_cfg_labels[i], idx, 0x15);
13903		if (err < 0)
13904			return err;
13905
13906		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13907		imux->items[imux->num_items].index = idx1;
13908		imux->num_items++;
13909	}
13910	return 0;
13911}
13912
13913static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13914					      hda_nid_t nid,
13915					      int pin_type, int dac_idx)
13916{
13917	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13918			    pin_type);
13919	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13920			    AMP_OUT_UNMUTE);
13921}
13922
13923static void alc861_auto_init_multi_out(struct hda_codec *codec)
13924{
13925	struct alc_spec *spec = codec->spec;
13926	int i;
13927
13928	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13929	for (i = 0; i < spec->autocfg.line_outs; i++) {
13930		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13931		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13932		if (nid)
13933			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13934							  spec->multiout.dac_nids[i]);
13935	}
13936}
13937
13938static void alc861_auto_init_hp_out(struct hda_codec *codec)
13939{
13940	struct alc_spec *spec = codec->spec;
13941	hda_nid_t pin;
13942
13943	pin = spec->autocfg.hp_pins[0];
13944	if (pin) /* connect to front */
13945		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13946						  spec->multiout.dac_nids[0]);
13947	pin = spec->autocfg.speaker_pins[0];
13948	if (pin)
13949		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13950}
13951
13952static void alc861_auto_init_analog_input(struct hda_codec *codec)
13953{
13954	struct alc_spec *spec = codec->spec;
13955	int i;
13956
13957	for (i = 0; i < AUTO_PIN_LAST; i++) {
13958		hda_nid_t nid = spec->autocfg.input_pins[i];
13959		if (nid >= 0x0c && nid <= 0x11)
13960			alc_set_input_pin(codec, nid, i);
13961	}
13962}
13963
13964/* parse the BIOS configuration and set up the alc_spec */
13965/* return 1 if successful, 0 if the proper config is not found,
13966 * or a negative error code
13967 */
13968static int alc861_parse_auto_config(struct hda_codec *codec)
13969{
13970	struct alc_spec *spec = codec->spec;
13971	int err;
13972	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13973
13974	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13975					   alc861_ignore);
13976	if (err < 0)
13977		return err;
13978	if (!spec->autocfg.line_outs)
13979		return 0; /* can't find valid BIOS pin config */
13980
13981	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13982	if (err < 0)
13983		return err;
13984	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13985	if (err < 0)
13986		return err;
13987	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13988	if (err < 0)
13989		return err;
13990	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13991	if (err < 0)
13992		return err;
13993
13994	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13995
13996	if (spec->autocfg.dig_outs)
13997		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13998
13999	if (spec->kctls.list)
14000		add_mixer(spec, spec->kctls.list);
14001
14002	add_verb(spec, alc861_auto_init_verbs);
14003
14004	spec->num_mux_defs = 1;
14005	spec->input_mux = &spec->private_imux[0];
14006
14007	spec->adc_nids = alc861_adc_nids;
14008	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14009	set_capture_mixer(spec);
14010
14011	return 1;
14012}
14013
14014/* additional initialization for auto-configuration model */
14015static void alc861_auto_init(struct hda_codec *codec)
14016{
14017	struct alc_spec *spec = codec->spec;
14018	alc861_auto_init_multi_out(codec);
14019	alc861_auto_init_hp_out(codec);
14020	alc861_auto_init_analog_input(codec);
14021	if (spec->unsol_event)
14022		alc_inithook(codec);
14023}
14024
14025#ifdef CONFIG_SND_HDA_POWER_SAVE
14026static struct hda_amp_list alc861_loopbacks[] = {
14027	{ 0x15, HDA_INPUT, 0 },
14028	{ 0x15, HDA_INPUT, 1 },
14029	{ 0x15, HDA_INPUT, 2 },
14030	{ 0x15, HDA_INPUT, 3 },
14031	{ } /* end */
14032};
14033#endif
14034
14035
14036/*
14037 * configuration and preset
14038 */
14039static const char *alc861_models[ALC861_MODEL_LAST] = {
14040	[ALC861_3ST]		= "3stack",
14041	[ALC660_3ST]		= "3stack-660",
14042	[ALC861_3ST_DIG]	= "3stack-dig",
14043	[ALC861_6ST_DIG]	= "6stack-dig",
14044	[ALC861_UNIWILL_M31]	= "uniwill-m31",
14045	[ALC861_TOSHIBA]	= "toshiba",
14046	[ALC861_ASUS]		= "asus",
14047	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
14048	[ALC861_AUTO]		= "auto",
14049};
14050
14051static struct snd_pci_quirk alc861_cfg_tbl[] = {
14052	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14053	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14054	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14055	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14056	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14057	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14058	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14059	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14060	 *        Any other models that need this preset?
14061	 */
14062	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14063	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14064	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14065	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14066	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14067	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14068	/* FIXME: the below seems conflict */
14069	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14070	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14071	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14072	{}
14073};
14074
14075static struct alc_config_preset alc861_presets[] = {
14076	[ALC861_3ST] = {
14077		.mixers = { alc861_3ST_mixer },
14078		.init_verbs = { alc861_threestack_init_verbs },
14079		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14080		.dac_nids = alc861_dac_nids,
14081		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14082		.channel_mode = alc861_threestack_modes,
14083		.need_dac_fix = 1,
14084		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14085		.adc_nids = alc861_adc_nids,
14086		.input_mux = &alc861_capture_source,
14087	},
14088	[ALC861_3ST_DIG] = {
14089		.mixers = { alc861_base_mixer },
14090		.init_verbs = { alc861_threestack_init_verbs },
14091		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14092		.dac_nids = alc861_dac_nids,
14093		.dig_out_nid = ALC861_DIGOUT_NID,
14094		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14095		.channel_mode = alc861_threestack_modes,
14096		.need_dac_fix = 1,
14097		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14098		.adc_nids = alc861_adc_nids,
14099		.input_mux = &alc861_capture_source,
14100	},
14101	[ALC861_6ST_DIG] = {
14102		.mixers = { alc861_base_mixer },
14103		.init_verbs = { alc861_base_init_verbs },
14104		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14105		.dac_nids = alc861_dac_nids,
14106		.dig_out_nid = ALC861_DIGOUT_NID,
14107		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14108		.channel_mode = alc861_8ch_modes,
14109		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14110		.adc_nids = alc861_adc_nids,
14111		.input_mux = &alc861_capture_source,
14112	},
14113	[ALC660_3ST] = {
14114		.mixers = { alc861_3ST_mixer },
14115		.init_verbs = { alc861_threestack_init_verbs },
14116		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
14117		.dac_nids = alc660_dac_nids,
14118		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14119		.channel_mode = alc861_threestack_modes,
14120		.need_dac_fix = 1,
14121		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14122		.adc_nids = alc861_adc_nids,
14123		.input_mux = &alc861_capture_source,
14124	},
14125	[ALC861_UNIWILL_M31] = {
14126		.mixers = { alc861_uniwill_m31_mixer },
14127		.init_verbs = { alc861_uniwill_m31_init_verbs },
14128		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14129		.dac_nids = alc861_dac_nids,
14130		.dig_out_nid = ALC861_DIGOUT_NID,
14131		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14132		.channel_mode = alc861_uniwill_m31_modes,
14133		.need_dac_fix = 1,
14134		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14135		.adc_nids = alc861_adc_nids,
14136		.input_mux = &alc861_capture_source,
14137	},
14138	[ALC861_TOSHIBA] = {
14139		.mixers = { alc861_toshiba_mixer },
14140		.init_verbs = { alc861_base_init_verbs,
14141				alc861_toshiba_init_verbs },
14142		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14143		.dac_nids = alc861_dac_nids,
14144		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14145		.channel_mode = alc883_3ST_2ch_modes,
14146		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14147		.adc_nids = alc861_adc_nids,
14148		.input_mux = &alc861_capture_source,
14149		.unsol_event = alc861_toshiba_unsol_event,
14150		.init_hook = alc861_toshiba_automute,
14151	},
14152	[ALC861_ASUS] = {
14153		.mixers = { alc861_asus_mixer },
14154		.init_verbs = { alc861_asus_init_verbs },
14155		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14156		.dac_nids = alc861_dac_nids,
14157		.dig_out_nid = ALC861_DIGOUT_NID,
14158		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14159		.channel_mode = alc861_asus_modes,
14160		.need_dac_fix = 1,
14161		.hp_nid = 0x06,
14162		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14163		.adc_nids = alc861_adc_nids,
14164		.input_mux = &alc861_capture_source,
14165	},
14166	[ALC861_ASUS_LAPTOP] = {
14167		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14168		.init_verbs = { alc861_asus_init_verbs,
14169				alc861_asus_laptop_init_verbs },
14170		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
14171		.dac_nids = alc861_dac_nids,
14172		.dig_out_nid = ALC861_DIGOUT_NID,
14173		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14174		.channel_mode = alc883_3ST_2ch_modes,
14175		.need_dac_fix = 1,
14176		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14177		.adc_nids = alc861_adc_nids,
14178		.input_mux = &alc861_capture_source,
14179	},
14180};
14181
14182
14183static int patch_alc861(struct hda_codec *codec)
14184{
14185	struct alc_spec *spec;
14186	int board_config;
14187	int err;
14188
14189	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14190	if (spec == NULL)
14191		return -ENOMEM;
14192
14193	codec->spec = spec;
14194
14195        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14196						  alc861_models,
14197						  alc861_cfg_tbl);
14198
14199	if (board_config < 0) {
14200		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14201		       "trying auto-probe from BIOS...\n");
14202		board_config = ALC861_AUTO;
14203	}
14204
14205	if (board_config == ALC861_AUTO) {
14206		/* automatic parse from the BIOS config */
14207		err = alc861_parse_auto_config(codec);
14208		if (err < 0) {
14209			alc_free(codec);
14210			return err;
14211		} else if (!err) {
14212			printk(KERN_INFO
14213			       "hda_codec: Cannot set up configuration "
14214			       "from BIOS.  Using base mode...\n");
14215		   board_config = ALC861_3ST_DIG;
14216		}
14217	}
14218
14219	err = snd_hda_attach_beep_device(codec, 0x23);
14220	if (err < 0) {
14221		alc_free(codec);
14222		return err;
14223	}
14224
14225	if (board_config != ALC861_AUTO)
14226		setup_preset(spec, &alc861_presets[board_config]);
14227
14228	spec->stream_name_analog = "ALC861 Analog";
14229	spec->stream_analog_playback = &alc861_pcm_analog_playback;
14230	spec->stream_analog_capture = &alc861_pcm_analog_capture;
14231
14232	spec->stream_name_digital = "ALC861 Digital";
14233	spec->stream_digital_playback = &alc861_pcm_digital_playback;
14234	spec->stream_digital_capture = &alc861_pcm_digital_capture;
14235
14236	set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14237
14238	spec->vmaster_nid = 0x03;
14239
14240	codec->patch_ops = alc_patch_ops;
14241	if (board_config == ALC861_AUTO)
14242		spec->init_hook = alc861_auto_init;
14243#ifdef CONFIG_SND_HDA_POWER_SAVE
14244	if (!spec->loopback.amplist)
14245		spec->loopback.amplist = alc861_loopbacks;
14246#endif
14247	codec->proc_widget_hook = print_realtek_coef;
14248
14249	return 0;
14250}
14251
14252/*
14253 * ALC861-VD support
14254 *
14255 * Based on ALC882
14256 *
14257 * In addition, an independent DAC
14258 */
14259#define ALC861VD_DIGOUT_NID	0x06
14260
14261static hda_nid_t alc861vd_dac_nids[4] = {
14262	/* front, surr, clfe, side surr */
14263	0x02, 0x03, 0x04, 0x05
14264};
14265
14266/* dac_nids for ALC660vd are in a different order - according to
14267 * Realtek's driver.
14268 * This should probably tesult in a different mixer for 6stack models
14269 * of ALC660vd codecs, but for now there is only 3stack mixer
14270 * - and it is the same as in 861vd.
14271 * adc_nids in ALC660vd are (is) the same as in 861vd
14272 */
14273static hda_nid_t alc660vd_dac_nids[3] = {
14274	/* front, rear, clfe, rear_surr */
14275	0x02, 0x04, 0x03
14276};
14277
14278static hda_nid_t alc861vd_adc_nids[1] = {
14279	/* ADC0 */
14280	0x09,
14281};
14282
14283static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14284
14285/* input MUX */
14286/* FIXME: should be a matrix-type input source selection */
14287static struct hda_input_mux alc861vd_capture_source = {
14288	.num_items = 4,
14289	.items = {
14290		{ "Mic", 0x0 },
14291		{ "Front Mic", 0x1 },
14292		{ "Line", 0x2 },
14293		{ "CD", 0x4 },
14294	},
14295};
14296
14297static struct hda_input_mux alc861vd_dallas_capture_source = {
14298	.num_items = 2,
14299	.items = {
14300		{ "Ext Mic", 0x0 },
14301		{ "Int Mic", 0x1 },
14302	},
14303};
14304
14305static struct hda_input_mux alc861vd_hp_capture_source = {
14306	.num_items = 2,
14307	.items = {
14308		{ "Front Mic", 0x0 },
14309		{ "ATAPI Mic", 0x1 },
14310	},
14311};
14312
14313/*
14314 * 2ch mode
14315 */
14316static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14317	{ 2, NULL }
14318};
14319
14320/*
14321 * 6ch mode
14322 */
14323static struct hda_verb alc861vd_6stack_ch6_init[] = {
14324	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14325	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14326	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14327	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14328	{ } /* end */
14329};
14330
14331/*
14332 * 8ch mode
14333 */
14334static struct hda_verb alc861vd_6stack_ch8_init[] = {
14335	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14336	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14337	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14338	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14339	{ } /* end */
14340};
14341
14342static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14343	{ 6, alc861vd_6stack_ch6_init },
14344	{ 8, alc861vd_6stack_ch8_init },
14345};
14346
14347static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14348	{
14349		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14350		.name = "Channel Mode",
14351		.info = alc_ch_mode_info,
14352		.get = alc_ch_mode_get,
14353		.put = alc_ch_mode_put,
14354	},
14355	{ } /* end */
14356};
14357
14358/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14359 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14360 */
14361static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14362	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14363	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14364
14365	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14366	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14367
14368	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14369				HDA_OUTPUT),
14370	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14371				HDA_OUTPUT),
14372	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14373	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14374
14375	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14376	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14377
14378	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14379
14380	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14381	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14382	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14383
14384	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14385	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14386	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14387
14388	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14389	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14390
14391	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14392	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14393
14394	{ } /* end */
14395};
14396
14397static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14398	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14399	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14400
14401	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14402
14403	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14404	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14405	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14406
14407	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14408	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14409	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14410
14411	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14412	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14413
14414	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14415	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14416
14417	{ } /* end */
14418};
14419
14420static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14421	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14422	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14423	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14424
14425	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14426
14427	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14428	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14429	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14430
14431	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14432	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14433	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14434
14435	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14436	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14437
14438	{ } /* end */
14439};
14440
14441/* Pin assignment: Speaker=0x14, HP = 0x15,
14442 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14443 */
14444static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14445	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14446	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14447	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14448	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14449	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14450	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14451	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14452	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14453	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14454	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14455	{ } /* end */
14456};
14457
14458/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14459 *                 Front Mic=0x18, ATAPI Mic = 0x19,
14460 */
14461static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14462	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14463	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14464	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14465	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14466	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14467	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14468	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14469	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14470
14471	{ } /* end */
14472};
14473
14474/*
14475 * generic initialization of ADC, input mixers and output mixers
14476 */
14477static struct hda_verb alc861vd_volume_init_verbs[] = {
14478	/*
14479	 * Unmute ADC0 and set the default input to mic-in
14480	 */
14481	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14482	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14483
14484	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14485	 * the analog-loopback mixer widget
14486	 */
14487	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14488	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14489	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14490	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14491	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14492	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14493
14494	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14495	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14496	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14497	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14498	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14499
14500	/*
14501	 * Set up output mixers (0x02 - 0x05)
14502	 */
14503	/* set vol=0 to output mixers */
14504	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14505	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14506	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14507	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14508
14509	/* set up input amps for analog loopback */
14510	/* Amp Indices: DAC = 0, mixer = 1 */
14511	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14512	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14513	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14514	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14515	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14516	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14517	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14518	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14519
14520	{ }
14521};
14522
14523/*
14524 * 3-stack pin configuration:
14525 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14526 */
14527static struct hda_verb alc861vd_3stack_init_verbs[] = {
14528	/*
14529	 * Set pin mode and muting
14530	 */
14531	/* set front pin widgets 0x14 for output */
14532	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14533	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14534	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14535
14536	/* Mic (rear) pin: input vref at 80% */
14537	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14538	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14539	/* Front Mic pin: input vref at 80% */
14540	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14541	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14542	/* Line In pin: input */
14543	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14544	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14545	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14546	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14547	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14548	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14549	/* CD pin widget for input */
14550	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14551
14552	{ }
14553};
14554
14555/*
14556 * 6-stack pin configuration:
14557 */
14558static struct hda_verb alc861vd_6stack_init_verbs[] = {
14559	/*
14560	 * Set pin mode and muting
14561	 */
14562	/* set front pin widgets 0x14 for output */
14563	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14564	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14565	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14566
14567	/* Rear Pin: output 1 (0x0d) */
14568	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14570	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14571	/* CLFE Pin: output 2 (0x0e) */
14572	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14573	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14574	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14575	/* Side Pin: output 3 (0x0f) */
14576	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14577	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14579
14580	/* Mic (rear) pin: input vref at 80% */
14581	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14582	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14583	/* Front Mic pin: input vref at 80% */
14584	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14585	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14586	/* Line In pin: input */
14587	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14588	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14589	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14590	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14591	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14592	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14593	/* CD pin widget for input */
14594	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14595
14596	{ }
14597};
14598
14599static struct hda_verb alc861vd_eapd_verbs[] = {
14600	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14601	{ }
14602};
14603
14604static struct hda_verb alc660vd_eapd_verbs[] = {
14605	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14606	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14607	{ }
14608};
14609
14610static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14611	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14612	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14613	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14614	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14615	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14616	{}
14617};
14618
14619/* toggle speaker-output according to the hp-jack state */
14620static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14621{
14622	unsigned int present;
14623	unsigned char bits;
14624
14625	present = snd_hda_codec_read(codec, 0x1b, 0,
14626				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14627	bits = present ? HDA_AMP_MUTE : 0;
14628	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14629				 HDA_AMP_MUTE, bits);
14630}
14631
14632static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14633{
14634	unsigned int present;
14635	unsigned char bits;
14636
14637	present = snd_hda_codec_read(codec, 0x18, 0,
14638				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14639	bits = present ? HDA_AMP_MUTE : 0;
14640	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14641				 HDA_AMP_MUTE, bits);
14642}
14643
14644static void alc861vd_lenovo_automute(struct hda_codec *codec)
14645{
14646	alc861vd_lenovo_hp_automute(codec);
14647	alc861vd_lenovo_mic_automute(codec);
14648}
14649
14650static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14651					unsigned int res)
14652{
14653	switch (res >> 26) {
14654	case ALC880_HP_EVENT:
14655		alc861vd_lenovo_hp_automute(codec);
14656		break;
14657	case ALC880_MIC_EVENT:
14658		alc861vd_lenovo_mic_automute(codec);
14659		break;
14660	}
14661}
14662
14663static struct hda_verb alc861vd_dallas_verbs[] = {
14664	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14665	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14666	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14667	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14668
14669	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14670	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14671	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14672	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14673	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14674	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14675	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14676	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14677
14678	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14679	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14680	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14681	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14682	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14683	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14684	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14685	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14686
14687	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14688	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14689	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14690	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14691	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14692	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14693	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14694	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14695
14696	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14697	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14698	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14699	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14700
14701	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14702	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14703	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14704
14705	{ } /* end */
14706};
14707
14708/* toggle speaker-output according to the hp-jack state */
14709static void alc861vd_dallas_automute(struct hda_codec *codec)
14710{
14711	unsigned int present;
14712
14713	present = snd_hda_codec_read(codec, 0x15, 0,
14714				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14715	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14716				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14717}
14718
14719static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14720{
14721	if ((res >> 26) == ALC880_HP_EVENT)
14722		alc861vd_dallas_automute(codec);
14723}
14724
14725#ifdef CONFIG_SND_HDA_POWER_SAVE
14726#define alc861vd_loopbacks	alc880_loopbacks
14727#endif
14728
14729/* pcm configuration: identiacal with ALC880 */
14730#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
14731#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
14732#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
14733#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
14734
14735/*
14736 * configuration and preset
14737 */
14738static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14739	[ALC660VD_3ST]		= "3stack-660",
14740	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
14741	[ALC660VD_ASUS_V1S]	= "asus-v1s",
14742	[ALC861VD_3ST]		= "3stack",
14743	[ALC861VD_3ST_DIG]	= "3stack-digout",
14744	[ALC861VD_6ST_DIG]	= "6stack-digout",
14745	[ALC861VD_LENOVO]	= "lenovo",
14746	[ALC861VD_DALLAS]	= "dallas",
14747	[ALC861VD_HP]		= "hp",
14748	[ALC861VD_AUTO]		= "auto",
14749};
14750
14751static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14752	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14753	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14754	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14755	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14756	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14757	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14758	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14759	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14760	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14761	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14762	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14763	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14764	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14765	SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14766	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14767	{}
14768};
14769
14770static struct alc_config_preset alc861vd_presets[] = {
14771	[ALC660VD_3ST] = {
14772		.mixers = { alc861vd_3st_mixer },
14773		.init_verbs = { alc861vd_volume_init_verbs,
14774				 alc861vd_3stack_init_verbs },
14775		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14776		.dac_nids = alc660vd_dac_nids,
14777		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14778		.channel_mode = alc861vd_3stack_2ch_modes,
14779		.input_mux = &alc861vd_capture_source,
14780	},
14781	[ALC660VD_3ST_DIG] = {
14782		.mixers = { alc861vd_3st_mixer },
14783		.init_verbs = { alc861vd_volume_init_verbs,
14784				 alc861vd_3stack_init_verbs },
14785		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14786		.dac_nids = alc660vd_dac_nids,
14787		.dig_out_nid = ALC861VD_DIGOUT_NID,
14788		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14789		.channel_mode = alc861vd_3stack_2ch_modes,
14790		.input_mux = &alc861vd_capture_source,
14791	},
14792	[ALC861VD_3ST] = {
14793		.mixers = { alc861vd_3st_mixer },
14794		.init_verbs = { alc861vd_volume_init_verbs,
14795				 alc861vd_3stack_init_verbs },
14796		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14797		.dac_nids = alc861vd_dac_nids,
14798		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14799		.channel_mode = alc861vd_3stack_2ch_modes,
14800		.input_mux = &alc861vd_capture_source,
14801	},
14802	[ALC861VD_3ST_DIG] = {
14803		.mixers = { alc861vd_3st_mixer },
14804		.init_verbs = { alc861vd_volume_init_verbs,
14805		 		 alc861vd_3stack_init_verbs },
14806		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14807		.dac_nids = alc861vd_dac_nids,
14808		.dig_out_nid = ALC861VD_DIGOUT_NID,
14809		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14810		.channel_mode = alc861vd_3stack_2ch_modes,
14811		.input_mux = &alc861vd_capture_source,
14812	},
14813	[ALC861VD_6ST_DIG] = {
14814		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14815		.init_verbs = { alc861vd_volume_init_verbs,
14816				alc861vd_6stack_init_verbs },
14817		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14818		.dac_nids = alc861vd_dac_nids,
14819		.dig_out_nid = ALC861VD_DIGOUT_NID,
14820		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14821		.channel_mode = alc861vd_6stack_modes,
14822		.input_mux = &alc861vd_capture_source,
14823	},
14824	[ALC861VD_LENOVO] = {
14825		.mixers = { alc861vd_lenovo_mixer },
14826		.init_verbs = { alc861vd_volume_init_verbs,
14827				alc861vd_3stack_init_verbs,
14828				alc861vd_eapd_verbs,
14829				alc861vd_lenovo_unsol_verbs },
14830		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14831		.dac_nids = alc660vd_dac_nids,
14832		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14833		.channel_mode = alc861vd_3stack_2ch_modes,
14834		.input_mux = &alc861vd_capture_source,
14835		.unsol_event = alc861vd_lenovo_unsol_event,
14836		.init_hook = alc861vd_lenovo_automute,
14837	},
14838	[ALC861VD_DALLAS] = {
14839		.mixers = { alc861vd_dallas_mixer },
14840		.init_verbs = { alc861vd_dallas_verbs },
14841		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14842		.dac_nids = alc861vd_dac_nids,
14843		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14844		.channel_mode = alc861vd_3stack_2ch_modes,
14845		.input_mux = &alc861vd_dallas_capture_source,
14846		.unsol_event = alc861vd_dallas_unsol_event,
14847		.init_hook = alc861vd_dallas_automute,
14848	},
14849	[ALC861VD_HP] = {
14850		.mixers = { alc861vd_hp_mixer },
14851		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14852		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14853		.dac_nids = alc861vd_dac_nids,
14854		.dig_out_nid = ALC861VD_DIGOUT_NID,
14855		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14856		.channel_mode = alc861vd_3stack_2ch_modes,
14857		.input_mux = &alc861vd_hp_capture_source,
14858		.unsol_event = alc861vd_dallas_unsol_event,
14859		.init_hook = alc861vd_dallas_automute,
14860	},
14861	[ALC660VD_ASUS_V1S] = {
14862		.mixers = { alc861vd_lenovo_mixer },
14863		.init_verbs = { alc861vd_volume_init_verbs,
14864				alc861vd_3stack_init_verbs,
14865				alc861vd_eapd_verbs,
14866				alc861vd_lenovo_unsol_verbs },
14867		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14868		.dac_nids = alc660vd_dac_nids,
14869		.dig_out_nid = ALC861VD_DIGOUT_NID,
14870		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14871		.channel_mode = alc861vd_3stack_2ch_modes,
14872		.input_mux = &alc861vd_capture_source,
14873		.unsol_event = alc861vd_lenovo_unsol_event,
14874		.init_hook = alc861vd_lenovo_automute,
14875	},
14876};
14877
14878/*
14879 * BIOS auto configuration
14880 */
14881static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14882				hda_nid_t nid, int pin_type, int dac_idx)
14883{
14884	alc_set_pin_output(codec, nid, pin_type);
14885}
14886
14887static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14888{
14889	struct alc_spec *spec = codec->spec;
14890	int i;
14891
14892	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14893	for (i = 0; i <= HDA_SIDE; i++) {
14894		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14895		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14896		if (nid)
14897			alc861vd_auto_set_output_and_unmute(codec, nid,
14898							    pin_type, i);
14899	}
14900}
14901
14902
14903static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14904{
14905	struct alc_spec *spec = codec->spec;
14906	hda_nid_t pin;
14907
14908	pin = spec->autocfg.hp_pins[0];
14909	if (pin) /* connect to front and  use dac 0 */
14910		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14911	pin = spec->autocfg.speaker_pins[0];
14912	if (pin)
14913		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14914}
14915
14916#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
14917#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
14918
14919static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14920{
14921	struct alc_spec *spec = codec->spec;
14922	int i;
14923
14924	for (i = 0; i < AUTO_PIN_LAST; i++) {
14925		hda_nid_t nid = spec->autocfg.input_pins[i];
14926		if (alc861vd_is_input_pin(nid)) {
14927			alc_set_input_pin(codec, nid, i);
14928			if (nid != ALC861VD_PIN_CD_NID &&
14929			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14930				snd_hda_codec_write(codec, nid, 0,
14931						AC_VERB_SET_AMP_GAIN_MUTE,
14932						AMP_OUT_MUTE);
14933		}
14934	}
14935}
14936
14937#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
14938
14939#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
14940#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
14941
14942/* add playback controls from the parsed DAC table */
14943/* Based on ALC880 version. But ALC861VD has separate,
14944 * different NIDs for mute/unmute switch and volume control */
14945static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14946					     const struct auto_pin_cfg *cfg)
14947{
14948	char name[32];
14949	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14950	hda_nid_t nid_v, nid_s;
14951	int i, err;
14952
14953	for (i = 0; i < cfg->line_outs; i++) {
14954		if (!spec->multiout.dac_nids[i])
14955			continue;
14956		nid_v = alc861vd_idx_to_mixer_vol(
14957				alc880_dac_to_idx(
14958					spec->multiout.dac_nids[i]));
14959		nid_s = alc861vd_idx_to_mixer_switch(
14960				alc880_dac_to_idx(
14961					spec->multiout.dac_nids[i]));
14962
14963		if (i == 2) {
14964			/* Center/LFE */
14965			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14966					  "Center Playback Volume",
14967					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14968							      HDA_OUTPUT));
14969			if (err < 0)
14970				return err;
14971			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14972					  "LFE Playback Volume",
14973					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14974							      HDA_OUTPUT));
14975			if (err < 0)
14976				return err;
14977			err = add_control(spec, ALC_CTL_BIND_MUTE,
14978					  "Center Playback Switch",
14979					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14980							      HDA_INPUT));
14981			if (err < 0)
14982				return err;
14983			err = add_control(spec, ALC_CTL_BIND_MUTE,
14984					  "LFE Playback Switch",
14985					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14986							      HDA_INPUT));
14987			if (err < 0)
14988				return err;
14989		} else {
14990			sprintf(name, "%s Playback Volume", chname[i]);
14991			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14992					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14993							      HDA_OUTPUT));
14994			if (err < 0)
14995				return err;
14996			sprintf(name, "%s Playback Switch", chname[i]);
14997			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14998					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14999							      HDA_INPUT));
15000			if (err < 0)
15001				return err;
15002		}
15003	}
15004	return 0;
15005}
15006
15007/* add playback controls for speaker and HP outputs */
15008/* Based on ALC880 version. But ALC861VD has separate,
15009 * different NIDs for mute/unmute switch and volume control */
15010static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15011					hda_nid_t pin, const char *pfx)
15012{
15013	hda_nid_t nid_v, nid_s;
15014	int err;
15015	char name[32];
15016
15017	if (!pin)
15018		return 0;
15019
15020	if (alc880_is_fixed_pin(pin)) {
15021		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15022		/* specify the DAC as the extra output */
15023		if (!spec->multiout.hp_nid)
15024			spec->multiout.hp_nid = nid_v;
15025		else
15026			spec->multiout.extra_out_nid[0] = nid_v;
15027		/* control HP volume/switch on the output mixer amp */
15028		nid_v = alc861vd_idx_to_mixer_vol(
15029				alc880_fixed_pin_idx(pin));
15030		nid_s = alc861vd_idx_to_mixer_switch(
15031				alc880_fixed_pin_idx(pin));
15032
15033		sprintf(name, "%s Playback Volume", pfx);
15034		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15035				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15036		if (err < 0)
15037			return err;
15038		sprintf(name, "%s Playback Switch", pfx);
15039		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15040				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15041		if (err < 0)
15042			return err;
15043	} else if (alc880_is_multi_pin(pin)) {
15044		/* set manual connection */
15045		/* we have only a switch on HP-out PIN */
15046		sprintf(name, "%s Playback Switch", pfx);
15047		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15048				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15049		if (err < 0)
15050			return err;
15051	}
15052	return 0;
15053}
15054
15055/* parse the BIOS configuration and set up the alc_spec
15056 * return 1 if successful, 0 if the proper config is not found,
15057 * or a negative error code
15058 * Based on ALC880 version - had to change it to override
15059 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15060static int alc861vd_parse_auto_config(struct hda_codec *codec)
15061{
15062	struct alc_spec *spec = codec->spec;
15063	int err;
15064	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15065
15066	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15067					   alc861vd_ignore);
15068	if (err < 0)
15069		return err;
15070	if (!spec->autocfg.line_outs)
15071		return 0; /* can't find valid BIOS pin config */
15072
15073	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15074	if (err < 0)
15075		return err;
15076	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15077	if (err < 0)
15078		return err;
15079	err = alc861vd_auto_create_extra_out(spec,
15080					     spec->autocfg.speaker_pins[0],
15081					     "Speaker");
15082	if (err < 0)
15083		return err;
15084	err = alc861vd_auto_create_extra_out(spec,
15085					     spec->autocfg.hp_pins[0],
15086					     "Headphone");
15087	if (err < 0)
15088		return err;
15089	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15090	if (err < 0)
15091		return err;
15092
15093	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15094
15095	if (spec->autocfg.dig_outs)
15096		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15097
15098	if (spec->kctls.list)
15099		add_mixer(spec, spec->kctls.list);
15100
15101	add_verb(spec, alc861vd_volume_init_verbs);
15102
15103	spec->num_mux_defs = 1;
15104	spec->input_mux = &spec->private_imux[0];
15105
15106	err = alc_auto_add_mic_boost(codec);
15107	if (err < 0)
15108		return err;
15109
15110	return 1;
15111}
15112
15113/* additional initialization for auto-configuration model */
15114static void alc861vd_auto_init(struct hda_codec *codec)
15115{
15116	struct alc_spec *spec = codec->spec;
15117	alc861vd_auto_init_multi_out(codec);
15118	alc861vd_auto_init_hp_out(codec);
15119	alc861vd_auto_init_analog_input(codec);
15120	alc861vd_auto_init_input_src(codec);
15121	if (spec->unsol_event)
15122		alc_inithook(codec);
15123}
15124
15125static int patch_alc861vd(struct hda_codec *codec)
15126{
15127	struct alc_spec *spec;
15128	int err, board_config;
15129
15130	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15131	if (spec == NULL)
15132		return -ENOMEM;
15133
15134	codec->spec = spec;
15135
15136	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15137						  alc861vd_models,
15138						  alc861vd_cfg_tbl);
15139
15140	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15141		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
15142			"ALC861VD, trying auto-probe from BIOS...\n");
15143		board_config = ALC861VD_AUTO;
15144	}
15145
15146	if (board_config == ALC861VD_AUTO) {
15147		/* automatic parse from the BIOS config */
15148		err = alc861vd_parse_auto_config(codec);
15149		if (err < 0) {
15150			alc_free(codec);
15151			return err;
15152		} else if (!err) {
15153			printk(KERN_INFO
15154			       "hda_codec: Cannot set up configuration "
15155			       "from BIOS.  Using base mode...\n");
15156			board_config = ALC861VD_3ST;
15157		}
15158	}
15159
15160	err = snd_hda_attach_beep_device(codec, 0x23);
15161	if (err < 0) {
15162		alc_free(codec);
15163		return err;
15164	}
15165
15166	if (board_config != ALC861VD_AUTO)
15167		setup_preset(spec, &alc861vd_presets[board_config]);
15168
15169	if (codec->vendor_id == 0x10ec0660) {
15170		spec->stream_name_analog = "ALC660-VD Analog";
15171		spec->stream_name_digital = "ALC660-VD Digital";
15172		/* always turn on EAPD */
15173		add_verb(spec, alc660vd_eapd_verbs);
15174	} else {
15175		spec->stream_name_analog = "ALC861VD Analog";
15176		spec->stream_name_digital = "ALC861VD Digital";
15177	}
15178
15179	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15180	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15181
15182	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15183	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15184
15185	spec->adc_nids = alc861vd_adc_nids;
15186	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15187	spec->capsrc_nids = alc861vd_capsrc_nids;
15188	spec->capture_style = CAPT_MIX;
15189
15190	set_capture_mixer(spec);
15191	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15192
15193	spec->vmaster_nid = 0x02;
15194
15195	codec->patch_ops = alc_patch_ops;
15196
15197	if (board_config == ALC861VD_AUTO)
15198		spec->init_hook = alc861vd_auto_init;
15199#ifdef CONFIG_SND_HDA_POWER_SAVE
15200	if (!spec->loopback.amplist)
15201		spec->loopback.amplist = alc861vd_loopbacks;
15202#endif
15203	codec->proc_widget_hook = print_realtek_coef;
15204
15205	return 0;
15206}
15207
15208/*
15209 * ALC662 support
15210 *
15211 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15212 * configuration.  Each pin widget can choose any input DACs and a mixer.
15213 * Each ADC is connected from a mixer of all inputs.  This makes possible
15214 * 6-channel independent captures.
15215 *
15216 * In addition, an independent DAC for the multi-playback (not used in this
15217 * driver yet).
15218 */
15219#define ALC662_DIGOUT_NID	0x06
15220#define ALC662_DIGIN_NID	0x0a
15221
15222static hda_nid_t alc662_dac_nids[4] = {
15223	/* front, rear, clfe, rear_surr */
15224	0x02, 0x03, 0x04
15225};
15226
15227static hda_nid_t alc272_dac_nids[2] = {
15228	0x02, 0x03
15229};
15230
15231static hda_nid_t alc662_adc_nids[1] = {
15232	/* ADC1-2 */
15233	0x09,
15234};
15235
15236static hda_nid_t alc272_adc_nids[1] = {
15237	/* ADC1-2 */
15238	0x08,
15239};
15240
15241static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15242static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15243
15244
15245/* input MUX */
15246/* FIXME: should be a matrix-type input source selection */
15247static struct hda_input_mux alc662_capture_source = {
15248	.num_items = 4,
15249	.items = {
15250		{ "Mic", 0x0 },
15251		{ "Front Mic", 0x1 },
15252		{ "Line", 0x2 },
15253		{ "CD", 0x4 },
15254	},
15255};
15256
15257static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15258	.num_items = 2,
15259	.items = {
15260		{ "Mic", 0x1 },
15261		{ "Line", 0x2 },
15262	},
15263};
15264
15265static struct hda_input_mux alc662_eeepc_capture_source = {
15266	.num_items = 2,
15267	.items = {
15268		{ "i-Mic", 0x1 },
15269		{ "e-Mic", 0x0 },
15270	},
15271};
15272
15273static struct hda_input_mux alc663_capture_source = {
15274	.num_items = 3,
15275	.items = {
15276		{ "Mic", 0x0 },
15277		{ "Front Mic", 0x1 },
15278		{ "Line", 0x2 },
15279	},
15280};
15281
15282static struct hda_input_mux alc663_m51va_capture_source = {
15283	.num_items = 2,
15284	.items = {
15285		{ "Ext-Mic", 0x0 },
15286		{ "D-Mic", 0x9 },
15287	},
15288};
15289
15290/*
15291 * 2ch mode
15292 */
15293static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15294	{ 2, NULL }
15295};
15296
15297/*
15298 * 2ch mode
15299 */
15300static struct hda_verb alc662_3ST_ch2_init[] = {
15301	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15302	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15303	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15304	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15305	{ } /* end */
15306};
15307
15308/*
15309 * 6ch mode
15310 */
15311static struct hda_verb alc662_3ST_ch6_init[] = {
15312	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15313	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15314	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15315	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15316	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15317	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15318	{ } /* end */
15319};
15320
15321static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15322	{ 2, alc662_3ST_ch2_init },
15323	{ 6, alc662_3ST_ch6_init },
15324};
15325
15326/*
15327 * 2ch mode
15328 */
15329static struct hda_verb alc662_sixstack_ch6_init[] = {
15330	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15331	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15332	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15333	{ } /* end */
15334};
15335
15336/*
15337 * 6ch mode
15338 */
15339static struct hda_verb alc662_sixstack_ch8_init[] = {
15340	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15341	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15342	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15343	{ } /* end */
15344};
15345
15346static struct hda_channel_mode alc662_5stack_modes[2] = {
15347	{ 2, alc662_sixstack_ch6_init },
15348	{ 6, alc662_sixstack_ch8_init },
15349};
15350
15351/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15352 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15353 */
15354
15355static struct snd_kcontrol_new alc662_base_mixer[] = {
15356	/* output mixer control */
15357	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15358	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15359	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15360	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15361	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15362	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15363	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15364	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15365	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15366
15367	/*Input mixer control */
15368	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15369	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15370	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15371	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15372	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15373	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15374	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15375	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15376	{ } /* end */
15377};
15378
15379static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15380	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15381	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15382	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15383	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15384	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15385	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15386	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15387	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15388	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15389	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15390	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15391	{ } /* end */
15392};
15393
15394static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15395	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15396	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15397	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15398	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15399	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15400	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15401	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15402	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15403	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15404	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15405	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15406	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15407	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15408	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15409	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15410	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15411	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15412	{ } /* end */
15413};
15414
15415static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15416	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15417	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15418	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15419	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15420	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15421	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15422	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15423	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15424	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15425	{ } /* end */
15426};
15427
15428static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15429	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15430
15431	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15432	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15433
15434	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15435	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15436	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15437
15438	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15439	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15440	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15441	{ } /* end */
15442};
15443
15444static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15445	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15446	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15447	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15448	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15449	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15450	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15451	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15452	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15453	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15454	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15455	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15456	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15457	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15458	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15459	{ } /* end */
15460};
15461
15462static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15463	.ops = &snd_hda_bind_vol,
15464	.values = {
15465		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15466		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15467		0
15468	},
15469};
15470
15471static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15472	.ops = &snd_hda_bind_sw,
15473	.values = {
15474		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15475		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15476		0
15477	},
15478};
15479
15480static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15481	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15482	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15483	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15484	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15485	{ } /* end */
15486};
15487
15488static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15489	.ops = &snd_hda_bind_sw,
15490	.values = {
15491		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15492		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15493		HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15494		0
15495	},
15496};
15497
15498static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15499	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15500	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15501	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15502	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15503	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15504	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15505
15506	{ } /* end */
15507};
15508
15509static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15510	.ops = &snd_hda_bind_sw,
15511	.values = {
15512		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15513		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15514		HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15515		0
15516	},
15517};
15518
15519static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15520	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15521	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15522	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15523	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15524	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15525	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15526	{ } /* end */
15527};
15528
15529static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15530	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15531	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15532	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15533	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15534	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15535	HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15536	HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15537	{ } /* end */
15538};
15539
15540static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15541	.ops = &snd_hda_bind_vol,
15542	.values = {
15543		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15544		HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15545		0
15546	},
15547};
15548
15549static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15550	.ops = &snd_hda_bind_sw,
15551	.values = {
15552		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15553		HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15554		0
15555	},
15556};
15557
15558static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15559	HDA_BIND_VOL("Master Playback Volume",
15560				&alc663_asus_two_bind_master_vol),
15561	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15562	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15563	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15564	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15565	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15566	{ } /* end */
15567};
15568
15569static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15570	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15571	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15572	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15573	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15574	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15575	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15576	{ } /* end */
15577};
15578
15579static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15580	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15581	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15582	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15583	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15584	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15585
15586	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15587	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15588	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15589	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15590	{ } /* end */
15591};
15592
15593static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15594	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15595	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15596	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15597
15598	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15599	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15600	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15601	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15602	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15603	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15604	{ } /* end */
15605};
15606
15607static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15608	{
15609		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15610		.name = "Channel Mode",
15611		.info = alc_ch_mode_info,
15612		.get = alc_ch_mode_get,
15613		.put = alc_ch_mode_put,
15614	},
15615	{ } /* end */
15616};
15617
15618static struct hda_verb alc662_init_verbs[] = {
15619	/* ADC: mute amp left and right */
15620	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15621	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15622	/* Front mixer: unmute input/output amp left and right (volume = 0) */
15623
15624	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15625	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15626	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15627	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15628	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15629
15630	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15631	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15632	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15634	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15635	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15636
15637	/* Front Pin: output 0 (0x0c) */
15638	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15639	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15640
15641	/* Rear Pin: output 1 (0x0d) */
15642	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15643	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15644
15645	/* CLFE Pin: output 2 (0x0e) */
15646	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15647	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15648
15649	/* Mic (rear) pin: input vref at 80% */
15650	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15651	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15652	/* Front Mic pin: input vref at 80% */
15653	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15654	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15655	/* Line In pin: input */
15656	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15657	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15658	/* Line-2 In: Headphone output (output 0 - 0x0c) */
15659	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15660	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15661	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15662	/* CD pin widget for input */
15663	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15664
15665	/* FIXME: use matrix-type input source selection */
15666	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15667	/* Input mixer */
15668	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15669	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15670
15671	/* always trun on EAPD */
15672	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15673	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15674
15675	{ }
15676};
15677
15678static struct hda_verb alc662_sue_init_verbs[] = {
15679	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15680	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15681	{}
15682};
15683
15684static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15685	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15686	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15687	{}
15688};
15689
15690/* Set Unsolicited Event*/
15691static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15692	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15693	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15694	{}
15695};
15696
15697/*
15698 * generic initialization of ADC, input mixers and output mixers
15699 */
15700static struct hda_verb alc662_auto_init_verbs[] = {
15701	/*
15702	 * Unmute ADC and set the default input to mic-in
15703	 */
15704	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15705	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706
15707	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15708	 * mixer widget
15709	 * Note: PASD motherboards uses the Line In 2 as the input for front
15710	 * panel mic (mic 2)
15711	 */
15712	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15713	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15714	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15715	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15716	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15717	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15718
15719	/*
15720	 * Set up output mixers (0x0c - 0x0f)
15721	 */
15722	/* set vol=0 to output mixers */
15723	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15724	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15725	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15726
15727	/* set up input amps for analog loopback */
15728	/* Amp Indices: DAC = 0, mixer = 1 */
15729	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15730	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15731	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15732	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15733	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15735
15736
15737	/* FIXME: use matrix-type input source selection */
15738	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15739	/* Input mixer */
15740	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15741	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15742	{ }
15743};
15744
15745/* additional verbs for ALC663 */
15746static struct hda_verb alc663_auto_init_verbs[] = {
15747	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15749	{ }
15750};
15751
15752static struct hda_verb alc663_m51va_init_verbs[] = {
15753	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15754	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15755	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15756	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15757	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15758	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15759	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15760	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15761	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15762	{}
15763};
15764
15765static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15766	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15767	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15768	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15769	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15770	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15772	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15773	{}
15774};
15775
15776static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15777	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15778	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15779	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15780	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15781	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15782	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15784	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15785	{}
15786};
15787
15788static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15789	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15790	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15791	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15792	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15793	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15794	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15795	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15796	{}
15797};
15798
15799static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15800	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15801	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15802	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15803	{0x21, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15804	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15805	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15806	{0x15, AC_VERB_SET_CONNECT_SEL, 0x0},	/* Headphone */
15807	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15808	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15809	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15810	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15811	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15812	{}
15813};
15814
15815static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15816	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15817	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15818	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15820	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15821	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15822	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15823	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15824	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15825	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15826	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15827	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15828	{}
15829};
15830
15831static struct hda_verb alc663_g71v_init_verbs[] = {
15832	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15833	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15834	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15835
15836	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15837	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15838	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15839
15840	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15841	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15842	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15843	{}
15844};
15845
15846static struct hda_verb alc663_g50v_init_verbs[] = {
15847	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15848	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15849	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
15850
15851	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15852	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15853	{}
15854};
15855
15856static struct hda_verb alc662_ecs_init_verbs[] = {
15857	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15858	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15859	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15860	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15861	{}
15862};
15863
15864static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15865	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15866	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15867	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15868	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15869	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15870	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15871	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15872	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15873	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15874	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15875	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15876	{}
15877};
15878
15879static struct hda_verb alc272_dell_init_verbs[] = {
15880	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15881	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15882	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15883	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15884	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15885	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15886	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */
15887	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15888	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15889	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15890	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15891	{}
15892};
15893
15894static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15895	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15896	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15897	{ } /* end */
15898};
15899
15900static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15901	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15902	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15903	{ } /* end */
15904};
15905
15906static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15907{
15908	unsigned int present;
15909	unsigned char bits;
15910
15911	present = snd_hda_codec_read(codec, 0x14, 0,
15912				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15913	bits = present ? HDA_AMP_MUTE : 0;
15914	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15915				 HDA_AMP_MUTE, bits);
15916}
15917
15918static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15919{
15920	unsigned int present;
15921	unsigned char bits;
15922
15923 	present = snd_hda_codec_read(codec, 0x1b, 0,
15924				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15925	bits = present ? HDA_AMP_MUTE : 0;
15926	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15927				 HDA_AMP_MUTE, bits);
15928	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15929				 HDA_AMP_MUTE, bits);
15930}
15931
15932static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15933					   unsigned int res)
15934{
15935	if ((res >> 26) == ALC880_HP_EVENT)
15936		alc662_lenovo_101e_all_automute(codec);
15937	if ((res >> 26) == ALC880_FRONT_EVENT)
15938		alc662_lenovo_101e_ispeaker_automute(codec);
15939}
15940
15941static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15942{
15943	unsigned int present;
15944
15945	present = snd_hda_codec_read(codec, 0x18, 0,
15946				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15947	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15948			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15949	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15950			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15951	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15952			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15953	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15954			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15955}
15956
15957/* unsolicited event for HP jack sensing */
15958static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15959				     unsigned int res)
15960{
15961	if ((res >> 26) == ALC880_HP_EVENT)
15962		alc262_hippo1_automute( codec );
15963
15964	if ((res >> 26) == ALC880_MIC_EVENT)
15965		alc662_eeepc_mic_automute(codec);
15966}
15967
15968static void alc662_eeepc_inithook(struct hda_codec *codec)
15969{
15970	alc262_hippo1_automute( codec );
15971	alc662_eeepc_mic_automute(codec);
15972}
15973
15974static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15975{
15976	unsigned int mute;
15977	unsigned int present;
15978
15979	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15980	present = snd_hda_codec_read(codec, 0x14, 0,
15981				     AC_VERB_GET_PIN_SENSE, 0);
15982	present = (present & 0x80000000) != 0;
15983	if (present) {
15984		/* mute internal speaker */
15985		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15986					HDA_AMP_MUTE, HDA_AMP_MUTE);
15987	} else {
15988		/* unmute internal speaker if necessary */
15989		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15990		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15991					HDA_AMP_MUTE, mute);
15992	}
15993}
15994
15995/* unsolicited event for HP jack sensing */
15996static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15997					  unsigned int res)
15998{
15999	if ((res >> 26) == ALC880_HP_EVENT)
16000		alc662_eeepc_ep20_automute(codec);
16001}
16002
16003static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16004{
16005	alc662_eeepc_ep20_automute(codec);
16006}
16007
16008static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16009{
16010	unsigned int present;
16011	unsigned char bits;
16012
16013	present = snd_hda_codec_read(codec, 0x21, 0,
16014			AC_VERB_GET_PIN_SENSE, 0)
16015			& AC_PINSENSE_PRESENCE;
16016	bits = present ? HDA_AMP_MUTE : 0;
16017	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16018				AMP_IN_MUTE(0), bits);
16019	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16020				AMP_IN_MUTE(0), bits);
16021}
16022
16023static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16024{
16025	unsigned int present;
16026	unsigned char bits;
16027
16028	present = snd_hda_codec_read(codec, 0x21, 0,
16029			AC_VERB_GET_PIN_SENSE, 0)
16030			& AC_PINSENSE_PRESENCE;
16031	bits = present ? HDA_AMP_MUTE : 0;
16032	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16033				AMP_IN_MUTE(0), bits);
16034	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16035				AMP_IN_MUTE(0), bits);
16036	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16037				AMP_IN_MUTE(0), bits);
16038	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16039				AMP_IN_MUTE(0), bits);
16040}
16041
16042static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16043{
16044	unsigned int present;
16045	unsigned char bits;
16046
16047	present = snd_hda_codec_read(codec, 0x15, 0,
16048			AC_VERB_GET_PIN_SENSE, 0)
16049			& AC_PINSENSE_PRESENCE;
16050	bits = present ? HDA_AMP_MUTE : 0;
16051	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16052				AMP_IN_MUTE(0), bits);
16053	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16054				AMP_IN_MUTE(0), bits);
16055	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16056				AMP_IN_MUTE(0), bits);
16057	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16058				AMP_IN_MUTE(0), bits);
16059}
16060
16061static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16062{
16063	unsigned int present;
16064	unsigned char bits;
16065
16066	present = snd_hda_codec_read(codec, 0x1b, 0,
16067			AC_VERB_GET_PIN_SENSE, 0)
16068			& AC_PINSENSE_PRESENCE;
16069	bits = present ? 0 : PIN_OUT;
16070	snd_hda_codec_write(codec, 0x14, 0,
16071			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16072}
16073
16074static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16075{
16076	unsigned int present1, present2;
16077
16078	present1 = snd_hda_codec_read(codec, 0x21, 0,
16079			AC_VERB_GET_PIN_SENSE, 0)
16080			& AC_PINSENSE_PRESENCE;
16081	present2 = snd_hda_codec_read(codec, 0x15, 0,
16082			AC_VERB_GET_PIN_SENSE, 0)
16083			& AC_PINSENSE_PRESENCE;
16084
16085	if (present1 || present2) {
16086		snd_hda_codec_write_cache(codec, 0x14, 0,
16087			AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16088	} else {
16089		snd_hda_codec_write_cache(codec, 0x14, 0,
16090			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16091	}
16092}
16093
16094static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16095{
16096	unsigned int present1, present2;
16097
16098	present1 = snd_hda_codec_read(codec, 0x1b, 0,
16099				AC_VERB_GET_PIN_SENSE, 0)
16100				& AC_PINSENSE_PRESENCE;
16101	present2 = snd_hda_codec_read(codec, 0x15, 0,
16102				AC_VERB_GET_PIN_SENSE, 0)
16103				& AC_PINSENSE_PRESENCE;
16104
16105	if (present1 || present2) {
16106		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16107				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16108		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16109				AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16110	} else {
16111		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16112				AMP_IN_MUTE(0), 0);
16113		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16114				AMP_IN_MUTE(0), 0);
16115	}
16116}
16117
16118static void alc663_m51va_mic_automute(struct hda_codec *codec)
16119{
16120	unsigned int present;
16121
16122	present = snd_hda_codec_read(codec, 0x18, 0,
16123			AC_VERB_GET_PIN_SENSE, 0)
16124			& AC_PINSENSE_PRESENCE;
16125	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16126			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16127	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16128			0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16129	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16130			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16131	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16132			0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16133}
16134
16135static void alc663_m51va_unsol_event(struct hda_codec *codec,
16136					   unsigned int res)
16137{
16138	switch (res >> 26) {
16139	case ALC880_HP_EVENT:
16140		alc663_m51va_speaker_automute(codec);
16141		break;
16142	case ALC880_MIC_EVENT:
16143		alc663_m51va_mic_automute(codec);
16144		break;
16145	}
16146}
16147
16148static void alc663_m51va_inithook(struct hda_codec *codec)
16149{
16150	alc663_m51va_speaker_automute(codec);
16151	alc663_m51va_mic_automute(codec);
16152}
16153
16154/* ***************** Mode1 ******************************/
16155static void alc663_mode1_unsol_event(struct hda_codec *codec,
16156					   unsigned int res)
16157{
16158	switch (res >> 26) {
16159	case ALC880_HP_EVENT:
16160		alc663_m51va_speaker_automute(codec);
16161		break;
16162	case ALC880_MIC_EVENT:
16163		alc662_eeepc_mic_automute(codec);
16164		break;
16165	}
16166}
16167
16168static void alc663_mode1_inithook(struct hda_codec *codec)
16169{
16170	alc663_m51va_speaker_automute(codec);
16171	alc662_eeepc_mic_automute(codec);
16172}
16173/* ***************** Mode2 ******************************/
16174static void alc662_mode2_unsol_event(struct hda_codec *codec,
16175					   unsigned int res)
16176{
16177	switch (res >> 26) {
16178	case ALC880_HP_EVENT:
16179		alc662_f5z_speaker_automute(codec);
16180		break;
16181	case ALC880_MIC_EVENT:
16182		alc662_eeepc_mic_automute(codec);
16183		break;
16184	}
16185}
16186
16187static void alc662_mode2_inithook(struct hda_codec *codec)
16188{
16189	alc662_f5z_speaker_automute(codec);
16190	alc662_eeepc_mic_automute(codec);
16191}
16192/* ***************** Mode3 ******************************/
16193static void alc663_mode3_unsol_event(struct hda_codec *codec,
16194					   unsigned int res)
16195{
16196	switch (res >> 26) {
16197	case ALC880_HP_EVENT:
16198		alc663_two_hp_m1_speaker_automute(codec);
16199		break;
16200	case ALC880_MIC_EVENT:
16201		alc662_eeepc_mic_automute(codec);
16202		break;
16203	}
16204}
16205
16206static void alc663_mode3_inithook(struct hda_codec *codec)
16207{
16208	alc663_two_hp_m1_speaker_automute(codec);
16209	alc662_eeepc_mic_automute(codec);
16210}
16211/* ***************** Mode4 ******************************/
16212static void alc663_mode4_unsol_event(struct hda_codec *codec,
16213					   unsigned int res)
16214{
16215	switch (res >> 26) {
16216	case ALC880_HP_EVENT:
16217		alc663_21jd_two_speaker_automute(codec);
16218		break;
16219	case ALC880_MIC_EVENT:
16220		alc662_eeepc_mic_automute(codec);
16221		break;
16222	}
16223}
16224
16225static void alc663_mode4_inithook(struct hda_codec *codec)
16226{
16227	alc663_21jd_two_speaker_automute(codec);
16228	alc662_eeepc_mic_automute(codec);
16229}
16230/* ***************** Mode5 ******************************/
16231static void alc663_mode5_unsol_event(struct hda_codec *codec,
16232					   unsigned int res)
16233{
16234	switch (res >> 26) {
16235	case ALC880_HP_EVENT:
16236		alc663_15jd_two_speaker_automute(codec);
16237		break;
16238	case ALC880_MIC_EVENT:
16239		alc662_eeepc_mic_automute(codec);
16240		break;
16241	}
16242}
16243
16244static void alc663_mode5_inithook(struct hda_codec *codec)
16245{
16246	alc663_15jd_two_speaker_automute(codec);
16247	alc662_eeepc_mic_automute(codec);
16248}
16249/* ***************** Mode6 ******************************/
16250static void alc663_mode6_unsol_event(struct hda_codec *codec,
16251					   unsigned int res)
16252{
16253	switch (res >> 26) {
16254	case ALC880_HP_EVENT:
16255		alc663_two_hp_m2_speaker_automute(codec);
16256		break;
16257	case ALC880_MIC_EVENT:
16258		alc662_eeepc_mic_automute(codec);
16259		break;
16260	}
16261}
16262
16263static void alc663_mode6_inithook(struct hda_codec *codec)
16264{
16265	alc663_two_hp_m2_speaker_automute(codec);
16266	alc662_eeepc_mic_automute(codec);
16267}
16268
16269static void alc663_g71v_hp_automute(struct hda_codec *codec)
16270{
16271	unsigned int present;
16272	unsigned char bits;
16273
16274	present = snd_hda_codec_read(codec, 0x21, 0,
16275				     AC_VERB_GET_PIN_SENSE, 0)
16276		& AC_PINSENSE_PRESENCE;
16277	bits = present ? HDA_AMP_MUTE : 0;
16278	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16279				 HDA_AMP_MUTE, bits);
16280	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16281				 HDA_AMP_MUTE, bits);
16282}
16283
16284static void alc663_g71v_front_automute(struct hda_codec *codec)
16285{
16286	unsigned int present;
16287	unsigned char bits;
16288
16289	present = snd_hda_codec_read(codec, 0x15, 0,
16290				     AC_VERB_GET_PIN_SENSE, 0)
16291		& AC_PINSENSE_PRESENCE;
16292	bits = present ? HDA_AMP_MUTE : 0;
16293	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16294				 HDA_AMP_MUTE, bits);
16295}
16296
16297static void alc663_g71v_unsol_event(struct hda_codec *codec,
16298					   unsigned int res)
16299{
16300	switch (res >> 26) {
16301	case ALC880_HP_EVENT:
16302		alc663_g71v_hp_automute(codec);
16303		break;
16304	case ALC880_FRONT_EVENT:
16305		alc663_g71v_front_automute(codec);
16306		break;
16307	case ALC880_MIC_EVENT:
16308		alc662_eeepc_mic_automute(codec);
16309		break;
16310	}
16311}
16312
16313static void alc663_g71v_inithook(struct hda_codec *codec)
16314{
16315	alc663_g71v_front_automute(codec);
16316	alc663_g71v_hp_automute(codec);
16317	alc662_eeepc_mic_automute(codec);
16318}
16319
16320static void alc663_g50v_unsol_event(struct hda_codec *codec,
16321					   unsigned int res)
16322{
16323	switch (res >> 26) {
16324	case ALC880_HP_EVENT:
16325		alc663_m51va_speaker_automute(codec);
16326		break;
16327	case ALC880_MIC_EVENT:
16328		alc662_eeepc_mic_automute(codec);
16329		break;
16330	}
16331}
16332
16333static void alc663_g50v_inithook(struct hda_codec *codec)
16334{
16335	alc663_m51va_speaker_automute(codec);
16336	alc662_eeepc_mic_automute(codec);
16337}
16338
16339/* bind hp and internal speaker mute (with plug check) */
16340static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16341				     struct snd_ctl_elem_value *ucontrol)
16342{
16343	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16344	long *valp = ucontrol->value.integer.value;
16345	int change;
16346
16347	change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16348					  HDA_AMP_MUTE,
16349					  valp[0] ? 0 : HDA_AMP_MUTE);
16350	change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16351					   HDA_AMP_MUTE,
16352					   valp[1] ? 0 : HDA_AMP_MUTE);
16353	if (change)
16354		alc262_hippo1_automute(codec);
16355	return change;
16356}
16357
16358static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16359	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16360	{
16361		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16362		.name = "Master Playback Switch",
16363		.info = snd_hda_mixer_amp_switch_info,
16364		.get = snd_hda_mixer_amp_switch_get,
16365		.put = alc662_ecs_master_sw_put,
16366		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16367	},
16368
16369	HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16370	HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16371	HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16372
16373	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16374	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16375	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16376	{ } /* end */
16377};
16378
16379#ifdef CONFIG_SND_HDA_POWER_SAVE
16380#define alc662_loopbacks	alc880_loopbacks
16381#endif
16382
16383
16384/* pcm configuration: identiacal with ALC880 */
16385#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
16386#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
16387#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
16388#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
16389
16390/*
16391 * configuration and preset
16392 */
16393static const char *alc662_models[ALC662_MODEL_LAST] = {
16394	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
16395	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
16396	[ALC662_3ST_6ch]	= "3stack-6ch",
16397	[ALC662_5ST_DIG]	= "6stack-dig",
16398	[ALC662_LENOVO_101E]	= "lenovo-101e",
16399	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16400	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16401	[ALC662_ECS] = "ecs",
16402	[ALC663_ASUS_M51VA] = "m51va",
16403	[ALC663_ASUS_G71V] = "g71v",
16404	[ALC663_ASUS_H13] = "h13",
16405	[ALC663_ASUS_G50V] = "g50v",
16406	[ALC663_ASUS_MODE1] = "asus-mode1",
16407	[ALC662_ASUS_MODE2] = "asus-mode2",
16408	[ALC663_ASUS_MODE3] = "asus-mode3",
16409	[ALC663_ASUS_MODE4] = "asus-mode4",
16410	[ALC663_ASUS_MODE5] = "asus-mode5",
16411	[ALC663_ASUS_MODE6] = "asus-mode6",
16412	[ALC662_AUTO]		= "auto",
16413};
16414
16415static struct snd_pci_quirk alc662_cfg_tbl[] = {
16416	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16417	SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16418	SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16419	SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16420	SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16421	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16422	SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16423	SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16424	SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16425	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16426	SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16427	SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16428	SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16429	SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16430	SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16431	SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16432	SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16433	SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16434	SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16435	SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16436	SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16437	SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16438	SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16439	SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16440	SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16441	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16442	/*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16443	SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16444	SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16445	SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16446	SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16447	SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16448	SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16449	SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16450	SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16451	SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16452	SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16453	SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16454	SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16455	SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16456	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16457	/*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16458	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16459	SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16460	SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16461	SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16462	SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16463	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16464	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16465	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16466	SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16467	SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16468		      ALC662_3ST_6ch_DIG),
16469	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16470		      ALC662_3ST_6ch_DIG),
16471	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16472	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16473	SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16474					ALC662_3ST_6ch_DIG),
16475	SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16476			   ALC663_ASUS_H13),
16477	{}
16478};
16479
16480static struct alc_config_preset alc662_presets[] = {
16481	[ALC662_3ST_2ch_DIG] = {
16482		.mixers = { alc662_3ST_2ch_mixer },
16483		.init_verbs = { alc662_init_verbs },
16484		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16485		.dac_nids = alc662_dac_nids,
16486		.dig_out_nid = ALC662_DIGOUT_NID,
16487		.dig_in_nid = ALC662_DIGIN_NID,
16488		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16489		.channel_mode = alc662_3ST_2ch_modes,
16490		.input_mux = &alc662_capture_source,
16491	},
16492	[ALC662_3ST_6ch_DIG] = {
16493		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16494		.init_verbs = { alc662_init_verbs },
16495		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16496		.dac_nids = alc662_dac_nids,
16497		.dig_out_nid = ALC662_DIGOUT_NID,
16498		.dig_in_nid = ALC662_DIGIN_NID,
16499		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16500		.channel_mode = alc662_3ST_6ch_modes,
16501		.need_dac_fix = 1,
16502		.input_mux = &alc662_capture_source,
16503	},
16504	[ALC662_3ST_6ch] = {
16505		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16506		.init_verbs = { alc662_init_verbs },
16507		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16508		.dac_nids = alc662_dac_nids,
16509		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16510		.channel_mode = alc662_3ST_6ch_modes,
16511		.need_dac_fix = 1,
16512		.input_mux = &alc662_capture_source,
16513	},
16514	[ALC662_5ST_DIG] = {
16515		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
16516		.init_verbs = { alc662_init_verbs },
16517		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16518		.dac_nids = alc662_dac_nids,
16519		.dig_out_nid = ALC662_DIGOUT_NID,
16520		.dig_in_nid = ALC662_DIGIN_NID,
16521		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16522		.channel_mode = alc662_5stack_modes,
16523		.input_mux = &alc662_capture_source,
16524	},
16525	[ALC662_LENOVO_101E] = {
16526		.mixers = { alc662_lenovo_101e_mixer },
16527		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16528		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16529		.dac_nids = alc662_dac_nids,
16530		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16531		.channel_mode = alc662_3ST_2ch_modes,
16532		.input_mux = &alc662_lenovo_101e_capture_source,
16533		.unsol_event = alc662_lenovo_101e_unsol_event,
16534		.init_hook = alc662_lenovo_101e_all_automute,
16535	},
16536	[ALC662_ASUS_EEEPC_P701] = {
16537		.mixers = { alc662_eeepc_p701_mixer },
16538		.init_verbs = { alc662_init_verbs,
16539				alc662_eeepc_sue_init_verbs },
16540		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16541		.dac_nids = alc662_dac_nids,
16542		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16543		.channel_mode = alc662_3ST_2ch_modes,
16544		.input_mux = &alc662_eeepc_capture_source,
16545		.unsol_event = alc662_eeepc_unsol_event,
16546		.init_hook = alc662_eeepc_inithook,
16547	},
16548	[ALC662_ASUS_EEEPC_EP20] = {
16549		.mixers = { alc662_eeepc_ep20_mixer,
16550			    alc662_chmode_mixer },
16551		.init_verbs = { alc662_init_verbs,
16552				alc662_eeepc_ep20_sue_init_verbs },
16553		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16554		.dac_nids = alc662_dac_nids,
16555		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16556		.channel_mode = alc662_3ST_6ch_modes,
16557		.input_mux = &alc662_lenovo_101e_capture_source,
16558		.unsol_event = alc662_eeepc_ep20_unsol_event,
16559		.init_hook = alc662_eeepc_ep20_inithook,
16560	},
16561	[ALC662_ECS] = {
16562		.mixers = { alc662_ecs_mixer },
16563		.init_verbs = { alc662_init_verbs,
16564				alc662_ecs_init_verbs },
16565		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16566		.dac_nids = alc662_dac_nids,
16567		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16568		.channel_mode = alc662_3ST_2ch_modes,
16569		.input_mux = &alc662_eeepc_capture_source,
16570		.unsol_event = alc662_eeepc_unsol_event,
16571		.init_hook = alc662_eeepc_inithook,
16572	},
16573	[ALC663_ASUS_M51VA] = {
16574		.mixers = { alc663_m51va_mixer },
16575		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16576		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16577		.dac_nids = alc662_dac_nids,
16578		.dig_out_nid = ALC662_DIGOUT_NID,
16579		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16580		.channel_mode = alc662_3ST_2ch_modes,
16581		.input_mux = &alc663_m51va_capture_source,
16582		.unsol_event = alc663_m51va_unsol_event,
16583		.init_hook = alc663_m51va_inithook,
16584	},
16585	[ALC663_ASUS_G71V] = {
16586		.mixers = { alc663_g71v_mixer },
16587		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16588		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16589		.dac_nids = alc662_dac_nids,
16590		.dig_out_nid = ALC662_DIGOUT_NID,
16591		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16592		.channel_mode = alc662_3ST_2ch_modes,
16593		.input_mux = &alc662_eeepc_capture_source,
16594		.unsol_event = alc663_g71v_unsol_event,
16595		.init_hook = alc663_g71v_inithook,
16596	},
16597	[ALC663_ASUS_H13] = {
16598		.mixers = { alc663_m51va_mixer },
16599		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16600		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16601		.dac_nids = alc662_dac_nids,
16602		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16603		.channel_mode = alc662_3ST_2ch_modes,
16604		.input_mux = &alc663_m51va_capture_source,
16605		.unsol_event = alc663_m51va_unsol_event,
16606		.init_hook = alc663_m51va_inithook,
16607	},
16608	[ALC663_ASUS_G50V] = {
16609		.mixers = { alc663_g50v_mixer },
16610		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16611		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16612		.dac_nids = alc662_dac_nids,
16613		.dig_out_nid = ALC662_DIGOUT_NID,
16614		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16615		.channel_mode = alc662_3ST_6ch_modes,
16616		.input_mux = &alc663_capture_source,
16617		.unsol_event = alc663_g50v_unsol_event,
16618		.init_hook = alc663_g50v_inithook,
16619	},
16620	[ALC663_ASUS_MODE1] = {
16621		.mixers = { alc663_m51va_mixer },
16622		.cap_mixer = alc662_auto_capture_mixer,
16623		.init_verbs = { alc662_init_verbs,
16624				alc663_21jd_amic_init_verbs },
16625		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16626		.hp_nid = 0x03,
16627		.dac_nids = alc662_dac_nids,
16628		.dig_out_nid = ALC662_DIGOUT_NID,
16629		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16630		.channel_mode = alc662_3ST_2ch_modes,
16631		.input_mux = &alc662_eeepc_capture_source,
16632		.unsol_event = alc663_mode1_unsol_event,
16633		.init_hook = alc663_mode1_inithook,
16634	},
16635	[ALC662_ASUS_MODE2] = {
16636		.mixers = { alc662_1bjd_mixer },
16637		.cap_mixer = alc662_auto_capture_mixer,
16638		.init_verbs = { alc662_init_verbs,
16639				alc662_1bjd_amic_init_verbs },
16640		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16641		.dac_nids = alc662_dac_nids,
16642		.dig_out_nid = ALC662_DIGOUT_NID,
16643		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16644		.channel_mode = alc662_3ST_2ch_modes,
16645		.input_mux = &alc662_eeepc_capture_source,
16646		.unsol_event = alc662_mode2_unsol_event,
16647		.init_hook = alc662_mode2_inithook,
16648	},
16649	[ALC663_ASUS_MODE3] = {
16650		.mixers = { alc663_two_hp_m1_mixer },
16651		.cap_mixer = alc662_auto_capture_mixer,
16652		.init_verbs = { alc662_init_verbs,
16653				alc663_two_hp_amic_m1_init_verbs },
16654		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16655		.hp_nid = 0x03,
16656		.dac_nids = alc662_dac_nids,
16657		.dig_out_nid = ALC662_DIGOUT_NID,
16658		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16659		.channel_mode = alc662_3ST_2ch_modes,
16660		.input_mux = &alc662_eeepc_capture_source,
16661		.unsol_event = alc663_mode3_unsol_event,
16662		.init_hook = alc663_mode3_inithook,
16663	},
16664	[ALC663_ASUS_MODE4] = {
16665		.mixers = { alc663_asus_21jd_clfe_mixer },
16666		.cap_mixer = alc662_auto_capture_mixer,
16667		.init_verbs = { alc662_init_verbs,
16668				alc663_21jd_amic_init_verbs},
16669		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16670		.hp_nid = 0x03,
16671		.dac_nids = alc662_dac_nids,
16672		.dig_out_nid = ALC662_DIGOUT_NID,
16673		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16674		.channel_mode = alc662_3ST_2ch_modes,
16675		.input_mux = &alc662_eeepc_capture_source,
16676		.unsol_event = alc663_mode4_unsol_event,
16677		.init_hook = alc663_mode4_inithook,
16678	},
16679	[ALC663_ASUS_MODE5] = {
16680		.mixers = { alc663_asus_15jd_clfe_mixer },
16681		.cap_mixer = alc662_auto_capture_mixer,
16682		.init_verbs = { alc662_init_verbs,
16683				alc663_15jd_amic_init_verbs },
16684		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16685		.hp_nid = 0x03,
16686		.dac_nids = alc662_dac_nids,
16687		.dig_out_nid = ALC662_DIGOUT_NID,
16688		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16689		.channel_mode = alc662_3ST_2ch_modes,
16690		.input_mux = &alc662_eeepc_capture_source,
16691		.unsol_event = alc663_mode5_unsol_event,
16692		.init_hook = alc663_mode5_inithook,
16693	},
16694	[ALC663_ASUS_MODE6] = {
16695		.mixers = { alc663_two_hp_m2_mixer },
16696		.cap_mixer = alc662_auto_capture_mixer,
16697		.init_verbs = { alc662_init_verbs,
16698				alc663_two_hp_amic_m2_init_verbs },
16699		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
16700		.hp_nid = 0x03,
16701		.dac_nids = alc662_dac_nids,
16702		.dig_out_nid = ALC662_DIGOUT_NID,
16703		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16704		.channel_mode = alc662_3ST_2ch_modes,
16705		.input_mux = &alc662_eeepc_capture_source,
16706		.unsol_event = alc663_mode6_unsol_event,
16707		.init_hook = alc663_mode6_inithook,
16708	},
16709	[ALC272_DELL] = {
16710		.mixers = { alc663_m51va_mixer },
16711		.cap_mixer = alc272_auto_capture_mixer,
16712		.init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16713		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
16714		.dac_nids = alc662_dac_nids,
16715		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16716		.adc_nids = alc272_adc_nids,
16717		.num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16718		.capsrc_nids = alc272_capsrc_nids,
16719		.channel_mode = alc662_3ST_2ch_modes,
16720		.input_mux = &alc663_m51va_capture_source,
16721		.unsol_event = alc663_m51va_unsol_event,
16722		.init_hook = alc663_m51va_inithook,
16723	},
16724	[ALC272_DELL_ZM1] = {
16725		.mixers = { alc663_m51va_mixer },
16726		.cap_mixer = alc662_auto_capture_mixer,
16727		.init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16728		.num_dacs = ARRAY_SIZE(alc272_dac_nids),
16729		.dac_nids = alc662_dac_nids,
16730		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16731		.adc_nids = alc662_adc_nids,
16732		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16733		.capsrc_nids = alc662_capsrc_nids,
16734		.channel_mode = alc662_3ST_2ch_modes,
16735		.input_mux = &alc663_m51va_capture_source,
16736		.unsol_event = alc663_m51va_unsol_event,
16737		.init_hook = alc663_m51va_inithook,
16738	},
16739};
16740
16741
16742/*
16743 * BIOS auto configuration
16744 */
16745
16746/* add playback controls from the parsed DAC table */
16747static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16748					     const struct auto_pin_cfg *cfg)
16749{
16750	char name[32];
16751	static const char *chname[4] = {
16752		"Front", "Surround", NULL /*CLFE*/, "Side"
16753	};
16754	hda_nid_t nid;
16755	int i, err;
16756
16757	for (i = 0; i < cfg->line_outs; i++) {
16758		if (!spec->multiout.dac_nids[i])
16759			continue;
16760		nid = alc880_idx_to_dac(i);
16761		if (i == 2) {
16762			/* Center/LFE */
16763			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16764					  "Center Playback Volume",
16765					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16766							      HDA_OUTPUT));
16767			if (err < 0)
16768				return err;
16769			err = add_control(spec, ALC_CTL_WIDGET_VOL,
16770					  "LFE Playback Volume",
16771					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16772							      HDA_OUTPUT));
16773			if (err < 0)
16774				return err;
16775			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16776					  "Center Playback Switch",
16777					  HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16778							      HDA_INPUT));
16779			if (err < 0)
16780				return err;
16781			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16782					  "LFE Playback Switch",
16783					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16784							      HDA_INPUT));
16785			if (err < 0)
16786				return err;
16787		} else {
16788			sprintf(name, "%s Playback Volume", chname[i]);
16789			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16790					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16791							      HDA_OUTPUT));
16792			if (err < 0)
16793				return err;
16794			sprintf(name, "%s Playback Switch", chname[i]);
16795			err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16796				HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16797						    3, 0, HDA_INPUT));
16798			if (err < 0)
16799				return err;
16800		}
16801	}
16802	return 0;
16803}
16804
16805/* add playback controls for speaker and HP outputs */
16806static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16807					const char *pfx)
16808{
16809	hda_nid_t nid;
16810	int err;
16811	char name[32];
16812
16813	if (!pin)
16814		return 0;
16815
16816	if (pin == 0x17) {
16817		/* ALC663 has a mono output pin on 0x17 */
16818		sprintf(name, "%s Playback Switch", pfx);
16819		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16820				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16821		return err;
16822	}
16823
16824	if (alc880_is_fixed_pin(pin)) {
16825		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16826		/* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16827		/* specify the DAC as the extra output */
16828		if (!spec->multiout.hp_nid)
16829			spec->multiout.hp_nid = nid;
16830		else
16831			spec->multiout.extra_out_nid[0] = nid;
16832		/* control HP volume/switch on the output mixer amp */
16833		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16834		sprintf(name, "%s Playback Volume", pfx);
16835		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16836				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16837		if (err < 0)
16838			return err;
16839		sprintf(name, "%s Playback Switch", pfx);
16840		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16841				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16842		if (err < 0)
16843			return err;
16844	} else if (alc880_is_multi_pin(pin)) {
16845		/* set manual connection */
16846		/* we have only a switch on HP-out PIN */
16847		sprintf(name, "%s Playback Switch", pfx);
16848		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16849				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16850		if (err < 0)
16851			return err;
16852	}
16853	return 0;
16854}
16855
16856/* return the index of the src widget from the connection list of the nid.
16857 * return -1 if not found
16858 */
16859static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16860				hda_nid_t src)
16861{
16862	hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16863	int i, conns;
16864
16865	conns = snd_hda_get_connections(codec, nid, conn_list,
16866					ARRAY_SIZE(conn_list));
16867	if (conns < 0)
16868		return -1;
16869	for (i = 0; i < conns; i++)
16870		if (conn_list[i] == src)
16871			return i;
16872	return -1;
16873}
16874
16875static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16876{
16877	unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16878	return (pincap & AC_PINCAP_IN) != 0;
16879}
16880
16881/* create playback/capture controls for input pins */
16882static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16883						const struct auto_pin_cfg *cfg)
16884{
16885	struct alc_spec *spec = codec->spec;
16886	struct hda_input_mux *imux = &spec->private_imux[0];
16887	int i, err, idx;
16888
16889	for (i = 0; i < AUTO_PIN_LAST; i++) {
16890		if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16891			idx = alc662_input_pin_idx(codec, 0x0b,
16892						   cfg->input_pins[i]);
16893			if (idx >= 0) {
16894				err = new_analog_input(spec, cfg->input_pins[i],
16895						       auto_pin_cfg_labels[i],
16896						       idx, 0x0b);
16897				if (err < 0)
16898					return err;
16899			}
16900			idx = alc662_input_pin_idx(codec, 0x22,
16901						   cfg->input_pins[i]);
16902			if (idx >= 0) {
16903				imux->items[imux->num_items].label =
16904					auto_pin_cfg_labels[i];
16905				imux->items[imux->num_items].index = idx;
16906				imux->num_items++;
16907			}
16908		}
16909	}
16910	return 0;
16911}
16912
16913static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16914					      hda_nid_t nid, int pin_type,
16915					      int dac_idx)
16916{
16917	alc_set_pin_output(codec, nid, pin_type);
16918	/* need the manual connection? */
16919	if (alc880_is_multi_pin(nid)) {
16920		struct alc_spec *spec = codec->spec;
16921		int idx = alc880_multi_pin_idx(nid);
16922		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16923				    AC_VERB_SET_CONNECT_SEL,
16924				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16925	}
16926}
16927
16928static void alc662_auto_init_multi_out(struct hda_codec *codec)
16929{
16930	struct alc_spec *spec = codec->spec;
16931	int i;
16932
16933	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16934	for (i = 0; i <= HDA_SIDE; i++) {
16935		hda_nid_t nid = spec->autocfg.line_out_pins[i];
16936		int pin_type = get_pin_type(spec->autocfg.line_out_type);
16937		if (nid)
16938			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16939							  i);
16940	}
16941}
16942
16943static void alc662_auto_init_hp_out(struct hda_codec *codec)
16944{
16945	struct alc_spec *spec = codec->spec;
16946	hda_nid_t pin;
16947
16948	pin = spec->autocfg.hp_pins[0];
16949	if (pin) /* connect to front */
16950		/* use dac 0 */
16951		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16952	pin = spec->autocfg.speaker_pins[0];
16953	if (pin)
16954		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16955}
16956
16957#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
16958
16959static void alc662_auto_init_analog_input(struct hda_codec *codec)
16960{
16961	struct alc_spec *spec = codec->spec;
16962	int i;
16963
16964	for (i = 0; i < AUTO_PIN_LAST; i++) {
16965		hda_nid_t nid = spec->autocfg.input_pins[i];
16966		if (alc662_is_input_pin(codec, nid)) {
16967			alc_set_input_pin(codec, nid, i);
16968			if (nid != ALC662_PIN_CD_NID &&
16969			    (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16970				snd_hda_codec_write(codec, nid, 0,
16971						    AC_VERB_SET_AMP_GAIN_MUTE,
16972						    AMP_OUT_MUTE);
16973		}
16974	}
16975}
16976
16977#define alc662_auto_init_input_src	alc882_auto_init_input_src
16978
16979static int alc662_parse_auto_config(struct hda_codec *codec)
16980{
16981	struct alc_spec *spec = codec->spec;
16982	int err;
16983	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16984
16985	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16986					   alc662_ignore);
16987	if (err < 0)
16988		return err;
16989	if (!spec->autocfg.line_outs)
16990		return 0; /* can't find valid BIOS pin config */
16991
16992	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16993	if (err < 0)
16994		return err;
16995	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16996	if (err < 0)
16997		return err;
16998	err = alc662_auto_create_extra_out(spec,
16999					   spec->autocfg.speaker_pins[0],
17000					   "Speaker");
17001	if (err < 0)
17002		return err;
17003	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17004					   "Headphone");
17005	if (err < 0)
17006		return err;
17007	err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17008	if (err < 0)
17009		return err;
17010
17011	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17012
17013	if (spec->autocfg.dig_outs)
17014		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17015
17016	if (spec->kctls.list)
17017		add_mixer(spec, spec->kctls.list);
17018
17019	spec->num_mux_defs = 1;
17020	spec->input_mux = &spec->private_imux[0];
17021
17022	add_verb(spec, alc662_auto_init_verbs);
17023	if (codec->vendor_id == 0x10ec0663)
17024		add_verb(spec, alc663_auto_init_verbs);
17025
17026	err = alc_auto_add_mic_boost(codec);
17027	if (err < 0)
17028		return err;
17029
17030	return 1;
17031}
17032
17033/* additional initialization for auto-configuration model */
17034static void alc662_auto_init(struct hda_codec *codec)
17035{
17036	struct alc_spec *spec = codec->spec;
17037	alc662_auto_init_multi_out(codec);
17038	alc662_auto_init_hp_out(codec);
17039	alc662_auto_init_analog_input(codec);
17040	alc662_auto_init_input_src(codec);
17041	if (spec->unsol_event)
17042		alc_inithook(codec);
17043}
17044
17045static int patch_alc662(struct hda_codec *codec)
17046{
17047	struct alc_spec *spec;
17048	int err, board_config;
17049
17050	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17051	if (!spec)
17052		return -ENOMEM;
17053
17054	codec->spec = spec;
17055
17056	alc_fix_pll_init(codec, 0x20, 0x04, 15);
17057
17058	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17059						  alc662_models,
17060			  	                  alc662_cfg_tbl);
17061	if (board_config < 0) {
17062		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
17063		       "trying auto-probe from BIOS...\n");
17064		board_config = ALC662_AUTO;
17065	}
17066
17067	if (board_config == ALC662_AUTO) {
17068		/* automatic parse from the BIOS config */
17069		err = alc662_parse_auto_config(codec);
17070		if (err < 0) {
17071			alc_free(codec);
17072			return err;
17073		} else if (!err) {
17074			printk(KERN_INFO
17075			       "hda_codec: Cannot set up configuration "
17076			       "from BIOS.  Using base mode...\n");
17077			board_config = ALC662_3ST_2ch_DIG;
17078		}
17079	}
17080
17081	err = snd_hda_attach_beep_device(codec, 0x1);
17082	if (err < 0) {
17083		alc_free(codec);
17084		return err;
17085	}
17086
17087	if (board_config != ALC662_AUTO)
17088		setup_preset(spec, &alc662_presets[board_config]);
17089
17090	if (codec->vendor_id == 0x10ec0663) {
17091		spec->stream_name_analog = "ALC663 Analog";
17092		spec->stream_name_digital = "ALC663 Digital";
17093	} else if (codec->vendor_id == 0x10ec0272) {
17094		spec->stream_name_analog = "ALC272 Analog";
17095		spec->stream_name_digital = "ALC272 Digital";
17096	} else {
17097		spec->stream_name_analog = "ALC662 Analog";
17098		spec->stream_name_digital = "ALC662 Digital";
17099	}
17100
17101	spec->stream_analog_playback = &alc662_pcm_analog_playback;
17102	spec->stream_analog_capture = &alc662_pcm_analog_capture;
17103
17104	spec->stream_digital_playback = &alc662_pcm_digital_playback;
17105	spec->stream_digital_capture = &alc662_pcm_digital_capture;
17106
17107	spec->adc_nids = alc662_adc_nids;
17108	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17109	spec->capsrc_nids = alc662_capsrc_nids;
17110	spec->capture_style = CAPT_MIX;
17111
17112	if (!spec->cap_mixer)
17113		set_capture_mixer(spec);
17114	if (codec->vendor_id == 0x10ec0662)
17115		set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17116	else
17117		set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17118
17119	spec->vmaster_nid = 0x02;
17120
17121	codec->patch_ops = alc_patch_ops;
17122	if (board_config == ALC662_AUTO)
17123		spec->init_hook = alc662_auto_init;
17124#ifdef CONFIG_SND_HDA_POWER_SAVE
17125	if (!spec->loopback.amplist)
17126		spec->loopback.amplist = alc662_loopbacks;
17127#endif
17128	codec->proc_widget_hook = print_realtek_coef;
17129
17130	return 0;
17131}
17132
17133/*
17134 * patch entries
17135 */
17136static struct hda_codec_preset snd_hda_preset_realtek[] = {
17137	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17138	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17139	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17140	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17141	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17142	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17143	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17144	  .patch = patch_alc861 },
17145	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17146	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17147	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17148	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17149	  .patch = patch_alc883 },
17150	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17151	  .patch = patch_alc662 },
17152	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17153	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17154	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17155	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17156	{ .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17157	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
17158	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17159	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
17160	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17161	{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17162	{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17163	  .patch = patch_alc883 },
17164	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17165	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17166	{} /* terminator */
17167};
17168
17169MODULE_ALIAS("snd-hda-codec-id:10ec*");
17170
17171MODULE_LICENSE("GPL");
17172MODULE_DESCRIPTION("Realtek HD-audio codec");
17173
17174static struct hda_codec_preset_list realtek_list = {
17175	.preset = snd_hda_preset_realtek,
17176	.owner = THIS_MODULE,
17177};
17178
17179static int __init patch_realtek_init(void)
17180{
17181	return snd_hda_add_codec_preset(&realtek_list);
17182}
17183
17184static void __exit patch_realtek_exit(void)
17185{
17186	snd_hda_delete_codec_preset(&realtek_list);
17187}
17188
17189module_init(patch_realtek_init)
17190module_exit(patch_realtek_exit)
17191