patch_realtek.c revision 963f803fb1bbce87f6049c22c737ae379e1047d3
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 *                    PeiSen Hou <pshou@realtek.com.tw>
8 *                    Takashi Iwai <tiwai@suse.de>
9 *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10 *
11 *  This driver is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This driver is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24 */
25
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
33#include "hda_patch.h"
34
35#define ALC880_FRONT_EVENT		0x01
36#define ALC880_DCVOL_EVENT		0x02
37#define ALC880_HP_EVENT			0x04
38#define ALC880_MIC_EVENT		0x08
39
40/* ALC880 board config type */
41enum {
42	ALC880_3ST,
43	ALC880_3ST_DIG,
44	ALC880_5ST,
45	ALC880_5ST_DIG,
46	ALC880_W810,
47	ALC880_Z71V,
48	ALC880_6ST,
49	ALC880_6ST_DIG,
50	ALC880_F1734,
51	ALC880_ASUS,
52	ALC880_ASUS_DIG,
53	ALC880_ASUS_W1V,
54	ALC880_ASUS_DIG2,
55	ALC880_FUJITSU,
56	ALC880_UNIWILL_DIG,
57	ALC880_UNIWILL,
58	ALC880_UNIWILL_P53,
59	ALC880_CLEVO,
60	ALC880_TCL_S700,
61	ALC880_LG,
62	ALC880_LG_LW,
63	ALC880_MEDION_RIM,
64#ifdef CONFIG_SND_DEBUG
65	ALC880_TEST,
66#endif
67	ALC880_AUTO,
68	ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73	ALC260_BASIC,
74	ALC260_HP,
75	ALC260_HP_3013,
76	ALC260_FUJITSU_S702X,
77	ALC260_ACER,
78	ALC260_WILL,
79	ALC260_REPLACER_672V,
80#ifdef CONFIG_SND_DEBUG
81	ALC260_TEST,
82#endif
83	ALC260_AUTO,
84	ALC260_MODEL_LAST /* last tag */
85};
86
87/* ALC262 models */
88enum {
89	ALC262_BASIC,
90	ALC262_HIPPO,
91	ALC262_HIPPO_1,
92	ALC262_FUJITSU,
93	ALC262_HP_BPC,
94	ALC262_HP_BPC_D7000_WL,
95	ALC262_HP_BPC_D7000_WF,
96	ALC262_HP_TC_T5735,
97	ALC262_HP_RP5700,
98	ALC262_BENQ_ED8,
99	ALC262_SONY_ASSAMD,
100	ALC262_BENQ_T31,
101	ALC262_ULTRA,
102	ALC262_LENOVO_3000,
103	ALC262_NEC,
104	ALC262_AUTO,
105	ALC262_MODEL_LAST /* last tag */
106};
107
108/* ALC268 models */
109enum {
110	ALC267_QUANTA_IL1,
111	ALC268_3ST,
112	ALC268_TOSHIBA,
113	ALC268_ACER,
114	ALC268_DELL,
115	ALC268_ZEPTO,
116#ifdef CONFIG_SND_DEBUG
117	ALC268_TEST,
118#endif
119	ALC268_AUTO,
120	ALC268_MODEL_LAST /* last tag */
121};
122
123/* ALC269 models */
124enum {
125	ALC269_BASIC,
126	ALC269_ASUS_EEEPC_P703,
127	ALC269_ASUS_EEEPC_P901,
128	ALC269_AUTO,
129	ALC269_MODEL_LAST /* last tag */
130};
131
132/* ALC861 models */
133enum {
134	ALC861_3ST,
135	ALC660_3ST,
136	ALC861_3ST_DIG,
137	ALC861_6ST_DIG,
138	ALC861_UNIWILL_M31,
139	ALC861_TOSHIBA,
140	ALC861_ASUS,
141	ALC861_ASUS_LAPTOP,
142	ALC861_AUTO,
143	ALC861_MODEL_LAST,
144};
145
146/* ALC861-VD models */
147enum {
148	ALC660VD_3ST,
149	ALC660VD_3ST_DIG,
150	ALC861VD_3ST,
151	ALC861VD_3ST_DIG,
152	ALC861VD_6ST_DIG,
153	ALC861VD_LENOVO,
154	ALC861VD_DALLAS,
155	ALC861VD_HP,
156	ALC861VD_AUTO,
157	ALC861VD_MODEL_LAST,
158};
159
160/* ALC662 models */
161enum {
162	ALC662_3ST_2ch_DIG,
163	ALC662_3ST_6ch_DIG,
164	ALC662_3ST_6ch,
165	ALC662_5ST_DIG,
166	ALC662_LENOVO_101E,
167	ALC662_ASUS_EEEPC_P701,
168	ALC662_ASUS_EEEPC_EP20,
169	ALC663_ASUS_M51VA,
170	ALC663_ASUS_G71V,
171	ALC663_ASUS_H13,
172	ALC663_ASUS_G50V,
173	ALC662_AUTO,
174	ALC662_MODEL_LAST,
175};
176
177/* ALC882 models */
178enum {
179	ALC882_3ST_DIG,
180	ALC882_6ST_DIG,
181	ALC882_ARIMA,
182	ALC882_W2JC,
183	ALC882_TARGA,
184	ALC882_ASUS_A7J,
185	ALC882_ASUS_A7M,
186	ALC885_MACPRO,
187	ALC885_MBP3,
188	ALC885_IMAC24,
189	ALC882_AUTO,
190	ALC882_MODEL_LAST,
191};
192
193/* ALC883 models */
194enum {
195	ALC883_3ST_2ch_DIG,
196	ALC883_3ST_6ch_DIG,
197	ALC883_3ST_6ch,
198	ALC883_6ST_DIG,
199	ALC883_TARGA_DIG,
200	ALC883_TARGA_2ch_DIG,
201	ALC883_ACER,
202	ALC883_ACER_ASPIRE,
203	ALC883_MEDION,
204	ALC883_MEDION_MD2,
205	ALC883_LAPTOP_EAPD,
206	ALC883_LENOVO_101E_2ch,
207	ALC883_LENOVO_NB0763,
208	ALC888_LENOVO_MS7195_DIG,
209	ALC883_HAIER_W66,
210	ALC888_3ST_HP,
211	ALC888_6ST_DELL,
212	ALC883_MITAC,
213	ALC883_CLEVO_M720,
214	ALC883_FUJITSU_PI2515,
215	ALC883_3ST_6ch_INTEL,
216	ALC883_AUTO,
217	ALC883_MODEL_LAST,
218};
219
220/* for GPIO Poll */
221#define GPIO_MASK	0x03
222
223struct alc_spec {
224	/* codec parameterization */
225	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
226	unsigned int num_mixers;
227
228	const struct hda_verb *init_verbs[5];	/* initialization verbs
229						 * don't forget NULL
230						 * termination!
231						 */
232	unsigned int num_init_verbs;
233
234	char *stream_name_analog;	/* analog PCM stream */
235	struct hda_pcm_stream *stream_analog_playback;
236	struct hda_pcm_stream *stream_analog_capture;
237	struct hda_pcm_stream *stream_analog_alt_playback;
238	struct hda_pcm_stream *stream_analog_alt_capture;
239
240	char *stream_name_digital;	/* digital PCM stream */
241	struct hda_pcm_stream *stream_digital_playback;
242	struct hda_pcm_stream *stream_digital_capture;
243
244	/* playback */
245	struct hda_multi_out multiout;	/* playback set-up
246					 * max_channels, dacs must be set
247					 * dig_out_nid and hp_nid are optional
248					 */
249	hda_nid_t alt_dac_nid;
250
251	/* capture */
252	unsigned int num_adc_nids;
253	hda_nid_t *adc_nids;
254	hda_nid_t *capsrc_nids;
255	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
256
257	/* capture source */
258	unsigned int num_mux_defs;
259	const struct hda_input_mux *input_mux;
260	unsigned int cur_mux[3];
261
262	/* channel model */
263	const struct hda_channel_mode *channel_mode;
264	int num_channel_mode;
265	int need_dac_fix;
266
267	/* PCM information */
268	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
269
270	/* dynamic controls, init_verbs and input_mux */
271	struct auto_pin_cfg autocfg;
272	unsigned int num_kctl_alloc, num_kctl_used;
273	struct snd_kcontrol_new *kctl_alloc;
274	struct hda_input_mux private_imux;
275	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
276
277	/* hooks */
278	void (*init_hook)(struct hda_codec *codec);
279	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
280
281	/* for pin sensing */
282	unsigned int sense_updated: 1;
283	unsigned int jack_present: 1;
284	unsigned int master_sw: 1;
285
286	/* for virtual master */
287	hda_nid_t vmaster_nid;
288#ifdef CONFIG_SND_HDA_POWER_SAVE
289	struct hda_loopback_check loopback;
290#endif
291
292	/* for PLL fix */
293	hda_nid_t pll_nid;
294	unsigned int pll_coef_idx, pll_coef_bit;
295};
296
297/*
298 * configuration template - to be copied to the spec instance
299 */
300struct alc_config_preset {
301	struct snd_kcontrol_new *mixers[5]; /* should be identical size
302					     * with spec
303					     */
304	const struct hda_verb *init_verbs[5];
305	unsigned int num_dacs;
306	hda_nid_t *dac_nids;
307	hda_nid_t dig_out_nid;		/* optional */
308	hda_nid_t hp_nid;		/* optional */
309	unsigned int num_adc_nids;
310	hda_nid_t *adc_nids;
311	hda_nid_t *capsrc_nids;
312	hda_nid_t dig_in_nid;
313	unsigned int num_channel_mode;
314	const struct hda_channel_mode *channel_mode;
315	int need_dac_fix;
316	unsigned int num_mux_defs;
317	const struct hda_input_mux *input_mux;
318	void (*unsol_event)(struct hda_codec *, unsigned int);
319	void (*init_hook)(struct hda_codec *);
320#ifdef CONFIG_SND_HDA_POWER_SAVE
321	struct hda_amp_list *loopbacks;
322#endif
323};
324
325
326/*
327 * input MUX handling
328 */
329static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
330			     struct snd_ctl_elem_info *uinfo)
331{
332	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
333	struct alc_spec *spec = codec->spec;
334	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
335	if (mux_idx >= spec->num_mux_defs)
336		mux_idx = 0;
337	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
338}
339
340static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
341			    struct snd_ctl_elem_value *ucontrol)
342{
343	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
344	struct alc_spec *spec = codec->spec;
345	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
346
347	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
348	return 0;
349}
350
351static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
352			    struct snd_ctl_elem_value *ucontrol)
353{
354	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
355	struct alc_spec *spec = codec->spec;
356	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
357	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
358	hda_nid_t nid = spec->capsrc_nids ?
359		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
360	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
361				     nid, &spec->cur_mux[adc_idx]);
362}
363
364
365/*
366 * channel mode setting
367 */
368static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
369			    struct snd_ctl_elem_info *uinfo)
370{
371	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
372	struct alc_spec *spec = codec->spec;
373	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
374				    spec->num_channel_mode);
375}
376
377static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
378			   struct snd_ctl_elem_value *ucontrol)
379{
380	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
381	struct alc_spec *spec = codec->spec;
382	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
383				   spec->num_channel_mode,
384				   spec->multiout.max_channels);
385}
386
387static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
388			   struct snd_ctl_elem_value *ucontrol)
389{
390	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
391	struct alc_spec *spec = codec->spec;
392	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
393				      spec->num_channel_mode,
394				      &spec->multiout.max_channels);
395	if (err >= 0 && spec->need_dac_fix)
396		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
397	return err;
398}
399
400/*
401 * Control the mode of pin widget settings via the mixer.  "pc" is used
402 * instead of "%" to avoid consequences of accidently treating the % as
403 * being part of a format specifier.  Maximum allowed length of a value is
404 * 63 characters plus NULL terminator.
405 *
406 * Note: some retasking pin complexes seem to ignore requests for input
407 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
408 * are requested.  Therefore order this list so that this behaviour will not
409 * cause problems when mixer clients move through the enum sequentially.
410 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
411 * March 2006.
412 */
413static char *alc_pin_mode_names[] = {
414	"Mic 50pc bias", "Mic 80pc bias",
415	"Line in", "Line out", "Headphone out",
416};
417static unsigned char alc_pin_mode_values[] = {
418	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
419};
420/* The control can present all 5 options, or it can limit the options based
421 * in the pin being assumed to be exclusively an input or an output pin.  In
422 * addition, "input" pins may or may not process the mic bias option
423 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
424 * accept requests for bias as of chip versions up to March 2006) and/or
425 * wiring in the computer.
426 */
427#define ALC_PIN_DIR_IN              0x00
428#define ALC_PIN_DIR_OUT             0x01
429#define ALC_PIN_DIR_INOUT           0x02
430#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
431#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
432
433/* Info about the pin modes supported by the different pin direction modes.
434 * For each direction the minimum and maximum values are given.
435 */
436static signed char alc_pin_mode_dir_info[5][2] = {
437	{ 0, 2 },    /* ALC_PIN_DIR_IN */
438	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
439	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
440	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
441	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
442};
443#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
444#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
445#define alc_pin_mode_n_items(_dir) \
446	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
447
448static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
449			     struct snd_ctl_elem_info *uinfo)
450{
451	unsigned int item_num = uinfo->value.enumerated.item;
452	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
453
454	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
455	uinfo->count = 1;
456	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
457
458	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
459		item_num = alc_pin_mode_min(dir);
460	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
461	return 0;
462}
463
464static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
465			    struct snd_ctl_elem_value *ucontrol)
466{
467	unsigned int i;
468	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
469	hda_nid_t nid = kcontrol->private_value & 0xffff;
470	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
471	long *valp = ucontrol->value.integer.value;
472	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
473						 AC_VERB_GET_PIN_WIDGET_CONTROL,
474						 0x00);
475
476	/* Find enumerated value for current pinctl setting */
477	i = alc_pin_mode_min(dir);
478	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
479		i++;
480	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
481	return 0;
482}
483
484static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
485			    struct snd_ctl_elem_value *ucontrol)
486{
487	signed int change;
488	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
489	hda_nid_t nid = kcontrol->private_value & 0xffff;
490	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
491	long val = *ucontrol->value.integer.value;
492	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
493						 AC_VERB_GET_PIN_WIDGET_CONTROL,
494						 0x00);
495
496	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
497		val = alc_pin_mode_min(dir);
498
499	change = pinctl != alc_pin_mode_values[val];
500	if (change) {
501		/* Set pin mode to that requested */
502		snd_hda_codec_write_cache(codec, nid, 0,
503					  AC_VERB_SET_PIN_WIDGET_CONTROL,
504					  alc_pin_mode_values[val]);
505
506		/* Also enable the retasking pin's input/output as required
507		 * for the requested pin mode.  Enum values of 2 or less are
508		 * input modes.
509		 *
510		 * Dynamically switching the input/output buffers probably
511		 * reduces noise slightly (particularly on input) so we'll
512		 * do it.  However, having both input and output buffers
513		 * enabled simultaneously doesn't seem to be problematic if
514		 * this turns out to be necessary in the future.
515		 */
516		if (val <= 2) {
517			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
518						 HDA_AMP_MUTE, HDA_AMP_MUTE);
519			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
520						 HDA_AMP_MUTE, 0);
521		} else {
522			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
523						 HDA_AMP_MUTE, HDA_AMP_MUTE);
524			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
525						 HDA_AMP_MUTE, 0);
526		}
527	}
528	return change;
529}
530
531#define ALC_PIN_MODE(xname, nid, dir) \
532	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
533	  .info = alc_pin_mode_info, \
534	  .get = alc_pin_mode_get, \
535	  .put = alc_pin_mode_put, \
536	  .private_value = nid | (dir<<16) }
537
538/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
539 * together using a mask with more than one bit set.  This control is
540 * currently used only by the ALC260 test model.  At this stage they are not
541 * needed for any "production" models.
542 */
543#ifdef CONFIG_SND_DEBUG
544#define alc_gpio_data_info	snd_ctl_boolean_mono_info
545
546static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
547			     struct snd_ctl_elem_value *ucontrol)
548{
549	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
550	hda_nid_t nid = kcontrol->private_value & 0xffff;
551	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
552	long *valp = ucontrol->value.integer.value;
553	unsigned int val = snd_hda_codec_read(codec, nid, 0,
554					      AC_VERB_GET_GPIO_DATA, 0x00);
555
556	*valp = (val & mask) != 0;
557	return 0;
558}
559static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
560			     struct snd_ctl_elem_value *ucontrol)
561{
562	signed int change;
563	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564	hda_nid_t nid = kcontrol->private_value & 0xffff;
565	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
566	long val = *ucontrol->value.integer.value;
567	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
568						    AC_VERB_GET_GPIO_DATA,
569						    0x00);
570
571	/* Set/unset the masked GPIO bit(s) as needed */
572	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
573	if (val == 0)
574		gpio_data &= ~mask;
575	else
576		gpio_data |= mask;
577	snd_hda_codec_write_cache(codec, nid, 0,
578				  AC_VERB_SET_GPIO_DATA, gpio_data);
579
580	return change;
581}
582#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
583	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
584	  .info = alc_gpio_data_info, \
585	  .get = alc_gpio_data_get, \
586	  .put = alc_gpio_data_put, \
587	  .private_value = nid | (mask<<16) }
588#endif   /* CONFIG_SND_DEBUG */
589
590/* A switch control to allow the enabling of the digital IO pins on the
591 * ALC260.  This is incredibly simplistic; the intention of this control is
592 * to provide something in the test model allowing digital outputs to be
593 * identified if present.  If models are found which can utilise these
594 * outputs a more complete mixer control can be devised for those models if
595 * necessary.
596 */
597#ifdef CONFIG_SND_DEBUG
598#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
599
600static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
601			      struct snd_ctl_elem_value *ucontrol)
602{
603	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
604	hda_nid_t nid = kcontrol->private_value & 0xffff;
605	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
606	long *valp = ucontrol->value.integer.value;
607	unsigned int val = snd_hda_codec_read(codec, nid, 0,
608					      AC_VERB_GET_DIGI_CONVERT_1, 0x00);
609
610	*valp = (val & mask) != 0;
611	return 0;
612}
613static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
614			      struct snd_ctl_elem_value *ucontrol)
615{
616	signed int change;
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 val = *ucontrol->value.integer.value;
621	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
622						    AC_VERB_GET_DIGI_CONVERT_1,
623						    0x00);
624
625	/* Set/unset the masked control bit(s) as needed */
626	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
627	if (val==0)
628		ctrl_data &= ~mask;
629	else
630		ctrl_data |= mask;
631	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
632				  ctrl_data);
633
634	return change;
635}
636#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
637	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
638	  .info = alc_spdif_ctrl_info, \
639	  .get = alc_spdif_ctrl_get, \
640	  .put = alc_spdif_ctrl_put, \
641	  .private_value = nid | (mask<<16) }
642#endif   /* CONFIG_SND_DEBUG */
643
644/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
645 * Again, this is only used in the ALC26x test models to help identify when
646 * the EAPD line must be asserted for features to work.
647 */
648#ifdef CONFIG_SND_DEBUG
649#define alc_eapd_ctrl_info	snd_ctl_boolean_mono_info
650
651static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
652			      struct snd_ctl_elem_value *ucontrol)
653{
654	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
655	hda_nid_t nid = kcontrol->private_value & 0xffff;
656	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
657	long *valp = ucontrol->value.integer.value;
658	unsigned int val = snd_hda_codec_read(codec, nid, 0,
659					      AC_VERB_GET_EAPD_BTLENABLE, 0x00);
660
661	*valp = (val & mask) != 0;
662	return 0;
663}
664
665static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
666			      struct snd_ctl_elem_value *ucontrol)
667{
668	int change;
669	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
670	hda_nid_t nid = kcontrol->private_value & 0xffff;
671	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
672	long val = *ucontrol->value.integer.value;
673	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
674						    AC_VERB_GET_EAPD_BTLENABLE,
675						    0x00);
676
677	/* Set/unset the masked control bit(s) as needed */
678	change = (!val ? 0 : mask) != (ctrl_data & mask);
679	if (!val)
680		ctrl_data &= ~mask;
681	else
682		ctrl_data |= mask;
683	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
684				  ctrl_data);
685
686	return change;
687}
688
689#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
690	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
691	  .info = alc_eapd_ctrl_info, \
692	  .get = alc_eapd_ctrl_get, \
693	  .put = alc_eapd_ctrl_put, \
694	  .private_value = nid | (mask<<16) }
695#endif   /* CONFIG_SND_DEBUG */
696
697/*
698 * set up from the preset table
699 */
700static void setup_preset(struct alc_spec *spec,
701			 const struct alc_config_preset *preset)
702{
703	int i;
704
705	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
706		spec->mixers[spec->num_mixers++] = preset->mixers[i];
707	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
708	     i++)
709		spec->init_verbs[spec->num_init_verbs++] =
710			preset->init_verbs[i];
711
712	spec->channel_mode = preset->channel_mode;
713	spec->num_channel_mode = preset->num_channel_mode;
714	spec->need_dac_fix = preset->need_dac_fix;
715
716	spec->multiout.max_channels = spec->channel_mode[0].channels;
717
718	spec->multiout.num_dacs = preset->num_dacs;
719	spec->multiout.dac_nids = preset->dac_nids;
720	spec->multiout.dig_out_nid = preset->dig_out_nid;
721	spec->multiout.hp_nid = preset->hp_nid;
722
723	spec->num_mux_defs = preset->num_mux_defs;
724	if (!spec->num_mux_defs)
725		spec->num_mux_defs = 1;
726	spec->input_mux = preset->input_mux;
727
728	spec->num_adc_nids = preset->num_adc_nids;
729	spec->adc_nids = preset->adc_nids;
730	spec->capsrc_nids = preset->capsrc_nids;
731	spec->dig_in_nid = preset->dig_in_nid;
732
733	spec->unsol_event = preset->unsol_event;
734	spec->init_hook = preset->init_hook;
735#ifdef CONFIG_SND_HDA_POWER_SAVE
736	spec->loopback.amplist = preset->loopbacks;
737#endif
738}
739
740/* Enable GPIO mask and set output */
741static struct hda_verb alc_gpio1_init_verbs[] = {
742	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
743	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
744	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
745	{ }
746};
747
748static struct hda_verb alc_gpio2_init_verbs[] = {
749	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
750	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
751	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
752	{ }
753};
754
755static struct hda_verb alc_gpio3_init_verbs[] = {
756	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
757	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
758	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
759	{ }
760};
761
762/*
763 * Fix hardware PLL issue
764 * On some codecs, the analog PLL gating control must be off while
765 * the default value is 1.
766 */
767static void alc_fix_pll(struct hda_codec *codec)
768{
769	struct alc_spec *spec = codec->spec;
770	unsigned int val;
771
772	if (!spec->pll_nid)
773		return;
774	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
775			    spec->pll_coef_idx);
776	val = snd_hda_codec_read(codec, spec->pll_nid, 0,
777				 AC_VERB_GET_PROC_COEF, 0);
778	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
779			    spec->pll_coef_idx);
780	snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
781			    val & ~(1 << spec->pll_coef_bit));
782}
783
784static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
785			     unsigned int coef_idx, unsigned int coef_bit)
786{
787	struct alc_spec *spec = codec->spec;
788	spec->pll_nid = nid;
789	spec->pll_coef_idx = coef_idx;
790	spec->pll_coef_bit = coef_bit;
791	alc_fix_pll(codec);
792}
793
794static void alc_sku_automute(struct hda_codec *codec)
795{
796	struct alc_spec *spec = codec->spec;
797	unsigned int present;
798	unsigned int hp_nid = spec->autocfg.hp_pins[0];
799	unsigned int sp_nid = spec->autocfg.speaker_pins[0];
800
801	/* need to execute and sync at first */
802	snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
803	present = snd_hda_codec_read(codec, hp_nid, 0,
804				     AC_VERB_GET_PIN_SENSE, 0);
805	spec->jack_present = (present & 0x80000000) != 0;
806	snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
807			    spec->jack_present ? 0 : PIN_OUT);
808}
809
810/* unsolicited event for HP jack sensing */
811static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
812{
813	if (codec->vendor_id == 0x10ec0880)
814		res >>= 28;
815	else
816		res >>= 26;
817	if (res != ALC880_HP_EVENT)
818		return;
819
820	alc_sku_automute(codec);
821}
822
823/* additional initialization for ALC888 variants */
824static void alc888_coef_init(struct hda_codec *codec)
825{
826	unsigned int tmp;
827
828	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
829	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
830	snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
831	if ((tmp & 0xf0) == 2)
832		/* alc888S-VC */
833		snd_hda_codec_read(codec, 0x20, 0,
834				   AC_VERB_SET_PROC_COEF, 0x830);
835	 else
836		 /* alc888-VB */
837		 snd_hda_codec_read(codec, 0x20, 0,
838				    AC_VERB_SET_PROC_COEF, 0x3030);
839}
840
841/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
842 *	31 ~ 16 :	Manufacture ID
843 *	15 ~ 8	:	SKU ID
844 *	7  ~ 0	:	Assembly ID
845 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
846 */
847static void alc_subsystem_id(struct hda_codec *codec,
848			     unsigned int porta, unsigned int porte,
849			     unsigned int portd)
850{
851	unsigned int ass, tmp, i;
852	unsigned nid;
853	struct alc_spec *spec = codec->spec;
854
855	ass = codec->subsystem_id & 0xffff;
856	if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
857		goto do_sku;
858
859	/*
860	 * 31~30	: port conetcivity
861	 * 29~21	: reserve
862	 * 20		: PCBEEP input
863	 * 19~16	: Check sum (15:1)
864	 * 15~1		: Custom
865	 * 0		: override
866	*/
867	nid = 0x1d;
868	if (codec->vendor_id == 0x10ec0260)
869		nid = 0x17;
870	ass = snd_hda_codec_read(codec, nid, 0,
871				 AC_VERB_GET_CONFIG_DEFAULT, 0);
872	if (!(ass & 1) && !(ass & 0x100000))
873		return;
874	if ((ass >> 30) != 1)	/* no physical connection */
875		return;
876
877	/* check sum */
878	tmp = 0;
879	for (i = 1; i < 16; i++) {
880		if ((ass >> i) & 1)
881			tmp++;
882	}
883	if (((ass >> 16) & 0xf) != tmp)
884		return;
885do_sku:
886	/*
887	 * 0 : override
888	 * 1 :	Swap Jack
889	 * 2 : 0 --> Desktop, 1 --> Laptop
890	 * 3~5 : External Amplifier control
891	 * 7~6 : Reserved
892	*/
893	tmp = (ass & 0x38) >> 3;	/* external Amp control */
894	switch (tmp) {
895	case 1:
896		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
897		break;
898	case 3:
899		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
900		break;
901	case 7:
902		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
903		break;
904	case 5:	/* set EAPD output high */
905		switch (codec->vendor_id) {
906		case 0x10ec0260:
907			snd_hda_codec_write(codec, 0x0f, 0,
908					    AC_VERB_SET_EAPD_BTLENABLE, 2);
909			snd_hda_codec_write(codec, 0x10, 0,
910					    AC_VERB_SET_EAPD_BTLENABLE, 2);
911			break;
912		case 0x10ec0262:
913		case 0x10ec0267:
914		case 0x10ec0268:
915		case 0x10ec0269:
916		case 0x10ec0660:
917		case 0x10ec0662:
918		case 0x10ec0663:
919		case 0x10ec0862:
920		case 0x10ec0889:
921			snd_hda_codec_write(codec, 0x14, 0,
922					    AC_VERB_SET_EAPD_BTLENABLE, 2);
923			snd_hda_codec_write(codec, 0x15, 0,
924					    AC_VERB_SET_EAPD_BTLENABLE, 2);
925			break;
926		}
927		switch (codec->vendor_id) {
928		case 0x10ec0260:
929			snd_hda_codec_write(codec, 0x1a, 0,
930					    AC_VERB_SET_COEF_INDEX, 7);
931			tmp = snd_hda_codec_read(codec, 0x1a, 0,
932						 AC_VERB_GET_PROC_COEF, 0);
933			snd_hda_codec_write(codec, 0x1a, 0,
934					    AC_VERB_SET_COEF_INDEX, 7);
935			snd_hda_codec_write(codec, 0x1a, 0,
936					    AC_VERB_SET_PROC_COEF,
937					    tmp | 0x2010);
938			break;
939		case 0x10ec0262:
940		case 0x10ec0880:
941		case 0x10ec0882:
942		case 0x10ec0883:
943		case 0x10ec0885:
944		case 0x10ec0889:
945			snd_hda_codec_write(codec, 0x20, 0,
946					    AC_VERB_SET_COEF_INDEX, 7);
947			tmp = snd_hda_codec_read(codec, 0x20, 0,
948						 AC_VERB_GET_PROC_COEF, 0);
949			snd_hda_codec_write(codec, 0x20, 0,
950					    AC_VERB_SET_COEF_INDEX, 7);
951			snd_hda_codec_write(codec, 0x20, 0,
952					    AC_VERB_SET_PROC_COEF,
953					    tmp | 0x2010);
954			break;
955		case 0x10ec0888:
956			/*alc888_coef_init(codec);*/ /* called in alc_init() */
957			break;
958		case 0x10ec0267:
959		case 0x10ec0268:
960			snd_hda_codec_write(codec, 0x20, 0,
961					    AC_VERB_SET_COEF_INDEX, 7);
962			tmp = snd_hda_codec_read(codec, 0x20, 0,
963						 AC_VERB_GET_PROC_COEF, 0);
964			snd_hda_codec_write(codec, 0x20, 0,
965					    AC_VERB_SET_COEF_INDEX, 7);
966			snd_hda_codec_write(codec, 0x20, 0,
967					    AC_VERB_SET_PROC_COEF,
968					    tmp | 0x3000);
969			break;
970		}
971	default:
972		break;
973	}
974
975	/* is laptop or Desktop and enable the function "Mute internal speaker
976	 * when the external headphone out jack is plugged"
977	 */
978	if (!(ass & 0x8000))
979		return;
980	/*
981	 * 10~8 : Jack location
982	 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
983	 * 14~13: Resvered
984	 * 15   : 1 --> enable the function "Mute internal speaker
985	 *	        when the external headphone out jack is plugged"
986	 */
987	if (!spec->autocfg.speaker_pins[0]) {
988		if (spec->autocfg.line_out_pins[0])
989			spec->autocfg.speaker_pins[0] =
990				spec->autocfg.line_out_pins[0];
991		else
992			return;
993	}
994
995	if (!spec->autocfg.hp_pins[0]) {
996		tmp = (ass >> 11) & 0x3;	/* HP to chassis */
997		if (tmp == 0)
998			spec->autocfg.hp_pins[0] = porta;
999		else if (tmp == 1)
1000			spec->autocfg.hp_pins[0] = porte;
1001		else if (tmp == 2)
1002			spec->autocfg.hp_pins[0] = portd;
1003		else
1004			return;
1005	}
1006
1007	snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1008			    AC_VERB_SET_UNSOLICITED_ENABLE,
1009			    AC_USRSP_EN | ALC880_HP_EVENT);
1010	spec->unsol_event = alc_sku_unsol_event;
1011}
1012
1013/*
1014 * Fix-up pin default configurations
1015 */
1016
1017struct alc_pincfg {
1018	hda_nid_t nid;
1019	u32 val;
1020};
1021
1022static void alc_fix_pincfg(struct hda_codec *codec,
1023			   const struct snd_pci_quirk *quirk,
1024			   const struct alc_pincfg **pinfix)
1025{
1026	const struct alc_pincfg *cfg;
1027
1028	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1029	if (!quirk)
1030		return;
1031
1032	cfg = pinfix[quirk->value];
1033	for (; cfg->nid; cfg++) {
1034		int i;
1035		u32 val = cfg->val;
1036		for (i = 0; i < 4; i++) {
1037			snd_hda_codec_write(codec, cfg->nid, 0,
1038				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1039				    val & 0xff);
1040			val >>= 8;
1041		}
1042	}
1043}
1044
1045/*
1046 * ALC880 3-stack model
1047 *
1048 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1049 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1050 *                 F-Mic = 0x1b, HP = 0x19
1051 */
1052
1053static hda_nid_t alc880_dac_nids[4] = {
1054	/* front, rear, clfe, rear_surr */
1055	0x02, 0x05, 0x04, 0x03
1056};
1057
1058static hda_nid_t alc880_adc_nids[3] = {
1059	/* ADC0-2 */
1060	0x07, 0x08, 0x09,
1061};
1062
1063/* The datasheet says the node 0x07 is connected from inputs,
1064 * but it shows zero connection in the real implementation on some devices.
1065 * Note: this is a 915GAV bug, fixed on 915GLV
1066 */
1067static hda_nid_t alc880_adc_nids_alt[2] = {
1068	/* ADC1-2 */
1069	0x08, 0x09,
1070};
1071
1072#define ALC880_DIGOUT_NID	0x06
1073#define ALC880_DIGIN_NID	0x0a
1074
1075static struct hda_input_mux alc880_capture_source = {
1076	.num_items = 4,
1077	.items = {
1078		{ "Mic", 0x0 },
1079		{ "Front Mic", 0x3 },
1080		{ "Line", 0x2 },
1081		{ "CD", 0x4 },
1082	},
1083};
1084
1085/* channel source setting (2/6 channel selection for 3-stack) */
1086/* 2ch mode */
1087static struct hda_verb alc880_threestack_ch2_init[] = {
1088	/* set line-in to input, mute it */
1089	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1090	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1091	/* set mic-in to input vref 80%, mute it */
1092	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1093	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1094	{ } /* end */
1095};
1096
1097/* 6ch mode */
1098static struct hda_verb alc880_threestack_ch6_init[] = {
1099	/* set line-in to output, unmute it */
1100	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1101	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1102	/* set mic-in to output, unmute it */
1103	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1104	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1105	{ } /* end */
1106};
1107
1108static struct hda_channel_mode alc880_threestack_modes[2] = {
1109	{ 2, alc880_threestack_ch2_init },
1110	{ 6, alc880_threestack_ch6_init },
1111};
1112
1113static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1114	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1115	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1116	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1117	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1118	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1119	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1120	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1121	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1122	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1123	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1124	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1125	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1126	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1127	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1128	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1129	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1130	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1131	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1132	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1133	{
1134		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1135		.name = "Channel Mode",
1136		.info = alc_ch_mode_info,
1137		.get = alc_ch_mode_get,
1138		.put = alc_ch_mode_put,
1139	},
1140	{ } /* end */
1141};
1142
1143/* capture mixer elements */
1144static struct snd_kcontrol_new alc880_capture_mixer[] = {
1145	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1146	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1147	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1148	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1149	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1150	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1151	{
1152		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1153		/* The multiple "Capture Source" controls confuse alsamixer
1154		 * So call somewhat different..
1155		 */
1156		/* .name = "Capture Source", */
1157		.name = "Input Source",
1158		.count = 3,
1159		.info = alc_mux_enum_info,
1160		.get = alc_mux_enum_get,
1161		.put = alc_mux_enum_put,
1162	},
1163	{ } /* end */
1164};
1165
1166/* capture mixer elements (in case NID 0x07 not available) */
1167static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1168	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1169	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1170	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1171	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1172	{
1173		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1174		/* The multiple "Capture Source" controls confuse alsamixer
1175		 * So call somewhat different..
1176		 */
1177		/* .name = "Capture Source", */
1178		.name = "Input Source",
1179		.count = 2,
1180		.info = alc_mux_enum_info,
1181		.get = alc_mux_enum_get,
1182		.put = alc_mux_enum_put,
1183	},
1184	{ } /* end */
1185};
1186
1187
1188
1189/*
1190 * ALC880 5-stack model
1191 *
1192 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1193 *      Side = 0x02 (0xd)
1194 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1195 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1196 */
1197
1198/* additional mixers to alc880_three_stack_mixer */
1199static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1200	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1201	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1202	{ } /* end */
1203};
1204
1205/* channel source setting (6/8 channel selection for 5-stack) */
1206/* 6ch mode */
1207static struct hda_verb alc880_fivestack_ch6_init[] = {
1208	/* set line-in to input, mute it */
1209	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1210	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1211	{ } /* end */
1212};
1213
1214/* 8ch mode */
1215static struct hda_verb alc880_fivestack_ch8_init[] = {
1216	/* set line-in to output, unmute it */
1217	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1218	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1219	{ } /* end */
1220};
1221
1222static struct hda_channel_mode alc880_fivestack_modes[2] = {
1223	{ 6, alc880_fivestack_ch6_init },
1224	{ 8, alc880_fivestack_ch8_init },
1225};
1226
1227
1228/*
1229 * ALC880 6-stack model
1230 *
1231 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1232 *      Side = 0x05 (0x0f)
1233 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1234 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1235 */
1236
1237static hda_nid_t alc880_6st_dac_nids[4] = {
1238	/* front, rear, clfe, rear_surr */
1239	0x02, 0x03, 0x04, 0x05
1240};
1241
1242static struct hda_input_mux alc880_6stack_capture_source = {
1243	.num_items = 4,
1244	.items = {
1245		{ "Mic", 0x0 },
1246		{ "Front Mic", 0x1 },
1247		{ "Line", 0x2 },
1248		{ "CD", 0x4 },
1249	},
1250};
1251
1252/* fixed 8-channels */
1253static struct hda_channel_mode alc880_sixstack_modes[1] = {
1254	{ 8, NULL },
1255};
1256
1257static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1258	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1259	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1260	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1261	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1262	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1263	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1264	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1265	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1266	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1267	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1268	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1269	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1270	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1271	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1272	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1273	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1274	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1275	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1276	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1277	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1278	{
1279		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1280		.name = "Channel Mode",
1281		.info = alc_ch_mode_info,
1282		.get = alc_ch_mode_get,
1283		.put = alc_ch_mode_put,
1284	},
1285	{ } /* end */
1286};
1287
1288
1289/*
1290 * ALC880 W810 model
1291 *
1292 * W810 has rear IO for:
1293 * Front (DAC 02)
1294 * Surround (DAC 03)
1295 * Center/LFE (DAC 04)
1296 * Digital out (06)
1297 *
1298 * The system also has a pair of internal speakers, and a headphone jack.
1299 * These are both connected to Line2 on the codec, hence to DAC 02.
1300 *
1301 * There is a variable resistor to control the speaker or headphone
1302 * volume. This is a hardware-only device without a software API.
1303 *
1304 * Plugging headphones in will disable the internal speakers. This is
1305 * implemented in hardware, not via the driver using jack sense. In
1306 * a similar fashion, plugging into the rear socket marked "front" will
1307 * disable both the speakers and headphones.
1308 *
1309 * For input, there's a microphone jack, and an "audio in" jack.
1310 * These may not do anything useful with this driver yet, because I
1311 * haven't setup any initialization verbs for these yet...
1312 */
1313
1314static hda_nid_t alc880_w810_dac_nids[3] = {
1315	/* front, rear/surround, clfe */
1316	0x02, 0x03, 0x04
1317};
1318
1319/* fixed 6 channels */
1320static struct hda_channel_mode alc880_w810_modes[1] = {
1321	{ 6, NULL }
1322};
1323
1324/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1325static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1326	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1327	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1328	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1329	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1330	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1331	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1332	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1333	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1334	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1335	{ } /* end */
1336};
1337
1338
1339/*
1340 * Z710V model
1341 *
1342 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1343 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1344 *                 Line = 0x1a
1345 */
1346
1347static hda_nid_t alc880_z71v_dac_nids[1] = {
1348	0x02
1349};
1350#define ALC880_Z71V_HP_DAC	0x03
1351
1352/* fixed 2 channels */
1353static struct hda_channel_mode alc880_2_jack_modes[1] = {
1354	{ 2, NULL }
1355};
1356
1357static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1358	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1359	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1360	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1361	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1362	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1363	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1364	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1365	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1366	{ } /* end */
1367};
1368
1369
1370/*
1371 * ALC880 F1734 model
1372 *
1373 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1374 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1375 */
1376
1377static hda_nid_t alc880_f1734_dac_nids[1] = {
1378	0x03
1379};
1380#define ALC880_F1734_HP_DAC	0x02
1381
1382static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1383	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1384	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1385	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1386	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1387	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1388	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1389	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1390	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1391	{ } /* end */
1392};
1393
1394static struct hda_input_mux alc880_f1734_capture_source = {
1395	.num_items = 2,
1396	.items = {
1397		{ "Mic", 0x1 },
1398		{ "CD", 0x4 },
1399	},
1400};
1401
1402
1403/*
1404 * ALC880 ASUS model
1405 *
1406 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1407 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1408 *  Mic = 0x18, Line = 0x1a
1409 */
1410
1411#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1412#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1413
1414static struct snd_kcontrol_new alc880_asus_mixer[] = {
1415	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1416	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1417	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1418	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1419	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1420	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1421	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1422	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1423	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1424	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1425	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1426	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1427	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1428	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1429	{
1430		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1431		.name = "Channel Mode",
1432		.info = alc_ch_mode_info,
1433		.get = alc_ch_mode_get,
1434		.put = alc_ch_mode_put,
1435	},
1436	{ } /* end */
1437};
1438
1439/*
1440 * ALC880 ASUS W1V model
1441 *
1442 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1443 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1444 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1445 */
1446
1447/* additional mixers to alc880_asus_mixer */
1448static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1449	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1450	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1451	{ } /* end */
1452};
1453
1454/* additional mixers to alc880_asus_mixer */
1455static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1456	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1457	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1458	{ } /* end */
1459};
1460
1461/* TCL S700 */
1462static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1463	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1464	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1465	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1466	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1467	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1468	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1469	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1470	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1471	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1472	{
1473		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1474		/* The multiple "Capture Source" controls confuse alsamixer
1475		 * So call somewhat different..
1476		 */
1477		/* .name = "Capture Source", */
1478		.name = "Input Source",
1479		.count = 1,
1480		.info = alc_mux_enum_info,
1481		.get = alc_mux_enum_get,
1482		.put = alc_mux_enum_put,
1483	},
1484	{ } /* end */
1485};
1486
1487/* Uniwill */
1488static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1489	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1490	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1491	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1492	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1493	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1494	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1495	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1496	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1497	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1498	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1499	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1500	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1501	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1502	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1503	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1504	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1505	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1506	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1507	{
1508		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509		.name = "Channel Mode",
1510		.info = alc_ch_mode_info,
1511		.get = alc_ch_mode_get,
1512		.put = alc_ch_mode_put,
1513	},
1514	{ } /* end */
1515};
1516
1517static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1518	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1519	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1520	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1521	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1522	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1523	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1524	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1525	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1526	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1527	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1528	{ } /* end */
1529};
1530
1531static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1532	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1533	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1534	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1535	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1536	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1537	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1538	{ } /* end */
1539};
1540
1541/*
1542 * virtual master controls
1543 */
1544
1545/*
1546 * slave controls for virtual master
1547 */
1548static const char *alc_slave_vols[] = {
1549	"Front Playback Volume",
1550	"Surround Playback Volume",
1551	"Center Playback Volume",
1552	"LFE Playback Volume",
1553	"Side Playback Volume",
1554	"Headphone Playback Volume",
1555	"Speaker Playback Volume",
1556	"Mono Playback Volume",
1557	"Line-Out Playback Volume",
1558	NULL,
1559};
1560
1561static const char *alc_slave_sws[] = {
1562	"Front Playback Switch",
1563	"Surround Playback Switch",
1564	"Center Playback Switch",
1565	"LFE Playback Switch",
1566	"Side Playback Switch",
1567	"Headphone Playback Switch",
1568	"Speaker Playback Switch",
1569	"Mono Playback Switch",
1570	"IEC958 Playback Switch",
1571	NULL,
1572};
1573
1574/*
1575 * build control elements
1576 */
1577static int alc_build_controls(struct hda_codec *codec)
1578{
1579	struct alc_spec *spec = codec->spec;
1580	int err;
1581	int i;
1582
1583	for (i = 0; i < spec->num_mixers; i++) {
1584		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1585		if (err < 0)
1586			return err;
1587	}
1588
1589	if (spec->multiout.dig_out_nid) {
1590		err = snd_hda_create_spdif_out_ctls(codec,
1591						    spec->multiout.dig_out_nid);
1592		if (err < 0)
1593			return err;
1594		err = snd_hda_create_spdif_share_sw(codec,
1595						    &spec->multiout);
1596		if (err < 0)
1597			return err;
1598		spec->multiout.share_spdif = 1;
1599	}
1600	if (spec->dig_in_nid) {
1601		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1602		if (err < 0)
1603			return err;
1604	}
1605
1606	/* if we have no master control, let's create it */
1607	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1608		unsigned int vmaster_tlv[4];
1609		snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1610					HDA_OUTPUT, vmaster_tlv);
1611		err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1612					  vmaster_tlv, alc_slave_vols);
1613		if (err < 0)
1614			return err;
1615	}
1616	if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1617		err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1618					  NULL, alc_slave_sws);
1619		if (err < 0)
1620			return err;
1621	}
1622
1623	return 0;
1624}
1625
1626
1627/*
1628 * initialize the codec volumes, etc
1629 */
1630
1631/*
1632 * generic initialization of ADC, input mixers and output mixers
1633 */
1634static struct hda_verb alc880_volume_init_verbs[] = {
1635	/*
1636	 * Unmute ADC0-2 and set the default input to mic-in
1637	 */
1638	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1639	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1640	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1641	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1642	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1643	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1644
1645	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1646	 * mixer widget
1647	 * Note: PASD motherboards uses the Line In 2 as the input for front
1648	 * panel mic (mic 2)
1649	 */
1650	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1651	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1652	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1653	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1654	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1655	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1656	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1657	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1658
1659	/*
1660	 * Set up output mixers (0x0c - 0x0f)
1661	 */
1662	/* set vol=0 to output mixers */
1663	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1664	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1665	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1666	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1667	/* set up input amps for analog loopback */
1668	/* Amp Indices: DAC = 0, mixer = 1 */
1669	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1670	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1671	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1672	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1673	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1674	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1675	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1676	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1677
1678	{ }
1679};
1680
1681/*
1682 * 3-stack pin configuration:
1683 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1684 */
1685static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1686	/*
1687	 * preset connection lists of input pins
1688	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1689	 */
1690	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1691	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1692	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1693
1694	/*
1695	 * Set pin mode and muting
1696	 */
1697	/* set front pin widgets 0x14 for output */
1698	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1699	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1700	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1701	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1702	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1703	/* Mic2 (as headphone out) for HP output */
1704	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1705	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706	/* Line In pin widget for input */
1707	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1708	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1709	/* Line2 (as front mic) pin widget for input and vref at 80% */
1710	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1711	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1712	/* CD pin widget for input */
1713	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1714
1715	{ }
1716};
1717
1718/*
1719 * 5-stack pin configuration:
1720 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1721 * line-in/side = 0x1a, f-mic = 0x1b
1722 */
1723static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1724	/*
1725	 * preset connection lists of input pins
1726	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1727	 */
1728	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1729	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1730
1731	/*
1732	 * Set pin mode and muting
1733	 */
1734	/* set pin widgets 0x14-0x17 for output */
1735	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1736	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1737	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1738	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1739	/* unmute pins for output (no gain on this amp) */
1740	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1741	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1742	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1743	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744
1745	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1746	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1747	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1748	/* Mic2 (as headphone out) for HP output */
1749	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1750	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1751	/* Line In pin widget for input */
1752	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1753	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1754	/* Line2 (as front mic) pin widget for input and vref at 80% */
1755	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1756	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1757	/* CD pin widget for input */
1758	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1759
1760	{ }
1761};
1762
1763/*
1764 * W810 pin configuration:
1765 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1766 */
1767static struct hda_verb alc880_pin_w810_init_verbs[] = {
1768	/* hphone/speaker input selector: front DAC */
1769	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1770
1771	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1772	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1773	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1774	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1775	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1776	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1777
1778	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1779	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1780
1781	{ }
1782};
1783
1784/*
1785 * Z71V pin configuration:
1786 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1787 */
1788static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1789	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1790	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1791	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1792	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1793
1794	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1795	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1796	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1797	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1798
1799	{ }
1800};
1801
1802/*
1803 * 6-stack pin configuration:
1804 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1805 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1806 */
1807static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1808	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1809
1810	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1811	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1812	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1813	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1814	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1815	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1816	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1817	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818
1819	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1820	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1821	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1822	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1823	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1824	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1825	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1826	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1827	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1828
1829	{ }
1830};
1831
1832/*
1833 * Uniwill pin configuration:
1834 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1835 * line = 0x1a
1836 */
1837static struct hda_verb alc880_uniwill_init_verbs[] = {
1838	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1839
1840	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1841	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1842	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1843	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1844	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1845	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1846	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1847	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1849	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1850	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1851	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1852	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1853	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1854
1855	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1856	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1857	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1858	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1859	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1860	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1861	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1862	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1863	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1864
1865	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1866	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1867
1868	{ }
1869};
1870
1871/*
1872* Uniwill P53
1873* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1874 */
1875static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1876	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1877
1878	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1879	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1880	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1881	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1882	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1883	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1884	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1885	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1886	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1887	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1888	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1889	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1890
1891	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1892	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1893	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1894	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1895	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1896	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1897
1898	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1899	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1900
1901	{ }
1902};
1903
1904static struct hda_verb alc880_beep_init_verbs[] = {
1905	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1906	{ }
1907};
1908
1909/* toggle speaker-output according to the hp-jack state */
1910static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1911{
1912 	unsigned int present;
1913	unsigned char bits;
1914
1915 	present = snd_hda_codec_read(codec, 0x14, 0,
1916				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1917	bits = present ? HDA_AMP_MUTE : 0;
1918	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1919				 HDA_AMP_MUTE, bits);
1920	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1921				 HDA_AMP_MUTE, bits);
1922}
1923
1924/* auto-toggle front mic */
1925static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1926{
1927 	unsigned int present;
1928	unsigned char bits;
1929
1930	present = snd_hda_codec_read(codec, 0x18, 0,
1931				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1932	bits = present ? HDA_AMP_MUTE : 0;
1933	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1934}
1935
1936static void alc880_uniwill_automute(struct hda_codec *codec)
1937{
1938	alc880_uniwill_hp_automute(codec);
1939	alc880_uniwill_mic_automute(codec);
1940}
1941
1942static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1943				       unsigned int res)
1944{
1945	/* Looks like the unsol event is incompatible with the standard
1946	 * definition.  4bit tag is placed at 28 bit!
1947	 */
1948	switch (res >> 28) {
1949	case ALC880_HP_EVENT:
1950		alc880_uniwill_hp_automute(codec);
1951		break;
1952	case ALC880_MIC_EVENT:
1953		alc880_uniwill_mic_automute(codec);
1954		break;
1955	}
1956}
1957
1958static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1959{
1960 	unsigned int present;
1961	unsigned char bits;
1962
1963 	present = snd_hda_codec_read(codec, 0x14, 0,
1964				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1965	bits = present ? HDA_AMP_MUTE : 0;
1966	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1967}
1968
1969static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1970{
1971	unsigned int present;
1972
1973	present = snd_hda_codec_read(codec, 0x21, 0,
1974				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1975	present &= HDA_AMP_VOLMASK;
1976	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1977				 HDA_AMP_VOLMASK, present);
1978	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1979				 HDA_AMP_VOLMASK, present);
1980}
1981
1982static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1983					   unsigned int res)
1984{
1985	/* Looks like the unsol event is incompatible with the standard
1986	 * definition.  4bit tag is placed at 28 bit!
1987	 */
1988	if ((res >> 28) == ALC880_HP_EVENT)
1989		alc880_uniwill_p53_hp_automute(codec);
1990	if ((res >> 28) == ALC880_DCVOL_EVENT)
1991		alc880_uniwill_p53_dcvol_automute(codec);
1992}
1993
1994/*
1995 * F1734 pin configuration:
1996 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1997 */
1998static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1999	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2000	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2001	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2002	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2003	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2004
2005	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2006	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2008	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2009
2010	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2011	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2012	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2013	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2014	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2015	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2016	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2017	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2018	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2019
2020	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2021	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2022
2023	{ }
2024};
2025
2026/*
2027 * ASUS pin configuration:
2028 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2029 */
2030static struct hda_verb alc880_pin_asus_init_verbs[] = {
2031	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2032	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2033	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2034	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2035
2036	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2037	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2038	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2039	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2040	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2041	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2042	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2043	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2044
2045	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2046	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2047	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2048	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2049	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2050	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2051	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2052	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2053	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2054
2055	{ }
2056};
2057
2058/* Enable GPIO mask and set output */
2059#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
2060#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
2061
2062/* Clevo m520g init */
2063static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2064	/* headphone output */
2065	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2066	/* line-out */
2067	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2068	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2069	/* Line-in */
2070	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2071	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2072	/* CD */
2073	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2074	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2075	/* Mic1 (rear panel) */
2076	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2077	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2078	/* Mic2 (front panel) */
2079	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2080	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2081	/* headphone */
2082	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2083	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2084        /* change to EAPD mode */
2085	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2086	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2087
2088	{ }
2089};
2090
2091static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2092	/* change to EAPD mode */
2093	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2094	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2095
2096	/* Headphone output */
2097	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2098	/* Front output*/
2099	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2100	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2101
2102	/* Line In pin widget for input */
2103	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2104	/* CD pin widget for input */
2105	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2106	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2107	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2108
2109	/* change to EAPD mode */
2110	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2111	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2112
2113	{ }
2114};
2115
2116/*
2117 * LG m1 express dual
2118 *
2119 * Pin assignment:
2120 *   Rear Line-In/Out (blue): 0x14
2121 *   Build-in Mic-In: 0x15
2122 *   Speaker-out: 0x17
2123 *   HP-Out (green): 0x1b
2124 *   Mic-In/Out (red): 0x19
2125 *   SPDIF-Out: 0x1e
2126 */
2127
2128/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2129static hda_nid_t alc880_lg_dac_nids[3] = {
2130	0x05, 0x02, 0x03
2131};
2132
2133/* seems analog CD is not working */
2134static struct hda_input_mux alc880_lg_capture_source = {
2135	.num_items = 3,
2136	.items = {
2137		{ "Mic", 0x1 },
2138		{ "Line", 0x5 },
2139		{ "Internal Mic", 0x6 },
2140	},
2141};
2142
2143/* 2,4,6 channel modes */
2144static struct hda_verb alc880_lg_ch2_init[] = {
2145	/* set line-in and mic-in to input */
2146	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2147	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2148	{ }
2149};
2150
2151static struct hda_verb alc880_lg_ch4_init[] = {
2152	/* set line-in to out and mic-in to input */
2153	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2154	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2155	{ }
2156};
2157
2158static struct hda_verb alc880_lg_ch6_init[] = {
2159	/* set line-in and mic-in to output */
2160	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2161	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2162	{ }
2163};
2164
2165static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2166	{ 2, alc880_lg_ch2_init },
2167	{ 4, alc880_lg_ch4_init },
2168	{ 6, alc880_lg_ch6_init },
2169};
2170
2171static struct snd_kcontrol_new alc880_lg_mixer[] = {
2172	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2173	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2174	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2175	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2176	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2177	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2178	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2179	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2180	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2181	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2182	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2183	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2184	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2185	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2186	{
2187		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2188		.name = "Channel Mode",
2189		.info = alc_ch_mode_info,
2190		.get = alc_ch_mode_get,
2191		.put = alc_ch_mode_put,
2192	},
2193	{ } /* end */
2194};
2195
2196static struct hda_verb alc880_lg_init_verbs[] = {
2197	/* set capture source to mic-in */
2198	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2199	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2200	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2201	/* mute all amp mixer inputs */
2202	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2203	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2204	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2205	/* line-in to input */
2206	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2207	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2208	/* built-in mic */
2209	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2210	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2211	/* speaker-out */
2212	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2213	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2214	/* mic-in to input */
2215	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2216	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2217	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2218	/* HP-out */
2219	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2220	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2221	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2222	/* jack sense */
2223	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2224	{ }
2225};
2226
2227/* toggle speaker-output according to the hp-jack state */
2228static void alc880_lg_automute(struct hda_codec *codec)
2229{
2230	unsigned int present;
2231	unsigned char bits;
2232
2233	present = snd_hda_codec_read(codec, 0x1b, 0,
2234				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2235	bits = present ? HDA_AMP_MUTE : 0;
2236	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2237				 HDA_AMP_MUTE, bits);
2238}
2239
2240static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2241{
2242	/* Looks like the unsol event is incompatible with the standard
2243	 * definition.  4bit tag is placed at 28 bit!
2244	 */
2245	if ((res >> 28) == 0x01)
2246		alc880_lg_automute(codec);
2247}
2248
2249/*
2250 * LG LW20
2251 *
2252 * Pin assignment:
2253 *   Speaker-out: 0x14
2254 *   Mic-In: 0x18
2255 *   Built-in Mic-In: 0x19
2256 *   Line-In: 0x1b
2257 *   HP-Out: 0x1a
2258 *   SPDIF-Out: 0x1e
2259 */
2260
2261static struct hda_input_mux alc880_lg_lw_capture_source = {
2262	.num_items = 3,
2263	.items = {
2264		{ "Mic", 0x0 },
2265		{ "Internal Mic", 0x1 },
2266		{ "Line In", 0x2 },
2267	},
2268};
2269
2270#define alc880_lg_lw_modes alc880_threestack_modes
2271
2272static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2273	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2274	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2275	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2276	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2277	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2278	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2279	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2280	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2281	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2282	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2283	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2284	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2285	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2286	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2287	{
2288		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2289		.name = "Channel Mode",
2290		.info = alc_ch_mode_info,
2291		.get = alc_ch_mode_get,
2292		.put = alc_ch_mode_put,
2293	},
2294	{ } /* end */
2295};
2296
2297static struct hda_verb alc880_lg_lw_init_verbs[] = {
2298	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2299	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2300	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2301
2302	/* set capture source to mic-in */
2303	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2304	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2305	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2306	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2307	/* speaker-out */
2308	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2309	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310	/* HP-out */
2311	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2312	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2313	/* mic-in to input */
2314	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2315	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2316	/* built-in mic */
2317	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2318	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2319	/* jack sense */
2320	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2321	{ }
2322};
2323
2324/* toggle speaker-output according to the hp-jack state */
2325static void alc880_lg_lw_automute(struct hda_codec *codec)
2326{
2327	unsigned int present;
2328	unsigned char bits;
2329
2330	present = snd_hda_codec_read(codec, 0x1b, 0,
2331				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2332	bits = present ? HDA_AMP_MUTE : 0;
2333	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2334				 HDA_AMP_MUTE, bits);
2335}
2336
2337static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2338{
2339	/* Looks like the unsol event is incompatible with the standard
2340	 * definition.  4bit tag is placed at 28 bit!
2341	 */
2342	if ((res >> 28) == 0x01)
2343		alc880_lg_lw_automute(codec);
2344}
2345
2346static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2347	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2348	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2349	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2350	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2351	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2352	HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2353	{ } /* end */
2354};
2355
2356static struct hda_input_mux alc880_medion_rim_capture_source = {
2357	.num_items = 2,
2358	.items = {
2359		{ "Mic", 0x0 },
2360		{ "Internal Mic", 0x1 },
2361	},
2362};
2363
2364static struct hda_verb alc880_medion_rim_init_verbs[] = {
2365	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2366
2367	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2368	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2369
2370	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2371	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2372	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2373	/* Mic2 (as headphone out) for HP output */
2374	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2375	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2376	/* Internal Speaker */
2377	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2378	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2379
2380	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2381	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2382
2383	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2384	{ }
2385};
2386
2387/* toggle speaker-output according to the hp-jack state */
2388static void alc880_medion_rim_automute(struct hda_codec *codec)
2389{
2390	unsigned int present;
2391	unsigned char bits;
2392
2393	present = snd_hda_codec_read(codec, 0x14, 0,
2394				     AC_VERB_GET_PIN_SENSE, 0)
2395		& AC_PINSENSE_PRESENCE;
2396	bits = present ? HDA_AMP_MUTE : 0;
2397	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2398				 HDA_AMP_MUTE, bits);
2399	if (present)
2400		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2401	else
2402		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2403}
2404
2405static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2406					  unsigned int res)
2407{
2408	/* Looks like the unsol event is incompatible with the standard
2409	 * definition.  4bit tag is placed at 28 bit!
2410	 */
2411	if ((res >> 28) == ALC880_HP_EVENT)
2412		alc880_medion_rim_automute(codec);
2413}
2414
2415#ifdef CONFIG_SND_HDA_POWER_SAVE
2416static struct hda_amp_list alc880_loopbacks[] = {
2417	{ 0x0b, HDA_INPUT, 0 },
2418	{ 0x0b, HDA_INPUT, 1 },
2419	{ 0x0b, HDA_INPUT, 2 },
2420	{ 0x0b, HDA_INPUT, 3 },
2421	{ 0x0b, HDA_INPUT, 4 },
2422	{ } /* end */
2423};
2424
2425static struct hda_amp_list alc880_lg_loopbacks[] = {
2426	{ 0x0b, HDA_INPUT, 1 },
2427	{ 0x0b, HDA_INPUT, 6 },
2428	{ 0x0b, HDA_INPUT, 7 },
2429	{ } /* end */
2430};
2431#endif
2432
2433/*
2434 * Common callbacks
2435 */
2436
2437static int alc_init(struct hda_codec *codec)
2438{
2439	struct alc_spec *spec = codec->spec;
2440	unsigned int i;
2441
2442	alc_fix_pll(codec);
2443	if (codec->vendor_id == 0x10ec0888)
2444		alc888_coef_init(codec);
2445
2446	for (i = 0; i < spec->num_init_verbs; i++)
2447		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2448
2449	if (spec->init_hook)
2450		spec->init_hook(codec);
2451
2452	return 0;
2453}
2454
2455static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2456{
2457	struct alc_spec *spec = codec->spec;
2458
2459	if (spec->unsol_event)
2460		spec->unsol_event(codec, res);
2461}
2462
2463#ifdef CONFIG_SND_HDA_POWER_SAVE
2464static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2465{
2466	struct alc_spec *spec = codec->spec;
2467	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2468}
2469#endif
2470
2471/*
2472 * Analog playback callbacks
2473 */
2474static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2475				    struct hda_codec *codec,
2476				    struct snd_pcm_substream *substream)
2477{
2478	struct alc_spec *spec = codec->spec;
2479	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2480					     hinfo);
2481}
2482
2483static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2484				       struct hda_codec *codec,
2485				       unsigned int stream_tag,
2486				       unsigned int format,
2487				       struct snd_pcm_substream *substream)
2488{
2489	struct alc_spec *spec = codec->spec;
2490	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2491						stream_tag, format, substream);
2492}
2493
2494static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2495				       struct hda_codec *codec,
2496				       struct snd_pcm_substream *substream)
2497{
2498	struct alc_spec *spec = codec->spec;
2499	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2500}
2501
2502/*
2503 * Digital out
2504 */
2505static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2506					struct hda_codec *codec,
2507					struct snd_pcm_substream *substream)
2508{
2509	struct alc_spec *spec = codec->spec;
2510	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2511}
2512
2513static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2514					   struct hda_codec *codec,
2515					   unsigned int stream_tag,
2516					   unsigned int format,
2517					   struct snd_pcm_substream *substream)
2518{
2519	struct alc_spec *spec = codec->spec;
2520	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2521					     stream_tag, format, substream);
2522}
2523
2524static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2525					 struct hda_codec *codec,
2526					 struct snd_pcm_substream *substream)
2527{
2528	struct alc_spec *spec = codec->spec;
2529	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2530}
2531
2532/*
2533 * Analog capture
2534 */
2535static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2536				      struct hda_codec *codec,
2537				      unsigned int stream_tag,
2538				      unsigned int format,
2539				      struct snd_pcm_substream *substream)
2540{
2541	struct alc_spec *spec = codec->spec;
2542
2543	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2544				   stream_tag, 0, format);
2545	return 0;
2546}
2547
2548static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2549				      struct hda_codec *codec,
2550				      struct snd_pcm_substream *substream)
2551{
2552	struct alc_spec *spec = codec->spec;
2553
2554	snd_hda_codec_cleanup_stream(codec,
2555				     spec->adc_nids[substream->number + 1]);
2556	return 0;
2557}
2558
2559
2560/*
2561 */
2562static struct hda_pcm_stream alc880_pcm_analog_playback = {
2563	.substreams = 1,
2564	.channels_min = 2,
2565	.channels_max = 8,
2566	/* NID is set in alc_build_pcms */
2567	.ops = {
2568		.open = alc880_playback_pcm_open,
2569		.prepare = alc880_playback_pcm_prepare,
2570		.cleanup = alc880_playback_pcm_cleanup
2571	},
2572};
2573
2574static struct hda_pcm_stream alc880_pcm_analog_capture = {
2575	.substreams = 1,
2576	.channels_min = 2,
2577	.channels_max = 2,
2578	/* NID is set in alc_build_pcms */
2579};
2580
2581static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2582	.substreams = 1,
2583	.channels_min = 2,
2584	.channels_max = 2,
2585	/* NID is set in alc_build_pcms */
2586};
2587
2588static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2589	.substreams = 2, /* can be overridden */
2590	.channels_min = 2,
2591	.channels_max = 2,
2592	/* NID is set in alc_build_pcms */
2593	.ops = {
2594		.prepare = alc880_alt_capture_pcm_prepare,
2595		.cleanup = alc880_alt_capture_pcm_cleanup
2596	},
2597};
2598
2599static struct hda_pcm_stream alc880_pcm_digital_playback = {
2600	.substreams = 1,
2601	.channels_min = 2,
2602	.channels_max = 2,
2603	/* NID is set in alc_build_pcms */
2604	.ops = {
2605		.open = alc880_dig_playback_pcm_open,
2606		.close = alc880_dig_playback_pcm_close,
2607		.prepare = alc880_dig_playback_pcm_prepare
2608	},
2609};
2610
2611static struct hda_pcm_stream alc880_pcm_digital_capture = {
2612	.substreams = 1,
2613	.channels_min = 2,
2614	.channels_max = 2,
2615	/* NID is set in alc_build_pcms */
2616};
2617
2618/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2619static struct hda_pcm_stream alc_pcm_null_stream = {
2620	.substreams = 0,
2621	.channels_min = 0,
2622	.channels_max = 0,
2623};
2624
2625static int alc_build_pcms(struct hda_codec *codec)
2626{
2627	struct alc_spec *spec = codec->spec;
2628	struct hda_pcm *info = spec->pcm_rec;
2629	int i;
2630
2631	codec->num_pcms = 1;
2632	codec->pcm_info = info;
2633
2634	info->name = spec->stream_name_analog;
2635	if (spec->stream_analog_playback) {
2636		if (snd_BUG_ON(!spec->multiout.dac_nids))
2637			return -EINVAL;
2638		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2639		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2640	}
2641	if (spec->stream_analog_capture) {
2642		if (snd_BUG_ON(!spec->adc_nids))
2643			return -EINVAL;
2644		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2645		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2646	}
2647
2648	if (spec->channel_mode) {
2649		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2650		for (i = 0; i < spec->num_channel_mode; i++) {
2651			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2652				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2653			}
2654		}
2655	}
2656
2657	/* SPDIF for stream index #1 */
2658	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2659		codec->num_pcms = 2;
2660		info = spec->pcm_rec + 1;
2661		info->name = spec->stream_name_digital;
2662		info->pcm_type = HDA_PCM_TYPE_SPDIF;
2663		if (spec->multiout.dig_out_nid &&
2664		    spec->stream_digital_playback) {
2665			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2666			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2667		}
2668		if (spec->dig_in_nid &&
2669		    spec->stream_digital_capture) {
2670			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2671			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2672		}
2673		/* FIXME: do we need this for all Realtek codec models? */
2674		codec->spdif_status_reset = 1;
2675	}
2676
2677	/* If the use of more than one ADC is requested for the current
2678	 * model, configure a second analog capture-only PCM.
2679	 */
2680	/* Additional Analaog capture for index #2 */
2681	if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2682	    (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2683		codec->num_pcms = 3;
2684		info = spec->pcm_rec + 2;
2685		info->name = spec->stream_name_analog;
2686		if (spec->alt_dac_nid) {
2687			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2688				*spec->stream_analog_alt_playback;
2689			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2690				spec->alt_dac_nid;
2691		} else {
2692			info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2693				alc_pcm_null_stream;
2694			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2695		}
2696		if (spec->num_adc_nids > 1) {
2697			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2698				*spec->stream_analog_alt_capture;
2699			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2700				spec->adc_nids[1];
2701			info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2702				spec->num_adc_nids - 1;
2703		} else {
2704			info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2705				alc_pcm_null_stream;
2706			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2707		}
2708	}
2709
2710	return 0;
2711}
2712
2713static void alc_free(struct hda_codec *codec)
2714{
2715	struct alc_spec *spec = codec->spec;
2716	unsigned int i;
2717
2718	if (!spec)
2719		return;
2720
2721	if (spec->kctl_alloc) {
2722		for (i = 0; i < spec->num_kctl_used; i++)
2723			kfree(spec->kctl_alloc[i].name);
2724		kfree(spec->kctl_alloc);
2725	}
2726	kfree(spec);
2727	codec->spec = NULL; /* to be sure */
2728}
2729
2730/*
2731 */
2732static struct hda_codec_ops alc_patch_ops = {
2733	.build_controls = alc_build_controls,
2734	.build_pcms = alc_build_pcms,
2735	.init = alc_init,
2736	.free = alc_free,
2737	.unsol_event = alc_unsol_event,
2738#ifdef CONFIG_SND_HDA_POWER_SAVE
2739	.check_power_status = alc_check_power_status,
2740#endif
2741};
2742
2743
2744/*
2745 * Test configuration for debugging
2746 *
2747 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2748 * enum controls.
2749 */
2750#ifdef CONFIG_SND_DEBUG
2751static hda_nid_t alc880_test_dac_nids[4] = {
2752	0x02, 0x03, 0x04, 0x05
2753};
2754
2755static struct hda_input_mux alc880_test_capture_source = {
2756	.num_items = 7,
2757	.items = {
2758		{ "In-1", 0x0 },
2759		{ "In-2", 0x1 },
2760		{ "In-3", 0x2 },
2761		{ "In-4", 0x3 },
2762		{ "CD", 0x4 },
2763		{ "Front", 0x5 },
2764		{ "Surround", 0x6 },
2765	},
2766};
2767
2768static struct hda_channel_mode alc880_test_modes[4] = {
2769	{ 2, NULL },
2770	{ 4, NULL },
2771	{ 6, NULL },
2772	{ 8, NULL },
2773};
2774
2775static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2776				 struct snd_ctl_elem_info *uinfo)
2777{
2778	static char *texts[] = {
2779		"N/A", "Line Out", "HP Out",
2780		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2781	};
2782	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2783	uinfo->count = 1;
2784	uinfo->value.enumerated.items = 8;
2785	if (uinfo->value.enumerated.item >= 8)
2786		uinfo->value.enumerated.item = 7;
2787	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2788	return 0;
2789}
2790
2791static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2792				struct snd_ctl_elem_value *ucontrol)
2793{
2794	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2795	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2796	unsigned int pin_ctl, item = 0;
2797
2798	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2799				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2800	if (pin_ctl & AC_PINCTL_OUT_EN) {
2801		if (pin_ctl & AC_PINCTL_HP_EN)
2802			item = 2;
2803		else
2804			item = 1;
2805	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2806		switch (pin_ctl & AC_PINCTL_VREFEN) {
2807		case AC_PINCTL_VREF_HIZ: item = 3; break;
2808		case AC_PINCTL_VREF_50:  item = 4; break;
2809		case AC_PINCTL_VREF_GRD: item = 5; break;
2810		case AC_PINCTL_VREF_80:  item = 6; break;
2811		case AC_PINCTL_VREF_100: item = 7; break;
2812		}
2813	}
2814	ucontrol->value.enumerated.item[0] = item;
2815	return 0;
2816}
2817
2818static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2819				struct snd_ctl_elem_value *ucontrol)
2820{
2821	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2822	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2823	static unsigned int ctls[] = {
2824		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2825		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2826		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2827		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2828		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2829		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2830	};
2831	unsigned int old_ctl, new_ctl;
2832
2833	old_ctl = snd_hda_codec_read(codec, nid, 0,
2834				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2835	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2836	if (old_ctl != new_ctl) {
2837		int val;
2838		snd_hda_codec_write_cache(codec, nid, 0,
2839					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2840					  new_ctl);
2841		val = ucontrol->value.enumerated.item[0] >= 3 ?
2842			HDA_AMP_MUTE : 0;
2843		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2844					 HDA_AMP_MUTE, val);
2845		return 1;
2846	}
2847	return 0;
2848}
2849
2850static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2851				 struct snd_ctl_elem_info *uinfo)
2852{
2853	static char *texts[] = {
2854		"Front", "Surround", "CLFE", "Side"
2855	};
2856	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2857	uinfo->count = 1;
2858	uinfo->value.enumerated.items = 4;
2859	if (uinfo->value.enumerated.item >= 4)
2860		uinfo->value.enumerated.item = 3;
2861	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2862	return 0;
2863}
2864
2865static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2866				struct snd_ctl_elem_value *ucontrol)
2867{
2868	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2869	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2870	unsigned int sel;
2871
2872	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2873	ucontrol->value.enumerated.item[0] = sel & 3;
2874	return 0;
2875}
2876
2877static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2878				struct snd_ctl_elem_value *ucontrol)
2879{
2880	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2881	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2882	unsigned int sel;
2883
2884	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2885	if (ucontrol->value.enumerated.item[0] != sel) {
2886		sel = ucontrol->value.enumerated.item[0] & 3;
2887		snd_hda_codec_write_cache(codec, nid, 0,
2888					  AC_VERB_SET_CONNECT_SEL, sel);
2889		return 1;
2890	}
2891	return 0;
2892}
2893
2894#define PIN_CTL_TEST(xname,nid) {			\
2895		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2896			.name = xname,		       \
2897			.info = alc_test_pin_ctl_info, \
2898			.get = alc_test_pin_ctl_get,   \
2899			.put = alc_test_pin_ctl_put,   \
2900			.private_value = nid	       \
2901			}
2902
2903#define PIN_SRC_TEST(xname,nid) {			\
2904		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2905			.name = xname,		       \
2906			.info = alc_test_pin_src_info, \
2907			.get = alc_test_pin_src_get,   \
2908			.put = alc_test_pin_src_put,   \
2909			.private_value = nid	       \
2910			}
2911
2912static struct snd_kcontrol_new alc880_test_mixer[] = {
2913	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2914	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2915	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2916	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2917	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2918	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2919	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2920	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2921	PIN_CTL_TEST("Front Pin Mode", 0x14),
2922	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2923	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2924	PIN_CTL_TEST("Side Pin Mode", 0x17),
2925	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2926	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2927	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2928	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2929	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2930	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2931	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2932	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2933	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2934	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2935	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2936	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2937	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2938	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2939	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2940	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2941	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2942	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2943	{
2944		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2945		.name = "Channel Mode",
2946		.info = alc_ch_mode_info,
2947		.get = alc_ch_mode_get,
2948		.put = alc_ch_mode_put,
2949	},
2950	{ } /* end */
2951};
2952
2953static struct hda_verb alc880_test_init_verbs[] = {
2954	/* Unmute inputs of 0x0c - 0x0f */
2955	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2956	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2957	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2958	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2959	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2960	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2961	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2962	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2963	/* Vol output for 0x0c-0x0f */
2964	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2965	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2966	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2967	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2968	/* Set output pins 0x14-0x17 */
2969	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2970	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2971	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2972	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2973	/* Unmute output pins 0x14-0x17 */
2974	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2975	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2976	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2977	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2978	/* Set input pins 0x18-0x1c */
2979	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2980	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2981	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2982	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2983	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2984	/* Mute input pins 0x18-0x1b */
2985	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2986	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2987	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2988	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2989	/* ADC set up */
2990	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2991	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2992	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2993	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2994	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2995	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2996	/* Analog input/passthru */
2997	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2998	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2999	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3000	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3001	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3002	{ }
3003};
3004#endif
3005
3006/*
3007 */
3008
3009static const char *alc880_models[ALC880_MODEL_LAST] = {
3010	[ALC880_3ST]		= "3stack",
3011	[ALC880_TCL_S700]	= "tcl",
3012	[ALC880_3ST_DIG]	= "3stack-digout",
3013	[ALC880_CLEVO]		= "clevo",
3014	[ALC880_5ST]		= "5stack",
3015	[ALC880_5ST_DIG]	= "5stack-digout",
3016	[ALC880_W810]		= "w810",
3017	[ALC880_Z71V]		= "z71v",
3018	[ALC880_6ST]		= "6stack",
3019	[ALC880_6ST_DIG]	= "6stack-digout",
3020	[ALC880_ASUS]		= "asus",
3021	[ALC880_ASUS_W1V]	= "asus-w1v",
3022	[ALC880_ASUS_DIG]	= "asus-dig",
3023	[ALC880_ASUS_DIG2]	= "asus-dig2",
3024	[ALC880_UNIWILL_DIG]	= "uniwill",
3025	[ALC880_UNIWILL_P53]	= "uniwill-p53",
3026	[ALC880_FUJITSU]	= "fujitsu",
3027	[ALC880_F1734]		= "F1734",
3028	[ALC880_LG]		= "lg",
3029	[ALC880_LG_LW]		= "lg-lw",
3030	[ALC880_MEDION_RIM]	= "medion",
3031#ifdef CONFIG_SND_DEBUG
3032	[ALC880_TEST]		= "test",
3033#endif
3034	[ALC880_AUTO]		= "auto",
3035};
3036
3037static struct snd_pci_quirk alc880_cfg_tbl[] = {
3038	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3039	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3040	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3041	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3042	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3043	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3044	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3045	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3046	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3047	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3048	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3049	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3050	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3051	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3052	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3053	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3054	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3055	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3056	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3057	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3058	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3059	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3060	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3061	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3062	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3063	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3064	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3065	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3066	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3067	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3068	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3069	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3070	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3071	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3072	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3073	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3074	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3075	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3076	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3077	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3078	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3079	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3080	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3081	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3082	SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3083	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3084	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3085	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3086	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3087	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3088	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3089	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3090	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3091	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3092	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3093	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3094	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3095	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3096	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3097	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3098	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3099	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3100	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3101	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3102	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3103	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3104	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3105	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3106	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3107	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3108	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3109	{}
3110};
3111
3112/*
3113 * ALC880 codec presets
3114 */
3115static struct alc_config_preset alc880_presets[] = {
3116	[ALC880_3ST] = {
3117		.mixers = { alc880_three_stack_mixer },
3118		.init_verbs = { alc880_volume_init_verbs,
3119				alc880_pin_3stack_init_verbs },
3120		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3121		.dac_nids = alc880_dac_nids,
3122		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3123		.channel_mode = alc880_threestack_modes,
3124		.need_dac_fix = 1,
3125		.input_mux = &alc880_capture_source,
3126	},
3127	[ALC880_3ST_DIG] = {
3128		.mixers = { alc880_three_stack_mixer },
3129		.init_verbs = { alc880_volume_init_verbs,
3130				alc880_pin_3stack_init_verbs },
3131		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3132		.dac_nids = alc880_dac_nids,
3133		.dig_out_nid = ALC880_DIGOUT_NID,
3134		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3135		.channel_mode = alc880_threestack_modes,
3136		.need_dac_fix = 1,
3137		.input_mux = &alc880_capture_source,
3138	},
3139	[ALC880_TCL_S700] = {
3140		.mixers = { alc880_tcl_s700_mixer },
3141		.init_verbs = { alc880_volume_init_verbs,
3142				alc880_pin_tcl_S700_init_verbs,
3143				alc880_gpio2_init_verbs },
3144		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3145		.dac_nids = alc880_dac_nids,
3146		.hp_nid = 0x03,
3147		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3148		.channel_mode = alc880_2_jack_modes,
3149		.input_mux = &alc880_capture_source,
3150	},
3151	[ALC880_5ST] = {
3152		.mixers = { alc880_three_stack_mixer,
3153			    alc880_five_stack_mixer},
3154		.init_verbs = { alc880_volume_init_verbs,
3155				alc880_pin_5stack_init_verbs },
3156		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3157		.dac_nids = alc880_dac_nids,
3158		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3159		.channel_mode = alc880_fivestack_modes,
3160		.input_mux = &alc880_capture_source,
3161	},
3162	[ALC880_5ST_DIG] = {
3163		.mixers = { alc880_three_stack_mixer,
3164			    alc880_five_stack_mixer },
3165		.init_verbs = { alc880_volume_init_verbs,
3166				alc880_pin_5stack_init_verbs },
3167		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3168		.dac_nids = alc880_dac_nids,
3169		.dig_out_nid = ALC880_DIGOUT_NID,
3170		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3171		.channel_mode = alc880_fivestack_modes,
3172		.input_mux = &alc880_capture_source,
3173	},
3174	[ALC880_6ST] = {
3175		.mixers = { alc880_six_stack_mixer },
3176		.init_verbs = { alc880_volume_init_verbs,
3177				alc880_pin_6stack_init_verbs },
3178		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3179		.dac_nids = alc880_6st_dac_nids,
3180		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3181		.channel_mode = alc880_sixstack_modes,
3182		.input_mux = &alc880_6stack_capture_source,
3183	},
3184	[ALC880_6ST_DIG] = {
3185		.mixers = { alc880_six_stack_mixer },
3186		.init_verbs = { alc880_volume_init_verbs,
3187				alc880_pin_6stack_init_verbs },
3188		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3189		.dac_nids = alc880_6st_dac_nids,
3190		.dig_out_nid = ALC880_DIGOUT_NID,
3191		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3192		.channel_mode = alc880_sixstack_modes,
3193		.input_mux = &alc880_6stack_capture_source,
3194	},
3195	[ALC880_W810] = {
3196		.mixers = { alc880_w810_base_mixer },
3197		.init_verbs = { alc880_volume_init_verbs,
3198				alc880_pin_w810_init_verbs,
3199				alc880_gpio2_init_verbs },
3200		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3201		.dac_nids = alc880_w810_dac_nids,
3202		.dig_out_nid = ALC880_DIGOUT_NID,
3203		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3204		.channel_mode = alc880_w810_modes,
3205		.input_mux = &alc880_capture_source,
3206	},
3207	[ALC880_Z71V] = {
3208		.mixers = { alc880_z71v_mixer },
3209		.init_verbs = { alc880_volume_init_verbs,
3210				alc880_pin_z71v_init_verbs },
3211		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3212		.dac_nids = alc880_z71v_dac_nids,
3213		.dig_out_nid = ALC880_DIGOUT_NID,
3214		.hp_nid = 0x03,
3215		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3216		.channel_mode = alc880_2_jack_modes,
3217		.input_mux = &alc880_capture_source,
3218	},
3219	[ALC880_F1734] = {
3220		.mixers = { alc880_f1734_mixer },
3221		.init_verbs = { alc880_volume_init_verbs,
3222				alc880_pin_f1734_init_verbs },
3223		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3224		.dac_nids = alc880_f1734_dac_nids,
3225		.hp_nid = 0x02,
3226		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3227		.channel_mode = alc880_2_jack_modes,
3228		.input_mux = &alc880_f1734_capture_source,
3229		.unsol_event = alc880_uniwill_p53_unsol_event,
3230		.init_hook = alc880_uniwill_p53_hp_automute,
3231	},
3232	[ALC880_ASUS] = {
3233		.mixers = { alc880_asus_mixer },
3234		.init_verbs = { alc880_volume_init_verbs,
3235				alc880_pin_asus_init_verbs,
3236				alc880_gpio1_init_verbs },
3237		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3238		.dac_nids = alc880_asus_dac_nids,
3239		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3240		.channel_mode = alc880_asus_modes,
3241		.need_dac_fix = 1,
3242		.input_mux = &alc880_capture_source,
3243	},
3244	[ALC880_ASUS_DIG] = {
3245		.mixers = { alc880_asus_mixer },
3246		.init_verbs = { alc880_volume_init_verbs,
3247				alc880_pin_asus_init_verbs,
3248				alc880_gpio1_init_verbs },
3249		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3250		.dac_nids = alc880_asus_dac_nids,
3251		.dig_out_nid = ALC880_DIGOUT_NID,
3252		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3253		.channel_mode = alc880_asus_modes,
3254		.need_dac_fix = 1,
3255		.input_mux = &alc880_capture_source,
3256	},
3257	[ALC880_ASUS_DIG2] = {
3258		.mixers = { alc880_asus_mixer },
3259		.init_verbs = { alc880_volume_init_verbs,
3260				alc880_pin_asus_init_verbs,
3261				alc880_gpio2_init_verbs }, /* use GPIO2 */
3262		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3263		.dac_nids = alc880_asus_dac_nids,
3264		.dig_out_nid = ALC880_DIGOUT_NID,
3265		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3266		.channel_mode = alc880_asus_modes,
3267		.need_dac_fix = 1,
3268		.input_mux = &alc880_capture_source,
3269	},
3270	[ALC880_ASUS_W1V] = {
3271		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3272		.init_verbs = { alc880_volume_init_verbs,
3273				alc880_pin_asus_init_verbs,
3274				alc880_gpio1_init_verbs },
3275		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3276		.dac_nids = alc880_asus_dac_nids,
3277		.dig_out_nid = ALC880_DIGOUT_NID,
3278		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3279		.channel_mode = alc880_asus_modes,
3280		.need_dac_fix = 1,
3281		.input_mux = &alc880_capture_source,
3282	},
3283	[ALC880_UNIWILL_DIG] = {
3284		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3285		.init_verbs = { alc880_volume_init_verbs,
3286				alc880_pin_asus_init_verbs },
3287		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3288		.dac_nids = alc880_asus_dac_nids,
3289		.dig_out_nid = ALC880_DIGOUT_NID,
3290		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3291		.channel_mode = alc880_asus_modes,
3292		.need_dac_fix = 1,
3293		.input_mux = &alc880_capture_source,
3294	},
3295	[ALC880_UNIWILL] = {
3296		.mixers = { alc880_uniwill_mixer },
3297		.init_verbs = { alc880_volume_init_verbs,
3298				alc880_uniwill_init_verbs },
3299		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3300		.dac_nids = alc880_asus_dac_nids,
3301		.dig_out_nid = ALC880_DIGOUT_NID,
3302		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3303		.channel_mode = alc880_threestack_modes,
3304		.need_dac_fix = 1,
3305		.input_mux = &alc880_capture_source,
3306		.unsol_event = alc880_uniwill_unsol_event,
3307		.init_hook = alc880_uniwill_automute,
3308	},
3309	[ALC880_UNIWILL_P53] = {
3310		.mixers = { alc880_uniwill_p53_mixer },
3311		.init_verbs = { alc880_volume_init_verbs,
3312				alc880_uniwill_p53_init_verbs },
3313		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3314		.dac_nids = alc880_asus_dac_nids,
3315		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3316		.channel_mode = alc880_threestack_modes,
3317		.input_mux = &alc880_capture_source,
3318		.unsol_event = alc880_uniwill_p53_unsol_event,
3319		.init_hook = alc880_uniwill_p53_hp_automute,
3320	},
3321	[ALC880_FUJITSU] = {
3322		.mixers = { alc880_fujitsu_mixer,
3323			    alc880_pcbeep_mixer, },
3324		.init_verbs = { alc880_volume_init_verbs,
3325				alc880_uniwill_p53_init_verbs,
3326	       			alc880_beep_init_verbs },
3327		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3328		.dac_nids = alc880_dac_nids,
3329		.dig_out_nid = ALC880_DIGOUT_NID,
3330		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3331		.channel_mode = alc880_2_jack_modes,
3332		.input_mux = &alc880_capture_source,
3333		.unsol_event = alc880_uniwill_p53_unsol_event,
3334		.init_hook = alc880_uniwill_p53_hp_automute,
3335	},
3336	[ALC880_CLEVO] = {
3337		.mixers = { alc880_three_stack_mixer },
3338		.init_verbs = { alc880_volume_init_verbs,
3339				alc880_pin_clevo_init_verbs },
3340		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3341		.dac_nids = alc880_dac_nids,
3342		.hp_nid = 0x03,
3343		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3344		.channel_mode = alc880_threestack_modes,
3345		.need_dac_fix = 1,
3346		.input_mux = &alc880_capture_source,
3347	},
3348	[ALC880_LG] = {
3349		.mixers = { alc880_lg_mixer },
3350		.init_verbs = { alc880_volume_init_verbs,
3351				alc880_lg_init_verbs },
3352		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3353		.dac_nids = alc880_lg_dac_nids,
3354		.dig_out_nid = ALC880_DIGOUT_NID,
3355		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3356		.channel_mode = alc880_lg_ch_modes,
3357		.need_dac_fix = 1,
3358		.input_mux = &alc880_lg_capture_source,
3359		.unsol_event = alc880_lg_unsol_event,
3360		.init_hook = alc880_lg_automute,
3361#ifdef CONFIG_SND_HDA_POWER_SAVE
3362		.loopbacks = alc880_lg_loopbacks,
3363#endif
3364	},
3365	[ALC880_LG_LW] = {
3366		.mixers = { alc880_lg_lw_mixer },
3367		.init_verbs = { alc880_volume_init_verbs,
3368				alc880_lg_lw_init_verbs },
3369		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3370		.dac_nids = alc880_dac_nids,
3371		.dig_out_nid = ALC880_DIGOUT_NID,
3372		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3373		.channel_mode = alc880_lg_lw_modes,
3374		.input_mux = &alc880_lg_lw_capture_source,
3375		.unsol_event = alc880_lg_lw_unsol_event,
3376		.init_hook = alc880_lg_lw_automute,
3377	},
3378	[ALC880_MEDION_RIM] = {
3379		.mixers = { alc880_medion_rim_mixer },
3380		.init_verbs = { alc880_volume_init_verbs,
3381				alc880_medion_rim_init_verbs,
3382				alc_gpio2_init_verbs },
3383		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
3384		.dac_nids = alc880_dac_nids,
3385		.dig_out_nid = ALC880_DIGOUT_NID,
3386		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3387		.channel_mode = alc880_2_jack_modes,
3388		.input_mux = &alc880_medion_rim_capture_source,
3389		.unsol_event = alc880_medion_rim_unsol_event,
3390		.init_hook = alc880_medion_rim_automute,
3391	},
3392#ifdef CONFIG_SND_DEBUG
3393	[ALC880_TEST] = {
3394		.mixers = { alc880_test_mixer },
3395		.init_verbs = { alc880_test_init_verbs },
3396		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3397		.dac_nids = alc880_test_dac_nids,
3398		.dig_out_nid = ALC880_DIGOUT_NID,
3399		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3400		.channel_mode = alc880_test_modes,
3401		.input_mux = &alc880_test_capture_source,
3402	},
3403#endif
3404};
3405
3406/*
3407 * Automatic parse of I/O pins from the BIOS configuration
3408 */
3409
3410#define NUM_CONTROL_ALLOC	32
3411#define NUM_VERB_ALLOC		32
3412
3413enum {
3414	ALC_CTL_WIDGET_VOL,
3415	ALC_CTL_WIDGET_MUTE,
3416	ALC_CTL_BIND_MUTE,
3417};
3418static struct snd_kcontrol_new alc880_control_templates[] = {
3419	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3420	HDA_CODEC_MUTE(NULL, 0, 0, 0),
3421	HDA_BIND_MUTE(NULL, 0, 0, 0),
3422};
3423
3424/* add dynamic controls */
3425static int add_control(struct alc_spec *spec, int type, const char *name,
3426		       unsigned long val)
3427{
3428	struct snd_kcontrol_new *knew;
3429
3430	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3431		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3432
3433		/* array + terminator */
3434		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3435		if (!knew)
3436			return -ENOMEM;
3437		if (spec->kctl_alloc) {
3438			memcpy(knew, spec->kctl_alloc,
3439			       sizeof(*knew) * spec->num_kctl_alloc);
3440			kfree(spec->kctl_alloc);
3441		}
3442		spec->kctl_alloc = knew;
3443		spec->num_kctl_alloc = num;
3444	}
3445
3446	knew = &spec->kctl_alloc[spec->num_kctl_used];
3447	*knew = alc880_control_templates[type];
3448	knew->name = kstrdup(name, GFP_KERNEL);
3449	if (!knew->name)
3450		return -ENOMEM;
3451	knew->private_value = val;
3452	spec->num_kctl_used++;
3453	return 0;
3454}
3455
3456#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
3457#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
3458#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
3459#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
3460#define alc880_is_input_pin(nid)	((nid) >= 0x18)
3461#define alc880_input_pin_idx(nid)	((nid) - 0x18)
3462#define alc880_idx_to_dac(nid)		((nid) + 0x02)
3463#define alc880_dac_to_idx(nid)		((nid) - 0x02)
3464#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
3465#define alc880_idx_to_selector(nid)	((nid) + 0x10)
3466#define ALC880_PIN_CD_NID		0x1c
3467
3468/* fill in the dac_nids table from the parsed pin configuration */
3469static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3470				     const struct auto_pin_cfg *cfg)
3471{
3472	hda_nid_t nid;
3473	int assigned[4];
3474	int i, j;
3475
3476	memset(assigned, 0, sizeof(assigned));
3477	spec->multiout.dac_nids = spec->private_dac_nids;
3478
3479	/* check the pins hardwired to audio widget */
3480	for (i = 0; i < cfg->line_outs; i++) {
3481		nid = cfg->line_out_pins[i];
3482		if (alc880_is_fixed_pin(nid)) {
3483			int idx = alc880_fixed_pin_idx(nid);
3484			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3485			assigned[idx] = 1;
3486		}
3487	}
3488	/* left pins can be connect to any audio widget */
3489	for (i = 0; i < cfg->line_outs; i++) {
3490		nid = cfg->line_out_pins[i];
3491		if (alc880_is_fixed_pin(nid))
3492			continue;
3493		/* search for an empty channel */
3494		for (j = 0; j < cfg->line_outs; j++) {
3495			if (!assigned[j]) {
3496				spec->multiout.dac_nids[i] =
3497					alc880_idx_to_dac(j);
3498				assigned[j] = 1;
3499				break;
3500			}
3501		}
3502	}
3503	spec->multiout.num_dacs = cfg->line_outs;
3504	return 0;
3505}
3506
3507/* add playback controls from the parsed DAC table */
3508static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3509					     const struct auto_pin_cfg *cfg)
3510{
3511	char name[32];
3512	static const char *chname[4] = {
3513		"Front", "Surround", NULL /*CLFE*/, "Side"
3514	};
3515	hda_nid_t nid;
3516	int i, err;
3517
3518	for (i = 0; i < cfg->line_outs; i++) {
3519		if (!spec->multiout.dac_nids[i])
3520			continue;
3521		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3522		if (i == 2) {
3523			/* Center/LFE */
3524			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3525					  "Center Playback Volume",
3526					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3527							      HDA_OUTPUT));
3528			if (err < 0)
3529				return err;
3530			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3531					  "LFE Playback Volume",
3532					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3533							      HDA_OUTPUT));
3534			if (err < 0)
3535				return err;
3536			err = add_control(spec, ALC_CTL_BIND_MUTE,
3537					  "Center Playback Switch",
3538					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3539							      HDA_INPUT));
3540			if (err < 0)
3541				return err;
3542			err = add_control(spec, ALC_CTL_BIND_MUTE,
3543					  "LFE Playback Switch",
3544					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3545							      HDA_INPUT));
3546			if (err < 0)
3547				return err;
3548		} else {
3549			sprintf(name, "%s Playback Volume", chname[i]);
3550			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3551					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3552							      HDA_OUTPUT));
3553			if (err < 0)
3554				return err;
3555			sprintf(name, "%s Playback Switch", chname[i]);
3556			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3557					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3558							      HDA_INPUT));
3559			if (err < 0)
3560				return err;
3561		}
3562	}
3563	return 0;
3564}
3565
3566/* add playback controls for speaker and HP outputs */
3567static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3568					const char *pfx)
3569{
3570	hda_nid_t nid;
3571	int err;
3572	char name[32];
3573
3574	if (!pin)
3575		return 0;
3576
3577	if (alc880_is_fixed_pin(pin)) {
3578		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3579		/* specify the DAC as the extra output */
3580		if (!spec->multiout.hp_nid)
3581			spec->multiout.hp_nid = nid;
3582		else
3583			spec->multiout.extra_out_nid[0] = nid;
3584		/* control HP volume/switch on the output mixer amp */
3585		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3586		sprintf(name, "%s Playback Volume", pfx);
3587		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3588				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3589		if (err < 0)
3590			return err;
3591		sprintf(name, "%s Playback Switch", pfx);
3592		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3593				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3594		if (err < 0)
3595			return err;
3596	} else if (alc880_is_multi_pin(pin)) {
3597		/* set manual connection */
3598		/* we have only a switch on HP-out PIN */
3599		sprintf(name, "%s Playback Switch", pfx);
3600		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3601				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3602		if (err < 0)
3603			return err;
3604	}
3605	return 0;
3606}
3607
3608/* create input playback/capture controls for the given pin */
3609static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3610			    const char *ctlname,
3611			    int idx, hda_nid_t mix_nid)
3612{
3613	char name[32];
3614	int err;
3615
3616	sprintf(name, "%s Playback Volume", ctlname);
3617	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3618			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3619	if (err < 0)
3620		return err;
3621	sprintf(name, "%s Playback Switch", ctlname);
3622	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3623			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3624	if (err < 0)
3625		return err;
3626	return 0;
3627}
3628
3629/* create playback/capture controls for input pins */
3630static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3631						const struct auto_pin_cfg *cfg)
3632{
3633	struct hda_input_mux *imux = &spec->private_imux;
3634	int i, err, idx;
3635
3636	for (i = 0; i < AUTO_PIN_LAST; i++) {
3637		if (alc880_is_input_pin(cfg->input_pins[i])) {
3638			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3639			err = new_analog_input(spec, cfg->input_pins[i],
3640					       auto_pin_cfg_labels[i],
3641					       idx, 0x0b);
3642			if (err < 0)
3643				return err;
3644			imux->items[imux->num_items].label =
3645				auto_pin_cfg_labels[i];
3646			imux->items[imux->num_items].index =
3647				alc880_input_pin_idx(cfg->input_pins[i]);
3648			imux->num_items++;
3649		}
3650	}
3651	return 0;
3652}
3653
3654static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3655			       unsigned int pin_type)
3656{
3657	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3658			    pin_type);
3659	/* unmute pin */
3660	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3661			    AMP_OUT_UNMUTE);
3662}
3663
3664static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3665					      hda_nid_t nid, int pin_type,
3666					      int dac_idx)
3667{
3668	alc_set_pin_output(codec, nid, pin_type);
3669	/* need the manual connection? */
3670	if (alc880_is_multi_pin(nid)) {
3671		struct alc_spec *spec = codec->spec;
3672		int idx = alc880_multi_pin_idx(nid);
3673		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3674				    AC_VERB_SET_CONNECT_SEL,
3675				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3676	}
3677}
3678
3679static int get_pin_type(int line_out_type)
3680{
3681	if (line_out_type == AUTO_PIN_HP_OUT)
3682		return PIN_HP;
3683	else
3684		return PIN_OUT;
3685}
3686
3687static void alc880_auto_init_multi_out(struct hda_codec *codec)
3688{
3689	struct alc_spec *spec = codec->spec;
3690	int i;
3691
3692	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3693	for (i = 0; i < spec->autocfg.line_outs; i++) {
3694		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3695		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3696		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3697	}
3698}
3699
3700static void alc880_auto_init_extra_out(struct hda_codec *codec)
3701{
3702	struct alc_spec *spec = codec->spec;
3703	hda_nid_t pin;
3704
3705	pin = spec->autocfg.speaker_pins[0];
3706	if (pin) /* connect to front */
3707		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3708	pin = spec->autocfg.hp_pins[0];
3709	if (pin) /* connect to front */
3710		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3711}
3712
3713static void alc880_auto_init_analog_input(struct hda_codec *codec)
3714{
3715	struct alc_spec *spec = codec->spec;
3716	int i;
3717
3718	for (i = 0; i < AUTO_PIN_LAST; i++) {
3719		hda_nid_t nid = spec->autocfg.input_pins[i];
3720		if (alc880_is_input_pin(nid)) {
3721			snd_hda_codec_write(codec, nid, 0,
3722					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3723					    i <= AUTO_PIN_FRONT_MIC ?
3724					    PIN_VREF80 : PIN_IN);
3725			if (nid != ALC880_PIN_CD_NID)
3726				snd_hda_codec_write(codec, nid, 0,
3727						    AC_VERB_SET_AMP_GAIN_MUTE,
3728						    AMP_OUT_MUTE);
3729		}
3730	}
3731}
3732
3733/* parse the BIOS configuration and set up the alc_spec */
3734/* return 1 if successful, 0 if the proper config is not found,
3735 * or a negative error code
3736 */
3737static int alc880_parse_auto_config(struct hda_codec *codec)
3738{
3739	struct alc_spec *spec = codec->spec;
3740	int err;
3741	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3742
3743	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3744					   alc880_ignore);
3745	if (err < 0)
3746		return err;
3747	if (!spec->autocfg.line_outs)
3748		return 0; /* can't find valid BIOS pin config */
3749
3750	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3751	if (err < 0)
3752		return err;
3753	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3754	if (err < 0)
3755		return err;
3756	err = alc880_auto_create_extra_out(spec,
3757					   spec->autocfg.speaker_pins[0],
3758					   "Speaker");
3759	if (err < 0)
3760		return err;
3761	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3762					   "Headphone");
3763	if (err < 0)
3764		return err;
3765	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3766	if (err < 0)
3767		return err;
3768
3769	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3770
3771	if (spec->autocfg.dig_out_pin)
3772		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3773	if (spec->autocfg.dig_in_pin)
3774		spec->dig_in_nid = ALC880_DIGIN_NID;
3775
3776	if (spec->kctl_alloc)
3777		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3778
3779	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3780
3781	spec->num_mux_defs = 1;
3782	spec->input_mux = &spec->private_imux;
3783
3784	return 1;
3785}
3786
3787/* additional initialization for auto-configuration model */
3788static void alc880_auto_init(struct hda_codec *codec)
3789{
3790	struct alc_spec *spec = codec->spec;
3791	alc880_auto_init_multi_out(codec);
3792	alc880_auto_init_extra_out(codec);
3793	alc880_auto_init_analog_input(codec);
3794	if (spec->unsol_event)
3795		alc_sku_automute(codec);
3796}
3797
3798/*
3799 * OK, here we have finally the patch for ALC880
3800 */
3801
3802static int patch_alc880(struct hda_codec *codec)
3803{
3804	struct alc_spec *spec;
3805	int board_config;
3806	int err;
3807
3808	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3809	if (spec == NULL)
3810		return -ENOMEM;
3811
3812	codec->spec = spec;
3813
3814	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3815						  alc880_models,
3816						  alc880_cfg_tbl);
3817	if (board_config < 0) {
3818		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3819		       "trying auto-probe from BIOS...\n");
3820		board_config = ALC880_AUTO;
3821	}
3822
3823	if (board_config == ALC880_AUTO) {
3824		/* automatic parse from the BIOS config */
3825		err = alc880_parse_auto_config(codec);
3826		if (err < 0) {
3827			alc_free(codec);
3828			return err;
3829		} else if (!err) {
3830			printk(KERN_INFO
3831			       "hda_codec: Cannot set up configuration "
3832			       "from BIOS.  Using 3-stack mode...\n");
3833			board_config = ALC880_3ST;
3834		}
3835	}
3836
3837	if (board_config != ALC880_AUTO)
3838		setup_preset(spec, &alc880_presets[board_config]);
3839
3840	spec->stream_name_analog = "ALC880 Analog";
3841	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3842	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3843	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3844
3845	spec->stream_name_digital = "ALC880 Digital";
3846	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3847	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3848
3849	if (!spec->adc_nids && spec->input_mux) {
3850		/* check whether NID 0x07 is valid */
3851		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3852		/* get type */
3853		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3854		if (wcap != AC_WID_AUD_IN) {
3855			spec->adc_nids = alc880_adc_nids_alt;
3856			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3857			spec->mixers[spec->num_mixers] =
3858				alc880_capture_alt_mixer;
3859			spec->num_mixers++;
3860		} else {
3861			spec->adc_nids = alc880_adc_nids;
3862			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3863			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3864			spec->num_mixers++;
3865		}
3866	}
3867
3868	spec->vmaster_nid = 0x0c;
3869
3870	codec->patch_ops = alc_patch_ops;
3871	if (board_config == ALC880_AUTO)
3872		spec->init_hook = alc880_auto_init;
3873#ifdef CONFIG_SND_HDA_POWER_SAVE
3874	if (!spec->loopback.amplist)
3875		spec->loopback.amplist = alc880_loopbacks;
3876#endif
3877
3878	return 0;
3879}
3880
3881
3882/*
3883 * ALC260 support
3884 */
3885
3886static hda_nid_t alc260_dac_nids[1] = {
3887	/* front */
3888	0x02,
3889};
3890
3891static hda_nid_t alc260_adc_nids[1] = {
3892	/* ADC0 */
3893	0x04,
3894};
3895
3896static hda_nid_t alc260_adc_nids_alt[1] = {
3897	/* ADC1 */
3898	0x05,
3899};
3900
3901static hda_nid_t alc260_hp_adc_nids[2] = {
3902	/* ADC1, 0 */
3903	0x05, 0x04
3904};
3905
3906/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3907 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3908 */
3909static hda_nid_t alc260_dual_adc_nids[2] = {
3910	/* ADC0, ADC1 */
3911	0x04, 0x05
3912};
3913
3914#define ALC260_DIGOUT_NID	0x03
3915#define ALC260_DIGIN_NID	0x06
3916
3917static struct hda_input_mux alc260_capture_source = {
3918	.num_items = 4,
3919	.items = {
3920		{ "Mic", 0x0 },
3921		{ "Front Mic", 0x1 },
3922		{ "Line", 0x2 },
3923		{ "CD", 0x4 },
3924	},
3925};
3926
3927/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3928 * headphone jack and the internal CD lines since these are the only pins at
3929 * which audio can appear.  For flexibility, also allow the option of
3930 * recording the mixer output on the second ADC (ADC0 doesn't have a
3931 * connection to the mixer output).
3932 */
3933static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3934	{
3935		.num_items = 3,
3936		.items = {
3937			{ "Mic/Line", 0x0 },
3938			{ "CD", 0x4 },
3939			{ "Headphone", 0x2 },
3940		},
3941	},
3942	{
3943		.num_items = 4,
3944		.items = {
3945			{ "Mic/Line", 0x0 },
3946			{ "CD", 0x4 },
3947			{ "Headphone", 0x2 },
3948			{ "Mixer", 0x5 },
3949		},
3950	},
3951
3952};
3953
3954/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3955 * the Fujitsu S702x, but jacks are marked differently.
3956 */
3957static struct hda_input_mux alc260_acer_capture_sources[2] = {
3958	{
3959		.num_items = 4,
3960		.items = {
3961			{ "Mic", 0x0 },
3962			{ "Line", 0x2 },
3963			{ "CD", 0x4 },
3964			{ "Headphone", 0x5 },
3965		},
3966	},
3967	{
3968		.num_items = 5,
3969		.items = {
3970			{ "Mic", 0x0 },
3971			{ "Line", 0x2 },
3972			{ "CD", 0x4 },
3973			{ "Headphone", 0x6 },
3974			{ "Mixer", 0x5 },
3975		},
3976	},
3977};
3978/*
3979 * This is just place-holder, so there's something for alc_build_pcms to look
3980 * at when it calculates the maximum number of channels. ALC260 has no mixer
3981 * element which allows changing the channel mode, so the verb list is
3982 * never used.
3983 */
3984static struct hda_channel_mode alc260_modes[1] = {
3985	{ 2, NULL },
3986};
3987
3988
3989/* Mixer combinations
3990 *
3991 * basic: base_output + input + pc_beep + capture
3992 * HP: base_output + input + capture_alt
3993 * HP_3013: hp_3013 + input + capture
3994 * fujitsu: fujitsu + capture
3995 * acer: acer + capture
3996 */
3997
3998static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3999	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4000	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4001	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4002	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4003	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4004	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4005	{ } /* end */
4006};
4007
4008static struct snd_kcontrol_new alc260_input_mixer[] = {
4009	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4010	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4011	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4012	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4013	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4014	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4015	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4016	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4017	{ } /* end */
4018};
4019
4020static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4021	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4022	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4023	{ } /* end */
4024};
4025
4026/* update HP, line and mono out pins according to the master switch */
4027static void alc260_hp_master_update(struct hda_codec *codec,
4028				    hda_nid_t hp, hda_nid_t line,
4029				    hda_nid_t mono)
4030{
4031	struct alc_spec *spec = codec->spec;
4032	unsigned int val = spec->master_sw ? PIN_HP : 0;
4033	/* change HP and line-out pins */
4034	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4035			    val);
4036	snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4037			    val);
4038	/* mono (speaker) depending on the HP jack sense */
4039	val = (val && !spec->jack_present) ? PIN_OUT : 0;
4040	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4041			    val);
4042}
4043
4044static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4045				   struct snd_ctl_elem_value *ucontrol)
4046{
4047	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4048	struct alc_spec *spec = codec->spec;
4049	*ucontrol->value.integer.value = spec->master_sw;
4050	return 0;
4051}
4052
4053static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4054				   struct snd_ctl_elem_value *ucontrol)
4055{
4056	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4057	struct alc_spec *spec = codec->spec;
4058	int val = !!*ucontrol->value.integer.value;
4059	hda_nid_t hp, line, mono;
4060
4061	if (val == spec->master_sw)
4062		return 0;
4063	spec->master_sw = val;
4064	hp = (kcontrol->private_value >> 16) & 0xff;
4065	line = (kcontrol->private_value >> 8) & 0xff;
4066	mono = kcontrol->private_value & 0xff;
4067	alc260_hp_master_update(codec, hp, line, mono);
4068	return 1;
4069}
4070
4071static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4072	{
4073		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4074		.name = "Master Playback Switch",
4075		.info = snd_ctl_boolean_mono_info,
4076		.get = alc260_hp_master_sw_get,
4077		.put = alc260_hp_master_sw_put,
4078		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4079	},
4080	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4081	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4082	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4083	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4084	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4085			      HDA_OUTPUT),
4086	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4087	{ } /* end */
4088};
4089
4090static struct hda_verb alc260_hp_unsol_verbs[] = {
4091	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4092	{},
4093};
4094
4095static void alc260_hp_automute(struct hda_codec *codec)
4096{
4097	struct alc_spec *spec = codec->spec;
4098	unsigned int present;
4099
4100	present = snd_hda_codec_read(codec, 0x10, 0,
4101				     AC_VERB_GET_PIN_SENSE, 0);
4102	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4103	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4104}
4105
4106static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4107{
4108	if ((res >> 26) == ALC880_HP_EVENT)
4109		alc260_hp_automute(codec);
4110}
4111
4112static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4113	{
4114		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4115		.name = "Master Playback Switch",
4116		.info = snd_ctl_boolean_mono_info,
4117		.get = alc260_hp_master_sw_get,
4118		.put = alc260_hp_master_sw_put,
4119		.private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4120	},
4121	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4122	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4123	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4124	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4125	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4126	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4127	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4128	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4129	{ } /* end */
4130};
4131
4132static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4133	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4134	{},
4135};
4136
4137static void alc260_hp_3013_automute(struct hda_codec *codec)
4138{
4139	struct alc_spec *spec = codec->spec;
4140	unsigned int present;
4141
4142	present = snd_hda_codec_read(codec, 0x15, 0,
4143				     AC_VERB_GET_PIN_SENSE, 0);
4144	spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4145	alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4146}
4147
4148static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4149				       unsigned int res)
4150{
4151	if ((res >> 26) == ALC880_HP_EVENT)
4152		alc260_hp_3013_automute(codec);
4153}
4154
4155/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
4156 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
4157 */
4158static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4159	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4160	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4161	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4162	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4163	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4164	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4165	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4166	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4167	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4168	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4169	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4170	HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4171	{ } /* end */
4172};
4173
4174/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
4175 * versions of the ALC260 don't act on requests to enable mic bias from NID
4176 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
4177 * datasheet doesn't mention this restriction.  At this stage it's not clear
4178 * whether this behaviour is intentional or is a hardware bug in chip
4179 * revisions available in early 2006.  Therefore for now allow the
4180 * "Headphone Jack Mode" control to span all choices, but if it turns out
4181 * that the lack of mic bias for this NID is intentional we could change the
4182 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4183 *
4184 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4185 * don't appear to make the mic bias available from the "line" jack, even
4186 * though the NID used for this jack (0x14) can supply it.  The theory is
4187 * that perhaps Acer have included blocking capacitors between the ALC260
4188 * and the output jack.  If this turns out to be the case for all such
4189 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4190 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4191 *
4192 * The C20x Tablet series have a mono internal speaker which is controlled
4193 * via the chip's Mono sum widget and pin complex, so include the necessary
4194 * controls for such models.  On models without a "mono speaker" the control
4195 * won't do anything.
4196 */
4197static struct snd_kcontrol_new alc260_acer_mixer[] = {
4198	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4199	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4200	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4201	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4202			      HDA_OUTPUT),
4203	HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4204			   HDA_INPUT),
4205	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4206	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4207	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4208	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4209	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4210	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4211	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4212	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4213	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4214	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4215	{ } /* end */
4216};
4217
4218/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4219 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
4220 */
4221static struct snd_kcontrol_new alc260_will_mixer[] = {
4222	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4223	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4224	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4225	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4226	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4227	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4228	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4229	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4230	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4231	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4232	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4233	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4234	{ } /* end */
4235};
4236
4237/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4238 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4239 */
4240static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4241	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4242	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4243	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4244	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4245	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4246	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4247	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4248	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4249	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4250	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4251	{ } /* end */
4252};
4253
4254/* capture mixer elements */
4255static struct snd_kcontrol_new alc260_capture_mixer[] = {
4256	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4257	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4258	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4259	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4260	{
4261		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4262		/* The multiple "Capture Source" controls confuse alsamixer
4263		 * So call somewhat different..
4264		 */
4265		/* .name = "Capture Source", */
4266		.name = "Input Source",
4267		.count = 2,
4268		.info = alc_mux_enum_info,
4269		.get = alc_mux_enum_get,
4270		.put = alc_mux_enum_put,
4271	},
4272	{ } /* end */
4273};
4274
4275static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4276	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4277	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4278	{
4279		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4280		/* The multiple "Capture Source" controls confuse alsamixer
4281		 * So call somewhat different..
4282		 */
4283		/* .name = "Capture Source", */
4284		.name = "Input Source",
4285		.count = 1,
4286		.info = alc_mux_enum_info,
4287		.get = alc_mux_enum_get,
4288		.put = alc_mux_enum_put,
4289	},
4290	{ } /* end */
4291};
4292
4293/*
4294 * initialization verbs
4295 */
4296static struct hda_verb alc260_init_verbs[] = {
4297	/* Line In pin widget for input */
4298	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4299	/* CD pin widget for input */
4300	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4301	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4302	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4303	/* Mic2 (front panel) pin widget for input and vref at 80% */
4304	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4305	/* LINE-2 is used for line-out in rear */
4306	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4307	/* select line-out */
4308	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4309	/* LINE-OUT pin */
4310	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4311	/* enable HP */
4312	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4313	/* enable Mono */
4314	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4315	/* mute capture amp left and right */
4316	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4317	/* set connection select to line in (default select for this ADC) */
4318	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4319	/* mute capture amp left and right */
4320	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4321	/* set connection select to line in (default select for this ADC) */
4322	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4323	/* set vol=0 Line-Out mixer amp left and right */
4324	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4325	/* unmute pin widget amp left and right (no gain on this amp) */
4326	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4327	/* set vol=0 HP mixer amp left and right */
4328	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4329	/* unmute pin widget amp left and right (no gain on this amp) */
4330	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4331	/* set vol=0 Mono mixer amp left and right */
4332	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4333	/* unmute pin widget amp left and right (no gain on this amp) */
4334	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4335	/* unmute LINE-2 out pin */
4336	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4337	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4338	 * Line In 2 = 0x03
4339	 */
4340	/* mute analog inputs */
4341	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4342	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4343	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4344	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4345	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4346	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4347	/* mute Front out path */
4348	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4349	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4350	/* mute Headphone out path */
4351	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4352	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4353	/* mute Mono out path */
4354	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4355	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4356	{ }
4357};
4358
4359#if 0 /* should be identical with alc260_init_verbs? */
4360static struct hda_verb alc260_hp_init_verbs[] = {
4361	/* Headphone and output */
4362	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4363	/* mono output */
4364	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4365	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4366	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4367	/* Mic2 (front panel) pin widget for input and vref at 80% */
4368	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4369	/* Line In pin widget for input */
4370	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4371	/* Line-2 pin widget for output */
4372	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4373	/* CD pin widget for input */
4374	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4375	/* unmute amp left and right */
4376	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4377	/* set connection select to line in (default select for this ADC) */
4378	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4379	/* unmute Line-Out mixer amp left and right (volume = 0) */
4380	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4381	/* mute pin widget amp left and right (no gain on this amp) */
4382	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4383	/* unmute HP mixer amp left and right (volume = 0) */
4384	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4385	/* mute pin widget amp left and right (no gain on this amp) */
4386	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4387	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4388	 * Line In 2 = 0x03
4389	 */
4390	/* mute analog inputs */
4391	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4392	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4393	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4394	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4395	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4396	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4397	/* Unmute Front out path */
4398	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4399	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4400	/* Unmute Headphone out path */
4401	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4402	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4403	/* Unmute Mono out path */
4404	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4405	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4406	{ }
4407};
4408#endif
4409
4410static struct hda_verb alc260_hp_3013_init_verbs[] = {
4411	/* Line out and output */
4412	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4413	/* mono output */
4414	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4415	/* Mic1 (rear panel) pin widget for input and vref at 80% */
4416	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4417	/* Mic2 (front panel) pin widget for input and vref at 80% */
4418	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4419	/* Line In pin widget for input */
4420	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4421	/* Headphone pin widget for output */
4422	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4423	/* CD pin widget for input */
4424	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4425	/* unmute amp left and right */
4426	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4427	/* set connection select to line in (default select for this ADC) */
4428	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4429	/* unmute Line-Out mixer amp left and right (volume = 0) */
4430	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4431	/* mute pin widget amp left and right (no gain on this amp) */
4432	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4433	/* unmute HP mixer amp left and right (volume = 0) */
4434	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4435	/* mute pin widget amp left and right (no gain on this amp) */
4436	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4437	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4438	 * Line In 2 = 0x03
4439	 */
4440	/* mute analog inputs */
4441	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4442	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4443	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4444	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4445	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4446	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4447	/* Unmute Front out path */
4448	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4449	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4450	/* Unmute Headphone out path */
4451	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4452	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4453	/* Unmute Mono out path */
4454	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4455	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4456	{ }
4457};
4458
4459/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4460 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4461 * audio = 0x16, internal speaker = 0x10.
4462 */
4463static struct hda_verb alc260_fujitsu_init_verbs[] = {
4464	/* Disable all GPIOs */
4465	{0x01, AC_VERB_SET_GPIO_MASK, 0},
4466	/* Internal speaker is connected to headphone pin */
4467	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4468	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
4469	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4470	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4471	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4472	/* Ensure all other unused pins are disabled and muted. */
4473	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4474	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4475	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4476	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4477	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4478	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4479	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4480	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4481
4482	/* Disable digital (SPDIF) pins */
4483	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4484	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4485
4486	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4487	 * when acting as an output.
4488	 */
4489	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4490
4491	/* Start with output sum widgets muted and their output gains at min */
4492	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4493	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4494	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4495	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4496	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4497	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4498	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4499	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4500	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4501
4502	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4503	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4504	/* Unmute Line1 pin widget output buffer since it starts as an output.
4505	 * If the pin mode is changed by the user the pin mode control will
4506	 * take care of enabling the pin's input/output buffers as needed.
4507	 * Therefore there's no need to enable the input buffer at this
4508	 * stage.
4509	 */
4510	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4511	/* Unmute input buffer of pin widget used for Line-in (no equiv
4512	 * mixer ctrl)
4513	 */
4514	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4515
4516	/* Mute capture amp left and right */
4517	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4518	/* Set ADC connection select to match default mixer setting - line
4519	 * in (on mic1 pin)
4520	 */
4521	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4522
4523	/* Do the same for the second ADC: mute capture input amp and
4524	 * set ADC connection to line in (on mic1 pin)
4525	 */
4526	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4527	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4528
4529	/* Mute all inputs to mixer widget (even unconnected ones) */
4530	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4531	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4532	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4533	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4534	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4535	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4536	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4537	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4538
4539	{ }
4540};
4541
4542/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4543 * similar laptops (adapted from Fujitsu init verbs).
4544 */
4545static struct hda_verb alc260_acer_init_verbs[] = {
4546	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
4547	 * the headphone jack.  Turn this on and rely on the standard mute
4548	 * methods whenever the user wants to turn these outputs off.
4549	 */
4550	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4551	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4552	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4553	/* Internal speaker/Headphone jack is connected to Line-out pin */
4554	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4555	/* Internal microphone/Mic jack is connected to Mic1 pin */
4556	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4557	/* Line In jack is connected to Line1 pin */
4558	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4559	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4560	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4561	/* Ensure all other unused pins are disabled and muted. */
4562	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4563	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4564	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4565	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4566	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4567	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4568	/* Disable digital (SPDIF) pins */
4569	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4570	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4571
4572	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4573	 * bus when acting as outputs.
4574	 */
4575	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4576	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4577
4578	/* Start with output sum widgets muted and their output gains at min */
4579	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4580	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4581	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4582	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4583	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4584	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4585	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4586	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4587	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4588
4589	/* Unmute Line-out pin widget amp left and right
4590	 * (no equiv mixer ctrl)
4591	 */
4592	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4593	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4594	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4595	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4596	 * inputs. If the pin mode is changed by the user the pin mode control
4597	 * will take care of enabling the pin's input/output buffers as needed.
4598	 * Therefore there's no need to enable the input buffer at this
4599	 * stage.
4600	 */
4601	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4602	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4603
4604	/* Mute capture amp left and right */
4605	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4606	/* Set ADC connection select to match default mixer setting - mic
4607	 * (on mic1 pin)
4608	 */
4609	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4610
4611	/* Do similar with the second ADC: mute capture input amp and
4612	 * set ADC connection to mic to match ALSA's default state.
4613	 */
4614	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4615	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4616
4617	/* Mute all inputs to mixer widget (even unconnected ones) */
4618	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4619	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4620	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4621	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4622	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4623	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4624	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4625	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4626
4627	{ }
4628};
4629
4630static struct hda_verb alc260_will_verbs[] = {
4631	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4632	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4633	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4634	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4635	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4636	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4637	{}
4638};
4639
4640static struct hda_verb alc260_replacer_672v_verbs[] = {
4641	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4642	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4643	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4644
4645	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4646	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4647	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4648
4649	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4650	{}
4651};
4652
4653/* toggle speaker-output according to the hp-jack state */
4654static void alc260_replacer_672v_automute(struct hda_codec *codec)
4655{
4656        unsigned int present;
4657
4658	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4659        present = snd_hda_codec_read(codec, 0x0f, 0,
4660                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4661	if (present) {
4662		snd_hda_codec_write_cache(codec, 0x01, 0,
4663					  AC_VERB_SET_GPIO_DATA, 1);
4664		snd_hda_codec_write_cache(codec, 0x0f, 0,
4665					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4666					  PIN_HP);
4667	} else {
4668		snd_hda_codec_write_cache(codec, 0x01, 0,
4669					  AC_VERB_SET_GPIO_DATA, 0);
4670		snd_hda_codec_write_cache(codec, 0x0f, 0,
4671					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4672					  PIN_OUT);
4673	}
4674}
4675
4676static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4677                                       unsigned int res)
4678{
4679        if ((res >> 26) == ALC880_HP_EVENT)
4680                alc260_replacer_672v_automute(codec);
4681}
4682
4683/* Test configuration for debugging, modelled after the ALC880 test
4684 * configuration.
4685 */
4686#ifdef CONFIG_SND_DEBUG
4687static hda_nid_t alc260_test_dac_nids[1] = {
4688	0x02,
4689};
4690static hda_nid_t alc260_test_adc_nids[2] = {
4691	0x04, 0x05,
4692};
4693/* For testing the ALC260, each input MUX needs its own definition since
4694 * the signal assignments are different.  This assumes that the first ADC
4695 * is NID 0x04.
4696 */
4697static struct hda_input_mux alc260_test_capture_sources[2] = {
4698	{
4699		.num_items = 7,
4700		.items = {
4701			{ "MIC1 pin", 0x0 },
4702			{ "MIC2 pin", 0x1 },
4703			{ "LINE1 pin", 0x2 },
4704			{ "LINE2 pin", 0x3 },
4705			{ "CD pin", 0x4 },
4706			{ "LINE-OUT pin", 0x5 },
4707			{ "HP-OUT pin", 0x6 },
4708		},
4709        },
4710	{
4711		.num_items = 8,
4712		.items = {
4713			{ "MIC1 pin", 0x0 },
4714			{ "MIC2 pin", 0x1 },
4715			{ "LINE1 pin", 0x2 },
4716			{ "LINE2 pin", 0x3 },
4717			{ "CD pin", 0x4 },
4718			{ "Mixer", 0x5 },
4719			{ "LINE-OUT pin", 0x6 },
4720			{ "HP-OUT pin", 0x7 },
4721		},
4722        },
4723};
4724static struct snd_kcontrol_new alc260_test_mixer[] = {
4725	/* Output driver widgets */
4726	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4727	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4728	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4729	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4730	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4731	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4732
4733	/* Modes for retasking pin widgets
4734	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4735         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4736         * mention this restriction.  At this stage it's not clear whether
4737         * this behaviour is intentional or is a hardware bug in chip
4738         * revisions available at least up until early 2006.  Therefore for
4739         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4740         * choices, but if it turns out that the lack of mic bias for these
4741         * NIDs is intentional we could change their modes from
4742         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4743	 */
4744	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4745	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4746	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4747	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4748	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4749	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4750
4751	/* Loopback mixer controls */
4752	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4753	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4754	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4755	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4756	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4757	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4758	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4759	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4760	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4761	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4762	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4763	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4764	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4765	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4766	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4767	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4768
4769	/* Controls for GPIO pins, assuming they are configured as outputs */
4770	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4771	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4772	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4773	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4774
4775	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4776	 * is ambigious as to which NID is which; testing on laptops which
4777	 * make this output available should provide clarification.
4778	 */
4779	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4780	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4781
4782	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
4783	 * this output to turn on an external amplifier.
4784	 */
4785	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4786	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4787
4788	{ } /* end */
4789};
4790static struct hda_verb alc260_test_init_verbs[] = {
4791	/* Enable all GPIOs as outputs with an initial value of 0 */
4792	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4793	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4794	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4795
4796	/* Enable retasking pins as output, initially without power amp */
4797	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4798	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4799	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4800	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4801	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4802	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4803
4804	/* Disable digital (SPDIF) pins initially, but users can enable
4805	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4806	 * payload also sets the generation to 0, output to be in "consumer"
4807	 * PCM format, copyright asserted, no pre-emphasis and no validity
4808	 * control.
4809	 */
4810	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4811	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4812
4813	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4814	 * OUT1 sum bus when acting as an output.
4815	 */
4816	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4817	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4818	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4819	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4820
4821	/* Start with output sum widgets muted and their output gains at min */
4822	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4823	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4824	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4825	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4826	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4827	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4828	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4829	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4830	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4831
4832	/* Unmute retasking pin widget output buffers since the default
4833	 * state appears to be output.  As the pin mode is changed by the
4834	 * user the pin mode control will take care of enabling the pin's
4835	 * input/output buffers as needed.
4836	 */
4837	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4838	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4839	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4840	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4841	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4842	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4843	/* Also unmute the mono-out pin widget */
4844	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4845
4846	/* Mute capture amp left and right */
4847	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4848	/* Set ADC connection select to match default mixer setting (mic1
4849	 * pin)
4850	 */
4851	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4852
4853	/* Do the same for the second ADC: mute capture input amp and
4854	 * set ADC connection to mic1 pin
4855	 */
4856	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4857	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4858
4859	/* Mute all inputs to mixer widget (even unconnected ones) */
4860	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4861	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4862	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4863	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4864	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4865	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4866	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4867	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4868
4869	{ }
4870};
4871#endif
4872
4873#define alc260_pcm_analog_playback	alc880_pcm_analog_alt_playback
4874#define alc260_pcm_analog_capture	alc880_pcm_analog_capture
4875
4876#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4877#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4878
4879/*
4880 * for BIOS auto-configuration
4881 */
4882
4883static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4884					const char *pfx)
4885{
4886	hda_nid_t nid_vol;
4887	unsigned long vol_val, sw_val;
4888	char name[32];
4889	int err;
4890
4891	if (nid >= 0x0f && nid < 0x11) {
4892		nid_vol = nid - 0x7;
4893		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4894		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4895	} else if (nid == 0x11) {
4896		nid_vol = nid - 0x7;
4897		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4898		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4899	} else if (nid >= 0x12 && nid <= 0x15) {
4900		nid_vol = 0x08;
4901		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4902		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4903	} else
4904		return 0; /* N/A */
4905
4906	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4907	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4908	if (err < 0)
4909		return err;
4910	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4911	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4912	if (err < 0)
4913		return err;
4914	return 1;
4915}
4916
4917/* add playback controls from the parsed DAC table */
4918static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4919					     const struct auto_pin_cfg *cfg)
4920{
4921	hda_nid_t nid;
4922	int err;
4923
4924	spec->multiout.num_dacs = 1;
4925	spec->multiout.dac_nids = spec->private_dac_nids;
4926	spec->multiout.dac_nids[0] = 0x02;
4927
4928	nid = cfg->line_out_pins[0];
4929	if (nid) {
4930		err = alc260_add_playback_controls(spec, nid, "Front");
4931		if (err < 0)
4932			return err;
4933	}
4934
4935	nid = cfg->speaker_pins[0];
4936	if (nid) {
4937		err = alc260_add_playback_controls(spec, nid, "Speaker");
4938		if (err < 0)
4939			return err;
4940	}
4941
4942	nid = cfg->hp_pins[0];
4943	if (nid) {
4944		err = alc260_add_playback_controls(spec, nid, "Headphone");
4945		if (err < 0)
4946			return err;
4947	}
4948	return 0;
4949}
4950
4951/* create playback/capture controls for input pins */
4952static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4953						const struct auto_pin_cfg *cfg)
4954{
4955	struct hda_input_mux *imux = &spec->private_imux;
4956	int i, err, idx;
4957
4958	for (i = 0; i < AUTO_PIN_LAST; i++) {
4959		if (cfg->input_pins[i] >= 0x12) {
4960			idx = cfg->input_pins[i] - 0x12;
4961			err = new_analog_input(spec, cfg->input_pins[i],
4962					       auto_pin_cfg_labels[i], idx,
4963					       0x07);
4964			if (err < 0)
4965				return err;
4966			imux->items[imux->num_items].label =
4967				auto_pin_cfg_labels[i];
4968			imux->items[imux->num_items].index = idx;
4969			imux->num_items++;
4970		}
4971		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4972			idx = cfg->input_pins[i] - 0x09;
4973			err = new_analog_input(spec, cfg->input_pins[i],
4974					       auto_pin_cfg_labels[i], idx,
4975					       0x07);
4976			if (err < 0)
4977				return err;
4978			imux->items[imux->num_items].label =
4979				auto_pin_cfg_labels[i];
4980			imux->items[imux->num_items].index = idx;
4981			imux->num_items++;
4982		}
4983	}
4984	return 0;
4985}
4986
4987static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4988					      hda_nid_t nid, int pin_type,
4989					      int sel_idx)
4990{
4991	alc_set_pin_output(codec, nid, pin_type);
4992	/* need the manual connection? */
4993	if (nid >= 0x12) {
4994		int idx = nid - 0x12;
4995		snd_hda_codec_write(codec, idx + 0x0b, 0,
4996				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4997	}
4998}
4999
5000static void alc260_auto_init_multi_out(struct hda_codec *codec)
5001{
5002	struct alc_spec *spec = codec->spec;
5003	hda_nid_t nid;
5004
5005	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5006	nid = spec->autocfg.line_out_pins[0];
5007	if (nid) {
5008		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5009		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5010	}
5011
5012	nid = spec->autocfg.speaker_pins[0];
5013	if (nid)
5014		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5015
5016	nid = spec->autocfg.hp_pins[0];
5017	if (nid)
5018		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5019}
5020
5021#define ALC260_PIN_CD_NID		0x16
5022static void alc260_auto_init_analog_input(struct hda_codec *codec)
5023{
5024	struct alc_spec *spec = codec->spec;
5025	int i;
5026
5027	for (i = 0; i < AUTO_PIN_LAST; i++) {
5028		hda_nid_t nid = spec->autocfg.input_pins[i];
5029		if (nid >= 0x12) {
5030			snd_hda_codec_write(codec, nid, 0,
5031					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5032					    i <= AUTO_PIN_FRONT_MIC ?
5033					    PIN_VREF80 : PIN_IN);
5034			if (nid != ALC260_PIN_CD_NID)
5035				snd_hda_codec_write(codec, nid, 0,
5036						    AC_VERB_SET_AMP_GAIN_MUTE,
5037						    AMP_OUT_MUTE);
5038		}
5039	}
5040}
5041
5042/*
5043 * generic initialization of ADC, input mixers and output mixers
5044 */
5045static struct hda_verb alc260_volume_init_verbs[] = {
5046	/*
5047	 * Unmute ADC0-1 and set the default input to mic-in
5048	 */
5049	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5050	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5051	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5052	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5053
5054	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5055	 * mixer widget
5056	 * Note: PASD motherboards uses the Line In 2 as the input for
5057	 * front panel mic (mic 2)
5058	 */
5059	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5060	/* mute analog inputs */
5061	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5062	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5063	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5064	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5065	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5066
5067	/*
5068	 * Set up output mixers (0x08 - 0x0a)
5069	 */
5070	/* set vol=0 to output mixers */
5071	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5072	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5073	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5074	/* set up input amps for analog loopback */
5075	/* Amp Indices: DAC = 0, mixer = 1 */
5076	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5077	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5078	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5079	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5080	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5081	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5082
5083	{ }
5084};
5085
5086static int alc260_parse_auto_config(struct hda_codec *codec)
5087{
5088	struct alc_spec *spec = codec->spec;
5089	unsigned int wcap;
5090	int err;
5091	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5092
5093	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5094					   alc260_ignore);
5095	if (err < 0)
5096		return err;
5097	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5098	if (err < 0)
5099		return err;
5100	if (!spec->kctl_alloc)
5101		return 0; /* can't find valid BIOS pin config */
5102	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5103	if (err < 0)
5104		return err;
5105
5106	spec->multiout.max_channels = 2;
5107
5108	if (spec->autocfg.dig_out_pin)
5109		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5110	if (spec->kctl_alloc)
5111		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5112
5113	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5114
5115	spec->num_mux_defs = 1;
5116	spec->input_mux = &spec->private_imux;
5117
5118	/* check whether NID 0x04 is valid */
5119	wcap = get_wcaps(codec, 0x04);
5120	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5121	if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5122		spec->adc_nids = alc260_adc_nids_alt;
5123		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5124		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5125	} else {
5126		spec->adc_nids = alc260_adc_nids;
5127		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5128		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5129	}
5130	spec->num_mixers++;
5131
5132	return 1;
5133}
5134
5135/* additional initialization for auto-configuration model */
5136static void alc260_auto_init(struct hda_codec *codec)
5137{
5138	struct alc_spec *spec = codec->spec;
5139	alc260_auto_init_multi_out(codec);
5140	alc260_auto_init_analog_input(codec);
5141	if (spec->unsol_event)
5142		alc_sku_automute(codec);
5143}
5144
5145#ifdef CONFIG_SND_HDA_POWER_SAVE
5146static struct hda_amp_list alc260_loopbacks[] = {
5147	{ 0x07, HDA_INPUT, 0 },
5148	{ 0x07, HDA_INPUT, 1 },
5149	{ 0x07, HDA_INPUT, 2 },
5150	{ 0x07, HDA_INPUT, 3 },
5151	{ 0x07, HDA_INPUT, 4 },
5152	{ } /* end */
5153};
5154#endif
5155
5156/*
5157 * ALC260 configurations
5158 */
5159static const char *alc260_models[ALC260_MODEL_LAST] = {
5160	[ALC260_BASIC]		= "basic",
5161	[ALC260_HP]		= "hp",
5162	[ALC260_HP_3013]	= "hp-3013",
5163	[ALC260_FUJITSU_S702X]	= "fujitsu",
5164	[ALC260_ACER]		= "acer",
5165	[ALC260_WILL]		= "will",
5166	[ALC260_REPLACER_672V]	= "replacer",
5167#ifdef CONFIG_SND_DEBUG
5168	[ALC260_TEST]		= "test",
5169#endif
5170	[ALC260_AUTO]		= "auto",
5171};
5172
5173static struct snd_pci_quirk alc260_cfg_tbl[] = {
5174	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5175	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5176	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5177	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5178	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5179	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5180	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5181	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5182	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5183	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5184	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5185	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5186	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5187	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5188	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5189	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5190	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5191	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5192	{}
5193};
5194
5195static struct alc_config_preset alc260_presets[] = {
5196	[ALC260_BASIC] = {
5197		.mixers = { alc260_base_output_mixer,
5198			    alc260_input_mixer,
5199			    alc260_pc_beep_mixer,
5200			    alc260_capture_mixer },
5201		.init_verbs = { alc260_init_verbs },
5202		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5203		.dac_nids = alc260_dac_nids,
5204		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5205		.adc_nids = alc260_adc_nids,
5206		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5207		.channel_mode = alc260_modes,
5208		.input_mux = &alc260_capture_source,
5209	},
5210	[ALC260_HP] = {
5211		.mixers = { alc260_hp_output_mixer,
5212			    alc260_input_mixer,
5213			    alc260_capture_alt_mixer },
5214		.init_verbs = { alc260_init_verbs,
5215				alc260_hp_unsol_verbs },
5216		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5217		.dac_nids = alc260_dac_nids,
5218		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5219		.adc_nids = alc260_hp_adc_nids,
5220		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5221		.channel_mode = alc260_modes,
5222		.input_mux = &alc260_capture_source,
5223		.unsol_event = alc260_hp_unsol_event,
5224		.init_hook = alc260_hp_automute,
5225	},
5226	[ALC260_HP_3013] = {
5227		.mixers = { alc260_hp_3013_mixer,
5228			    alc260_input_mixer,
5229			    alc260_capture_alt_mixer },
5230		.init_verbs = { alc260_hp_3013_init_verbs,
5231				alc260_hp_3013_unsol_verbs },
5232		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5233		.dac_nids = alc260_dac_nids,
5234		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5235		.adc_nids = alc260_hp_adc_nids,
5236		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5237		.channel_mode = alc260_modes,
5238		.input_mux = &alc260_capture_source,
5239		.unsol_event = alc260_hp_3013_unsol_event,
5240		.init_hook = alc260_hp_3013_automute,
5241	},
5242	[ALC260_FUJITSU_S702X] = {
5243		.mixers = { alc260_fujitsu_mixer,
5244			    alc260_capture_mixer },
5245		.init_verbs = { alc260_fujitsu_init_verbs },
5246		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5247		.dac_nids = alc260_dac_nids,
5248		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5249		.adc_nids = alc260_dual_adc_nids,
5250		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5251		.channel_mode = alc260_modes,
5252		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5253		.input_mux = alc260_fujitsu_capture_sources,
5254	},
5255	[ALC260_ACER] = {
5256		.mixers = { alc260_acer_mixer,
5257			    alc260_capture_mixer },
5258		.init_verbs = { alc260_acer_init_verbs },
5259		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5260		.dac_nids = alc260_dac_nids,
5261		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5262		.adc_nids = alc260_dual_adc_nids,
5263		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5264		.channel_mode = alc260_modes,
5265		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5266		.input_mux = alc260_acer_capture_sources,
5267	},
5268	[ALC260_WILL] = {
5269		.mixers = { alc260_will_mixer,
5270			    alc260_capture_mixer },
5271		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
5272		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5273		.dac_nids = alc260_dac_nids,
5274		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5275		.adc_nids = alc260_adc_nids,
5276		.dig_out_nid = ALC260_DIGOUT_NID,
5277		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5278		.channel_mode = alc260_modes,
5279		.input_mux = &alc260_capture_source,
5280	},
5281	[ALC260_REPLACER_672V] = {
5282		.mixers = { alc260_replacer_672v_mixer,
5283			    alc260_capture_mixer },
5284		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5285		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
5286		.dac_nids = alc260_dac_nids,
5287		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5288		.adc_nids = alc260_adc_nids,
5289		.dig_out_nid = ALC260_DIGOUT_NID,
5290		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5291		.channel_mode = alc260_modes,
5292		.input_mux = &alc260_capture_source,
5293		.unsol_event = alc260_replacer_672v_unsol_event,
5294		.init_hook = alc260_replacer_672v_automute,
5295	},
5296#ifdef CONFIG_SND_DEBUG
5297	[ALC260_TEST] = {
5298		.mixers = { alc260_test_mixer,
5299			    alc260_capture_mixer },
5300		.init_verbs = { alc260_test_init_verbs },
5301		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5302		.dac_nids = alc260_test_dac_nids,
5303		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5304		.adc_nids = alc260_test_adc_nids,
5305		.num_channel_mode = ARRAY_SIZE(alc260_modes),
5306		.channel_mode = alc260_modes,
5307		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5308		.input_mux = alc260_test_capture_sources,
5309	},
5310#endif
5311};
5312
5313static int patch_alc260(struct hda_codec *codec)
5314{
5315	struct alc_spec *spec;
5316	int err, board_config;
5317
5318	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5319	if (spec == NULL)
5320		return -ENOMEM;
5321
5322	codec->spec = spec;
5323
5324	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5325						  alc260_models,
5326						  alc260_cfg_tbl);
5327	if (board_config < 0) {
5328		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5329			   "trying auto-probe from BIOS...\n");
5330		board_config = ALC260_AUTO;
5331	}
5332
5333	if (board_config == ALC260_AUTO) {
5334		/* automatic parse from the BIOS config */
5335		err = alc260_parse_auto_config(codec);
5336		if (err < 0) {
5337			alc_free(codec);
5338			return err;
5339		} else if (!err) {
5340			printk(KERN_INFO
5341			       "hda_codec: Cannot set up configuration "
5342			       "from BIOS.  Using base mode...\n");
5343			board_config = ALC260_BASIC;
5344		}
5345	}
5346
5347	if (board_config != ALC260_AUTO)
5348		setup_preset(spec, &alc260_presets[board_config]);
5349
5350	spec->stream_name_analog = "ALC260 Analog";
5351	spec->stream_analog_playback = &alc260_pcm_analog_playback;
5352	spec->stream_analog_capture = &alc260_pcm_analog_capture;
5353
5354	spec->stream_name_digital = "ALC260 Digital";
5355	spec->stream_digital_playback = &alc260_pcm_digital_playback;
5356	spec->stream_digital_capture = &alc260_pcm_digital_capture;
5357
5358	spec->vmaster_nid = 0x08;
5359
5360	codec->patch_ops = alc_patch_ops;
5361	if (board_config == ALC260_AUTO)
5362		spec->init_hook = alc260_auto_init;
5363#ifdef CONFIG_SND_HDA_POWER_SAVE
5364	if (!spec->loopback.amplist)
5365		spec->loopback.amplist = alc260_loopbacks;
5366#endif
5367
5368	return 0;
5369}
5370
5371
5372/*
5373 * ALC882 support
5374 *
5375 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5376 * configuration.  Each pin widget can choose any input DACs and a mixer.
5377 * Each ADC is connected from a mixer of all inputs.  This makes possible
5378 * 6-channel independent captures.
5379 *
5380 * In addition, an independent DAC for the multi-playback (not used in this
5381 * driver yet).
5382 */
5383#define ALC882_DIGOUT_NID	0x06
5384#define ALC882_DIGIN_NID	0x0a
5385
5386static struct hda_channel_mode alc882_ch_modes[1] = {
5387	{ 8, NULL }
5388};
5389
5390static hda_nid_t alc882_dac_nids[4] = {
5391	/* front, rear, clfe, rear_surr */
5392	0x02, 0x03, 0x04, 0x05
5393};
5394
5395/* identical with ALC880 */
5396#define alc882_adc_nids		alc880_adc_nids
5397#define alc882_adc_nids_alt	alc880_adc_nids_alt
5398
5399static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5400static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5401
5402/* input MUX */
5403/* FIXME: should be a matrix-type input source selection */
5404
5405static struct hda_input_mux alc882_capture_source = {
5406	.num_items = 4,
5407	.items = {
5408		{ "Mic", 0x0 },
5409		{ "Front Mic", 0x1 },
5410		{ "Line", 0x2 },
5411		{ "CD", 0x4 },
5412	},
5413};
5414#define alc882_mux_enum_info alc_mux_enum_info
5415#define alc882_mux_enum_get alc_mux_enum_get
5416
5417static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5418			       struct snd_ctl_elem_value *ucontrol)
5419{
5420	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5421	struct alc_spec *spec = codec->spec;
5422	const struct hda_input_mux *imux = spec->input_mux;
5423	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5424	hda_nid_t nid = spec->capsrc_nids ?
5425		spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5426	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5427	unsigned int i, idx;
5428
5429	idx = ucontrol->value.enumerated.item[0];
5430	if (idx >= imux->num_items)
5431		idx = imux->num_items - 1;
5432	if (*cur_val == idx)
5433		return 0;
5434	for (i = 0; i < imux->num_items; i++) {
5435		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5436		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5437					 imux->items[i].index,
5438					 HDA_AMP_MUTE, v);
5439	}
5440	*cur_val = idx;
5441	return 1;
5442}
5443
5444/*
5445 * 2ch mode
5446 */
5447static struct hda_verb alc882_3ST_ch2_init[] = {
5448	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5449	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5450	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5451	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5452	{ } /* end */
5453};
5454
5455/*
5456 * 6ch mode
5457 */
5458static struct hda_verb alc882_3ST_ch6_init[] = {
5459	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5460	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5461	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5462	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5463	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5464	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5465	{ } /* end */
5466};
5467
5468static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5469	{ 2, alc882_3ST_ch2_init },
5470	{ 6, alc882_3ST_ch6_init },
5471};
5472
5473/*
5474 * 6ch mode
5475 */
5476static struct hda_verb alc882_sixstack_ch6_init[] = {
5477	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5478	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5479	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5480	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5481	{ } /* end */
5482};
5483
5484/*
5485 * 8ch mode
5486 */
5487static struct hda_verb alc882_sixstack_ch8_init[] = {
5488	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5489	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5490	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5491	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5492	{ } /* end */
5493};
5494
5495static struct hda_channel_mode alc882_sixstack_modes[2] = {
5496	{ 6, alc882_sixstack_ch6_init },
5497	{ 8, alc882_sixstack_ch8_init },
5498};
5499
5500/*
5501 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5502 */
5503
5504/*
5505 * 2ch mode
5506 */
5507static struct hda_verb alc885_mbp_ch2_init[] = {
5508	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5509	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5510	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5511	{ } /* end */
5512};
5513
5514/*
5515 * 6ch mode
5516 */
5517static struct hda_verb alc885_mbp_ch6_init[] = {
5518	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5519	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5520	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5521	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5522	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5523	{ } /* end */
5524};
5525
5526static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5527	{ 2, alc885_mbp_ch2_init },
5528	{ 6, alc885_mbp_ch6_init },
5529};
5530
5531
5532/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5533 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5534 */
5535static struct snd_kcontrol_new alc882_base_mixer[] = {
5536	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5537	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5538	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5539	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5540	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5541	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5542	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5543	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5544	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5545	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5546	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5547	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5548	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5549	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5550	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5551	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5552	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5553	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5554	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5555	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5556	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5557	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5558	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5559	{ } /* end */
5560};
5561
5562static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5563	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5564	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5565	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5566	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5567	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5568	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5569	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5570	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5571	HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5572	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5573	{ } /* end */
5574};
5575static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5576	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5577	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5578	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5579	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5580	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5581	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5582	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5583	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5584	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5585	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5586	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5587	{ } /* end */
5588};
5589
5590static struct snd_kcontrol_new alc882_targa_mixer[] = {
5591	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5592	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5593	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5594	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5595	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5596	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5597	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5598	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5599	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5600	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5601	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5602	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5603	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5604	{ } /* end */
5605};
5606
5607/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5608 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5609 */
5610static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5611	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5612	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5613	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5614	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5615	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5616	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5617	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5618	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5619	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5620	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5621	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5622	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5623	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5624	{ } /* end */
5625};
5626
5627static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5628	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5629	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5630	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5631	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5632	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5633	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5634	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5635	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5636	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5637	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5638	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5639	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5640	{ } /* end */
5641};
5642
5643static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5644	{
5645		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5646		.name = "Channel Mode",
5647		.info = alc_ch_mode_info,
5648		.get = alc_ch_mode_get,
5649		.put = alc_ch_mode_put,
5650	},
5651	{ } /* end */
5652};
5653
5654static struct hda_verb alc882_init_verbs[] = {
5655	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5656	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5657	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5658	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5659	/* Rear mixer */
5660	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5661	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5662	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5663	/* CLFE mixer */
5664	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5665	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5666	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5667	/* Side mixer */
5668	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5669	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5670	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5671
5672	/* Front Pin: output 0 (0x0c) */
5673	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5674	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5675	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5676	/* Rear Pin: output 1 (0x0d) */
5677	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5678	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5679	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5680	/* CLFE Pin: output 2 (0x0e) */
5681	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5682	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5683	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5684	/* Side Pin: output 3 (0x0f) */
5685	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5686	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5687	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5688	/* Mic (rear) pin: input vref at 80% */
5689	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5690	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5691	/* Front Mic pin: input vref at 80% */
5692	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5693	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5694	/* Line In pin: input */
5695	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5696	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5697	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5698	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5699	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5700	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5701	/* CD pin widget for input */
5702	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5703
5704	/* FIXME: use matrix-type input source selection */
5705	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5706	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5707	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5708	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5709	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5710	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5711	/* Input mixer2 */
5712	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5713	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5714	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5715	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5716	/* Input mixer3 */
5717	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5718	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5719	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5720	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5721	/* ADC1: mute amp left and right */
5722	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5723	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5724	/* ADC2: mute amp left and right */
5725	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5726	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5727	/* ADC3: mute amp left and right */
5728	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5729	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5730
5731	{ }
5732};
5733
5734static struct hda_verb alc882_eapd_verbs[] = {
5735	/* change to EAPD mode */
5736	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5737	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5738	{ }
5739};
5740
5741/* Mac Pro test */
5742static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5743	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5744	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5745	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5746	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5747	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5748	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5749	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5750	{ } /* end */
5751};
5752
5753static struct hda_verb alc882_macpro_init_verbs[] = {
5754	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5755	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5756	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5757	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5758	/* Front Pin: output 0 (0x0c) */
5759	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5760	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5761	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5762	/* Front Mic pin: input vref at 80% */
5763	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5764	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5765	/* Speaker:  output */
5766	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5767	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5768	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5769	/* Headphone output (output 0 - 0x0c) */
5770	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5771	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5772	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5773
5774	/* FIXME: use matrix-type input source selection */
5775	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5776	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5777	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5778	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5779	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5780	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5781	/* Input mixer2 */
5782	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5783	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5784	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5785	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5786	/* Input mixer3 */
5787	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5788	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5789	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5790	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5791	/* ADC1: mute amp left and right */
5792	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5793	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5794	/* ADC2: mute amp left and right */
5795	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5796	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5797	/* ADC3: mute amp left and right */
5798	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5799	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5800
5801	{ }
5802};
5803
5804/* Macbook Pro rev3 */
5805static struct hda_verb alc885_mbp3_init_verbs[] = {
5806	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5807	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5808	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5809	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5810	/* Rear mixer */
5811	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5812	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5813	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5814	/* Front Pin: output 0 (0x0c) */
5815	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5816	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5817	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5818	/* HP Pin: output 0 (0x0d) */
5819	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5820	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5821	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5822	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5823	/* Mic (rear) pin: input vref at 80% */
5824	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5825	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5826	/* Front Mic pin: input vref at 80% */
5827	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5828	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5829	/* Line In pin: use output 1 when in LineOut mode */
5830	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5831	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5832	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5833
5834	/* FIXME: use matrix-type input source selection */
5835	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5836	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5837	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5838	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5839	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5840	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5841	/* Input mixer2 */
5842	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5843	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5844	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5845	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5846	/* Input mixer3 */
5847	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5848	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5849	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5850	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5851	/* ADC1: mute amp left and right */
5852	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5853	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5854	/* ADC2: mute amp left and right */
5855	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5856	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5857	/* ADC3: mute amp left and right */
5858	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5859	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5860
5861	{ }
5862};
5863
5864/* iMac 24 mixer. */
5865static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5866	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5867	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5868	{ } /* end */
5869};
5870
5871/* iMac 24 init verbs. */
5872static struct hda_verb alc885_imac24_init_verbs[] = {
5873	/* Internal speakers: output 0 (0x0c) */
5874	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5875	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5876	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5877	/* Internal speakers: output 0 (0x0c) */
5878	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5879	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5880	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5881	/* Headphone: output 0 (0x0c) */
5882	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5883	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5884	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5885	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5886	/* Front Mic: input vref at 80% */
5887	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5888	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5889	{ }
5890};
5891
5892/* Toggle speaker-output according to the hp-jack state */
5893static void alc885_imac24_automute(struct hda_codec *codec)
5894{
5895 	unsigned int present;
5896
5897 	present = snd_hda_codec_read(codec, 0x14, 0,
5898				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5899	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5900				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5901	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5902				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5903}
5904
5905/* Processes unsolicited events. */
5906static void alc885_imac24_unsol_event(struct hda_codec *codec,
5907				      unsigned int res)
5908{
5909	/* Headphone insertion or removal. */
5910	if ((res >> 26) == ALC880_HP_EVENT)
5911		alc885_imac24_automute(codec);
5912}
5913
5914static void alc885_mbp3_automute(struct hda_codec *codec)
5915{
5916 	unsigned int present;
5917
5918 	present = snd_hda_codec_read(codec, 0x15, 0,
5919				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5920	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5921				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5922	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5923				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5924
5925}
5926static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5927				    unsigned int res)
5928{
5929	/* Headphone insertion or removal. */
5930	if ((res >> 26) == ALC880_HP_EVENT)
5931		alc885_mbp3_automute(codec);
5932}
5933
5934
5935static struct hda_verb alc882_targa_verbs[] = {
5936	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5937	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5938
5939	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5940	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5941
5942	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5943	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5944	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5945
5946	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5947	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5948	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5949	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5950	{ } /* end */
5951};
5952
5953/* toggle speaker-output according to the hp-jack state */
5954static void alc882_targa_automute(struct hda_codec *codec)
5955{
5956 	unsigned int present;
5957
5958 	present = snd_hda_codec_read(codec, 0x14, 0,
5959				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5960	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5961				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5962	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5963				  present ? 1 : 3);
5964}
5965
5966static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5967{
5968	/* Looks like the unsol event is incompatible with the standard
5969	 * definition.  4bit tag is placed at 26 bit!
5970	 */
5971	if (((res >> 26) == ALC880_HP_EVENT)) {
5972		alc882_targa_automute(codec);
5973	}
5974}
5975
5976static struct hda_verb alc882_asus_a7j_verbs[] = {
5977	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5978	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5979
5980	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5981	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5982	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5983
5984	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5985	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5986	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5987
5988	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5989	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5990	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5991	{ } /* end */
5992};
5993
5994static struct hda_verb alc882_asus_a7m_verbs[] = {
5995	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5996	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5997
5998	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5999	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6000	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6001
6002	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6003	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6004	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6005
6006	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6007	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6008	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6009 	{ } /* end */
6010};
6011
6012static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6013{
6014	unsigned int gpiostate, gpiomask, gpiodir;
6015
6016	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6017				       AC_VERB_GET_GPIO_DATA, 0);
6018
6019	if (!muted)
6020		gpiostate |= (1 << pin);
6021	else
6022		gpiostate &= ~(1 << pin);
6023
6024	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6025				      AC_VERB_GET_GPIO_MASK, 0);
6026	gpiomask |= (1 << pin);
6027
6028	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6029				     AC_VERB_GET_GPIO_DIRECTION, 0);
6030	gpiodir |= (1 << pin);
6031
6032
6033	snd_hda_codec_write(codec, codec->afg, 0,
6034			    AC_VERB_SET_GPIO_MASK, gpiomask);
6035	snd_hda_codec_write(codec, codec->afg, 0,
6036			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6037
6038	msleep(1);
6039
6040	snd_hda_codec_write(codec, codec->afg, 0,
6041			    AC_VERB_SET_GPIO_DATA, gpiostate);
6042}
6043
6044/* set up GPIO at initialization */
6045static void alc885_macpro_init_hook(struct hda_codec *codec)
6046{
6047	alc882_gpio_mute(codec, 0, 0);
6048	alc882_gpio_mute(codec, 1, 0);
6049}
6050
6051/* set up GPIO and update auto-muting at initialization */
6052static void alc885_imac24_init_hook(struct hda_codec *codec)
6053{
6054	alc885_macpro_init_hook(codec);
6055	alc885_imac24_automute(codec);
6056}
6057
6058/*
6059 * generic initialization of ADC, input mixers and output mixers
6060 */
6061static struct hda_verb alc882_auto_init_verbs[] = {
6062	/*
6063	 * Unmute ADC0-2 and set the default input to mic-in
6064	 */
6065	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6066	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6067	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6068	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6069	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6070	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6071
6072	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6073	 * mixer widget
6074	 * Note: PASD motherboards uses the Line In 2 as the input for
6075	 * front panel mic (mic 2)
6076	 */
6077	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6078	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6079	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6080	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6081	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6082	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6083
6084	/*
6085	 * Set up output mixers (0x0c - 0x0f)
6086	 */
6087	/* set vol=0 to output mixers */
6088	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6089	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6090	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6091	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6092	/* set up input amps for analog loopback */
6093	/* Amp Indices: DAC = 0, mixer = 1 */
6094	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6095	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6096	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6097	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6098	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6099	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6100	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6101	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6102	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6103	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6104
6105	/* FIXME: use matrix-type input source selection */
6106	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6107	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6108	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6109	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6110	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6111	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6112	/* Input mixer2 */
6113	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6114	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6115	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6116	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6117	/* Input mixer3 */
6118	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6119	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6120	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6121	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6122
6123	{ }
6124};
6125
6126/* capture mixer elements */
6127static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6128	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6129	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6130	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6131	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6132	{
6133		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6134		/* The multiple "Capture Source" controls confuse alsamixer
6135		 * So call somewhat different..
6136		 */
6137		/* .name = "Capture Source", */
6138		.name = "Input Source",
6139		.count = 2,
6140		.info = alc882_mux_enum_info,
6141		.get = alc882_mux_enum_get,
6142		.put = alc882_mux_enum_put,
6143	},
6144	{ } /* end */
6145};
6146
6147static struct snd_kcontrol_new alc882_capture_mixer[] = {
6148	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6149	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6150	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6151	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6152	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6153	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6154	{
6155		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6156		/* The multiple "Capture Source" controls confuse alsamixer
6157		 * So call somewhat different..
6158		 */
6159		/* .name = "Capture Source", */
6160		.name = "Input Source",
6161		.count = 3,
6162		.info = alc882_mux_enum_info,
6163		.get = alc882_mux_enum_get,
6164		.put = alc882_mux_enum_put,
6165	},
6166	{ } /* end */
6167};
6168
6169#ifdef CONFIG_SND_HDA_POWER_SAVE
6170#define alc882_loopbacks	alc880_loopbacks
6171#endif
6172
6173/* pcm configuration: identiacal with ALC880 */
6174#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
6175#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
6176#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
6177#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
6178
6179/*
6180 * configuration and preset
6181 */
6182static const char *alc882_models[ALC882_MODEL_LAST] = {
6183	[ALC882_3ST_DIG]	= "3stack-dig",
6184	[ALC882_6ST_DIG]	= "6stack-dig",
6185	[ALC882_ARIMA]		= "arima",
6186	[ALC882_W2JC]		= "w2jc",
6187	[ALC882_TARGA]		= "targa",
6188	[ALC882_ASUS_A7J]	= "asus-a7j",
6189	[ALC882_ASUS_A7M]	= "asus-a7m",
6190	[ALC885_MACPRO]		= "macpro",
6191	[ALC885_MBP3]		= "mbp3",
6192	[ALC885_IMAC24]		= "imac24",
6193	[ALC882_AUTO]		= "auto",
6194};
6195
6196static struct snd_pci_quirk alc882_cfg_tbl[] = {
6197	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6198	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6199	SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6200	SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6201	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6202	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6203	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6204	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6205	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6206	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
6207	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6208	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6209	{}
6210};
6211
6212static struct alc_config_preset alc882_presets[] = {
6213	[ALC882_3ST_DIG] = {
6214		.mixers = { alc882_base_mixer },
6215		.init_verbs = { alc882_init_verbs },
6216		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6217		.dac_nids = alc882_dac_nids,
6218		.dig_out_nid = ALC882_DIGOUT_NID,
6219		.dig_in_nid = ALC882_DIGIN_NID,
6220		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6221		.channel_mode = alc882_ch_modes,
6222		.need_dac_fix = 1,
6223		.input_mux = &alc882_capture_source,
6224	},
6225	[ALC882_6ST_DIG] = {
6226		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6227		.init_verbs = { alc882_init_verbs },
6228		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6229		.dac_nids = alc882_dac_nids,
6230		.dig_out_nid = ALC882_DIGOUT_NID,
6231		.dig_in_nid = ALC882_DIGIN_NID,
6232		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6233		.channel_mode = alc882_sixstack_modes,
6234		.input_mux = &alc882_capture_source,
6235	},
6236	[ALC882_ARIMA] = {
6237		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
6238		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6239		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6240		.dac_nids = alc882_dac_nids,
6241		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6242		.channel_mode = alc882_sixstack_modes,
6243		.input_mux = &alc882_capture_source,
6244	},
6245	[ALC882_W2JC] = {
6246		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6247		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6248				alc880_gpio1_init_verbs },
6249		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6250		.dac_nids = alc882_dac_nids,
6251		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6252		.channel_mode = alc880_threestack_modes,
6253		.need_dac_fix = 1,
6254		.input_mux = &alc882_capture_source,
6255		.dig_out_nid = ALC882_DIGOUT_NID,
6256	},
6257	[ALC885_MBP3] = {
6258		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6259		.init_verbs = { alc885_mbp3_init_verbs,
6260				alc880_gpio1_init_verbs },
6261		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6262		.dac_nids = alc882_dac_nids,
6263		.channel_mode = alc885_mbp_6ch_modes,
6264		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6265		.input_mux = &alc882_capture_source,
6266		.dig_out_nid = ALC882_DIGOUT_NID,
6267		.dig_in_nid = ALC882_DIGIN_NID,
6268		.unsol_event = alc885_mbp3_unsol_event,
6269		.init_hook = alc885_mbp3_automute,
6270	},
6271	[ALC885_MACPRO] = {
6272		.mixers = { alc882_macpro_mixer },
6273		.init_verbs = { alc882_macpro_init_verbs },
6274		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6275		.dac_nids = alc882_dac_nids,
6276		.dig_out_nid = ALC882_DIGOUT_NID,
6277		.dig_in_nid = ALC882_DIGIN_NID,
6278		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6279		.channel_mode = alc882_ch_modes,
6280		.input_mux = &alc882_capture_source,
6281		.init_hook = alc885_macpro_init_hook,
6282	},
6283	[ALC885_IMAC24] = {
6284		.mixers = { alc885_imac24_mixer },
6285		.init_verbs = { alc885_imac24_init_verbs },
6286		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6287		.dac_nids = alc882_dac_nids,
6288		.dig_out_nid = ALC882_DIGOUT_NID,
6289		.dig_in_nid = ALC882_DIGIN_NID,
6290		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6291		.channel_mode = alc882_ch_modes,
6292		.input_mux = &alc882_capture_source,
6293		.unsol_event = alc885_imac24_unsol_event,
6294		.init_hook = alc885_imac24_init_hook,
6295	},
6296	[ALC882_TARGA] = {
6297		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6298			    alc882_capture_mixer },
6299		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6300		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6301		.dac_nids = alc882_dac_nids,
6302		.dig_out_nid = ALC882_DIGOUT_NID,
6303		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6304		.adc_nids = alc882_adc_nids,
6305		.capsrc_nids = alc882_capsrc_nids,
6306		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6307		.channel_mode = alc882_3ST_6ch_modes,
6308		.need_dac_fix = 1,
6309		.input_mux = &alc882_capture_source,
6310		.unsol_event = alc882_targa_unsol_event,
6311		.init_hook = alc882_targa_automute,
6312	},
6313	[ALC882_ASUS_A7J] = {
6314		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6315			    alc882_capture_mixer },
6316		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6317		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6318		.dac_nids = alc882_dac_nids,
6319		.dig_out_nid = ALC882_DIGOUT_NID,
6320		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6321		.adc_nids = alc882_adc_nids,
6322		.capsrc_nids = alc882_capsrc_nids,
6323		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6324		.channel_mode = alc882_3ST_6ch_modes,
6325		.need_dac_fix = 1,
6326		.input_mux = &alc882_capture_source,
6327	},
6328	[ALC882_ASUS_A7M] = {
6329		.mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6330		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6331				alc880_gpio1_init_verbs,
6332				alc882_asus_a7m_verbs },
6333		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
6334		.dac_nids = alc882_dac_nids,
6335		.dig_out_nid = ALC882_DIGOUT_NID,
6336		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6337		.channel_mode = alc880_threestack_modes,
6338		.need_dac_fix = 1,
6339		.input_mux = &alc882_capture_source,
6340	},
6341};
6342
6343
6344/*
6345 * Pin config fixes
6346 */
6347enum {
6348	PINFIX_ABIT_AW9D_MAX
6349};
6350
6351static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6352	{ 0x15, 0x01080104 }, /* side */
6353	{ 0x16, 0x01011012 }, /* rear */
6354	{ 0x17, 0x01016011 }, /* clfe */
6355	{ }
6356};
6357
6358static const struct alc_pincfg *alc882_pin_fixes[] = {
6359	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6360};
6361
6362static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6363	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6364	{}
6365};
6366
6367/*
6368 * BIOS auto configuration
6369 */
6370static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6371					      hda_nid_t nid, int pin_type,
6372					      int dac_idx)
6373{
6374	/* set as output */
6375	struct alc_spec *spec = codec->spec;
6376	int idx;
6377
6378	alc_set_pin_output(codec, nid, pin_type);
6379	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6380		idx = 4;
6381	else
6382		idx = spec->multiout.dac_nids[dac_idx] - 2;
6383	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6384
6385}
6386
6387static void alc882_auto_init_multi_out(struct hda_codec *codec)
6388{
6389	struct alc_spec *spec = codec->spec;
6390	int i;
6391
6392	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6393	for (i = 0; i <= HDA_SIDE; i++) {
6394		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6395		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6396		if (nid)
6397			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6398							  i);
6399	}
6400}
6401
6402static void alc882_auto_init_hp_out(struct hda_codec *codec)
6403{
6404	struct alc_spec *spec = codec->spec;
6405	hda_nid_t pin;
6406
6407	pin = spec->autocfg.hp_pins[0];
6408	if (pin) /* connect to front */
6409		/* use dac 0 */
6410		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6411	pin = spec->autocfg.speaker_pins[0];
6412	if (pin)
6413		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6414}
6415
6416#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
6417#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
6418
6419static void alc882_auto_init_analog_input(struct hda_codec *codec)
6420{
6421	struct alc_spec *spec = codec->spec;
6422	int i;
6423
6424	for (i = 0; i < AUTO_PIN_LAST; i++) {
6425		hda_nid_t nid = spec->autocfg.input_pins[i];
6426		unsigned int vref;
6427		if (!nid)
6428			continue;
6429		vref = PIN_IN;
6430		if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6431			unsigned int pincap;
6432			pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6433			if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6434			    AC_PINCAP_VREF_80)
6435				vref = PIN_VREF80;
6436		}
6437		snd_hda_codec_write(codec, nid, 0,
6438				    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6439		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6440			snd_hda_codec_write(codec, nid, 0,
6441					    AC_VERB_SET_AMP_GAIN_MUTE,
6442					    AMP_OUT_MUTE);
6443	}
6444}
6445
6446static void alc882_auto_init_input_src(struct hda_codec *codec)
6447{
6448	struct alc_spec *spec = codec->spec;
6449	const struct hda_input_mux *imux = spec->input_mux;
6450	int c;
6451
6452	for (c = 0; c < spec->num_adc_nids; c++) {
6453		hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6454		hda_nid_t nid = spec->capsrc_nids[c];
6455		int conns, mute, idx, item;
6456
6457		conns = snd_hda_get_connections(codec, nid, conn_list,
6458						ARRAY_SIZE(conn_list));
6459		if (conns < 0)
6460			continue;
6461		for (idx = 0; idx < conns; idx++) {
6462			/* if the current connection is the selected one,
6463			 * unmute it as default - otherwise mute it
6464			 */
6465			mute = AMP_IN_MUTE(idx);
6466			for (item = 0; item < imux->num_items; item++) {
6467				if (imux->items[item].index == idx) {
6468					if (spec->cur_mux[c] == item)
6469						mute = AMP_IN_UNMUTE(idx);
6470					break;
6471				}
6472			}
6473			snd_hda_codec_write(codec, nid, 0,
6474					    AC_VERB_SET_AMP_GAIN_MUTE, mute);
6475		}
6476	}
6477}
6478
6479/* add mic boosts if needed */
6480static int alc_auto_add_mic_boost(struct hda_codec *codec)
6481{
6482	struct alc_spec *spec = codec->spec;
6483	int err;
6484	hda_nid_t nid;
6485
6486	nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6487	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6488		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6489				  "Mic Boost",
6490				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6491		if (err < 0)
6492			return err;
6493	}
6494	nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6495	if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6496		err = add_control(spec, ALC_CTL_WIDGET_VOL,
6497				  "Front Mic Boost",
6498				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6499		if (err < 0)
6500			return err;
6501	}
6502	return 0;
6503}
6504
6505/* almost identical with ALC880 parser... */
6506static int alc882_parse_auto_config(struct hda_codec *codec)
6507{
6508	struct alc_spec *spec = codec->spec;
6509	int err = alc880_parse_auto_config(codec);
6510
6511	if (err < 0)
6512		return err;
6513	else if (!err)
6514		return 0; /* no config found */
6515
6516	err = alc_auto_add_mic_boost(codec);
6517	if (err < 0)
6518		return err;
6519
6520	/* hack - override the init verbs */
6521	spec->init_verbs[0] = alc882_auto_init_verbs;
6522
6523	return 1; /* config found */
6524}
6525
6526/* additional initialization for auto-configuration model */
6527static void alc882_auto_init(struct hda_codec *codec)
6528{
6529	struct alc_spec *spec = codec->spec;
6530	alc882_auto_init_multi_out(codec);
6531	alc882_auto_init_hp_out(codec);
6532	alc882_auto_init_analog_input(codec);
6533	alc882_auto_init_input_src(codec);
6534	if (spec->unsol_event)
6535		alc_sku_automute(codec);
6536}
6537
6538static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6539
6540static int patch_alc882(struct hda_codec *codec)
6541{
6542	struct alc_spec *spec;
6543	int err, board_config;
6544
6545	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6546	if (spec == NULL)
6547		return -ENOMEM;
6548
6549	codec->spec = spec;
6550
6551	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6552						  alc882_models,
6553						  alc882_cfg_tbl);
6554
6555	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6556		/* Pick up systems that don't supply PCI SSID */
6557		switch (codec->subsystem_id) {
6558		case 0x106b0c00: /* Mac Pro */
6559			board_config = ALC885_MACPRO;
6560			break;
6561		case 0x106b1000: /* iMac 24 */
6562			board_config = ALC885_IMAC24;
6563			break;
6564		case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6565		case 0x106b2c00: /* Macbook Pro rev3 */
6566		case 0x106b3600: /* Macbook 3.1 */
6567			board_config = ALC885_MBP3;
6568			break;
6569		default:
6570			/* ALC889A is handled better as ALC888-compatible */
6571			if (codec->revision_id == 0x100103) {
6572				alc_free(codec);
6573				return patch_alc883(codec);
6574			}
6575			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6576		       			 "trying auto-probe from BIOS...\n");
6577			board_config = ALC882_AUTO;
6578		}
6579	}
6580
6581	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6582
6583	if (board_config == ALC882_AUTO) {
6584		/* automatic parse from the BIOS config */
6585		err = alc882_parse_auto_config(codec);
6586		if (err < 0) {
6587			alc_free(codec);
6588			return err;
6589		} else if (!err) {
6590			printk(KERN_INFO
6591			       "hda_codec: Cannot set up configuration "
6592			       "from BIOS.  Using base mode...\n");
6593			board_config = ALC882_3ST_DIG;
6594		}
6595	}
6596
6597	if (board_config != ALC882_AUTO)
6598		setup_preset(spec, &alc882_presets[board_config]);
6599
6600	if (codec->vendor_id == 0x10ec0885) {
6601		spec->stream_name_analog = "ALC885 Analog";
6602		spec->stream_name_digital = "ALC885 Digital";
6603	} else {
6604		spec->stream_name_analog = "ALC882 Analog";
6605		spec->stream_name_digital = "ALC882 Digital";
6606	}
6607
6608	spec->stream_analog_playback = &alc882_pcm_analog_playback;
6609	spec->stream_analog_capture = &alc882_pcm_analog_capture;
6610	/* FIXME: setup DAC5 */
6611	/*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6612	spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6613
6614	spec->stream_digital_playback = &alc882_pcm_digital_playback;
6615	spec->stream_digital_capture = &alc882_pcm_digital_capture;
6616
6617	if (!spec->adc_nids && spec->input_mux) {
6618		/* check whether NID 0x07 is valid */
6619		unsigned int wcap = get_wcaps(codec, 0x07);
6620		/* get type */
6621		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6622		if (wcap != AC_WID_AUD_IN) {
6623			spec->adc_nids = alc882_adc_nids_alt;
6624			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6625			spec->capsrc_nids = alc882_capsrc_nids_alt;
6626			spec->mixers[spec->num_mixers] =
6627				alc882_capture_alt_mixer;
6628			spec->num_mixers++;
6629		} else {
6630			spec->adc_nids = alc882_adc_nids;
6631			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6632			spec->capsrc_nids = alc882_capsrc_nids;
6633			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6634			spec->num_mixers++;
6635		}
6636	}
6637
6638	spec->vmaster_nid = 0x0c;
6639
6640	codec->patch_ops = alc_patch_ops;
6641	if (board_config == ALC882_AUTO)
6642		spec->init_hook = alc882_auto_init;
6643#ifdef CONFIG_SND_HDA_POWER_SAVE
6644	if (!spec->loopback.amplist)
6645		spec->loopback.amplist = alc882_loopbacks;
6646#endif
6647
6648	return 0;
6649}
6650
6651/*
6652 * ALC883 support
6653 *
6654 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6655 * configuration.  Each pin widget can choose any input DACs and a mixer.
6656 * Each ADC is connected from a mixer of all inputs.  This makes possible
6657 * 6-channel independent captures.
6658 *
6659 * In addition, an independent DAC for the multi-playback (not used in this
6660 * driver yet).
6661 */
6662#define ALC883_DIGOUT_NID	0x06
6663#define ALC883_DIGIN_NID	0x0a
6664
6665static hda_nid_t alc883_dac_nids[4] = {
6666	/* front, rear, clfe, rear_surr */
6667	0x02, 0x03, 0x04, 0x05
6668};
6669
6670static hda_nid_t alc883_adc_nids[2] = {
6671	/* ADC1-2 */
6672	0x08, 0x09,
6673};
6674
6675static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6676
6677/* input MUX */
6678/* FIXME: should be a matrix-type input source selection */
6679
6680static struct hda_input_mux alc883_capture_source = {
6681	.num_items = 4,
6682	.items = {
6683		{ "Mic", 0x0 },
6684		{ "Front Mic", 0x1 },
6685		{ "Line", 0x2 },
6686		{ "CD", 0x4 },
6687	},
6688};
6689
6690static struct hda_input_mux alc883_3stack_6ch_intel = {
6691	.num_items = 4,
6692	.items = {
6693		{ "Mic", 0x1 },
6694		{ "Front Mic", 0x0 },
6695		{ "Line", 0x2 },
6696		{ "CD", 0x4 },
6697	},
6698};
6699
6700static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6701	.num_items = 2,
6702	.items = {
6703		{ "Mic", 0x1 },
6704		{ "Line", 0x2 },
6705	},
6706};
6707
6708static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6709	.num_items = 4,
6710	.items = {
6711		{ "Mic", 0x0 },
6712		{ "iMic", 0x1 },
6713		{ "Line", 0x2 },
6714		{ "CD", 0x4 },
6715	},
6716};
6717
6718static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6719	.num_items = 2,
6720	.items = {
6721		{ "Mic", 0x0 },
6722		{ "Int Mic", 0x1 },
6723	},
6724};
6725
6726#define alc883_mux_enum_info alc_mux_enum_info
6727#define alc883_mux_enum_get alc_mux_enum_get
6728/* ALC883 has the ALC882-type input selection */
6729#define alc883_mux_enum_put alc882_mux_enum_put
6730
6731/*
6732 * 2ch mode
6733 */
6734static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6735	{ 2, NULL }
6736};
6737
6738/*
6739 * 2ch mode
6740 */
6741static struct hda_verb alc883_3ST_ch2_init[] = {
6742	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6743	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6744	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6745	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6746	{ } /* end */
6747};
6748
6749/*
6750 * 4ch mode
6751 */
6752static struct hda_verb alc883_3ST_ch4_init[] = {
6753	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6754	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6755	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6756	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6757	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6758	{ } /* end */
6759};
6760
6761/*
6762 * 6ch mode
6763 */
6764static struct hda_verb alc883_3ST_ch6_init[] = {
6765	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6766	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6767	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6768	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6769	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6770	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6771	{ } /* end */
6772};
6773
6774static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6775	{ 2, alc883_3ST_ch2_init },
6776	{ 4, alc883_3ST_ch4_init },
6777	{ 6, alc883_3ST_ch6_init },
6778};
6779
6780/*
6781 * 2ch mode
6782 */
6783static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6784	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6785	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6786	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6787	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6788	{ } /* end */
6789};
6790
6791/*
6792 * 4ch mode
6793 */
6794static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6795	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6796	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6797	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6798	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6799	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6800	{ } /* end */
6801};
6802
6803/*
6804 * 6ch mode
6805 */
6806static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6807	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6808	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6809	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6810	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6811	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6812	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6813	{ } /* end */
6814};
6815
6816static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6817	{ 2, alc883_3ST_ch2_intel_init },
6818	{ 4, alc883_3ST_ch4_intel_init },
6819	{ 6, alc883_3ST_ch6_intel_init },
6820};
6821
6822/*
6823 * 6ch mode
6824 */
6825static struct hda_verb alc883_sixstack_ch6_init[] = {
6826	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6827	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6828	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6829	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6830	{ } /* end */
6831};
6832
6833/*
6834 * 8ch mode
6835 */
6836static struct hda_verb alc883_sixstack_ch8_init[] = {
6837	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6838	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6839	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6840	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6841	{ } /* end */
6842};
6843
6844static struct hda_channel_mode alc883_sixstack_modes[2] = {
6845	{ 6, alc883_sixstack_ch6_init },
6846	{ 8, alc883_sixstack_ch8_init },
6847};
6848
6849static struct hda_verb alc883_medion_eapd_verbs[] = {
6850        /* eanable EAPD on medion laptop */
6851	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6852	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6853	{ }
6854};
6855
6856/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6857 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6858 */
6859
6860static struct snd_kcontrol_new alc883_base_mixer[] = {
6861	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6862	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6863	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6864	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6865	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6866	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6867	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6868	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6869	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6870	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6871	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6872	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6873	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6874	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6875	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6876	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6877	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6878	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6879	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6880	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6881	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6882	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6883	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6884	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6885	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6886	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6887	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6888	{
6889		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6890		/* .name = "Capture Source", */
6891		.name = "Input Source",
6892		.count = 2,
6893		.info = alc883_mux_enum_info,
6894		.get = alc883_mux_enum_get,
6895		.put = alc883_mux_enum_put,
6896	},
6897	{ } /* end */
6898};
6899
6900static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6901	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6902	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6903	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6904	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6905	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6906	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6907	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6908	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6909	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6910	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6911	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6912	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6913	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6914	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6915	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6916	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6917	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6918	{
6919		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6920		/* .name = "Capture Source", */
6921		.name = "Input Source",
6922		.count = 2,
6923		.info = alc883_mux_enum_info,
6924		.get = alc883_mux_enum_get,
6925		.put = alc883_mux_enum_put,
6926	},
6927	{ } /* end */
6928};
6929
6930static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
6931	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6932	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6933	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6934	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6935	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6936	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6937	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6938	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6939	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6940	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6941	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6942	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6943	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6944	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6945	{
6946		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6947		/* .name = "Capture Source", */
6948		.name = "Input Source",
6949		.count = 2,
6950		.info = alc883_mux_enum_info,
6951		.get = alc883_mux_enum_get,
6952		.put = alc883_mux_enum_put,
6953	},
6954	{ } /* end */
6955};
6956
6957static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
6958	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6959	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6960	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6961	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6962	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6963	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6964	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6965	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6966	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6967	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6968	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6969	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6970	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6971	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6972	{
6973		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6974		/* .name = "Capture Source", */
6975		.name = "Input Source",
6976		.count = 2,
6977		.info = alc883_mux_enum_info,
6978		.get = alc883_mux_enum_get,
6979		.put = alc883_mux_enum_put,
6980	},
6981	{ } /* end */
6982};
6983
6984static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6985	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6986	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6987	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6988	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6989	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6990	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6991	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6992	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6993	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6994	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6995	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6996	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6997	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6998	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6999	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7000	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7001	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7002	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7003	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7004	{
7005		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7006		/* .name = "Capture Source", */
7007		.name = "Input Source",
7008		.count = 2,
7009		.info = alc883_mux_enum_info,
7010		.get = alc883_mux_enum_get,
7011		.put = alc883_mux_enum_put,
7012	},
7013	{ } /* end */
7014};
7015
7016static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7017	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7018	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7019	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7020	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7021	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7022	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7023	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7024	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7025	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7026	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7027	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7028	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7029	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7030	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7031	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7032	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7033	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7034	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7035	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7036	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7037	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7038	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7039	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7040	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7041	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7042	{
7043		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7044		/* .name = "Capture Source", */
7045		.name = "Input Source",
7046		.count = 2,
7047		.info = alc883_mux_enum_info,
7048		.get = alc883_mux_enum_get,
7049		.put = alc883_mux_enum_put,
7050	},
7051	{ } /* end */
7052};
7053
7054static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7055	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7056	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7057	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7058	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7059	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7060			      HDA_OUTPUT),
7061	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7062	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7063	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7064	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7065	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7066	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7067	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7068	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7069	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7070	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7071	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7072	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7073	HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7074	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7075	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7076	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7077	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7078	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7079	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7080	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7081	{
7082		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7083		/* .name = "Capture Source", */
7084		.name = "Input Source",
7085		.count = 2,
7086		.info = alc883_mux_enum_info,
7087		.get = alc883_mux_enum_get,
7088		.put = alc883_mux_enum_put,
7089	},
7090	{ } /* end */
7091};
7092
7093static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7094	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7095	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7096	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7097	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7098	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7099	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7100	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7101	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7102	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7103	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7104	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7105	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7106	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7107	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7108	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7109	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7110	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7111	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7112	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7113	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7114	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7115	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7116	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7117
7118	{
7119		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7120		/* .name = "Capture Source", */
7121		.name = "Input Source",
7122		.count = 1,
7123		.info = alc883_mux_enum_info,
7124		.get = alc883_mux_enum_get,
7125		.put = alc883_mux_enum_put,
7126	},
7127	{ } /* end */
7128};
7129
7130static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7131	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7132	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7133	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7134	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7135	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7136	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7137	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7138	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7139	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7140	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7141	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7142	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7143	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7144	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7145	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7146	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7147	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7148	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7149	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7150	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7151	{
7152		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7153		/* .name = "Capture Source", */
7154		.name = "Input Source",
7155		.count = 2,
7156		.info = alc883_mux_enum_info,
7157		.get = alc883_mux_enum_get,
7158		.put = alc883_mux_enum_put,
7159	},
7160	{ } /* end */
7161};
7162
7163static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7164	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7165	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7166	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7167	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7168	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7169	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7170	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7171	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7172	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7173	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7174	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7175	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7176	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7177	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7178	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7179	{
7180		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7181		/* .name = "Capture Source", */
7182		.name = "Input Source",
7183		.count = 2,
7184		.info = alc883_mux_enum_info,
7185		.get = alc883_mux_enum_get,
7186		.put = alc883_mux_enum_put,
7187	},
7188	{ } /* end */
7189};
7190
7191static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7192	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7193	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7194	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7195	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7196	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7197	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7198	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7199	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7200	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7201	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7202	{
7203		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7204		/* .name = "Capture Source", */
7205		.name = "Input Source",
7206		.count = 1,
7207		.info = alc883_mux_enum_info,
7208		.get = alc883_mux_enum_get,
7209		.put = alc883_mux_enum_put,
7210	},
7211	{ } /* end */
7212};
7213
7214static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7215	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7216	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7217	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7218	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7219	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7220	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7221	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7222	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7223	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7224	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7225	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7226	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7227	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7228	{
7229		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7230		/* .name = "Capture Source", */
7231		.name = "Input Source",
7232		.count = 2,
7233		.info = alc883_mux_enum_info,
7234		.get = alc883_mux_enum_get,
7235		.put = alc883_mux_enum_put,
7236	},
7237	{ } /* end */
7238};
7239
7240static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7241	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7242	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7243	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7244	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7245	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7246	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7247	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7248	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7249	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7250	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7251	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7252	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7253	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7254	{
7255		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7256		/* .name = "Capture Source", */
7257		.name = "Input Source",
7258		.count = 2,
7259		.info = alc883_mux_enum_info,
7260		.get = alc883_mux_enum_get,
7261		.put = alc883_mux_enum_put,
7262	},
7263	{ } /* end */
7264};
7265
7266static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7267	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7268	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7269	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7270	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7271	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7272	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7273	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7274	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7275	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7276	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7277	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7278	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7279	{
7280		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7281		/* .name = "Capture Source", */
7282		.name = "Input Source",
7283		.count = 2,
7284		.info = alc883_mux_enum_info,
7285		.get = alc883_mux_enum_get,
7286		.put = alc883_mux_enum_put,
7287	},
7288	{ } /* end */
7289};
7290
7291static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7292	{
7293		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7294		.name = "Channel Mode",
7295		.info = alc_ch_mode_info,
7296		.get = alc_ch_mode_get,
7297		.put = alc_ch_mode_put,
7298	},
7299	{ } /* end */
7300};
7301
7302static struct hda_verb alc883_init_verbs[] = {
7303	/* ADC1: mute amp left and right */
7304	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7305	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7306	/* ADC2: mute amp left and right */
7307	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7308	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7309	/* Front mixer: unmute input/output amp left and right (volume = 0) */
7310	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7311	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7312	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7313	/* Rear mixer */
7314	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7315	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7316	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7317	/* CLFE mixer */
7318	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7319	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7320	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7321	/* Side mixer */
7322	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7323	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7324	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7325
7326	/* mute analog input loopbacks */
7327	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7328	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7329	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7330	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7331	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7332
7333	/* Front Pin: output 0 (0x0c) */
7334	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7335	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7336	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7337	/* Rear Pin: output 1 (0x0d) */
7338	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7339	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7340	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7341	/* CLFE Pin: output 2 (0x0e) */
7342	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7343	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7344	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7345	/* Side Pin: output 3 (0x0f) */
7346	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7347	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7348	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7349	/* Mic (rear) pin: input vref at 80% */
7350	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7351	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7352	/* Front Mic pin: input vref at 80% */
7353	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7354	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7355	/* Line In pin: input */
7356	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7357	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7358	/* Line-2 In: Headphone output (output 0 - 0x0c) */
7359	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7360	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7361	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7362	/* CD pin widget for input */
7363	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7364
7365	/* FIXME: use matrix-type input source selection */
7366	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7367	/* Input mixer2 */
7368	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7369	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7370	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7371	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7372	/* Input mixer3 */
7373	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7374	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7375	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7376	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7377	{ }
7378};
7379
7380/* toggle speaker-output according to the hp-jack state */
7381static void alc883_mitac_hp_automute(struct hda_codec *codec)
7382{
7383	unsigned int present;
7384
7385	present = snd_hda_codec_read(codec, 0x15, 0,
7386				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7387	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7388				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7389	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7390				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7391}
7392
7393/* auto-toggle front mic */
7394/*
7395static void alc883_mitac_mic_automute(struct hda_codec *codec)
7396{
7397	unsigned int present;
7398	unsigned char bits;
7399
7400	present = snd_hda_codec_read(codec, 0x18, 0,
7401				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7402	bits = present ? HDA_AMP_MUTE : 0;
7403	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7404}
7405*/
7406
7407static void alc883_mitac_automute(struct hda_codec *codec)
7408{
7409	alc883_mitac_hp_automute(codec);
7410	/* alc883_mitac_mic_automute(codec); */
7411}
7412
7413static void alc883_mitac_unsol_event(struct hda_codec *codec,
7414					   unsigned int res)
7415{
7416	switch (res >> 26) {
7417	case ALC880_HP_EVENT:
7418		alc883_mitac_hp_automute(codec);
7419		break;
7420	case ALC880_MIC_EVENT:
7421		/* alc883_mitac_mic_automute(codec); */
7422		break;
7423	}
7424}
7425
7426static struct hda_verb alc883_mitac_verbs[] = {
7427	/* HP */
7428	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7429	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7430	/* Subwoofer */
7431	{0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7432	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7433
7434	/* enable unsolicited event */
7435	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7436	/* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7437
7438	{ } /* end */
7439};
7440
7441static struct hda_verb alc883_clevo_m720_verbs[] = {
7442	/* HP */
7443	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7444	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7445	/* Int speaker */
7446	{0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7447	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7448
7449	/* enable unsolicited event */
7450	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7451	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7452
7453	{ } /* end */
7454};
7455
7456static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7457	/* HP */
7458	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7459	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7460	/* Subwoofer */
7461	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7462	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7463
7464	/* enable unsolicited event */
7465	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7466
7467	{ } /* end */
7468};
7469
7470static struct hda_verb alc883_tagra_verbs[] = {
7471	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7472	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7473
7474	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7475	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7476
7477	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7478	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7479	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7480
7481	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7482	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7483	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7484	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7485
7486	{ } /* end */
7487};
7488
7489static struct hda_verb alc883_lenovo_101e_verbs[] = {
7490	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7491	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7492        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7493	{ } /* end */
7494};
7495
7496static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7497        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7498	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7499        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7500        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7501	{ } /* end */
7502};
7503
7504static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7505	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7506	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7507	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7508	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7509	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
7510	{ } /* end */
7511};
7512
7513static struct hda_verb alc883_haier_w66_verbs[] = {
7514	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7515	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7516
7517	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7518
7519	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7520	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7521	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7522	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7523	{ } /* end */
7524};
7525
7526static struct hda_verb alc888_3st_hp_verbs[] = {
7527	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
7528	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
7529	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
7530	{ }
7531};
7532
7533static struct hda_verb alc888_6st_dell_verbs[] = {
7534	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7535	{ }
7536};
7537
7538static struct hda_verb alc888_3st_hp_2ch_init[] = {
7539	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7540	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7541	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7542	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7543	{ }
7544};
7545
7546static struct hda_verb alc888_3st_hp_6ch_init[] = {
7547	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7548	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7549	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7550	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7551	{ }
7552};
7553
7554static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7555	{ 2, alc888_3st_hp_2ch_init },
7556	{ 6, alc888_3st_hp_6ch_init },
7557};
7558
7559/* toggle front-jack and RCA according to the hp-jack state */
7560static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7561{
7562 	unsigned int present;
7563
7564 	present = snd_hda_codec_read(codec, 0x1b, 0,
7565				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7566	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7567				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7568	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7569				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7570}
7571
7572/* toggle RCA according to the front-jack state */
7573static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7574{
7575 	unsigned int present;
7576
7577 	present = snd_hda_codec_read(codec, 0x14, 0,
7578				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7579	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7580				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7581}
7582
7583static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7584					     unsigned int res)
7585{
7586	if ((res >> 26) == ALC880_HP_EVENT)
7587		alc888_lenovo_ms7195_front_automute(codec);
7588	if ((res >> 26) == ALC880_FRONT_EVENT)
7589		alc888_lenovo_ms7195_rca_automute(codec);
7590}
7591
7592static struct hda_verb alc883_medion_md2_verbs[] = {
7593	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7594	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7595
7596	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7597
7598	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7599	{ } /* end */
7600};
7601
7602/* toggle speaker-output according to the hp-jack state */
7603static void alc883_medion_md2_automute(struct hda_codec *codec)
7604{
7605 	unsigned int present;
7606
7607 	present = snd_hda_codec_read(codec, 0x14, 0,
7608				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7609	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7610				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7611}
7612
7613static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7614					  unsigned int res)
7615{
7616	if ((res >> 26) == ALC880_HP_EVENT)
7617		alc883_medion_md2_automute(codec);
7618}
7619
7620/* toggle speaker-output according to the hp-jack state */
7621static void alc883_tagra_automute(struct hda_codec *codec)
7622{
7623 	unsigned int present;
7624	unsigned char bits;
7625
7626 	present = snd_hda_codec_read(codec, 0x14, 0,
7627				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7628	bits = present ? HDA_AMP_MUTE : 0;
7629	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7630				 HDA_AMP_MUTE, bits);
7631	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7632				  present ? 1 : 3);
7633}
7634
7635static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7636{
7637	if ((res >> 26) == ALC880_HP_EVENT)
7638		alc883_tagra_automute(codec);
7639}
7640
7641/* toggle speaker-output according to the hp-jack state */
7642static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7643{
7644	unsigned int present;
7645	unsigned char bits;
7646
7647	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7648		& AC_PINSENSE_PRESENCE;
7649	bits = present ? HDA_AMP_MUTE : 0;
7650	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7651				 HDA_AMP_MUTE, bits);
7652}
7653
7654static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7655{
7656	unsigned int present;
7657
7658	present = snd_hda_codec_read(codec, 0x18, 0,
7659				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7660	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7661				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7662}
7663
7664static void alc883_clevo_m720_automute(struct hda_codec *codec)
7665{
7666	alc883_clevo_m720_hp_automute(codec);
7667	alc883_clevo_m720_mic_automute(codec);
7668}
7669
7670static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7671					   unsigned int res)
7672{
7673	switch (res >> 26) {
7674	case ALC880_HP_EVENT:
7675		alc883_clevo_m720_hp_automute(codec);
7676		break;
7677	case ALC880_MIC_EVENT:
7678		alc883_clevo_m720_mic_automute(codec);
7679		break;
7680	}
7681}
7682
7683/* toggle speaker-output according to the hp-jack state */
7684static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7685{
7686 	unsigned int present;
7687	unsigned char bits;
7688
7689 	present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7690		& AC_PINSENSE_PRESENCE;
7691	bits = present ? HDA_AMP_MUTE : 0;
7692	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7693				 HDA_AMP_MUTE, bits);
7694}
7695
7696static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7697						  unsigned int res)
7698{
7699	if ((res >> 26) == ALC880_HP_EVENT)
7700		alc883_2ch_fujitsu_pi2515_automute(codec);
7701}
7702
7703static void alc883_haier_w66_automute(struct hda_codec *codec)
7704{
7705	unsigned int present;
7706	unsigned char bits;
7707
7708	present = snd_hda_codec_read(codec, 0x1b, 0,
7709				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7710	bits = present ? 0x80 : 0;
7711	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7712				 0x80, bits);
7713}
7714
7715static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7716					 unsigned int res)
7717{
7718	if ((res >> 26) == ALC880_HP_EVENT)
7719		alc883_haier_w66_automute(codec);
7720}
7721
7722static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7723{
7724 	unsigned int present;
7725	unsigned char bits;
7726
7727 	present = snd_hda_codec_read(codec, 0x14, 0,
7728				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7729	bits = present ? HDA_AMP_MUTE : 0;
7730	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7731				 HDA_AMP_MUTE, bits);
7732}
7733
7734static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7735{
7736 	unsigned int present;
7737	unsigned char bits;
7738
7739 	present = snd_hda_codec_read(codec, 0x1b, 0,
7740				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7741	bits = present ? HDA_AMP_MUTE : 0;
7742	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7743				 HDA_AMP_MUTE, bits);
7744	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7745				 HDA_AMP_MUTE, bits);
7746}
7747
7748static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7749					   unsigned int res)
7750{
7751	if ((res >> 26) == ALC880_HP_EVENT)
7752		alc883_lenovo_101e_all_automute(codec);
7753	if ((res >> 26) == ALC880_FRONT_EVENT)
7754		alc883_lenovo_101e_ispeaker_automute(codec);
7755}
7756
7757/* toggle speaker-output according to the hp-jack state */
7758static void alc883_acer_aspire_automute(struct hda_codec *codec)
7759{
7760 	unsigned int present;
7761
7762 	present = snd_hda_codec_read(codec, 0x14, 0,
7763				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7764	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7765				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7766	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7767				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7768}
7769
7770static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7771					   unsigned int res)
7772{
7773	if ((res >> 26) == ALC880_HP_EVENT)
7774		alc883_acer_aspire_automute(codec);
7775}
7776
7777static struct hda_verb alc883_acer_eapd_verbs[] = {
7778	/* HP Pin: output 0 (0x0c) */
7779	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7780	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7781	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7782	/* Front Pin: output 0 (0x0c) */
7783	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7784	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7785	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7786	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7787        /* eanable EAPD on medion laptop */
7788	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7789	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7790	/* enable unsolicited event */
7791	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7792	{ }
7793};
7794
7795static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7796{
7797 	unsigned int present;
7798
7799 	present = snd_hda_codec_read(codec, 0x1b, 0,
7800				AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7801	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7802				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7803	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7804				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7805	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7806				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7807	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7808				HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7809}
7810
7811static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7812					     unsigned int res)
7813{
7814	switch (res >> 26) {
7815	case ALC880_HP_EVENT:
7816		printk("hp_event\n");
7817		alc888_6st_dell_front_automute(codec);
7818		break;
7819	}
7820}
7821
7822/*
7823 * generic initialization of ADC, input mixers and output mixers
7824 */
7825static struct hda_verb alc883_auto_init_verbs[] = {
7826	/*
7827	 * Unmute ADC0-2 and set the default input to mic-in
7828	 */
7829	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7830	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7831	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7832	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7833
7834	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7835	 * mixer widget
7836	 * Note: PASD motherboards uses the Line In 2 as the input for
7837	 * front panel mic (mic 2)
7838	 */
7839	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7840	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7841	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7842	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7843	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7844	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7845
7846	/*
7847	 * Set up output mixers (0x0c - 0x0f)
7848	 */
7849	/* set vol=0 to output mixers */
7850	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7851	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7852	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7853	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7854	/* set up input amps for analog loopback */
7855	/* Amp Indices: DAC = 0, mixer = 1 */
7856	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7857	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7858	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7859	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7860	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7861	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7862	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7863	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7864	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7865	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7866
7867	/* FIXME: use matrix-type input source selection */
7868	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7869	/* Input mixer1 */
7870	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7871	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7872	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7873	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7874	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7875	/* Input mixer2 */
7876	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7877	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7878	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7879	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7880	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7881
7882	{ }
7883};
7884
7885/* capture mixer elements */
7886static struct snd_kcontrol_new alc883_capture_mixer[] = {
7887	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7888	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7889	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7890	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7891	{
7892		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7893		/* The multiple "Capture Source" controls confuse alsamixer
7894		 * So call somewhat different..
7895		 */
7896		/* .name = "Capture Source", */
7897		.name = "Input Source",
7898		.count = 2,
7899		.info = alc882_mux_enum_info,
7900		.get = alc882_mux_enum_get,
7901		.put = alc882_mux_enum_put,
7902	},
7903	{ } /* end */
7904};
7905
7906#ifdef CONFIG_SND_HDA_POWER_SAVE
7907#define alc883_loopbacks	alc880_loopbacks
7908#endif
7909
7910/* pcm configuration: identiacal with ALC880 */
7911#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
7912#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
7913#define alc883_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
7914#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
7915#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
7916
7917/*
7918 * configuration and preset
7919 */
7920static const char *alc883_models[ALC883_MODEL_LAST] = {
7921	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
7922	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
7923	[ALC883_3ST_6ch]	= "3stack-6ch",
7924	[ALC883_6ST_DIG]	= "6stack-dig",
7925	[ALC883_TARGA_DIG]	= "targa-dig",
7926	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
7927	[ALC883_ACER]		= "acer",
7928	[ALC883_ACER_ASPIRE]	= "acer-aspire",
7929	[ALC883_MEDION]		= "medion",
7930	[ALC883_MEDION_MD2]	= "medion-md2",
7931	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
7932	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7933	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
7934	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7935	[ALC883_HAIER_W66] 	= "haier-w66",
7936	[ALC888_3ST_HP]		= "3stack-hp",
7937	[ALC888_6ST_DELL]	= "6stack-dell",
7938	[ALC883_MITAC]		= "mitac",
7939	[ALC883_CLEVO_M720]	= "clevo-m720",
7940	[ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
7941	[ALC883_3ST_6ch_INTEL]	= "3stack-6ch-intel",
7942	[ALC883_AUTO]		= "auto",
7943};
7944
7945static struct snd_pci_quirk alc883_cfg_tbl[] = {
7946	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7947	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7948	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7949	SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7950	SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
7951	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7952	SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
7953	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7954	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7955	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7956	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
7957	SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7958	SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
7959	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7960	SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7961	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7962	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7963	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7964	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7965	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7966	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7967	SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
7968	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7969	SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
7970	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7971	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7972	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7973	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7974	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7975	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7976	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7977	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7978	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7979	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7980	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7981	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7982	SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
7983	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7984	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7985	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7986	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7987	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
7988	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
7989	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7990	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7991	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7992	SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
7993	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7994	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7995	SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7996	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7997	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7998	SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7999	SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8000	SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8001	SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8002	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8003	{}
8004};
8005
8006static struct alc_config_preset alc883_presets[] = {
8007	[ALC883_3ST_2ch_DIG] = {
8008		.mixers = { alc883_3ST_2ch_mixer },
8009		.init_verbs = { alc883_init_verbs },
8010		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8011		.dac_nids = alc883_dac_nids,
8012		.dig_out_nid = ALC883_DIGOUT_NID,
8013		.dig_in_nid = ALC883_DIGIN_NID,
8014		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8015		.channel_mode = alc883_3ST_2ch_modes,
8016		.input_mux = &alc883_capture_source,
8017	},
8018	[ALC883_3ST_6ch_DIG] = {
8019		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8020		.init_verbs = { alc883_init_verbs },
8021		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8022		.dac_nids = alc883_dac_nids,
8023		.dig_out_nid = ALC883_DIGOUT_NID,
8024		.dig_in_nid = ALC883_DIGIN_NID,
8025		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8026		.channel_mode = alc883_3ST_6ch_modes,
8027		.need_dac_fix = 1,
8028		.input_mux = &alc883_capture_source,
8029	},
8030	[ALC883_3ST_6ch] = {
8031		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8032		.init_verbs = { alc883_init_verbs },
8033		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8034		.dac_nids = alc883_dac_nids,
8035		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8036		.channel_mode = alc883_3ST_6ch_modes,
8037		.need_dac_fix = 1,
8038		.input_mux = &alc883_capture_source,
8039	},
8040	[ALC883_3ST_6ch_INTEL] = {
8041		.mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8042		.init_verbs = { alc883_init_verbs },
8043		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8044		.dac_nids = alc883_dac_nids,
8045		.dig_out_nid = ALC883_DIGOUT_NID,
8046		.dig_in_nid = ALC883_DIGIN_NID,
8047		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8048		.channel_mode = alc883_3ST_6ch_intel_modes,
8049		.need_dac_fix = 1,
8050		.input_mux = &alc883_3stack_6ch_intel,
8051	},
8052	[ALC883_6ST_DIG] = {
8053		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8054		.init_verbs = { alc883_init_verbs },
8055		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8056		.dac_nids = alc883_dac_nids,
8057		.dig_out_nid = ALC883_DIGOUT_NID,
8058		.dig_in_nid = ALC883_DIGIN_NID,
8059		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8060		.channel_mode = alc883_sixstack_modes,
8061		.input_mux = &alc883_capture_source,
8062	},
8063	[ALC883_TARGA_DIG] = {
8064		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8065		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8066		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8067		.dac_nids = alc883_dac_nids,
8068		.dig_out_nid = ALC883_DIGOUT_NID,
8069		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8070		.channel_mode = alc883_3ST_6ch_modes,
8071		.need_dac_fix = 1,
8072		.input_mux = &alc883_capture_source,
8073		.unsol_event = alc883_tagra_unsol_event,
8074		.init_hook = alc883_tagra_automute,
8075	},
8076	[ALC883_TARGA_2ch_DIG] = {
8077		.mixers = { alc883_tagra_2ch_mixer},
8078		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8079		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8080		.dac_nids = alc883_dac_nids,
8081		.dig_out_nid = ALC883_DIGOUT_NID,
8082		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8083		.channel_mode = alc883_3ST_2ch_modes,
8084		.input_mux = &alc883_capture_source,
8085		.unsol_event = alc883_tagra_unsol_event,
8086		.init_hook = alc883_tagra_automute,
8087	},
8088	[ALC883_ACER] = {
8089		.mixers = { alc883_base_mixer },
8090		/* On TravelMate laptops, GPIO 0 enables the internal speaker
8091		 * and the headphone jack.  Turn this on and rely on the
8092		 * standard mute methods whenever the user wants to turn
8093		 * these outputs off.
8094		 */
8095		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8096		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8097		.dac_nids = alc883_dac_nids,
8098		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8099		.channel_mode = alc883_3ST_2ch_modes,
8100		.input_mux = &alc883_capture_source,
8101	},
8102	[ALC883_ACER_ASPIRE] = {
8103		.mixers = { alc883_acer_aspire_mixer },
8104		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8105		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8106		.dac_nids = alc883_dac_nids,
8107		.dig_out_nid = ALC883_DIGOUT_NID,
8108		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8109		.channel_mode = alc883_3ST_2ch_modes,
8110		.input_mux = &alc883_capture_source,
8111		.unsol_event = alc883_acer_aspire_unsol_event,
8112		.init_hook = alc883_acer_aspire_automute,
8113	},
8114	[ALC883_MEDION] = {
8115		.mixers = { alc883_fivestack_mixer,
8116			    alc883_chmode_mixer },
8117		.init_verbs = { alc883_init_verbs,
8118				alc883_medion_eapd_verbs },
8119		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8120		.dac_nids = alc883_dac_nids,
8121		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8122		.channel_mode = alc883_sixstack_modes,
8123		.input_mux = &alc883_capture_source,
8124	},
8125	[ALC883_MEDION_MD2] = {
8126		.mixers = { alc883_medion_md2_mixer},
8127		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8128		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8129		.dac_nids = alc883_dac_nids,
8130		.dig_out_nid = ALC883_DIGOUT_NID,
8131		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8132		.channel_mode = alc883_3ST_2ch_modes,
8133		.input_mux = &alc883_capture_source,
8134		.unsol_event = alc883_medion_md2_unsol_event,
8135		.init_hook = alc883_medion_md2_automute,
8136	},
8137	[ALC883_LAPTOP_EAPD] = {
8138		.mixers = { alc883_base_mixer },
8139		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8140		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8141		.dac_nids = alc883_dac_nids,
8142		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8143		.channel_mode = alc883_3ST_2ch_modes,
8144		.input_mux = &alc883_capture_source,
8145	},
8146	[ALC883_CLEVO_M720] = {
8147		.mixers = { alc883_clevo_m720_mixer },
8148		.init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8149		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8150		.dac_nids = alc883_dac_nids,
8151		.dig_out_nid = ALC883_DIGOUT_NID,
8152		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8153		.channel_mode = alc883_3ST_2ch_modes,
8154		.input_mux = &alc883_capture_source,
8155		.unsol_event = alc883_clevo_m720_unsol_event,
8156		.init_hook = alc883_clevo_m720_automute,
8157	},
8158	[ALC883_LENOVO_101E_2ch] = {
8159		.mixers = { alc883_lenovo_101e_2ch_mixer},
8160		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8161		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8162		.dac_nids = alc883_dac_nids,
8163		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8164		.channel_mode = alc883_3ST_2ch_modes,
8165		.input_mux = &alc883_lenovo_101e_capture_source,
8166		.unsol_event = alc883_lenovo_101e_unsol_event,
8167		.init_hook = alc883_lenovo_101e_all_automute,
8168	},
8169	[ALC883_LENOVO_NB0763] = {
8170		.mixers = { alc883_lenovo_nb0763_mixer },
8171		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8172		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8173		.dac_nids = alc883_dac_nids,
8174		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8175		.channel_mode = alc883_3ST_2ch_modes,
8176		.need_dac_fix = 1,
8177		.input_mux = &alc883_lenovo_nb0763_capture_source,
8178		.unsol_event = alc883_medion_md2_unsol_event,
8179		.init_hook = alc883_medion_md2_automute,
8180	},
8181	[ALC888_LENOVO_MS7195_DIG] = {
8182		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8183		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8184		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8185		.dac_nids = alc883_dac_nids,
8186		.dig_out_nid = ALC883_DIGOUT_NID,
8187		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8188		.channel_mode = alc883_3ST_6ch_modes,
8189		.need_dac_fix = 1,
8190		.input_mux = &alc883_capture_source,
8191		.unsol_event = alc883_lenovo_ms7195_unsol_event,
8192		.init_hook = alc888_lenovo_ms7195_front_automute,
8193	},
8194	[ALC883_HAIER_W66] = {
8195		.mixers = { alc883_tagra_2ch_mixer},
8196		.init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8197		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8198		.dac_nids = alc883_dac_nids,
8199		.dig_out_nid = ALC883_DIGOUT_NID,
8200		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8201		.channel_mode = alc883_3ST_2ch_modes,
8202		.input_mux = &alc883_capture_source,
8203		.unsol_event = alc883_haier_w66_unsol_event,
8204		.init_hook = alc883_haier_w66_automute,
8205	},
8206	[ALC888_3ST_HP] = {
8207		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8208		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8209		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8210		.dac_nids = alc883_dac_nids,
8211		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8212		.channel_mode = alc888_3st_hp_modes,
8213		.need_dac_fix = 1,
8214		.input_mux = &alc883_capture_source,
8215	},
8216	[ALC888_6ST_DELL] = {
8217		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
8218		.init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8219		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8220		.dac_nids = alc883_dac_nids,
8221		.dig_out_nid = ALC883_DIGOUT_NID,
8222		.dig_in_nid = ALC883_DIGIN_NID,
8223		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8224		.channel_mode = alc883_sixstack_modes,
8225		.input_mux = &alc883_capture_source,
8226		.unsol_event = alc888_6st_dell_unsol_event,
8227		.init_hook = alc888_6st_dell_front_automute,
8228	},
8229	[ALC883_MITAC] = {
8230		.mixers = { alc883_mitac_mixer },
8231		.init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8232		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8233		.dac_nids = alc883_dac_nids,
8234		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8235		.channel_mode = alc883_3ST_2ch_modes,
8236		.input_mux = &alc883_capture_source,
8237		.unsol_event = alc883_mitac_unsol_event,
8238		.init_hook = alc883_mitac_automute,
8239	},
8240	[ALC883_FUJITSU_PI2515] = {
8241		.mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8242		.init_verbs = { alc883_init_verbs,
8243				alc883_2ch_fujitsu_pi2515_verbs},
8244		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
8245		.dac_nids = alc883_dac_nids,
8246		.dig_out_nid = ALC883_DIGOUT_NID,
8247		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8248		.channel_mode = alc883_3ST_2ch_modes,
8249		.input_mux = &alc883_fujitsu_pi2515_capture_source,
8250		.unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8251		.init_hook = alc883_2ch_fujitsu_pi2515_automute,
8252	},
8253};
8254
8255
8256/*
8257 * BIOS auto configuration
8258 */
8259static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8260					      hda_nid_t nid, int pin_type,
8261					      int dac_idx)
8262{
8263	/* set as output */
8264	struct alc_spec *spec = codec->spec;
8265	int idx;
8266
8267	alc_set_pin_output(codec, nid, pin_type);
8268	if (spec->multiout.dac_nids[dac_idx] == 0x25)
8269		idx = 4;
8270	else
8271		idx = spec->multiout.dac_nids[dac_idx] - 2;
8272	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8273
8274}
8275
8276static void alc883_auto_init_multi_out(struct hda_codec *codec)
8277{
8278	struct alc_spec *spec = codec->spec;
8279	int i;
8280
8281	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8282	for (i = 0; i <= HDA_SIDE; i++) {
8283		hda_nid_t nid = spec->autocfg.line_out_pins[i];
8284		int pin_type = get_pin_type(spec->autocfg.line_out_type);
8285		if (nid)
8286			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8287							  i);
8288	}
8289}
8290
8291static void alc883_auto_init_hp_out(struct hda_codec *codec)
8292{
8293	struct alc_spec *spec = codec->spec;
8294	hda_nid_t pin;
8295
8296	pin = spec->autocfg.hp_pins[0];
8297	if (pin) /* connect to front */
8298		/* use dac 0 */
8299		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8300	pin = spec->autocfg.speaker_pins[0];
8301	if (pin)
8302		alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8303}
8304
8305#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
8306#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
8307
8308static void alc883_auto_init_analog_input(struct hda_codec *codec)
8309{
8310	struct alc_spec *spec = codec->spec;
8311	int i;
8312
8313	for (i = 0; i < AUTO_PIN_LAST; i++) {
8314		hda_nid_t nid = spec->autocfg.input_pins[i];
8315		if (alc883_is_input_pin(nid)) {
8316			snd_hda_codec_write(codec, nid, 0,
8317					    AC_VERB_SET_PIN_WIDGET_CONTROL,
8318					    (i <= AUTO_PIN_FRONT_MIC ?
8319					     PIN_VREF80 : PIN_IN));
8320			if (nid != ALC883_PIN_CD_NID)
8321				snd_hda_codec_write(codec, nid, 0,
8322						    AC_VERB_SET_AMP_GAIN_MUTE,
8323						    AMP_OUT_MUTE);
8324		}
8325	}
8326}
8327
8328#define alc883_auto_init_input_src	alc882_auto_init_input_src
8329
8330/* almost identical with ALC880 parser... */
8331static int alc883_parse_auto_config(struct hda_codec *codec)
8332{
8333	struct alc_spec *spec = codec->spec;
8334	int err = alc880_parse_auto_config(codec);
8335
8336	if (err < 0)
8337		return err;
8338	else if (!err)
8339		return 0; /* no config found */
8340
8341	err = alc_auto_add_mic_boost(codec);
8342	if (err < 0)
8343		return err;
8344
8345	/* hack - override the init verbs */
8346	spec->init_verbs[0] = alc883_auto_init_verbs;
8347	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8348	spec->num_mixers++;
8349
8350	return 1; /* config found */
8351}
8352
8353/* additional initialization for auto-configuration model */
8354static void alc883_auto_init(struct hda_codec *codec)
8355{
8356	struct alc_spec *spec = codec->spec;
8357	alc883_auto_init_multi_out(codec);
8358	alc883_auto_init_hp_out(codec);
8359	alc883_auto_init_analog_input(codec);
8360	alc883_auto_init_input_src(codec);
8361	if (spec->unsol_event)
8362		alc_sku_automute(codec);
8363}
8364
8365static int patch_alc883(struct hda_codec *codec)
8366{
8367	struct alc_spec *spec;
8368	int err, board_config;
8369
8370	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8371	if (spec == NULL)
8372		return -ENOMEM;
8373
8374	codec->spec = spec;
8375
8376	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8377
8378	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8379						  alc883_models,
8380						  alc883_cfg_tbl);
8381	if (board_config < 0) {
8382		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8383		       "trying auto-probe from BIOS...\n");
8384		board_config = ALC883_AUTO;
8385	}
8386
8387	if (board_config == ALC883_AUTO) {
8388		/* automatic parse from the BIOS config */
8389		err = alc883_parse_auto_config(codec);
8390		if (err < 0) {
8391			alc_free(codec);
8392			return err;
8393		} else if (!err) {
8394			printk(KERN_INFO
8395			       "hda_codec: Cannot set up configuration "
8396			       "from BIOS.  Using base mode...\n");
8397			board_config = ALC883_3ST_2ch_DIG;
8398		}
8399	}
8400
8401	if (board_config != ALC883_AUTO)
8402		setup_preset(spec, &alc883_presets[board_config]);
8403
8404	switch (codec->vendor_id) {
8405	case 0x10ec0888:
8406		spec->stream_name_analog = "ALC888 Analog";
8407		spec->stream_name_digital = "ALC888 Digital";
8408		break;
8409	case 0x10ec0889:
8410		spec->stream_name_analog = "ALC889 Analog";
8411		spec->stream_name_digital = "ALC889 Digital";
8412		break;
8413	default:
8414		spec->stream_name_analog = "ALC883 Analog";
8415		spec->stream_name_digital = "ALC883 Digital";
8416		break;
8417	}
8418
8419	spec->stream_analog_playback = &alc883_pcm_analog_playback;
8420	spec->stream_analog_capture = &alc883_pcm_analog_capture;
8421	spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8422
8423	spec->stream_digital_playback = &alc883_pcm_digital_playback;
8424	spec->stream_digital_capture = &alc883_pcm_digital_capture;
8425
8426	spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8427	spec->adc_nids = alc883_adc_nids;
8428	spec->capsrc_nids = alc883_capsrc_nids;
8429
8430	spec->vmaster_nid = 0x0c;
8431
8432	codec->patch_ops = alc_patch_ops;
8433	if (board_config == ALC883_AUTO)
8434		spec->init_hook = alc883_auto_init;
8435
8436#ifdef CONFIG_SND_HDA_POWER_SAVE
8437	if (!spec->loopback.amplist)
8438		spec->loopback.amplist = alc883_loopbacks;
8439#endif
8440
8441	return 0;
8442}
8443
8444/*
8445 * ALC262 support
8446 */
8447
8448#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
8449#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
8450
8451#define alc262_dac_nids		alc260_dac_nids
8452#define alc262_adc_nids		alc882_adc_nids
8453#define alc262_adc_nids_alt	alc882_adc_nids_alt
8454#define alc262_capsrc_nids	alc882_capsrc_nids
8455#define alc262_capsrc_nids_alt	alc882_capsrc_nids_alt
8456
8457#define alc262_modes		alc260_modes
8458#define alc262_capture_source	alc882_capture_source
8459
8460static struct snd_kcontrol_new alc262_base_mixer[] = {
8461	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8462	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8463	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8464	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8465	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8466	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8467	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8468	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8469	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8470	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8471	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8472	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8473	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8474	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8475	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8476	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8477	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8478	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8479	{ } /* end */
8480};
8481
8482static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8483	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8484	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8485	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8486	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8487	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8488	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8489	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8490	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8491	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8492	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8493	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8494	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8495	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8496	   HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8497	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8498	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8499	{ } /* end */
8500};
8501
8502/* update HP, line and mono-out pins according to the master switch */
8503static void alc262_hp_master_update(struct hda_codec *codec)
8504{
8505	struct alc_spec *spec = codec->spec;
8506	int val = spec->master_sw;
8507
8508	/* HP & line-out */
8509	snd_hda_codec_write_cache(codec, 0x1b, 0,
8510				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8511				  val ? PIN_HP : 0);
8512	snd_hda_codec_write_cache(codec, 0x15, 0,
8513				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8514				  val ? PIN_HP : 0);
8515	/* mono (speaker) depending on the HP jack sense */
8516	val = val && !spec->jack_present;
8517	snd_hda_codec_write_cache(codec, 0x16, 0,
8518				  AC_VERB_SET_PIN_WIDGET_CONTROL,
8519				  val ? PIN_OUT : 0);
8520}
8521
8522static void alc262_hp_bpc_automute(struct hda_codec *codec)
8523{
8524	struct alc_spec *spec = codec->spec;
8525	unsigned int presence;
8526	presence = snd_hda_codec_read(codec, 0x1b, 0,
8527				      AC_VERB_GET_PIN_SENSE, 0);
8528	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8529	alc262_hp_master_update(codec);
8530}
8531
8532static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8533{
8534	if ((res >> 26) != ALC880_HP_EVENT)
8535		return;
8536	alc262_hp_bpc_automute(codec);
8537}
8538
8539static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8540{
8541	struct alc_spec *spec = codec->spec;
8542	unsigned int presence;
8543	presence = snd_hda_codec_read(codec, 0x15, 0,
8544				      AC_VERB_GET_PIN_SENSE, 0);
8545	spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8546	alc262_hp_master_update(codec);
8547}
8548
8549static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8550					   unsigned int res)
8551{
8552	if ((res >> 26) != ALC880_HP_EVENT)
8553		return;
8554	alc262_hp_wildwest_automute(codec);
8555}
8556
8557static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8558				   struct snd_ctl_elem_value *ucontrol)
8559{
8560	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8561	struct alc_spec *spec = codec->spec;
8562	*ucontrol->value.integer.value = spec->master_sw;
8563	return 0;
8564}
8565
8566static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8567				   struct snd_ctl_elem_value *ucontrol)
8568{
8569	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8570	struct alc_spec *spec = codec->spec;
8571	int val = !!*ucontrol->value.integer.value;
8572
8573	if (val == spec->master_sw)
8574		return 0;
8575	spec->master_sw = val;
8576	alc262_hp_master_update(codec);
8577	return 1;
8578}
8579
8580static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8581	{
8582		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8583		.name = "Master Playback Switch",
8584		.info = snd_ctl_boolean_mono_info,
8585		.get = alc262_hp_master_sw_get,
8586		.put = alc262_hp_master_sw_put,
8587	},
8588	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8589	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8590	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8591	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8592			      HDA_OUTPUT),
8593	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8594			    HDA_OUTPUT),
8595	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8596	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8597	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8598	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8599	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8600	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8601	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8602	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8603	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8604	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8605	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8606	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8607	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8608	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8609	{ } /* end */
8610};
8611
8612static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8613	{
8614		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8615		.name = "Master Playback Switch",
8616		.info = snd_ctl_boolean_mono_info,
8617		.get = alc262_hp_master_sw_get,
8618		.put = alc262_hp_master_sw_put,
8619	},
8620	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8621	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8622	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8623	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8624	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8625			      HDA_OUTPUT),
8626	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8627			    HDA_OUTPUT),
8628	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8629	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8630	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8631	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8632	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8633	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8634	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8635	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8636	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8637	{ } /* end */
8638};
8639
8640static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8641	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8642	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8643	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8644	{ } /* end */
8645};
8646
8647/* mute/unmute internal speaker according to the hp jack and mute state */
8648static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8649{
8650	struct alc_spec *spec = codec->spec;
8651
8652	if (force || !spec->sense_updated) {
8653		unsigned int present;
8654		present = snd_hda_codec_read(codec, 0x15, 0,
8655					     AC_VERB_GET_PIN_SENSE, 0);
8656		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8657		spec->sense_updated = 1;
8658	}
8659	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8660				 spec->jack_present ? HDA_AMP_MUTE : 0);
8661}
8662
8663static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8664					unsigned int res)
8665{
8666	if ((res >> 26) != ALC880_HP_EVENT)
8667		return;
8668	alc262_hp_t5735_automute(codec, 1);
8669}
8670
8671static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8672{
8673	alc262_hp_t5735_automute(codec, 1);
8674}
8675
8676static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8677	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8678	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8679	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8680	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8681	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8682	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8683	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8684	{ } /* end */
8685};
8686
8687static struct hda_verb alc262_hp_t5735_verbs[] = {
8688	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8689	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8690
8691	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8692	{ }
8693};
8694
8695static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8696	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8697	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8698	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8699	HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8700	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8701	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8702	{ } /* end */
8703};
8704
8705static struct hda_verb alc262_hp_rp5700_verbs[] = {
8706	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8707	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8708	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8709	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8710	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8711	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8712	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8713	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8714	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8715	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8716	{}
8717};
8718
8719static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8720	.num_items = 1,
8721	.items = {
8722		{ "Line", 0x1 },
8723	},
8724};
8725
8726/* bind hp and internal speaker mute (with plug check) */
8727static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8728				     struct snd_ctl_elem_value *ucontrol)
8729{
8730	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8731	long *valp = ucontrol->value.integer.value;
8732	int change;
8733
8734	/* change hp mute */
8735	change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8736					  HDA_AMP_MUTE,
8737					  valp[0] ? 0 : HDA_AMP_MUTE);
8738	change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8739					   HDA_AMP_MUTE,
8740					   valp[1] ? 0 : HDA_AMP_MUTE);
8741	if (change) {
8742		/* change speaker according to HP jack state */
8743		struct alc_spec *spec = codec->spec;
8744		unsigned int mute;
8745		if (spec->jack_present)
8746			mute = HDA_AMP_MUTE;
8747		else
8748			mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8749						      HDA_OUTPUT, 0);
8750		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8751					 HDA_AMP_MUTE, mute);
8752	}
8753	return change;
8754}
8755
8756static struct snd_kcontrol_new alc262_sony_mixer[] = {
8757	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8758	{
8759		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8760		.name = "Master Playback Switch",
8761		.info = snd_hda_mixer_amp_switch_info,
8762		.get = snd_hda_mixer_amp_switch_get,
8763		.put = alc262_sony_master_sw_put,
8764		.private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8765	},
8766	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8767	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8768	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8769	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8770	{ } /* end */
8771};
8772
8773static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8774	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8775	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8776	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8777	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8778	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8779	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8780	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8781	{ } /* end */
8782};
8783
8784#define alc262_capture_mixer		alc882_capture_mixer
8785#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
8786
8787/*
8788 * generic initialization of ADC, input mixers and output mixers
8789 */
8790static struct hda_verb alc262_init_verbs[] = {
8791	/*
8792	 * Unmute ADC0-2 and set the default input to mic-in
8793	 */
8794	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8795	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8796	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8797	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8798	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8799	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8800
8801	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8802	 * mixer widget
8803	 * Note: PASD motherboards uses the Line In 2 as the input for
8804	 * front panel mic (mic 2)
8805	 */
8806	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8807	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8808	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8809	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8810	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8811	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8812
8813	/*
8814	 * Set up output mixers (0x0c - 0x0e)
8815	 */
8816	/* set vol=0 to output mixers */
8817	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8818	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8819	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8820	/* set up input amps for analog loopback */
8821	/* Amp Indices: DAC = 0, mixer = 1 */
8822	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8823	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8824	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8825	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8826	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8827	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8828
8829	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8830	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8831	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8832	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8833	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8834	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8835
8836	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8837	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8838	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8839	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8840	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8841
8842	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8843	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8844
8845	/* FIXME: use matrix-type input source selection */
8846	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8847	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8848	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8849	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8850	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8851	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8852	/* Input mixer2 */
8853	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8854	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8855	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8856	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8857	/* Input mixer3 */
8858	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8859	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8860	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8861	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8862
8863	{ }
8864};
8865
8866static struct hda_verb alc262_hippo_unsol_verbs[] = {
8867	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8868	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8869	{}
8870};
8871
8872static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8873	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8874	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8875	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8876
8877	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8878	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8879	{}
8880};
8881
8882static struct hda_verb alc262_sony_unsol_verbs[] = {
8883	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8884	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8885	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
8886
8887	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8888	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8889	{}
8890};
8891
8892/* mute/unmute internal speaker according to the hp jack and mute state */
8893static void alc262_hippo_automute(struct hda_codec *codec)
8894{
8895	struct alc_spec *spec = codec->spec;
8896	unsigned int mute;
8897	unsigned int present;
8898
8899	/* need to execute and sync at first */
8900	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8901	present = snd_hda_codec_read(codec, 0x15, 0,
8902				     AC_VERB_GET_PIN_SENSE, 0);
8903	spec->jack_present = (present & 0x80000000) != 0;
8904	if (spec->jack_present) {
8905		/* mute internal speaker */
8906		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8907					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8908	} else {
8909		/* unmute internal speaker if necessary */
8910		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8911		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8912					 HDA_AMP_MUTE, mute);
8913	}
8914}
8915
8916/* unsolicited event for HP jack sensing */
8917static void alc262_hippo_unsol_event(struct hda_codec *codec,
8918				       unsigned int res)
8919{
8920	if ((res >> 26) != ALC880_HP_EVENT)
8921		return;
8922	alc262_hippo_automute(codec);
8923}
8924
8925static void alc262_hippo1_automute(struct hda_codec *codec)
8926{
8927	unsigned int mute;
8928	unsigned int present;
8929
8930	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8931	present = snd_hda_codec_read(codec, 0x1b, 0,
8932				     AC_VERB_GET_PIN_SENSE, 0);
8933	present = (present & 0x80000000) != 0;
8934	if (present) {
8935		/* mute internal speaker */
8936		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8937					 HDA_AMP_MUTE, HDA_AMP_MUTE);
8938	} else {
8939		/* unmute internal speaker if necessary */
8940		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8941		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8942					 HDA_AMP_MUTE, mute);
8943	}
8944}
8945
8946/* unsolicited event for HP jack sensing */
8947static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8948				       unsigned int res)
8949{
8950	if ((res >> 26) != ALC880_HP_EVENT)
8951		return;
8952	alc262_hippo1_automute(codec);
8953}
8954
8955/*
8956 * nec model
8957 *  0x15 = headphone
8958 *  0x16 = internal speaker
8959 *  0x18 = external mic
8960 */
8961
8962static struct snd_kcontrol_new alc262_nec_mixer[] = {
8963	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8964	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
8965
8966	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8967	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8968	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8969
8970	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8971	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8972	{ } /* end */
8973};
8974
8975static struct hda_verb alc262_nec_verbs[] = {
8976	/* Unmute Speaker */
8977	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8978
8979	/* Headphone */
8980	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8981	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982
8983	/* External mic to headphone */
8984	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8985	/* External mic to speaker */
8986	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8987	{}
8988};
8989
8990/*
8991 * fujitsu model
8992 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
8993 *  0x1b = port replicator headphone out
8994 */
8995
8996#define ALC_HP_EVENT	0x37
8997
8998static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8999	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9000	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9001	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9002	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9003	{}
9004};
9005
9006static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9007	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9008	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9009	{}
9010};
9011
9012static struct hda_input_mux alc262_fujitsu_capture_source = {
9013	.num_items = 3,
9014	.items = {
9015		{ "Mic", 0x0 },
9016		{ "Int Mic", 0x1 },
9017		{ "CD", 0x4 },
9018	},
9019};
9020
9021static struct hda_input_mux alc262_HP_capture_source = {
9022	.num_items = 5,
9023	.items = {
9024		{ "Mic", 0x0 },
9025		{ "Front Mic", 0x1 },
9026		{ "Line", 0x2 },
9027		{ "CD", 0x4 },
9028		{ "AUX IN", 0x6 },
9029	},
9030};
9031
9032static struct hda_input_mux alc262_HP_D7000_capture_source = {
9033	.num_items = 4,
9034	.items = {
9035		{ "Mic", 0x0 },
9036		{ "Front Mic", 0x2 },
9037		{ "Line", 0x1 },
9038		{ "CD", 0x4 },
9039	},
9040};
9041
9042/* mute/unmute internal speaker according to the hp jacks and mute state */
9043static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9044{
9045	struct alc_spec *spec = codec->spec;
9046	unsigned int mute;
9047
9048	if (force || !spec->sense_updated) {
9049		unsigned int present;
9050		/* need to execute and sync at first */
9051		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9052		/* check laptop HP jack */
9053		present = snd_hda_codec_read(codec, 0x14, 0,
9054					     AC_VERB_GET_PIN_SENSE, 0);
9055		/* need to execute and sync at first */
9056		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9057		/* check docking HP jack */
9058		present |= snd_hda_codec_read(codec, 0x1b, 0,
9059					      AC_VERB_GET_PIN_SENSE, 0);
9060		if (present & AC_PINSENSE_PRESENCE)
9061			spec->jack_present = 1;
9062		else
9063			spec->jack_present = 0;
9064		spec->sense_updated = 1;
9065	}
9066	/* unmute internal speaker only if both HPs are unplugged and
9067	 * master switch is on
9068	 */
9069	if (spec->jack_present)
9070		mute = HDA_AMP_MUTE;
9071	else
9072		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9073	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9074				 HDA_AMP_MUTE, mute);
9075}
9076
9077/* unsolicited event for HP jack sensing */
9078static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9079				       unsigned int res)
9080{
9081	if ((res >> 26) != ALC_HP_EVENT)
9082		return;
9083	alc262_fujitsu_automute(codec, 1);
9084}
9085
9086static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9087{
9088	alc262_fujitsu_automute(codec, 1);
9089}
9090
9091/* bind volumes of both NID 0x0c and 0x0d */
9092static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9093	.ops = &snd_hda_bind_vol,
9094	.values = {
9095		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9096		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9097		0
9098	},
9099};
9100
9101/* mute/unmute internal speaker according to the hp jack and mute state */
9102static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9103{
9104	struct alc_spec *spec = codec->spec;
9105	unsigned int mute;
9106
9107	if (force || !spec->sense_updated) {
9108		unsigned int present_int_hp;
9109		/* need to execute and sync at first */
9110		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9111		present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9112					AC_VERB_GET_PIN_SENSE, 0);
9113		spec->jack_present = (present_int_hp & 0x80000000) != 0;
9114		spec->sense_updated = 1;
9115	}
9116	if (spec->jack_present) {
9117		/* mute internal speaker */
9118		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9119					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9120		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9121					 HDA_AMP_MUTE, HDA_AMP_MUTE);
9122	} else {
9123		/* unmute internal speaker if necessary */
9124		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9125		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9126					 HDA_AMP_MUTE, mute);
9127		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9128					 HDA_AMP_MUTE, mute);
9129	}
9130}
9131
9132/* unsolicited event for HP jack sensing */
9133static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9134				       unsigned int res)
9135{
9136	if ((res >> 26) != ALC_HP_EVENT)
9137		return;
9138	alc262_lenovo_3000_automute(codec, 1);
9139}
9140
9141/* bind hp and internal speaker mute (with plug check) */
9142static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9143					 struct snd_ctl_elem_value *ucontrol)
9144{
9145	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9146	long *valp = ucontrol->value.integer.value;
9147	int change;
9148
9149	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9150						 HDA_AMP_MUTE,
9151						 valp ? 0 : HDA_AMP_MUTE);
9152	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9153						 HDA_AMP_MUTE,
9154						 valp ? 0 : HDA_AMP_MUTE);
9155
9156	if (change)
9157		alc262_fujitsu_automute(codec, 0);
9158	return change;
9159}
9160
9161static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9162	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9163	{
9164		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9165		.name = "Master Playback Switch",
9166		.info = snd_hda_mixer_amp_switch_info,
9167		.get = snd_hda_mixer_amp_switch_get,
9168		.put = alc262_fujitsu_master_sw_put,
9169		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9170	},
9171	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9172	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9173	HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9174	HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9175	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9176	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9177	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9178	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9179	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9180	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9181	{ } /* end */
9182};
9183
9184/* bind hp and internal speaker mute (with plug check) */
9185static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9186					 struct snd_ctl_elem_value *ucontrol)
9187{
9188	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9189	long *valp = ucontrol->value.integer.value;
9190	int change;
9191
9192	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9193						 HDA_AMP_MUTE,
9194						 valp ? 0 : HDA_AMP_MUTE);
9195
9196	if (change)
9197		alc262_lenovo_3000_automute(codec, 0);
9198	return change;
9199}
9200
9201static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9202	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9203	{
9204		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9205		.name = "Master Playback Switch",
9206		.info = snd_hda_mixer_amp_switch_info,
9207		.get = snd_hda_mixer_amp_switch_get,
9208		.put = alc262_lenovo_3000_master_sw_put,
9209		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9210	},
9211	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9212	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9213	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9214	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9215	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9216	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9217	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9218	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9219	{ } /* end */
9220};
9221
9222/* additional init verbs for Benq laptops */
9223static struct hda_verb alc262_EAPD_verbs[] = {
9224	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9225	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
9226	{}
9227};
9228
9229static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9230	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9231	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9232
9233	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9234	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
9235	{}
9236};
9237
9238/* Samsung Q1 Ultra Vista model setup */
9239static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9240	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9241	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9242	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9243	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9244	HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9245	HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9246	{ } /* end */
9247};
9248
9249static struct hda_verb alc262_ultra_verbs[] = {
9250	/* output mixer */
9251	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9252	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9253	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9254	/* speaker */
9255	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9256	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9257	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9258	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9259	/* HP */
9260	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9261	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9262	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9263	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9264	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9265	/* internal mic */
9266	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9267	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9268	/* ADC, choose mic */
9269	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9270	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9271	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9272	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9273	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9274	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9275	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9276	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9277	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9278	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9279	{}
9280};
9281
9282/* mute/unmute internal speaker according to the hp jack and mute state */
9283static void alc262_ultra_automute(struct hda_codec *codec)
9284{
9285	struct alc_spec *spec = codec->spec;
9286	unsigned int mute;
9287
9288	mute = 0;
9289	/* auto-mute only when HP is used as HP */
9290	if (!spec->cur_mux[0]) {
9291		unsigned int present;
9292		/* need to execute and sync at first */
9293		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9294		present = snd_hda_codec_read(codec, 0x15, 0,
9295					     AC_VERB_GET_PIN_SENSE, 0);
9296		spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9297		if (spec->jack_present)
9298			mute = HDA_AMP_MUTE;
9299	}
9300	/* mute/unmute internal speaker */
9301	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9302				 HDA_AMP_MUTE, mute);
9303	/* mute/unmute HP */
9304	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9305				 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9306}
9307
9308/* unsolicited event for HP jack sensing */
9309static void alc262_ultra_unsol_event(struct hda_codec *codec,
9310				       unsigned int res)
9311{
9312	if ((res >> 26) != ALC880_HP_EVENT)
9313		return;
9314	alc262_ultra_automute(codec);
9315}
9316
9317static struct hda_input_mux alc262_ultra_capture_source = {
9318	.num_items = 2,
9319	.items = {
9320		{ "Mic", 0x1 },
9321		{ "Headphone", 0x7 },
9322	},
9323};
9324
9325static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9326				     struct snd_ctl_elem_value *ucontrol)
9327{
9328	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9329	struct alc_spec *spec = codec->spec;
9330	int ret;
9331
9332	ret = alc882_mux_enum_put(kcontrol, ucontrol);
9333	if (!ret)
9334		return 0;
9335	/* reprogram the HP pin as mic or HP according to the input source */
9336	snd_hda_codec_write_cache(codec, 0x15, 0,
9337				  AC_VERB_SET_PIN_WIDGET_CONTROL,
9338				  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9339	alc262_ultra_automute(codec); /* mute/unmute HP */
9340	return ret;
9341}
9342
9343static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9344	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9345	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9346	{
9347		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9348		.name = "Capture Source",
9349		.info = alc882_mux_enum_info,
9350		.get = alc882_mux_enum_get,
9351		.put = alc262_ultra_mux_enum_put,
9352	},
9353	{ } /* end */
9354};
9355
9356/* add playback controls from the parsed DAC table */
9357static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9358					     const struct auto_pin_cfg *cfg)
9359{
9360	hda_nid_t nid;
9361	int err;
9362
9363	spec->multiout.num_dacs = 1;	/* only use one dac */
9364	spec->multiout.dac_nids = spec->private_dac_nids;
9365	spec->multiout.dac_nids[0] = 2;
9366
9367	nid = cfg->line_out_pins[0];
9368	if (nid) {
9369		err = add_control(spec, ALC_CTL_WIDGET_VOL,
9370				  "Front Playback Volume",
9371				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9372		if (err < 0)
9373			return err;
9374		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9375				  "Front Playback Switch",
9376				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9377		if (err < 0)
9378			return err;
9379	}
9380
9381	nid = cfg->speaker_pins[0];
9382	if (nid) {
9383		if (nid == 0x16) {
9384			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9385					  "Speaker Playback Volume",
9386					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9387							      HDA_OUTPUT));
9388			if (err < 0)
9389				return err;
9390			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9391					  "Speaker Playback Switch",
9392					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9393							      HDA_OUTPUT));
9394			if (err < 0)
9395				return err;
9396		} else {
9397			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9398					  "Speaker Playback Switch",
9399					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9400							      HDA_OUTPUT));
9401			if (err < 0)
9402				return err;
9403		}
9404	}
9405	nid = cfg->hp_pins[0];
9406	if (nid) {
9407		/* spec->multiout.hp_nid = 2; */
9408		if (nid == 0x16) {
9409			err = add_control(spec, ALC_CTL_WIDGET_VOL,
9410					  "Headphone Playback Volume",
9411					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9412							      HDA_OUTPUT));
9413			if (err < 0)
9414				return err;
9415			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9416					  "Headphone Playback Switch",
9417					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9418							      HDA_OUTPUT));
9419			if (err < 0)
9420				return err;
9421		} else {
9422			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9423					  "Headphone Playback Switch",
9424					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9425							      HDA_OUTPUT));
9426			if (err < 0)
9427				return err;
9428		}
9429	}
9430	return 0;
9431}
9432
9433/* identical with ALC880 */
9434#define alc262_auto_create_analog_input_ctls \
9435	alc880_auto_create_analog_input_ctls
9436
9437/*
9438 * generic initialization of ADC, input mixers and output mixers
9439 */
9440static struct hda_verb alc262_volume_init_verbs[] = {
9441	/*
9442	 * Unmute ADC0-2 and set the default input to mic-in
9443	 */
9444	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9445	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9446	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9447	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9448	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9449	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9450
9451	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9452	 * mixer widget
9453	 * Note: PASD motherboards uses the Line In 2 as the input for
9454	 * front panel mic (mic 2)
9455	 */
9456	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9457	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9458	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9459	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9460	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9461	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9462
9463	/*
9464	 * Set up output mixers (0x0c - 0x0f)
9465	 */
9466	/* set vol=0 to output mixers */
9467	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9468	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9469	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9470
9471	/* set up input amps for analog loopback */
9472	/* Amp Indices: DAC = 0, mixer = 1 */
9473	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9474	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9475	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9476	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9477	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9478	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9479
9480	/* FIXME: use matrix-type input source selection */
9481	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9482	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9483	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9484	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9485	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9486	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9487	/* Input mixer2 */
9488	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9489	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9490	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9491	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9492	/* Input mixer3 */
9493	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9494	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9495	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9496	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9497
9498	{ }
9499};
9500
9501static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9502	/*
9503	 * Unmute ADC0-2 and set the default input to mic-in
9504	 */
9505	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9506	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9507	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9508	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9509	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9510	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9511
9512	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9513	 * mixer widget
9514	 * Note: PASD motherboards uses the Line In 2 as the input for
9515	 * front panel mic (mic 2)
9516	 */
9517	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9518	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9519	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9520	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9521	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9522	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9523	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9524        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9525
9526	/*
9527	 * Set up output mixers (0x0c - 0x0e)
9528	 */
9529	/* set vol=0 to output mixers */
9530	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9531	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9532	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9533
9534	/* set up input amps for analog loopback */
9535	/* Amp Indices: DAC = 0, mixer = 1 */
9536	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9537	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9538	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9539	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9540	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9541	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9542
9543	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9544	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9545	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9546
9547	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9548	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9549
9550	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9551	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9552
9553	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9554	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9555        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9556	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9557	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9558
9559	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9560	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9561        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9562	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9563	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9564	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9565
9566
9567	/* FIXME: use matrix-type input source selection */
9568	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9569	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9570	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9571	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9572	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9573	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9574	/* Input mixer2 */
9575	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9576	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9577	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9578	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9579	/* Input mixer3 */
9580	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9581	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9582	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9583	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9584
9585	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9586
9587	{ }
9588};
9589
9590static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9591	/*
9592	 * Unmute ADC0-2 and set the default input to mic-in
9593	 */
9594	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9595	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9596	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9597	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9598	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9599	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9600
9601	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9602	 * mixer widget
9603	 * Note: PASD motherboards uses the Line In 2 as the input for front
9604	 * panel mic (mic 2)
9605	 */
9606	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9607	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9608	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9609	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9610	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9611	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9612	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9613	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9614	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9615	/*
9616	 * Set up output mixers (0x0c - 0x0e)
9617	 */
9618	/* set vol=0 to output mixers */
9619	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9620	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9621	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9622
9623	/* set up input amps for analog loopback */
9624	/* Amp Indices: DAC = 0, mixer = 1 */
9625	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9626	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9627	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9628	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9629	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9630	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9631
9632
9633	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
9634	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
9635	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
9636	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
9637	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
9638	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
9639	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
9640
9641	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9642	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9643
9644	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9645	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9646
9647	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9648	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9649	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9650	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9651	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9652	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9653
9654	/* FIXME: use matrix-type input source selection */
9655	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9656	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9657	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9658	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9659	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9660	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9661	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9662        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
9663	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9664	/* Input mixer2 */
9665	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9666	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9667	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9668	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9669	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9670        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9671	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9672	/* Input mixer3 */
9673	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9674	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9675	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9676	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9677	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9678        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9679	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9680
9681	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9682
9683	{ }
9684};
9685
9686#ifdef CONFIG_SND_HDA_POWER_SAVE
9687#define alc262_loopbacks	alc880_loopbacks
9688#endif
9689
9690/* pcm configuration: identiacal with ALC880 */
9691#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
9692#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
9693#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
9694#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
9695
9696/*
9697 * BIOS auto configuration
9698 */
9699static int alc262_parse_auto_config(struct hda_codec *codec)
9700{
9701	struct alc_spec *spec = codec->spec;
9702	int err;
9703	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9704
9705	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9706					   alc262_ignore);
9707	if (err < 0)
9708		return err;
9709	if (!spec->autocfg.line_outs)
9710		return 0; /* can't find valid BIOS pin config */
9711	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9712	if (err < 0)
9713		return err;
9714	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9715	if (err < 0)
9716		return err;
9717
9718	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9719
9720	if (spec->autocfg.dig_out_pin)
9721		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9722	if (spec->autocfg.dig_in_pin)
9723		spec->dig_in_nid = ALC262_DIGIN_NID;
9724
9725	if (spec->kctl_alloc)
9726		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9727
9728	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
9729	spec->num_mux_defs = 1;
9730	spec->input_mux = &spec->private_imux;
9731
9732	err = alc_auto_add_mic_boost(codec);
9733	if (err < 0)
9734		return err;
9735
9736	return 1;
9737}
9738
9739#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
9740#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
9741#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
9742#define alc262_auto_init_input_src	alc882_auto_init_input_src
9743
9744
9745/* init callback for auto-configuration model -- overriding the default init */
9746static void alc262_auto_init(struct hda_codec *codec)
9747{
9748	struct alc_spec *spec = codec->spec;
9749	alc262_auto_init_multi_out(codec);
9750	alc262_auto_init_hp_out(codec);
9751	alc262_auto_init_analog_input(codec);
9752	alc262_auto_init_input_src(codec);
9753	if (spec->unsol_event)
9754		alc_sku_automute(codec);
9755}
9756
9757/*
9758 * configuration and preset
9759 */
9760static const char *alc262_models[ALC262_MODEL_LAST] = {
9761	[ALC262_BASIC]		= "basic",
9762	[ALC262_HIPPO]		= "hippo",
9763	[ALC262_HIPPO_1]	= "hippo_1",
9764	[ALC262_FUJITSU]	= "fujitsu",
9765	[ALC262_HP_BPC]		= "hp-bpc",
9766	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
9767	[ALC262_HP_TC_T5735]	= "hp-tc-t5735",
9768	[ALC262_HP_RP5700]	= "hp-rp5700",
9769	[ALC262_BENQ_ED8]	= "benq",
9770	[ALC262_BENQ_T31]	= "benq-t31",
9771	[ALC262_SONY_ASSAMD]	= "sony-assamd",
9772	[ALC262_ULTRA]		= "ultra",
9773	[ALC262_LENOVO_3000]	= "lenovo-3000",
9774	[ALC262_NEC]		= "nec",
9775	[ALC262_AUTO]		= "auto",
9776};
9777
9778static struct snd_pci_quirk alc262_cfg_tbl[] = {
9779	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9780	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
9781	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9782	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9783	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9784	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
9785	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
9786	SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
9787	SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
9788	SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
9789	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
9790	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
9791	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
9792	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
9793	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
9794	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
9795	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
9796	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
9797	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9798	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9799	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
9800	SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9801		      ALC262_HP_TC_T5735),
9802	SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
9803	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9804	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
9805	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9806	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9807	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9808	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9809		      ALC262_SONY_ASSAMD),
9810	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9811	SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9812	SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
9813	SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
9814	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
9815	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9816	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9817	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
9818	{}
9819};
9820
9821static struct alc_config_preset alc262_presets[] = {
9822	[ALC262_BASIC] = {
9823		.mixers = { alc262_base_mixer },
9824		.init_verbs = { alc262_init_verbs },
9825		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9826		.dac_nids = alc262_dac_nids,
9827		.hp_nid = 0x03,
9828		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9829		.channel_mode = alc262_modes,
9830		.input_mux = &alc262_capture_source,
9831	},
9832	[ALC262_HIPPO] = {
9833		.mixers = { alc262_base_mixer },
9834		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9835		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9836		.dac_nids = alc262_dac_nids,
9837		.hp_nid = 0x03,
9838		.dig_out_nid = ALC262_DIGOUT_NID,
9839		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9840		.channel_mode = alc262_modes,
9841		.input_mux = &alc262_capture_source,
9842		.unsol_event = alc262_hippo_unsol_event,
9843		.init_hook = alc262_hippo_automute,
9844	},
9845	[ALC262_HIPPO_1] = {
9846		.mixers = { alc262_hippo1_mixer },
9847		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9848		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9849		.dac_nids = alc262_dac_nids,
9850		.hp_nid = 0x02,
9851		.dig_out_nid = ALC262_DIGOUT_NID,
9852		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9853		.channel_mode = alc262_modes,
9854		.input_mux = &alc262_capture_source,
9855		.unsol_event = alc262_hippo1_unsol_event,
9856		.init_hook = alc262_hippo1_automute,
9857	},
9858	[ALC262_FUJITSU] = {
9859		.mixers = { alc262_fujitsu_mixer },
9860		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9861				alc262_fujitsu_unsol_verbs },
9862		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9863		.dac_nids = alc262_dac_nids,
9864		.hp_nid = 0x03,
9865		.dig_out_nid = ALC262_DIGOUT_NID,
9866		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9867		.channel_mode = alc262_modes,
9868		.input_mux = &alc262_fujitsu_capture_source,
9869		.unsol_event = alc262_fujitsu_unsol_event,
9870		.init_hook = alc262_fujitsu_init_hook,
9871	},
9872	[ALC262_HP_BPC] = {
9873		.mixers = { alc262_HP_BPC_mixer },
9874		.init_verbs = { alc262_HP_BPC_init_verbs },
9875		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9876		.dac_nids = alc262_dac_nids,
9877		.hp_nid = 0x03,
9878		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9879		.channel_mode = alc262_modes,
9880		.input_mux = &alc262_HP_capture_source,
9881		.unsol_event = alc262_hp_bpc_unsol_event,
9882		.init_hook = alc262_hp_bpc_automute,
9883	},
9884	[ALC262_HP_BPC_D7000_WF] = {
9885		.mixers = { alc262_HP_BPC_WildWest_mixer },
9886		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9887		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9888		.dac_nids = alc262_dac_nids,
9889		.hp_nid = 0x03,
9890		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9891		.channel_mode = alc262_modes,
9892		.input_mux = &alc262_HP_D7000_capture_source,
9893		.unsol_event = alc262_hp_wildwest_unsol_event,
9894		.init_hook = alc262_hp_wildwest_automute,
9895	},
9896	[ALC262_HP_BPC_D7000_WL] = {
9897		.mixers = { alc262_HP_BPC_WildWest_mixer,
9898			    alc262_HP_BPC_WildWest_option_mixer },
9899		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9900		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9901		.dac_nids = alc262_dac_nids,
9902		.hp_nid = 0x03,
9903		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9904		.channel_mode = alc262_modes,
9905		.input_mux = &alc262_HP_D7000_capture_source,
9906		.unsol_event = alc262_hp_wildwest_unsol_event,
9907		.init_hook = alc262_hp_wildwest_automute,
9908	},
9909	[ALC262_HP_TC_T5735] = {
9910		.mixers = { alc262_hp_t5735_mixer },
9911		.init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9912		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9913		.dac_nids = alc262_dac_nids,
9914		.hp_nid = 0x03,
9915		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9916		.channel_mode = alc262_modes,
9917		.input_mux = &alc262_capture_source,
9918		.unsol_event = alc262_hp_t5735_unsol_event,
9919		.init_hook = alc262_hp_t5735_init_hook,
9920	},
9921	[ALC262_HP_RP5700] = {
9922		.mixers = { alc262_hp_rp5700_mixer },
9923		.init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9924		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9925		.dac_nids = alc262_dac_nids,
9926		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9927		.channel_mode = alc262_modes,
9928		.input_mux = &alc262_hp_rp5700_capture_source,
9929        },
9930	[ALC262_BENQ_ED8] = {
9931		.mixers = { alc262_base_mixer },
9932		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9933		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9934		.dac_nids = alc262_dac_nids,
9935		.hp_nid = 0x03,
9936		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9937		.channel_mode = alc262_modes,
9938		.input_mux = &alc262_capture_source,
9939	},
9940	[ALC262_SONY_ASSAMD] = {
9941		.mixers = { alc262_sony_mixer },
9942		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9943		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9944		.dac_nids = alc262_dac_nids,
9945		.hp_nid = 0x02,
9946		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9947		.channel_mode = alc262_modes,
9948		.input_mux = &alc262_capture_source,
9949		.unsol_event = alc262_hippo_unsol_event,
9950		.init_hook = alc262_hippo_automute,
9951	},
9952	[ALC262_BENQ_T31] = {
9953		.mixers = { alc262_benq_t31_mixer },
9954		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9955		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9956		.dac_nids = alc262_dac_nids,
9957		.hp_nid = 0x03,
9958		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9959		.channel_mode = alc262_modes,
9960		.input_mux = &alc262_capture_source,
9961		.unsol_event = alc262_hippo_unsol_event,
9962		.init_hook = alc262_hippo_automute,
9963	},
9964	[ALC262_ULTRA] = {
9965		.mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
9966		.init_verbs = { alc262_ultra_verbs },
9967		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9968		.dac_nids = alc262_dac_nids,
9969		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9970		.channel_mode = alc262_modes,
9971		.input_mux = &alc262_ultra_capture_source,
9972		.adc_nids = alc262_adc_nids, /* ADC0 */
9973		.capsrc_nids = alc262_capsrc_nids,
9974		.num_adc_nids = 1, /* single ADC */
9975		.unsol_event = alc262_ultra_unsol_event,
9976		.init_hook = alc262_ultra_automute,
9977	},
9978	[ALC262_LENOVO_3000] = {
9979		.mixers = { alc262_lenovo_3000_mixer },
9980		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9981				alc262_lenovo_3000_unsol_verbs },
9982		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9983		.dac_nids = alc262_dac_nids,
9984		.hp_nid = 0x03,
9985		.dig_out_nid = ALC262_DIGOUT_NID,
9986		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9987		.channel_mode = alc262_modes,
9988		.input_mux = &alc262_fujitsu_capture_source,
9989		.unsol_event = alc262_lenovo_3000_unsol_event,
9990	},
9991	[ALC262_NEC] = {
9992		.mixers = { alc262_nec_mixer },
9993		.init_verbs = { alc262_nec_verbs },
9994		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
9995		.dac_nids = alc262_dac_nids,
9996		.hp_nid = 0x03,
9997		.num_channel_mode = ARRAY_SIZE(alc262_modes),
9998		.channel_mode = alc262_modes,
9999		.input_mux = &alc262_capture_source,
10000	},
10001};
10002
10003static int patch_alc262(struct hda_codec *codec)
10004{
10005	struct alc_spec *spec;
10006	int board_config;
10007	int err;
10008
10009	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10010	if (spec == NULL)
10011		return -ENOMEM;
10012
10013	codec->spec = spec;
10014#if 0
10015	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
10016	 * under-run
10017	 */
10018	{
10019	int tmp;
10020	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10021	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10022	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10023	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10024	}
10025#endif
10026
10027	alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10028
10029	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10030						  alc262_models,
10031						  alc262_cfg_tbl);
10032
10033	if (board_config < 0) {
10034		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10035		       "trying auto-probe from BIOS...\n");
10036		board_config = ALC262_AUTO;
10037	}
10038
10039	if (board_config == ALC262_AUTO) {
10040		/* automatic parse from the BIOS config */
10041		err = alc262_parse_auto_config(codec);
10042		if (err < 0) {
10043			alc_free(codec);
10044			return err;
10045		} else if (!err) {
10046			printk(KERN_INFO
10047			       "hda_codec: Cannot set up configuration "
10048			       "from BIOS.  Using base mode...\n");
10049			board_config = ALC262_BASIC;
10050		}
10051	}
10052
10053	if (board_config != ALC262_AUTO)
10054		setup_preset(spec, &alc262_presets[board_config]);
10055
10056	spec->stream_name_analog = "ALC262 Analog";
10057	spec->stream_analog_playback = &alc262_pcm_analog_playback;
10058	spec->stream_analog_capture = &alc262_pcm_analog_capture;
10059
10060	spec->stream_name_digital = "ALC262 Digital";
10061	spec->stream_digital_playback = &alc262_pcm_digital_playback;
10062	spec->stream_digital_capture = &alc262_pcm_digital_capture;
10063
10064	if (!spec->adc_nids && spec->input_mux) {
10065		/* check whether NID 0x07 is valid */
10066		unsigned int wcap = get_wcaps(codec, 0x07);
10067
10068		/* get type */
10069		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10070		if (wcap != AC_WID_AUD_IN) {
10071			spec->adc_nids = alc262_adc_nids_alt;
10072			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10073			spec->capsrc_nids = alc262_capsrc_nids_alt;
10074			spec->mixers[spec->num_mixers] =
10075				alc262_capture_alt_mixer;
10076			spec->num_mixers++;
10077		} else {
10078			spec->adc_nids = alc262_adc_nids;
10079			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10080			spec->capsrc_nids = alc262_capsrc_nids;
10081			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10082			spec->num_mixers++;
10083		}
10084	}
10085
10086	spec->vmaster_nid = 0x0c;
10087
10088	codec->patch_ops = alc_patch_ops;
10089	if (board_config == ALC262_AUTO)
10090		spec->init_hook = alc262_auto_init;
10091#ifdef CONFIG_SND_HDA_POWER_SAVE
10092	if (!spec->loopback.amplist)
10093		spec->loopback.amplist = alc262_loopbacks;
10094#endif
10095
10096	return 0;
10097}
10098
10099/*
10100 *  ALC268 channel source setting (2 channel)
10101 */
10102#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
10103#define alc268_modes		alc260_modes
10104
10105static hda_nid_t alc268_dac_nids[2] = {
10106	/* front, hp */
10107	0x02, 0x03
10108};
10109
10110static hda_nid_t alc268_adc_nids[2] = {
10111	/* ADC0-1 */
10112	0x08, 0x07
10113};
10114
10115static hda_nid_t alc268_adc_nids_alt[1] = {
10116	/* ADC0 */
10117	0x08
10118};
10119
10120static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10121
10122static struct snd_kcontrol_new alc268_base_mixer[] = {
10123	/* output mixer control */
10124	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10125	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10126	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10127	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10128	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10129	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10130	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10131	{ }
10132};
10133
10134/* bind Beep switches of both NID 0x0f and 0x10 */
10135static struct hda_bind_ctls alc268_bind_beep_sw = {
10136	.ops = &snd_hda_bind_sw,
10137	.values = {
10138		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10139		HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10140		0
10141	},
10142};
10143
10144static struct snd_kcontrol_new alc268_beep_mixer[] = {
10145	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10146	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10147	{ }
10148};
10149
10150static struct hda_verb alc268_eapd_verbs[] = {
10151	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10152	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10153	{ }
10154};
10155
10156/* Toshiba specific */
10157#define alc268_toshiba_automute	alc262_hippo_automute
10158
10159static struct hda_verb alc268_toshiba_verbs[] = {
10160	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10161	{ } /* end */
10162};
10163
10164/* Acer specific */
10165/* bind volumes of both NID 0x02 and 0x03 */
10166static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10167	.ops = &snd_hda_bind_vol,
10168	.values = {
10169		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10170		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10171		0
10172	},
10173};
10174
10175/* mute/unmute internal speaker according to the hp jack and mute state */
10176static void alc268_acer_automute(struct hda_codec *codec, int force)
10177{
10178	struct alc_spec *spec = codec->spec;
10179	unsigned int mute;
10180
10181	if (force || !spec->sense_updated) {
10182		unsigned int present;
10183		present = snd_hda_codec_read(codec, 0x14, 0,
10184				    	 AC_VERB_GET_PIN_SENSE, 0);
10185		spec->jack_present = (present & 0x80000000) != 0;
10186		spec->sense_updated = 1;
10187	}
10188	if (spec->jack_present)
10189		mute = HDA_AMP_MUTE; /* mute internal speaker */
10190	else /* unmute internal speaker if necessary */
10191		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10192	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10193				 HDA_AMP_MUTE, mute);
10194}
10195
10196
10197/* bind hp and internal speaker mute (with plug check) */
10198static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10199				     struct snd_ctl_elem_value *ucontrol)
10200{
10201	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10202	long *valp = ucontrol->value.integer.value;
10203	int change;
10204
10205	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10206					  HDA_AMP_MUTE,
10207					  valp[0] ? 0 : HDA_AMP_MUTE);
10208	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10209					   HDA_AMP_MUTE,
10210					   valp[1] ? 0 : HDA_AMP_MUTE);
10211	if (change)
10212		alc268_acer_automute(codec, 0);
10213	return change;
10214}
10215
10216static struct snd_kcontrol_new alc268_acer_mixer[] = {
10217	/* output mixer control */
10218	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10219	{
10220		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10221		.name = "Master Playback Switch",
10222		.info = snd_hda_mixer_amp_switch_info,
10223		.get = snd_hda_mixer_amp_switch_get,
10224		.put = alc268_acer_master_sw_put,
10225		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10226	},
10227	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10228	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10229	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10230	{ }
10231};
10232
10233static struct hda_verb alc268_acer_verbs[] = {
10234	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10235	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10236	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10237	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10238	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10239	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10240
10241	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10242	{ }
10243};
10244
10245/* unsolicited event for HP jack sensing */
10246static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10247				       unsigned int res)
10248{
10249	if ((res >> 26) != ALC880_HP_EVENT)
10250		return;
10251	alc268_toshiba_automute(codec);
10252}
10253
10254static void alc268_acer_unsol_event(struct hda_codec *codec,
10255				       unsigned int res)
10256{
10257	if ((res >> 26) != ALC880_HP_EVENT)
10258		return;
10259	alc268_acer_automute(codec, 1);
10260}
10261
10262static void alc268_acer_init_hook(struct hda_codec *codec)
10263{
10264	alc268_acer_automute(codec, 1);
10265}
10266
10267static struct snd_kcontrol_new alc268_dell_mixer[] = {
10268	/* output mixer control */
10269	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10270	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10271	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10272	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10273	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10274	HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10275	{ }
10276};
10277
10278static struct hda_verb alc268_dell_verbs[] = {
10279	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10280	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10281	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10282	{ }
10283};
10284
10285/* mute/unmute internal speaker according to the hp jack and mute state */
10286static void alc268_dell_automute(struct hda_codec *codec)
10287{
10288	unsigned int present;
10289	unsigned int mute;
10290
10291	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10292	if (present & 0x80000000)
10293		mute = HDA_AMP_MUTE;
10294	else
10295		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10296	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10297				 HDA_AMP_MUTE, mute);
10298}
10299
10300static void alc268_dell_unsol_event(struct hda_codec *codec,
10301				    unsigned int res)
10302{
10303	if ((res >> 26) != ALC880_HP_EVENT)
10304		return;
10305	alc268_dell_automute(codec);
10306}
10307
10308#define alc268_dell_init_hook	alc268_dell_automute
10309
10310static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10311	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10312	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10313	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10314	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10315	HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10316	HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10317	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10318	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10319	{ }
10320};
10321
10322static struct hda_verb alc267_quanta_il1_verbs[] = {
10323	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10324	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10325	{ }
10326};
10327
10328static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10329{
10330	unsigned int present;
10331
10332	present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10333		& AC_PINSENSE_PRESENCE;
10334	snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10335			    present ? 0 : PIN_OUT);
10336}
10337
10338static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10339{
10340	unsigned int present;
10341
10342	present = snd_hda_codec_read(codec, 0x18, 0,
10343				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10344	snd_hda_codec_write(codec, 0x23, 0,
10345			    AC_VERB_SET_CONNECT_SEL,
10346			    present ? 0x00 : 0x01);
10347}
10348
10349static void alc267_quanta_il1_automute(struct hda_codec *codec)
10350{
10351	alc267_quanta_il1_hp_automute(codec);
10352	alc267_quanta_il1_mic_automute(codec);
10353}
10354
10355static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10356					   unsigned int res)
10357{
10358	switch (res >> 26) {
10359	case ALC880_HP_EVENT:
10360		alc267_quanta_il1_hp_automute(codec);
10361		break;
10362	case ALC880_MIC_EVENT:
10363		alc267_quanta_il1_mic_automute(codec);
10364		break;
10365	}
10366}
10367
10368/*
10369 * generic initialization of ADC, input mixers and output mixers
10370 */
10371static struct hda_verb alc268_base_init_verbs[] = {
10372	/* Unmute DAC0-1 and set vol = 0 */
10373	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10374	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10375	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10376	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10377	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10378	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10379
10380	/*
10381	 * Set up output mixers (0x0c - 0x0e)
10382	 */
10383	/* set vol=0 to output mixers */
10384	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10385	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10386	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10387        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10388
10389	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10390	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10391
10392	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10393	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10394	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10395	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10396	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10397	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10398	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10399	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10400
10401	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10402	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10403	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10404	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10405	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10406	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10407	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10408
10409	/* set PCBEEP vol = 0, mute connections */
10410	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10411	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10412	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10413
10414	/* Unmute Selector 23h,24h and set the default input to mic-in */
10415
10416	{0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10417	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10418	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10419	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10420
10421	{ }
10422};
10423
10424/*
10425 * generic initialization of ADC, input mixers and output mixers
10426 */
10427static struct hda_verb alc268_volume_init_verbs[] = {
10428	/* set output DAC */
10429	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10430	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10431	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10432	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10433
10434	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10435	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10436	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10437	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10438	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10439
10440	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10441	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10442	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10443	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10444	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10445
10446	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10447	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10448	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10449	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10450
10451	/* set PCBEEP vol = 0, mute connections */
10452	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10453	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10454	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10455
10456	{ }
10457};
10458
10459#define alc268_mux_enum_info alc_mux_enum_info
10460#define alc268_mux_enum_get alc_mux_enum_get
10461#define alc268_mux_enum_put alc_mux_enum_put
10462
10463static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10464	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10465	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10466	{
10467		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10468		/* The multiple "Capture Source" controls confuse alsamixer
10469		 * So call somewhat different..
10470		 */
10471		/* .name = "Capture Source", */
10472		.name = "Input Source",
10473		.count = 1,
10474		.info = alc268_mux_enum_info,
10475		.get = alc268_mux_enum_get,
10476		.put = alc268_mux_enum_put,
10477	},
10478	{ } /* end */
10479};
10480
10481static struct snd_kcontrol_new alc268_capture_mixer[] = {
10482	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10483	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10484	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
10485	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
10486	{
10487		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10488		/* The multiple "Capture Source" controls confuse alsamixer
10489		 * So call somewhat different..
10490		 */
10491		/* .name = "Capture Source", */
10492		.name = "Input Source",
10493		.count = 2,
10494		.info = alc268_mux_enum_info,
10495		.get = alc268_mux_enum_get,
10496		.put = alc268_mux_enum_put,
10497	},
10498	{ } /* end */
10499};
10500
10501static struct hda_input_mux alc268_capture_source = {
10502	.num_items = 4,
10503	.items = {
10504		{ "Mic", 0x0 },
10505		{ "Front Mic", 0x1 },
10506		{ "Line", 0x2 },
10507		{ "CD", 0x3 },
10508	},
10509};
10510
10511static struct hda_input_mux alc268_acer_capture_source = {
10512	.num_items = 3,
10513	.items = {
10514		{ "Mic", 0x0 },
10515		{ "Internal Mic", 0x6 },
10516		{ "Line", 0x2 },
10517	},
10518};
10519
10520#ifdef CONFIG_SND_DEBUG
10521static struct snd_kcontrol_new alc268_test_mixer[] = {
10522	/* Volume widgets */
10523	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10524	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10525	HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10526	HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
10527	HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
10528	HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
10529	HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
10530	HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
10531	HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
10532	HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
10533	HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
10534	HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
10535	HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
10536	/* The below appears problematic on some hardwares */
10537	/*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
10538	HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10539	HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
10540	HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
10541	HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
10542
10543	/* Modes for retasking pin widgets */
10544	ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
10545	ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
10546	ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
10547	ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
10548
10549	/* Controls for GPIO pins, assuming they are configured as outputs */
10550	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
10551	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
10552	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
10553	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
10554
10555	/* Switches to allow the digital SPDIF output pin to be enabled.
10556	 * The ALC268 does not have an SPDIF input.
10557	 */
10558	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
10559
10560	/* A switch allowing EAPD to be enabled.  Some laptops seem to use
10561	 * this output to turn on an external amplifier.
10562	 */
10563	ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
10564	ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
10565
10566	{ } /* end */
10567};
10568#endif
10569
10570/* create input playback/capture controls for the given pin */
10571static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
10572				    const char *ctlname, int idx)
10573{
10574	char name[32];
10575	int err;
10576
10577	sprintf(name, "%s Playback Volume", ctlname);
10578	if (nid == 0x14) {
10579		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10580				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
10581						      HDA_OUTPUT));
10582		if (err < 0)
10583			return err;
10584	} else if (nid == 0x15) {
10585		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10586				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
10587						      HDA_OUTPUT));
10588		if (err < 0)
10589			return err;
10590	} else
10591		return -1;
10592	sprintf(name, "%s Playback Switch", ctlname);
10593	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10594			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
10595	if (err < 0)
10596		return err;
10597	return 0;
10598}
10599
10600/* add playback controls from the parsed DAC table */
10601static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10602					     const struct auto_pin_cfg *cfg)
10603{
10604	hda_nid_t nid;
10605	int err;
10606
10607	spec->multiout.num_dacs = 2;	/* only use one dac */
10608	spec->multiout.dac_nids = spec->private_dac_nids;
10609	spec->multiout.dac_nids[0] = 2;
10610	spec->multiout.dac_nids[1] = 3;
10611
10612	nid = cfg->line_out_pins[0];
10613	if (nid)
10614		alc268_new_analog_output(spec, nid, "Front", 0);
10615
10616	nid = cfg->speaker_pins[0];
10617	if (nid == 0x1d) {
10618		err = add_control(spec, ALC_CTL_WIDGET_VOL,
10619				  "Speaker Playback Volume",
10620				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10621		if (err < 0)
10622			return err;
10623	}
10624	nid = cfg->hp_pins[0];
10625	if (nid)
10626		alc268_new_analog_output(spec, nid, "Headphone", 0);
10627
10628	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
10629	if (nid == 0x16) {
10630		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10631				  "Mono Playback Switch",
10632				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
10633		if (err < 0)
10634			return err;
10635	}
10636	return 0;
10637}
10638
10639/* create playback/capture controls for input pins */
10640static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10641						const struct auto_pin_cfg *cfg)
10642{
10643	struct hda_input_mux *imux = &spec->private_imux;
10644	int i, idx1;
10645
10646	for (i = 0; i < AUTO_PIN_LAST; i++) {
10647		switch(cfg->input_pins[i]) {
10648		case 0x18:
10649			idx1 = 0;	/* Mic 1 */
10650			break;
10651		case 0x19:
10652			idx1 = 1;	/* Mic 2 */
10653			break;
10654		case 0x1a:
10655			idx1 = 2;	/* Line In */
10656			break;
10657		case 0x1c:
10658			idx1 = 3;	/* CD */
10659			break;
10660		case 0x12:
10661		case 0x13:
10662			idx1 = 6;	/* digital mics */
10663			break;
10664		default:
10665			continue;
10666		}
10667		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10668		imux->items[imux->num_items].index = idx1;
10669		imux->num_items++;
10670	}
10671	return 0;
10672}
10673
10674static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10675{
10676	struct alc_spec *spec = codec->spec;
10677	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10678	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10679	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10680	unsigned int	dac_vol1, dac_vol2;
10681
10682	if (speaker_nid) {
10683		snd_hda_codec_write(codec, speaker_nid, 0,
10684				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10685		snd_hda_codec_write(codec, 0x0f, 0,
10686				    AC_VERB_SET_AMP_GAIN_MUTE,
10687				    AMP_IN_UNMUTE(1));
10688		snd_hda_codec_write(codec, 0x10, 0,
10689				    AC_VERB_SET_AMP_GAIN_MUTE,
10690				    AMP_IN_UNMUTE(1));
10691	} else {
10692		snd_hda_codec_write(codec, 0x0f, 0,
10693				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10694		snd_hda_codec_write(codec, 0x10, 0,
10695				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10696	}
10697
10698	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
10699	if (line_nid == 0x14)
10700		dac_vol2 = AMP_OUT_ZERO;
10701	else if (line_nid == 0x15)
10702		dac_vol1 = AMP_OUT_ZERO;
10703	if (hp_nid == 0x14)
10704		dac_vol2 = AMP_OUT_ZERO;
10705	else if (hp_nid == 0x15)
10706		dac_vol1 = AMP_OUT_ZERO;
10707	if (line_nid != 0x16 || hp_nid != 0x16 ||
10708	    spec->autocfg.line_out_pins[1] != 0x16 ||
10709	    spec->autocfg.line_out_pins[2] != 0x16)
10710		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10711
10712	snd_hda_codec_write(codec, 0x02, 0,
10713			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10714	snd_hda_codec_write(codec, 0x03, 0,
10715			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10716}
10717
10718/* pcm configuration: identiacal with ALC880 */
10719#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
10720#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
10721#define alc268_pcm_analog_alt_capture	alc880_pcm_analog_alt_capture
10722#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
10723
10724/*
10725 * BIOS auto configuration
10726 */
10727static int alc268_parse_auto_config(struct hda_codec *codec)
10728{
10729	struct alc_spec *spec = codec->spec;
10730	int err;
10731	static hda_nid_t alc268_ignore[] = { 0 };
10732
10733	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10734					   alc268_ignore);
10735	if (err < 0)
10736		return err;
10737	if (!spec->autocfg.line_outs)
10738		return 0; /* can't find valid BIOS pin config */
10739
10740	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10741	if (err < 0)
10742		return err;
10743	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10744	if (err < 0)
10745		return err;
10746
10747	spec->multiout.max_channels = 2;
10748
10749	/* digital only support output */
10750	if (spec->autocfg.dig_out_pin)
10751		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10752
10753	if (spec->kctl_alloc)
10754		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10755
10756	if (spec->autocfg.speaker_pins[0] != 0x1d)
10757		spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
10758
10759	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10760	spec->num_mux_defs = 1;
10761	spec->input_mux = &spec->private_imux;
10762
10763	err = alc_auto_add_mic_boost(codec);
10764	if (err < 0)
10765		return err;
10766
10767	return 1;
10768}
10769
10770#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
10771#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
10772#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
10773
10774/* init callback for auto-configuration model -- overriding the default init */
10775static void alc268_auto_init(struct hda_codec *codec)
10776{
10777	struct alc_spec *spec = codec->spec;
10778	alc268_auto_init_multi_out(codec);
10779	alc268_auto_init_hp_out(codec);
10780	alc268_auto_init_mono_speaker_out(codec);
10781	alc268_auto_init_analog_input(codec);
10782	if (spec->unsol_event)
10783		alc_sku_automute(codec);
10784}
10785
10786/*
10787 * configuration and preset
10788 */
10789static const char *alc268_models[ALC268_MODEL_LAST] = {
10790	[ALC267_QUANTA_IL1]	= "quanta-il1",
10791	[ALC268_3ST]		= "3stack",
10792	[ALC268_TOSHIBA]	= "toshiba",
10793	[ALC268_ACER]		= "acer",
10794	[ALC268_DELL]		= "dell",
10795	[ALC268_ZEPTO]		= "zepto",
10796#ifdef CONFIG_SND_DEBUG
10797	[ALC268_TEST]		= "test",
10798#endif
10799	[ALC268_AUTO]		= "auto",
10800};
10801
10802static struct snd_pci_quirk alc268_cfg_tbl[] = {
10803	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
10804	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
10805	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
10806	SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
10807	SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
10808	SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
10809	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
10810	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
10811	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
10812	SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
10813	SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
10814	SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
10815	SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
10816	SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
10817	{}
10818};
10819
10820static struct alc_config_preset alc268_presets[] = {
10821	[ALC267_QUANTA_IL1] = {
10822		.mixers = { alc267_quanta_il1_mixer },
10823		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10824				alc267_quanta_il1_verbs },
10825		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10826		.dac_nids = alc268_dac_nids,
10827		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10828		.adc_nids = alc268_adc_nids_alt,
10829		.hp_nid = 0x03,
10830		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10831		.channel_mode = alc268_modes,
10832		.input_mux = &alc268_capture_source,
10833		.unsol_event = alc267_quanta_il1_unsol_event,
10834		.init_hook = alc267_quanta_il1_automute,
10835	},
10836	[ALC268_3ST] = {
10837		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10838			    alc268_beep_mixer },
10839		.init_verbs = { alc268_base_init_verbs },
10840		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10841		.dac_nids = alc268_dac_nids,
10842                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10843                .adc_nids = alc268_adc_nids_alt,
10844		.capsrc_nids = alc268_capsrc_nids,
10845		.hp_nid = 0x03,
10846		.dig_out_nid = ALC268_DIGOUT_NID,
10847		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10848		.channel_mode = alc268_modes,
10849		.input_mux = &alc268_capture_source,
10850	},
10851	[ALC268_TOSHIBA] = {
10852		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10853			    alc268_beep_mixer },
10854		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10855				alc268_toshiba_verbs },
10856		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10857		.dac_nids = alc268_dac_nids,
10858		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10859		.adc_nids = alc268_adc_nids_alt,
10860		.capsrc_nids = alc268_capsrc_nids,
10861		.hp_nid = 0x03,
10862		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10863		.channel_mode = alc268_modes,
10864		.input_mux = &alc268_capture_source,
10865		.unsol_event = alc268_toshiba_unsol_event,
10866		.init_hook = alc268_toshiba_automute,
10867	},
10868	[ALC268_ACER] = {
10869		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
10870			    alc268_beep_mixer },
10871		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10872				alc268_acer_verbs },
10873		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10874		.dac_nids = alc268_dac_nids,
10875		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10876		.adc_nids = alc268_adc_nids_alt,
10877		.capsrc_nids = alc268_capsrc_nids,
10878		.hp_nid = 0x02,
10879		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10880		.channel_mode = alc268_modes,
10881		.input_mux = &alc268_acer_capture_source,
10882		.unsol_event = alc268_acer_unsol_event,
10883		.init_hook = alc268_acer_init_hook,
10884	},
10885	[ALC268_DELL] = {
10886		.mixers = { alc268_dell_mixer, alc268_beep_mixer },
10887		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10888				alc268_dell_verbs },
10889		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10890		.dac_nids = alc268_dac_nids,
10891		.hp_nid = 0x02,
10892		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10893		.channel_mode = alc268_modes,
10894		.unsol_event = alc268_dell_unsol_event,
10895		.init_hook = alc268_dell_init_hook,
10896		.input_mux = &alc268_capture_source,
10897	},
10898	[ALC268_ZEPTO] = {
10899		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10900			    alc268_beep_mixer },
10901		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10902				alc268_toshiba_verbs },
10903		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10904		.dac_nids = alc268_dac_nids,
10905		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10906		.adc_nids = alc268_adc_nids_alt,
10907		.capsrc_nids = alc268_capsrc_nids,
10908		.hp_nid = 0x03,
10909		.dig_out_nid = ALC268_DIGOUT_NID,
10910		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10911		.channel_mode = alc268_modes,
10912		.input_mux = &alc268_capture_source,
10913		.unsol_event = alc268_toshiba_unsol_event,
10914		.init_hook = alc268_toshiba_automute
10915	},
10916#ifdef CONFIG_SND_DEBUG
10917	[ALC268_TEST] = {
10918		.mixers = { alc268_test_mixer, alc268_capture_mixer },
10919		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10920				alc268_volume_init_verbs },
10921		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
10922		.dac_nids = alc268_dac_nids,
10923		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10924		.adc_nids = alc268_adc_nids_alt,
10925		.capsrc_nids = alc268_capsrc_nids,
10926		.hp_nid = 0x03,
10927		.dig_out_nid = ALC268_DIGOUT_NID,
10928		.num_channel_mode = ARRAY_SIZE(alc268_modes),
10929		.channel_mode = alc268_modes,
10930		.input_mux = &alc268_capture_source,
10931	},
10932#endif
10933};
10934
10935static int patch_alc268(struct hda_codec *codec)
10936{
10937	struct alc_spec *spec;
10938	int board_config;
10939	int err;
10940
10941	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10942	if (spec == NULL)
10943		return -ENOMEM;
10944
10945	codec->spec = spec;
10946
10947	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10948						  alc268_models,
10949						  alc268_cfg_tbl);
10950
10951	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10952		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10953		       "trying auto-probe from BIOS...\n");
10954		board_config = ALC268_AUTO;
10955	}
10956
10957	if (board_config == ALC268_AUTO) {
10958		/* automatic parse from the BIOS config */
10959		err = alc268_parse_auto_config(codec);
10960		if (err < 0) {
10961			alc_free(codec);
10962			return err;
10963		} else if (!err) {
10964			printk(KERN_INFO
10965			       "hda_codec: Cannot set up configuration "
10966			       "from BIOS.  Using base mode...\n");
10967			board_config = ALC268_3ST;
10968		}
10969	}
10970
10971	if (board_config != ALC268_AUTO)
10972		setup_preset(spec, &alc268_presets[board_config]);
10973
10974	if (codec->vendor_id == 0x10ec0267) {
10975		spec->stream_name_analog = "ALC267 Analog";
10976		spec->stream_name_digital = "ALC267 Digital";
10977	} else {
10978		spec->stream_name_analog = "ALC268 Analog";
10979		spec->stream_name_digital = "ALC268 Digital";
10980	}
10981
10982	spec->stream_analog_playback = &alc268_pcm_analog_playback;
10983	spec->stream_analog_capture = &alc268_pcm_analog_capture;
10984	spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
10985
10986	spec->stream_digital_playback = &alc268_pcm_digital_playback;
10987
10988	if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
10989		/* override the amp caps for beep generator */
10990		snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
10991					  (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
10992					  (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
10993					  (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
10994					  (0 << AC_AMPCAP_MUTE_SHIFT));
10995
10996	if (!spec->adc_nids && spec->input_mux) {
10997		/* check whether NID 0x07 is valid */
10998		unsigned int wcap = get_wcaps(codec, 0x07);
10999		int i;
11000
11001		/* get type */
11002		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11003		if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11004			spec->adc_nids = alc268_adc_nids_alt;
11005			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11006			spec->mixers[spec->num_mixers] =
11007					alc268_capture_alt_mixer;
11008			spec->num_mixers++;
11009		} else {
11010			spec->adc_nids = alc268_adc_nids;
11011			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11012			spec->mixers[spec->num_mixers] =
11013				alc268_capture_mixer;
11014			spec->num_mixers++;
11015		}
11016		spec->capsrc_nids = alc268_capsrc_nids;
11017		/* set default input source */
11018		for (i = 0; i < spec->num_adc_nids; i++)
11019			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11020				0, AC_VERB_SET_CONNECT_SEL,
11021				spec->input_mux->items[0].index);
11022	}
11023
11024	spec->vmaster_nid = 0x02;
11025
11026	codec->patch_ops = alc_patch_ops;
11027	if (board_config == ALC268_AUTO)
11028		spec->init_hook = alc268_auto_init;
11029
11030	return 0;
11031}
11032
11033/*
11034 *  ALC269 channel source setting (2 channel)
11035 */
11036#define ALC269_DIGOUT_NID	ALC880_DIGOUT_NID
11037
11038#define alc269_dac_nids		alc260_dac_nids
11039
11040static hda_nid_t alc269_adc_nids[1] = {
11041	/* ADC1 */
11042	0x08,
11043};
11044
11045static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11046	.num_items = 2,
11047	.items = {
11048		{ "i-Mic", 0x5 },
11049		{ "e-Mic", 0x0 },
11050	},
11051};
11052
11053static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11054	.num_items = 2,
11055	.items = {
11056		{ "i-Mic", 0x1 },
11057		{ "e-Mic", 0x0 },
11058	},
11059};
11060
11061#define alc269_modes		alc260_modes
11062#define alc269_capture_source	alc880_lg_lw_capture_source
11063
11064static struct snd_kcontrol_new alc269_base_mixer[] = {
11065	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11066	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11067	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11068	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11069	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11070	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11071	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11072	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11073	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11074	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11075	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11076	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11077	{ } /* end */
11078};
11079
11080/* bind volumes of both NID 0x0c and 0x0d */
11081static struct hda_bind_ctls alc269_epc_bind_vol = {
11082	.ops = &snd_hda_bind_vol,
11083	.values = {
11084		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11085		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11086		0
11087	},
11088};
11089
11090static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11091	HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11092	HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11093	HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11094	{ } /* end */
11095};
11096
11097/* capture mixer elements */
11098static struct snd_kcontrol_new alc269_capture_mixer[] = {
11099	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11100	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11101	{
11102		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11103		/* The multiple "Capture Source" controls confuse alsamixer
11104		 * So call somewhat different..
11105		 */
11106		/* .name = "Capture Source", */
11107		.name = "Input Source",
11108		.count = 1,
11109		.info = alc_mux_enum_info,
11110		.get = alc_mux_enum_get,
11111		.put = alc_mux_enum_put,
11112	},
11113	{ } /* end */
11114};
11115
11116/* capture mixer elements */
11117static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11118	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11119	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11120	{ } /* end */
11121};
11122
11123/*
11124 * generic initialization of ADC, input mixers and output mixers
11125 */
11126static struct hda_verb alc269_init_verbs[] = {
11127	/*
11128	 * Unmute ADC0 and set the default input to mic-in
11129	 */
11130	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11131
11132	/* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11133	 * analog-loopback mixer widget
11134	 * Note: PASD motherboards uses the Line In 2 as the input for
11135	 * front panel mic (mic 2)
11136	 */
11137	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11138	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11139	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11140	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11141	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11142	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11143
11144	/*
11145	 * Set up output mixers (0x0c - 0x0e)
11146	 */
11147	/* set vol=0 to output mixers */
11148	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11149	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11150
11151	/* set up input amps for analog loopback */
11152	/* Amp Indices: DAC = 0, mixer = 1 */
11153	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11154	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11155	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11156	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11157	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11158	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11159
11160	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11161	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11162	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11163	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11164	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11165	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11166	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11167
11168	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11169	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11170	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11171	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11172	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11173	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11174	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11175
11176	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11177	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11178
11179	/* FIXME: use matrix-type input source selection */
11180	/* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11181	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11182	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11183	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11184	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11185	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11186
11187	/* set EAPD */
11188	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11189	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11190	{ }
11191};
11192
11193static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11194	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11195	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11196	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11197	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11198	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11199	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11200	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11201	{}
11202};
11203
11204static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11205	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11206	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11207	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11208	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11209	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11210	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11211	{}
11212};
11213
11214/* toggle speaker-output according to the hp-jack state */
11215static void alc269_speaker_automute(struct hda_codec *codec)
11216{
11217	unsigned int present;
11218	unsigned int bits;
11219
11220	present = snd_hda_codec_read(codec, 0x15, 0,
11221				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11222	bits = present ? AMP_IN_MUTE(0) : 0;
11223	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11224				 AMP_IN_MUTE(0), bits);
11225	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11226				 AMP_IN_MUTE(0), bits);
11227}
11228
11229static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11230{
11231	unsigned int present;
11232
11233	present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
11234		& AC_PINSENSE_PRESENCE;
11235	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11236			    present ? 0 : 5);
11237}
11238
11239static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11240{
11241	unsigned int present;
11242
11243	present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0)
11244		& AC_PINSENSE_PRESENCE;
11245	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11246			    present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0));
11247	snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11248			    present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1));
11249}
11250
11251/* unsolicited event for HP jack sensing */
11252static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11253					  unsigned int res)
11254{
11255	if ((res >> 26) == ALC880_HP_EVENT)
11256		alc269_speaker_automute(codec);
11257
11258	if ((res >> 26) == ALC880_MIC_EVENT)
11259		alc269_eeepc_dmic_automute(codec);
11260}
11261
11262static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11263{
11264	alc269_speaker_automute(codec);
11265	alc269_eeepc_dmic_automute(codec);
11266}
11267
11268/* unsolicited event for HP jack sensing */
11269static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11270					  unsigned int res)
11271{
11272	if ((res >> 26) == ALC880_HP_EVENT)
11273		alc269_speaker_automute(codec);
11274
11275	if ((res >> 26) == ALC880_MIC_EVENT)
11276		alc269_eeepc_amic_automute(codec);
11277}
11278
11279static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11280{
11281	alc269_speaker_automute(codec);
11282	alc269_eeepc_amic_automute(codec);
11283}
11284
11285/* add playback controls from the parsed DAC table */
11286static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11287					     const struct auto_pin_cfg *cfg)
11288{
11289	hda_nid_t nid;
11290	int err;
11291
11292	spec->multiout.num_dacs = 1;	/* only use one dac */
11293	spec->multiout.dac_nids = spec->private_dac_nids;
11294	spec->multiout.dac_nids[0] = 2;
11295
11296	nid = cfg->line_out_pins[0];
11297	if (nid) {
11298		err = add_control(spec, ALC_CTL_WIDGET_VOL,
11299				  "Front Playback Volume",
11300				  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
11301		if (err < 0)
11302			return err;
11303		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11304				  "Front Playback Switch",
11305				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11306		if (err < 0)
11307			return err;
11308	}
11309
11310	nid = cfg->speaker_pins[0];
11311	if (nid) {
11312		if (!cfg->line_out_pins[0]) {
11313			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11314					  "Speaker Playback Volume",
11315					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11316							      HDA_OUTPUT));
11317			if (err < 0)
11318				return err;
11319		}
11320		if (nid == 0x16) {
11321			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11322					  "Speaker Playback Switch",
11323					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11324							      HDA_OUTPUT));
11325			if (err < 0)
11326				return err;
11327		} else {
11328			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11329					  "Speaker Playback Switch",
11330					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11331							      HDA_OUTPUT));
11332			if (err < 0)
11333				return err;
11334		}
11335	}
11336	nid = cfg->hp_pins[0];
11337	if (nid) {
11338		/* spec->multiout.hp_nid = 2; */
11339		if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
11340			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11341					  "Headphone Playback Volume",
11342					  HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11343							      HDA_OUTPUT));
11344			if (err < 0)
11345				return err;
11346		}
11347		if (nid == 0x16) {
11348			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11349					  "Headphone Playback Switch",
11350					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11351							      HDA_OUTPUT));
11352			if (err < 0)
11353				return err;
11354		} else {
11355			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11356					  "Headphone Playback Switch",
11357					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11358							      HDA_OUTPUT));
11359			if (err < 0)
11360				return err;
11361		}
11362	}
11363	return 0;
11364}
11365
11366#define alc269_auto_create_analog_input_ctls \
11367	alc880_auto_create_analog_input_ctls
11368
11369#ifdef CONFIG_SND_HDA_POWER_SAVE
11370#define alc269_loopbacks	alc880_loopbacks
11371#endif
11372
11373/* pcm configuration: identiacal with ALC880 */
11374#define alc269_pcm_analog_playback	alc880_pcm_analog_playback
11375#define alc269_pcm_analog_capture	alc880_pcm_analog_capture
11376#define alc269_pcm_digital_playback	alc880_pcm_digital_playback
11377#define alc269_pcm_digital_capture	alc880_pcm_digital_capture
11378
11379/*
11380 * BIOS auto configuration
11381 */
11382static int alc269_parse_auto_config(struct hda_codec *codec)
11383{
11384	struct alc_spec *spec = codec->spec;
11385	int err;
11386	static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
11387
11388	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11389					   alc269_ignore);
11390	if (err < 0)
11391		return err;
11392
11393	err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
11394	if (err < 0)
11395		return err;
11396	err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
11397	if (err < 0)
11398		return err;
11399
11400	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11401
11402	if (spec->autocfg.dig_out_pin)
11403		spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
11404
11405	if (spec->kctl_alloc)
11406		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11407
11408	spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
11409	spec->num_mux_defs = 1;
11410	spec->input_mux = &spec->private_imux;
11411
11412	err = alc_auto_add_mic_boost(codec);
11413	if (err < 0)
11414		return err;
11415
11416	spec->mixers[spec->num_mixers] = alc269_capture_mixer;
11417	spec->num_mixers++;
11418
11419	return 1;
11420}
11421
11422#define alc269_auto_init_multi_out	alc882_auto_init_multi_out
11423#define alc269_auto_init_hp_out		alc882_auto_init_hp_out
11424#define alc269_auto_init_analog_input	alc882_auto_init_analog_input
11425
11426
11427/* init callback for auto-configuration model -- overriding the default init */
11428static void alc269_auto_init(struct hda_codec *codec)
11429{
11430	struct alc_spec *spec = codec->spec;
11431	alc269_auto_init_multi_out(codec);
11432	alc269_auto_init_hp_out(codec);
11433	alc269_auto_init_analog_input(codec);
11434	if (spec->unsol_event)
11435		alc_sku_automute(codec);
11436}
11437
11438/*
11439 * configuration and preset
11440 */
11441static const char *alc269_models[ALC269_MODEL_LAST] = {
11442	[ALC269_BASIC]		= "basic",
11443};
11444
11445static struct snd_pci_quirk alc269_cfg_tbl[] = {
11446	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
11447		      ALC269_ASUS_EEEPC_P703),
11448	SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
11449		      ALC269_ASUS_EEEPC_P901),
11450	{}
11451};
11452
11453static struct alc_config_preset alc269_presets[] = {
11454	[ALC269_BASIC] = {
11455		.mixers = { alc269_base_mixer, alc269_capture_mixer },
11456		.init_verbs = { alc269_init_verbs },
11457		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
11458		.dac_nids = alc269_dac_nids,
11459		.hp_nid = 0x03,
11460		.num_channel_mode = ARRAY_SIZE(alc269_modes),
11461		.channel_mode = alc269_modes,
11462		.input_mux = &alc269_capture_source,
11463	},
11464	[ALC269_ASUS_EEEPC_P703] = {
11465		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
11466		.init_verbs = { alc269_init_verbs,
11467				alc269_eeepc_amic_init_verbs },
11468		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
11469		.dac_nids = alc269_dac_nids,
11470		.hp_nid = 0x03,
11471		.num_channel_mode = ARRAY_SIZE(alc269_modes),
11472		.channel_mode = alc269_modes,
11473		.input_mux = &alc269_eeepc_amic_capture_source,
11474		.unsol_event = alc269_eeepc_amic_unsol_event,
11475		.init_hook = alc269_eeepc_amic_inithook,
11476	},
11477	[ALC269_ASUS_EEEPC_P901] = {
11478		.mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
11479		.init_verbs = { alc269_init_verbs,
11480				alc269_eeepc_dmic_init_verbs },
11481		.num_dacs = ARRAY_SIZE(alc269_dac_nids),
11482		.dac_nids = alc269_dac_nids,
11483		.hp_nid = 0x03,
11484		.num_channel_mode = ARRAY_SIZE(alc269_modes),
11485		.channel_mode = alc269_modes,
11486		.input_mux = &alc269_eeepc_dmic_capture_source,
11487		.unsol_event = alc269_eeepc_dmic_unsol_event,
11488		.init_hook = alc269_eeepc_dmic_inithook,
11489	},
11490};
11491
11492static int patch_alc269(struct hda_codec *codec)
11493{
11494	struct alc_spec *spec;
11495	int board_config;
11496	int err;
11497
11498	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11499	if (spec == NULL)
11500		return -ENOMEM;
11501
11502	codec->spec = spec;
11503
11504	alc_fix_pll_init(codec, 0x20, 0x04, 15);
11505
11506	board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
11507						  alc269_models,
11508						  alc269_cfg_tbl);
11509
11510	if (board_config < 0) {
11511		printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
11512		       "trying auto-probe from BIOS...\n");
11513		board_config = ALC269_AUTO;
11514	}
11515
11516	if (board_config == ALC269_AUTO) {
11517		/* automatic parse from the BIOS config */
11518		err = alc269_parse_auto_config(codec);
11519		if (err < 0) {
11520			alc_free(codec);
11521			return err;
11522		} else if (!err) {
11523			printk(KERN_INFO
11524			       "hda_codec: Cannot set up configuration "
11525			       "from BIOS.  Using base mode...\n");
11526			board_config = ALC269_BASIC;
11527		}
11528	}
11529
11530	if (board_config != ALC269_AUTO)
11531		setup_preset(spec, &alc269_presets[board_config]);
11532
11533	spec->stream_name_analog = "ALC269 Analog";
11534	spec->stream_analog_playback = &alc269_pcm_analog_playback;
11535	spec->stream_analog_capture = &alc269_pcm_analog_capture;
11536
11537	spec->stream_name_digital = "ALC269 Digital";
11538	spec->stream_digital_playback = &alc269_pcm_digital_playback;
11539	spec->stream_digital_capture = &alc269_pcm_digital_capture;
11540
11541	spec->adc_nids = alc269_adc_nids;
11542	spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
11543
11544	codec->patch_ops = alc_patch_ops;
11545	if (board_config == ALC269_AUTO)
11546		spec->init_hook = alc269_auto_init;
11547#ifdef CONFIG_SND_HDA_POWER_SAVE
11548	if (!spec->loopback.amplist)
11549		spec->loopback.amplist = alc269_loopbacks;
11550#endif
11551
11552	return 0;
11553}
11554
11555/*
11556 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
11557 */
11558
11559/*
11560 * set the path ways for 2 channel output
11561 * need to set the codec line out and mic 1 pin widgets to inputs
11562 */
11563static struct hda_verb alc861_threestack_ch2_init[] = {
11564	/* set pin widget 1Ah (line in) for input */
11565	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11566	/* set pin widget 18h (mic1/2) for input, for mic also enable
11567	 * the vref
11568	 */
11569	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11570
11571	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11572#if 0
11573	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11574	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11575#endif
11576	{ } /* end */
11577};
11578/*
11579 * 6ch mode
11580 * need to set the codec line out and mic 1 pin widgets to outputs
11581 */
11582static struct hda_verb alc861_threestack_ch6_init[] = {
11583	/* set pin widget 1Ah (line in) for output (Back Surround)*/
11584	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11585	/* set pin widget 18h (mic1) for output (CLFE)*/
11586	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11587
11588	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11589	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11590
11591	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11592#if 0
11593	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11594	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11595#endif
11596	{ } /* end */
11597};
11598
11599static struct hda_channel_mode alc861_threestack_modes[2] = {
11600	{ 2, alc861_threestack_ch2_init },
11601	{ 6, alc861_threestack_ch6_init },
11602};
11603/* Set mic1 as input and unmute the mixer */
11604static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
11605	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11606	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11607	{ } /* end */
11608};
11609/* Set mic1 as output and mute mixer */
11610static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
11611	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11612	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11613	{ } /* end */
11614};
11615
11616static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
11617	{ 2, alc861_uniwill_m31_ch2_init },
11618	{ 4, alc861_uniwill_m31_ch4_init },
11619};
11620
11621/* Set mic1 and line-in as input and unmute the mixer */
11622static struct hda_verb alc861_asus_ch2_init[] = {
11623	/* set pin widget 1Ah (line in) for input */
11624	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11625	/* set pin widget 18h (mic1/2) for input, for mic also enable
11626	 * the vref
11627	 */
11628	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11629
11630	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11631#if 0
11632	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11633	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11634#endif
11635	{ } /* end */
11636};
11637/* Set mic1 nad line-in as output and mute mixer */
11638static struct hda_verb alc861_asus_ch6_init[] = {
11639	/* set pin widget 1Ah (line in) for output (Back Surround)*/
11640	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11641	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11642	/* set pin widget 18h (mic1) for output (CLFE)*/
11643	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11644	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11645	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11646	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11647
11648	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11649#if 0
11650	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11651	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11652#endif
11653	{ } /* end */
11654};
11655
11656static struct hda_channel_mode alc861_asus_modes[2] = {
11657	{ 2, alc861_asus_ch2_init },
11658	{ 6, alc861_asus_ch6_init },
11659};
11660
11661/* patch-ALC861 */
11662
11663static struct snd_kcontrol_new alc861_base_mixer[] = {
11664        /* output mixer control */
11665	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11666	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11667	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11668	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11669	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11670
11671        /*Input mixer control */
11672	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11673	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11674	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11675	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11676	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11677	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11678	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11679	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11680	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11681	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11682
11683        /* Capture mixer control */
11684	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11685	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11686	{
11687		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11688		.name = "Capture Source",
11689		.count = 1,
11690		.info = alc_mux_enum_info,
11691		.get = alc_mux_enum_get,
11692		.put = alc_mux_enum_put,
11693	},
11694	{ } /* end */
11695};
11696
11697static struct snd_kcontrol_new alc861_3ST_mixer[] = {
11698        /* output mixer control */
11699	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11700	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11701	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11702	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11703	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11704
11705	/* Input mixer control */
11706	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11707	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11708	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11709	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11710	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11711	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11712	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11713	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11714	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11715	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11716
11717	/* Capture mixer control */
11718	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11719	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11720	{
11721		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11722		.name = "Capture Source",
11723		.count = 1,
11724		.info = alc_mux_enum_info,
11725		.get = alc_mux_enum_get,
11726		.put = alc_mux_enum_put,
11727	},
11728	{
11729		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11730		.name = "Channel Mode",
11731		.info = alc_ch_mode_info,
11732		.get = alc_ch_mode_get,
11733		.put = alc_ch_mode_put,
11734                .private_value = ARRAY_SIZE(alc861_threestack_modes),
11735	},
11736	{ } /* end */
11737};
11738
11739static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
11740        /* output mixer control */
11741	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11742	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11743	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11744
11745        /*Capture mixer control */
11746	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11747	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11748	{
11749		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11750		.name = "Capture Source",
11751		.count = 1,
11752		.info = alc_mux_enum_info,
11753		.get = alc_mux_enum_get,
11754		.put = alc_mux_enum_put,
11755	},
11756
11757	{ } /* end */
11758};
11759
11760static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
11761        /* output mixer control */
11762	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11763	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11764	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11765	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11766	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11767
11768	/* Input mixer control */
11769	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11770	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11771	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11772	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11773	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11774	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11775	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11776	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11777	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11778	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11779
11780	/* Capture mixer control */
11781	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11782	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11783	{
11784		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11785		.name = "Capture Source",
11786		.count = 1,
11787		.info = alc_mux_enum_info,
11788		.get = alc_mux_enum_get,
11789		.put = alc_mux_enum_put,
11790	},
11791	{
11792		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11793		.name = "Channel Mode",
11794		.info = alc_ch_mode_info,
11795		.get = alc_ch_mode_get,
11796		.put = alc_ch_mode_put,
11797                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
11798	},
11799	{ } /* end */
11800};
11801
11802static struct snd_kcontrol_new alc861_asus_mixer[] = {
11803        /* output mixer control */
11804	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11805	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11806	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11807	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11808	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11809
11810	/* Input mixer control */
11811	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11812	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11813	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11814	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11815	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11816	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11817	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11818	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11819	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11820	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
11821
11822	/* Capture mixer control */
11823	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11824	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11825	{
11826		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11827		.name = "Capture Source",
11828		.count = 1,
11829		.info = alc_mux_enum_info,
11830		.get = alc_mux_enum_get,
11831		.put = alc_mux_enum_put,
11832	},
11833	{
11834		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11835		.name = "Channel Mode",
11836		.info = alc_ch_mode_info,
11837		.get = alc_ch_mode_get,
11838		.put = alc_ch_mode_put,
11839                .private_value = ARRAY_SIZE(alc861_asus_modes),
11840	},
11841	{ }
11842};
11843
11844/* additional mixer */
11845static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
11846	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11847	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11848	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
11849	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
11850	{ }
11851};
11852
11853/*
11854 * generic initialization of ADC, input mixers and output mixers
11855 */
11856static struct hda_verb alc861_base_init_verbs[] = {
11857	/*
11858	 * Unmute ADC0 and set the default input to mic-in
11859	 */
11860	/* port-A for surround (rear panel) */
11861	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11862	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
11863	/* port-B for mic-in (rear panel) with vref */
11864	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11865	/* port-C for line-in (rear panel) */
11866	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11867	/* port-D for Front */
11868	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11869	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11870	/* port-E for HP out (front panel) */
11871	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11872	/* route front PCM to HP */
11873	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11874	/* port-F for mic-in (front panel) with vref */
11875	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11876	/* port-G for CLFE (rear panel) */
11877	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11878	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11879	/* port-H for side (rear panel) */
11880	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11881	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
11882	/* CD-in */
11883	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11884	/* route front mic to ADC1*/
11885	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11886	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11887
11888	/* Unmute DAC0~3 & spdif out*/
11889	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11890	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11891	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11892	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11893	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11894
11895	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11896	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11897        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11898	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11899        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11900
11901	/* Unmute Stereo Mixer 15 */
11902	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11903	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11904	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11905	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11906
11907	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11908	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11909	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11910	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11911	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11912	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11913	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11914	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11915	/* hp used DAC 3 (Front) */
11916	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11917        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11918
11919	{ }
11920};
11921
11922static struct hda_verb alc861_threestack_init_verbs[] = {
11923	/*
11924	 * Unmute ADC0 and set the default input to mic-in
11925	 */
11926	/* port-A for surround (rear panel) */
11927	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11928	/* port-B for mic-in (rear panel) with vref */
11929	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11930	/* port-C for line-in (rear panel) */
11931	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11932	/* port-D for Front */
11933	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11934	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11935	/* port-E for HP out (front panel) */
11936	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11937	/* route front PCM to HP */
11938	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11939	/* port-F for mic-in (front panel) with vref */
11940	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11941	/* port-G for CLFE (rear panel) */
11942	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11943	/* port-H for side (rear panel) */
11944	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11945	/* CD-in */
11946	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11947	/* route front mic to ADC1*/
11948	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11949	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11950	/* Unmute DAC0~3 & spdif out*/
11951	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11952	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11953	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11954	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11955	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11956
11957	/* Unmute Mixer 14 (mic) 1c (Line in)*/
11958	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11959        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11960	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11961        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11962
11963	/* Unmute Stereo Mixer 15 */
11964	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11965	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11966	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11967	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11968
11969	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11970	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11971	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11973	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11974	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11975	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11976	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11977	/* hp used DAC 3 (Front) */
11978	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11979        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11980	{ }
11981};
11982
11983static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11984	/*
11985	 * Unmute ADC0 and set the default input to mic-in
11986	 */
11987	/* port-A for surround (rear panel) */
11988	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11989	/* port-B for mic-in (rear panel) with vref */
11990	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11991	/* port-C for line-in (rear panel) */
11992	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11993	/* port-D for Front */
11994	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11995	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11996	/* port-E for HP out (front panel) */
11997	/* this has to be set to VREF80 */
11998	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11999	/* route front PCM to HP */
12000	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12001	/* port-F for mic-in (front panel) with vref */
12002	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12003	/* port-G for CLFE (rear panel) */
12004	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12005	/* port-H for side (rear panel) */
12006	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12007	/* CD-in */
12008	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12009	/* route front mic to ADC1*/
12010	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12011	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12012	/* Unmute DAC0~3 & spdif out*/
12013	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12014	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12015	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12016	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12017	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12018
12019	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12020	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12021        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12022	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12023        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12024
12025	/* Unmute Stereo Mixer 15 */
12026	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12027	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12028	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12029	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12030
12031	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12032	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12033	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12034	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12035	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12036	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12037	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12038	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12039	/* hp used DAC 3 (Front) */
12040	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12041        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12042	{ }
12043};
12044
12045static struct hda_verb alc861_asus_init_verbs[] = {
12046	/*
12047	 * Unmute ADC0 and set the default input to mic-in
12048	 */
12049	/* port-A for surround (rear panel)
12050	 * according to codec#0 this is the HP jack
12051	 */
12052	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12053	/* route front PCM to HP */
12054	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12055	/* port-B for mic-in (rear panel) with vref */
12056	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12057	/* port-C for line-in (rear panel) */
12058	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12059	/* port-D for Front */
12060	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12061	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12062	/* port-E for HP out (front panel) */
12063	/* this has to be set to VREF80 */
12064	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12065	/* route front PCM to HP */
12066	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12067	/* port-F for mic-in (front panel) with vref */
12068	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12069	/* port-G for CLFE (rear panel) */
12070	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12071	/* port-H for side (rear panel) */
12072	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12073	/* CD-in */
12074	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12075	/* route front mic to ADC1*/
12076	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12077	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078	/* Unmute DAC0~3 & spdif out*/
12079	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12080	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12081	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12082	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12083	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12084	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12085	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12086        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12087	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12088        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12089
12090	/* Unmute Stereo Mixer 15 */
12091	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12092	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12093	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12094	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12095
12096	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12098	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12099	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12100	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12101	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12102	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12103	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12104	/* hp used DAC 3 (Front) */
12105	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12106	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12107	{ }
12108};
12109
12110/* additional init verbs for ASUS laptops */
12111static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12112	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12113	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12114	{ }
12115};
12116
12117/*
12118 * generic initialization of ADC, input mixers and output mixers
12119 */
12120static struct hda_verb alc861_auto_init_verbs[] = {
12121	/*
12122	 * Unmute ADC0 and set the default input to mic-in
12123	 */
12124	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12125	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12126
12127	/* Unmute DAC0~3 & spdif out*/
12128	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12129	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12130	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12131	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12132	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12133
12134	/* Unmute Mixer 14 (mic) 1c (Line in)*/
12135	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12136	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12137	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12138	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12139
12140	/* Unmute Stereo Mixer 15 */
12141	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12142	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12143	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12144	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12145
12146	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12147	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12148	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12149	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12150	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12151	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12152	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12153	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12154
12155	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12156	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12157	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12158	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12159	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12160	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12161	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12162	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12163
12164	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
12165
12166	{ }
12167};
12168
12169static struct hda_verb alc861_toshiba_init_verbs[] = {
12170	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12171
12172	{ }
12173};
12174
12175/* toggle speaker-output according to the hp-jack state */
12176static void alc861_toshiba_automute(struct hda_codec *codec)
12177{
12178	unsigned int present;
12179
12180	present = snd_hda_codec_read(codec, 0x0f, 0,
12181				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12182	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12183				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12184	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12185				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12186}
12187
12188static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12189				       unsigned int res)
12190{
12191	if ((res >> 26) == ALC880_HP_EVENT)
12192		alc861_toshiba_automute(codec);
12193}
12194
12195/* pcm configuration: identiacal with ALC880 */
12196#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
12197#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
12198#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
12199#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
12200
12201
12202#define ALC861_DIGOUT_NID	0x07
12203
12204static struct hda_channel_mode alc861_8ch_modes[1] = {
12205	{ 8, NULL }
12206};
12207
12208static hda_nid_t alc861_dac_nids[4] = {
12209	/* front, surround, clfe, side */
12210	0x03, 0x06, 0x05, 0x04
12211};
12212
12213static hda_nid_t alc660_dac_nids[3] = {
12214	/* front, clfe, surround */
12215	0x03, 0x05, 0x06
12216};
12217
12218static hda_nid_t alc861_adc_nids[1] = {
12219	/* ADC0-2 */
12220	0x08,
12221};
12222
12223static struct hda_input_mux alc861_capture_source = {
12224	.num_items = 5,
12225	.items = {
12226		{ "Mic", 0x0 },
12227		{ "Front Mic", 0x3 },
12228		{ "Line", 0x1 },
12229		{ "CD", 0x4 },
12230		{ "Mixer", 0x5 },
12231	},
12232};
12233
12234/* fill in the dac_nids table from the parsed pin configuration */
12235static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12236				     const struct auto_pin_cfg *cfg)
12237{
12238	int i;
12239	hda_nid_t nid;
12240
12241	spec->multiout.dac_nids = spec->private_dac_nids;
12242	for (i = 0; i < cfg->line_outs; i++) {
12243		nid = cfg->line_out_pins[i];
12244		if (nid) {
12245			if (i >= ARRAY_SIZE(alc861_dac_nids))
12246				continue;
12247			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12248		}
12249	}
12250	spec->multiout.num_dacs = cfg->line_outs;
12251	return 0;
12252}
12253
12254/* add playback controls from the parsed DAC table */
12255static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12256					     const struct auto_pin_cfg *cfg)
12257{
12258	char name[32];
12259	static const char *chname[4] = {
12260		"Front", "Surround", NULL /*CLFE*/, "Side"
12261	};
12262	hda_nid_t nid;
12263	int i, idx, err;
12264
12265	for (i = 0; i < cfg->line_outs; i++) {
12266		nid = spec->multiout.dac_nids[i];
12267		if (!nid)
12268			continue;
12269		if (nid == 0x05) {
12270			/* Center/LFE */
12271			err = add_control(spec, ALC_CTL_BIND_MUTE,
12272					  "Center Playback Switch",
12273					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12274							      HDA_OUTPUT));
12275			if (err < 0)
12276				return err;
12277			err = add_control(spec, ALC_CTL_BIND_MUTE,
12278					  "LFE Playback Switch",
12279					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12280							      HDA_OUTPUT));
12281			if (err < 0)
12282				return err;
12283		} else {
12284			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
12285			     idx++)
12286				if (nid == alc861_dac_nids[idx])
12287					break;
12288			sprintf(name, "%s Playback Switch", chname[idx]);
12289			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12290					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12291							      HDA_OUTPUT));
12292			if (err < 0)
12293				return err;
12294		}
12295	}
12296	return 0;
12297}
12298
12299static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
12300{
12301	int err;
12302	hda_nid_t nid;
12303
12304	if (!pin)
12305		return 0;
12306
12307	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
12308		nid = 0x03;
12309		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12310				  "Headphone Playback Switch",
12311				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12312		if (err < 0)
12313			return err;
12314		spec->multiout.hp_nid = nid;
12315	}
12316	return 0;
12317}
12318
12319/* create playback/capture controls for input pins */
12320static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
12321						const struct auto_pin_cfg *cfg)
12322{
12323	struct hda_input_mux *imux = &spec->private_imux;
12324	int i, err, idx, idx1;
12325
12326	for (i = 0; i < AUTO_PIN_LAST; i++) {
12327		switch (cfg->input_pins[i]) {
12328		case 0x0c:
12329			idx1 = 1;
12330			idx = 2;	/* Line In */
12331			break;
12332		case 0x0f:
12333			idx1 = 2;
12334			idx = 2;	/* Line In */
12335			break;
12336		case 0x0d:
12337			idx1 = 0;
12338			idx = 1;	/* Mic In */
12339			break;
12340		case 0x10:
12341			idx1 = 3;
12342			idx = 1;	/* Mic In */
12343			break;
12344		case 0x11:
12345			idx1 = 4;
12346			idx = 0;	/* CD */
12347			break;
12348		default:
12349			continue;
12350		}
12351
12352		err = new_analog_input(spec, cfg->input_pins[i],
12353				       auto_pin_cfg_labels[i], idx, 0x15);
12354		if (err < 0)
12355			return err;
12356
12357		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12358		imux->items[imux->num_items].index = idx1;
12359		imux->num_items++;
12360	}
12361	return 0;
12362}
12363
12364static struct snd_kcontrol_new alc861_capture_mixer[] = {
12365	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12366	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12367
12368	{
12369		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12370		/* The multiple "Capture Source" controls confuse alsamixer
12371		 * So call somewhat different..
12372		 */
12373		/* .name = "Capture Source", */
12374		.name = "Input Source",
12375		.count = 1,
12376		.info = alc_mux_enum_info,
12377		.get = alc_mux_enum_get,
12378		.put = alc_mux_enum_put,
12379	},
12380	{ } /* end */
12381};
12382
12383static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
12384					      hda_nid_t nid,
12385					      int pin_type, int dac_idx)
12386{
12387	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
12388			    pin_type);
12389	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12390			    AMP_OUT_UNMUTE);
12391}
12392
12393static void alc861_auto_init_multi_out(struct hda_codec *codec)
12394{
12395	struct alc_spec *spec = codec->spec;
12396	int i;
12397
12398	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
12399	for (i = 0; i < spec->autocfg.line_outs; i++) {
12400		hda_nid_t nid = spec->autocfg.line_out_pins[i];
12401		int pin_type = get_pin_type(spec->autocfg.line_out_type);
12402		if (nid)
12403			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
12404							  spec->multiout.dac_nids[i]);
12405	}
12406}
12407
12408static void alc861_auto_init_hp_out(struct hda_codec *codec)
12409{
12410	struct alc_spec *spec = codec->spec;
12411	hda_nid_t pin;
12412
12413	pin = spec->autocfg.hp_pins[0];
12414	if (pin) /* connect to front */
12415		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
12416						  spec->multiout.dac_nids[0]);
12417	pin = spec->autocfg.speaker_pins[0];
12418	if (pin)
12419		alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
12420}
12421
12422static void alc861_auto_init_analog_input(struct hda_codec *codec)
12423{
12424	struct alc_spec *spec = codec->spec;
12425	int i;
12426
12427	for (i = 0; i < AUTO_PIN_LAST; i++) {
12428		hda_nid_t nid = spec->autocfg.input_pins[i];
12429		if (nid >= 0x0c && nid <= 0x11) {
12430			snd_hda_codec_write(codec, nid, 0,
12431					    AC_VERB_SET_PIN_WIDGET_CONTROL,
12432					    i <= AUTO_PIN_FRONT_MIC ?
12433					    PIN_VREF80 : PIN_IN);
12434		}
12435	}
12436}
12437
12438/* parse the BIOS configuration and set up the alc_spec */
12439/* return 1 if successful, 0 if the proper config is not found,
12440 * or a negative error code
12441 */
12442static int alc861_parse_auto_config(struct hda_codec *codec)
12443{
12444	struct alc_spec *spec = codec->spec;
12445	int err;
12446	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
12447
12448	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12449					   alc861_ignore);
12450	if (err < 0)
12451		return err;
12452	if (!spec->autocfg.line_outs)
12453		return 0; /* can't find valid BIOS pin config */
12454
12455	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
12456	if (err < 0)
12457		return err;
12458	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
12459	if (err < 0)
12460		return err;
12461	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
12462	if (err < 0)
12463		return err;
12464	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
12465	if (err < 0)
12466		return err;
12467
12468	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12469
12470	if (spec->autocfg.dig_out_pin)
12471		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
12472
12473	if (spec->kctl_alloc)
12474		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12475
12476	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
12477
12478	spec->num_mux_defs = 1;
12479	spec->input_mux = &spec->private_imux;
12480
12481	spec->adc_nids = alc861_adc_nids;
12482	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
12483	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
12484	spec->num_mixers++;
12485
12486	return 1;
12487}
12488
12489/* additional initialization for auto-configuration model */
12490static void alc861_auto_init(struct hda_codec *codec)
12491{
12492	struct alc_spec *spec = codec->spec;
12493	alc861_auto_init_multi_out(codec);
12494	alc861_auto_init_hp_out(codec);
12495	alc861_auto_init_analog_input(codec);
12496	if (spec->unsol_event)
12497		alc_sku_automute(codec);
12498}
12499
12500#ifdef CONFIG_SND_HDA_POWER_SAVE
12501static struct hda_amp_list alc861_loopbacks[] = {
12502	{ 0x15, HDA_INPUT, 0 },
12503	{ 0x15, HDA_INPUT, 1 },
12504	{ 0x15, HDA_INPUT, 2 },
12505	{ 0x15, HDA_INPUT, 3 },
12506	{ } /* end */
12507};
12508#endif
12509
12510
12511/*
12512 * configuration and preset
12513 */
12514static const char *alc861_models[ALC861_MODEL_LAST] = {
12515	[ALC861_3ST]		= "3stack",
12516	[ALC660_3ST]		= "3stack-660",
12517	[ALC861_3ST_DIG]	= "3stack-dig",
12518	[ALC861_6ST_DIG]	= "6stack-dig",
12519	[ALC861_UNIWILL_M31]	= "uniwill-m31",
12520	[ALC861_TOSHIBA]	= "toshiba",
12521	[ALC861_ASUS]		= "asus",
12522	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
12523	[ALC861_AUTO]		= "auto",
12524};
12525
12526static struct snd_pci_quirk alc861_cfg_tbl[] = {
12527	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
12528	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12529	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12530	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
12531	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
12532	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
12533	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
12534	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
12535	 *        Any other models that need this preset?
12536	 */
12537	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
12538	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
12539	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
12540	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
12541	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
12542	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
12543	/* FIXME: the below seems conflict */
12544	/* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
12545	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
12546	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
12547	{}
12548};
12549
12550static struct alc_config_preset alc861_presets[] = {
12551	[ALC861_3ST] = {
12552		.mixers = { alc861_3ST_mixer },
12553		.init_verbs = { alc861_threestack_init_verbs },
12554		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12555		.dac_nids = alc861_dac_nids,
12556		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12557		.channel_mode = alc861_threestack_modes,
12558		.need_dac_fix = 1,
12559		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12560		.adc_nids = alc861_adc_nids,
12561		.input_mux = &alc861_capture_source,
12562	},
12563	[ALC861_3ST_DIG] = {
12564		.mixers = { alc861_base_mixer },
12565		.init_verbs = { alc861_threestack_init_verbs },
12566		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12567		.dac_nids = alc861_dac_nids,
12568		.dig_out_nid = ALC861_DIGOUT_NID,
12569		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12570		.channel_mode = alc861_threestack_modes,
12571		.need_dac_fix = 1,
12572		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12573		.adc_nids = alc861_adc_nids,
12574		.input_mux = &alc861_capture_source,
12575	},
12576	[ALC861_6ST_DIG] = {
12577		.mixers = { alc861_base_mixer },
12578		.init_verbs = { alc861_base_init_verbs },
12579		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12580		.dac_nids = alc861_dac_nids,
12581		.dig_out_nid = ALC861_DIGOUT_NID,
12582		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
12583		.channel_mode = alc861_8ch_modes,
12584		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12585		.adc_nids = alc861_adc_nids,
12586		.input_mux = &alc861_capture_source,
12587	},
12588	[ALC660_3ST] = {
12589		.mixers = { alc861_3ST_mixer },
12590		.init_verbs = { alc861_threestack_init_verbs },
12591		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
12592		.dac_nids = alc660_dac_nids,
12593		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12594		.channel_mode = alc861_threestack_modes,
12595		.need_dac_fix = 1,
12596		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12597		.adc_nids = alc861_adc_nids,
12598		.input_mux = &alc861_capture_source,
12599	},
12600	[ALC861_UNIWILL_M31] = {
12601		.mixers = { alc861_uniwill_m31_mixer },
12602		.init_verbs = { alc861_uniwill_m31_init_verbs },
12603		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12604		.dac_nids = alc861_dac_nids,
12605		.dig_out_nid = ALC861_DIGOUT_NID,
12606		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
12607		.channel_mode = alc861_uniwill_m31_modes,
12608		.need_dac_fix = 1,
12609		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12610		.adc_nids = alc861_adc_nids,
12611		.input_mux = &alc861_capture_source,
12612	},
12613	[ALC861_TOSHIBA] = {
12614		.mixers = { alc861_toshiba_mixer },
12615		.init_verbs = { alc861_base_init_verbs,
12616				alc861_toshiba_init_verbs },
12617		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12618		.dac_nids = alc861_dac_nids,
12619		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12620		.channel_mode = alc883_3ST_2ch_modes,
12621		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12622		.adc_nids = alc861_adc_nids,
12623		.input_mux = &alc861_capture_source,
12624		.unsol_event = alc861_toshiba_unsol_event,
12625		.init_hook = alc861_toshiba_automute,
12626	},
12627	[ALC861_ASUS] = {
12628		.mixers = { alc861_asus_mixer },
12629		.init_verbs = { alc861_asus_init_verbs },
12630		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12631		.dac_nids = alc861_dac_nids,
12632		.dig_out_nid = ALC861_DIGOUT_NID,
12633		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
12634		.channel_mode = alc861_asus_modes,
12635		.need_dac_fix = 1,
12636		.hp_nid = 0x06,
12637		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12638		.adc_nids = alc861_adc_nids,
12639		.input_mux = &alc861_capture_source,
12640	},
12641	[ALC861_ASUS_LAPTOP] = {
12642		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
12643		.init_verbs = { alc861_asus_init_verbs,
12644				alc861_asus_laptop_init_verbs },
12645		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
12646		.dac_nids = alc861_dac_nids,
12647		.dig_out_nid = ALC861_DIGOUT_NID,
12648		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12649		.channel_mode = alc883_3ST_2ch_modes,
12650		.need_dac_fix = 1,
12651		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12652		.adc_nids = alc861_adc_nids,
12653		.input_mux = &alc861_capture_source,
12654	},
12655};
12656
12657
12658static int patch_alc861(struct hda_codec *codec)
12659{
12660	struct alc_spec *spec;
12661	int board_config;
12662	int err;
12663
12664	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12665	if (spec == NULL)
12666		return -ENOMEM;
12667
12668	codec->spec = spec;
12669
12670        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
12671						  alc861_models,
12672						  alc861_cfg_tbl);
12673
12674	if (board_config < 0) {
12675		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
12676		       "trying auto-probe from BIOS...\n");
12677		board_config = ALC861_AUTO;
12678	}
12679
12680	if (board_config == ALC861_AUTO) {
12681		/* automatic parse from the BIOS config */
12682		err = alc861_parse_auto_config(codec);
12683		if (err < 0) {
12684			alc_free(codec);
12685			return err;
12686		} else if (!err) {
12687			printk(KERN_INFO
12688			       "hda_codec: Cannot set up configuration "
12689			       "from BIOS.  Using base mode...\n");
12690		   board_config = ALC861_3ST_DIG;
12691		}
12692	}
12693
12694	if (board_config != ALC861_AUTO)
12695		setup_preset(spec, &alc861_presets[board_config]);
12696
12697	spec->stream_name_analog = "ALC861 Analog";
12698	spec->stream_analog_playback = &alc861_pcm_analog_playback;
12699	spec->stream_analog_capture = &alc861_pcm_analog_capture;
12700
12701	spec->stream_name_digital = "ALC861 Digital";
12702	spec->stream_digital_playback = &alc861_pcm_digital_playback;
12703	spec->stream_digital_capture = &alc861_pcm_digital_capture;
12704
12705	spec->vmaster_nid = 0x03;
12706
12707	codec->patch_ops = alc_patch_ops;
12708	if (board_config == ALC861_AUTO)
12709		spec->init_hook = alc861_auto_init;
12710#ifdef CONFIG_SND_HDA_POWER_SAVE
12711	if (!spec->loopback.amplist)
12712		spec->loopback.amplist = alc861_loopbacks;
12713#endif
12714
12715	return 0;
12716}
12717
12718/*
12719 * ALC861-VD support
12720 *
12721 * Based on ALC882
12722 *
12723 * In addition, an independent DAC
12724 */
12725#define ALC861VD_DIGOUT_NID	0x06
12726
12727static hda_nid_t alc861vd_dac_nids[4] = {
12728	/* front, surr, clfe, side surr */
12729	0x02, 0x03, 0x04, 0x05
12730};
12731
12732/* dac_nids for ALC660vd are in a different order - according to
12733 * Realtek's driver.
12734 * This should probably tesult in a different mixer for 6stack models
12735 * of ALC660vd codecs, but for now there is only 3stack mixer
12736 * - and it is the same as in 861vd.
12737 * adc_nids in ALC660vd are (is) the same as in 861vd
12738 */
12739static hda_nid_t alc660vd_dac_nids[3] = {
12740	/* front, rear, clfe, rear_surr */
12741	0x02, 0x04, 0x03
12742};
12743
12744static hda_nid_t alc861vd_adc_nids[1] = {
12745	/* ADC0 */
12746	0x09,
12747};
12748
12749static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
12750
12751/* input MUX */
12752/* FIXME: should be a matrix-type input source selection */
12753static struct hda_input_mux alc861vd_capture_source = {
12754	.num_items = 4,
12755	.items = {
12756		{ "Mic", 0x0 },
12757		{ "Front Mic", 0x1 },
12758		{ "Line", 0x2 },
12759		{ "CD", 0x4 },
12760	},
12761};
12762
12763static struct hda_input_mux alc861vd_dallas_capture_source = {
12764	.num_items = 2,
12765	.items = {
12766		{ "Ext Mic", 0x0 },
12767		{ "Int Mic", 0x1 },
12768	},
12769};
12770
12771static struct hda_input_mux alc861vd_hp_capture_source = {
12772	.num_items = 2,
12773	.items = {
12774		{ "Front Mic", 0x0 },
12775		{ "ATAPI Mic", 0x1 },
12776	},
12777};
12778
12779#define alc861vd_mux_enum_info alc_mux_enum_info
12780#define alc861vd_mux_enum_get alc_mux_enum_get
12781/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
12782#define alc861vd_mux_enum_put alc882_mux_enum_put
12783
12784/*
12785 * 2ch mode
12786 */
12787static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
12788	{ 2, NULL }
12789};
12790
12791/*
12792 * 6ch mode
12793 */
12794static struct hda_verb alc861vd_6stack_ch6_init[] = {
12795	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12796	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12797	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12798	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12799	{ } /* end */
12800};
12801
12802/*
12803 * 8ch mode
12804 */
12805static struct hda_verb alc861vd_6stack_ch8_init[] = {
12806	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12807	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12808	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12809	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12810	{ } /* end */
12811};
12812
12813static struct hda_channel_mode alc861vd_6stack_modes[2] = {
12814	{ 6, alc861vd_6stack_ch6_init },
12815	{ 8, alc861vd_6stack_ch8_init },
12816};
12817
12818static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
12819	{
12820		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12821		.name = "Channel Mode",
12822		.info = alc_ch_mode_info,
12823		.get = alc_ch_mode_get,
12824		.put = alc_ch_mode_put,
12825	},
12826	{ } /* end */
12827};
12828
12829static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
12830	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12831	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12832
12833	{
12834		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12835		/* The multiple "Capture Source" controls confuse alsamixer
12836		 * So call somewhat different..
12837		 */
12838		/* .name = "Capture Source", */
12839		.name = "Input Source",
12840		.count = 1,
12841		.info = alc861vd_mux_enum_info,
12842		.get = alc861vd_mux_enum_get,
12843		.put = alc861vd_mux_enum_put,
12844	},
12845	{ } /* end */
12846};
12847
12848/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12849 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12850 */
12851static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
12852	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12853	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12854
12855	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12856	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
12857
12858	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
12859				HDA_OUTPUT),
12860	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
12861				HDA_OUTPUT),
12862	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12863	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
12864
12865	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
12866	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
12867
12868	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12869
12870	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12871	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12872	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12873
12874	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12875	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12876	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12877
12878	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12879	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12880
12881	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12882	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12883
12884	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12885	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12886
12887	{ } /* end */
12888};
12889
12890static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12891	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12892	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12893
12894	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12895
12896	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12897	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12898	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12899
12900	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12901	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12902	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12903
12904	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12905	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12906
12907	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12908	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12909
12910	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12911	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12912
12913	{ } /* end */
12914};
12915
12916static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12917	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12918	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12919	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12920
12921	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12922
12923	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12924	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12925	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12926
12927	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12928	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12929	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12930
12931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12932	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12933
12934	{ } /* end */
12935};
12936
12937/* Pin assignment: Speaker=0x14, HP = 0x15,
12938 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
12939 */
12940static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12941	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12942	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
12943	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12944	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12945	HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12946	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12947	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12948	HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12949	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12950	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12951	HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
12952	HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
12953	{ } /* end */
12954};
12955
12956/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12957 *                 Front Mic=0x18, ATAPI Mic = 0x19,
12958 */
12959static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12960	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12961	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12962	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12963	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12964	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12965	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12966	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12967	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12968
12969	{ } /* end */
12970};
12971
12972/*
12973 * generic initialization of ADC, input mixers and output mixers
12974 */
12975static struct hda_verb alc861vd_volume_init_verbs[] = {
12976	/*
12977	 * Unmute ADC0 and set the default input to mic-in
12978	 */
12979	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12980	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12981
12982	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12983	 * the analog-loopback mixer widget
12984	 */
12985	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12986	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12987	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12988	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12989	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12990	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12991
12992	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
12993	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12994	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12995	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12996	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12997
12998	/*
12999	 * Set up output mixers (0x02 - 0x05)
13000	 */
13001	/* set vol=0 to output mixers */
13002	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13003	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13004	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13005	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13006
13007	/* set up input amps for analog loopback */
13008	/* Amp Indices: DAC = 0, mixer = 1 */
13009	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13010	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13011	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13012	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13013	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13014	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13015	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13016	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13017
13018	{ }
13019};
13020
13021/*
13022 * 3-stack pin configuration:
13023 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13024 */
13025static struct hda_verb alc861vd_3stack_init_verbs[] = {
13026	/*
13027	 * Set pin mode and muting
13028	 */
13029	/* set front pin widgets 0x14 for output */
13030	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13031	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13032	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13033
13034	/* Mic (rear) pin: input vref at 80% */
13035	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13036	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13037	/* Front Mic pin: input vref at 80% */
13038	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13039	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13040	/* Line In pin: input */
13041	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13042	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13043	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13044	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13045	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13046	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13047	/* CD pin widget for input */
13048	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13049
13050	{ }
13051};
13052
13053/*
13054 * 6-stack pin configuration:
13055 */
13056static struct hda_verb alc861vd_6stack_init_verbs[] = {
13057	/*
13058	 * Set pin mode and muting
13059	 */
13060	/* set front pin widgets 0x14 for output */
13061	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13062	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13063	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13064
13065	/* Rear Pin: output 1 (0x0d) */
13066	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13067	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13068	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13069	/* CLFE Pin: output 2 (0x0e) */
13070	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13071	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13072	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13073	/* Side Pin: output 3 (0x0f) */
13074	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13075	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13076	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13077
13078	/* Mic (rear) pin: input vref at 80% */
13079	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13080	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13081	/* Front Mic pin: input vref at 80% */
13082	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13083	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13084	/* Line In pin: input */
13085	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13086	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13087	/* Line-2 In: Headphone output (output 0 - 0x0c) */
13088	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13089	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13090	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13091	/* CD pin widget for input */
13092	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13093
13094	{ }
13095};
13096
13097static struct hda_verb alc861vd_eapd_verbs[] = {
13098	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13099	{ }
13100};
13101
13102static struct hda_verb alc660vd_eapd_verbs[] = {
13103	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13104	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13105	{ }
13106};
13107
13108static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13109	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13110	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13111	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13112	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13113	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13114	{}
13115};
13116
13117/* toggle speaker-output according to the hp-jack state */
13118static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13119{
13120	unsigned int present;
13121	unsigned char bits;
13122
13123	present = snd_hda_codec_read(codec, 0x1b, 0,
13124				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13125	bits = present ? HDA_AMP_MUTE : 0;
13126	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13127				 HDA_AMP_MUTE, bits);
13128}
13129
13130static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13131{
13132	unsigned int present;
13133	unsigned char bits;
13134
13135	present = snd_hda_codec_read(codec, 0x18, 0,
13136				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13137	bits = present ? HDA_AMP_MUTE : 0;
13138	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13139				 HDA_AMP_MUTE, bits);
13140}
13141
13142static void alc861vd_lenovo_automute(struct hda_codec *codec)
13143{
13144	alc861vd_lenovo_hp_automute(codec);
13145	alc861vd_lenovo_mic_automute(codec);
13146}
13147
13148static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13149					unsigned int res)
13150{
13151	switch (res >> 26) {
13152	case ALC880_HP_EVENT:
13153		alc861vd_lenovo_hp_automute(codec);
13154		break;
13155	case ALC880_MIC_EVENT:
13156		alc861vd_lenovo_mic_automute(codec);
13157		break;
13158	}
13159}
13160
13161static struct hda_verb alc861vd_dallas_verbs[] = {
13162	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13163	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13164	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13165	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13166
13167	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13168	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13169	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13170	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13171	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13172	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13173	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13174	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13175
13176	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13177	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13178	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13179	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13180	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13181	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13182	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13183	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13184
13185	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13186	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13187	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13188	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13189	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13190	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13191	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13192	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13193
13194	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13195	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13196	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13197	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13198
13199	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13200	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13201	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13202
13203	{ } /* end */
13204};
13205
13206/* toggle speaker-output according to the hp-jack state */
13207static void alc861vd_dallas_automute(struct hda_codec *codec)
13208{
13209	unsigned int present;
13210
13211	present = snd_hda_codec_read(codec, 0x15, 0,
13212				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13213	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13214				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13215}
13216
13217static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13218{
13219	if ((res >> 26) == ALC880_HP_EVENT)
13220		alc861vd_dallas_automute(codec);
13221}
13222
13223#ifdef CONFIG_SND_HDA_POWER_SAVE
13224#define alc861vd_loopbacks	alc880_loopbacks
13225#endif
13226
13227/* pcm configuration: identiacal with ALC880 */
13228#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
13229#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
13230#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
13231#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
13232
13233/*
13234 * configuration and preset
13235 */
13236static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13237	[ALC660VD_3ST]		= "3stack-660",
13238	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
13239	[ALC861VD_3ST]		= "3stack",
13240	[ALC861VD_3ST_DIG]	= "3stack-digout",
13241	[ALC861VD_6ST_DIG]	= "6stack-digout",
13242	[ALC861VD_LENOVO]	= "lenovo",
13243	[ALC861VD_DALLAS]	= "dallas",
13244	[ALC861VD_HP]		= "hp",
13245	[ALC861VD_AUTO]		= "auto",
13246};
13247
13248static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13249	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13250	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13251	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13252	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13253	SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13254	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13255	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13256	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13257	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13258	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13259	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13260	SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13261	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13262	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13263	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13264	SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13265	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13266	{}
13267};
13268
13269static struct alc_config_preset alc861vd_presets[] = {
13270	[ALC660VD_3ST] = {
13271		.mixers = { alc861vd_3st_mixer },
13272		.init_verbs = { alc861vd_volume_init_verbs,
13273				 alc861vd_3stack_init_verbs },
13274		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13275		.dac_nids = alc660vd_dac_nids,
13276		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13277		.channel_mode = alc861vd_3stack_2ch_modes,
13278		.input_mux = &alc861vd_capture_source,
13279	},
13280	[ALC660VD_3ST_DIG] = {
13281		.mixers = { alc861vd_3st_mixer },
13282		.init_verbs = { alc861vd_volume_init_verbs,
13283				 alc861vd_3stack_init_verbs },
13284		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13285		.dac_nids = alc660vd_dac_nids,
13286		.dig_out_nid = ALC861VD_DIGOUT_NID,
13287		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13288		.channel_mode = alc861vd_3stack_2ch_modes,
13289		.input_mux = &alc861vd_capture_source,
13290	},
13291	[ALC861VD_3ST] = {
13292		.mixers = { alc861vd_3st_mixer },
13293		.init_verbs = { alc861vd_volume_init_verbs,
13294				 alc861vd_3stack_init_verbs },
13295		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13296		.dac_nids = alc861vd_dac_nids,
13297		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13298		.channel_mode = alc861vd_3stack_2ch_modes,
13299		.input_mux = &alc861vd_capture_source,
13300	},
13301	[ALC861VD_3ST_DIG] = {
13302		.mixers = { alc861vd_3st_mixer },
13303		.init_verbs = { alc861vd_volume_init_verbs,
13304		 		 alc861vd_3stack_init_verbs },
13305		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13306		.dac_nids = alc861vd_dac_nids,
13307		.dig_out_nid = ALC861VD_DIGOUT_NID,
13308		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13309		.channel_mode = alc861vd_3stack_2ch_modes,
13310		.input_mux = &alc861vd_capture_source,
13311	},
13312	[ALC861VD_6ST_DIG] = {
13313		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
13314		.init_verbs = { alc861vd_volume_init_verbs,
13315				alc861vd_6stack_init_verbs },
13316		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13317		.dac_nids = alc861vd_dac_nids,
13318		.dig_out_nid = ALC861VD_DIGOUT_NID,
13319		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
13320		.channel_mode = alc861vd_6stack_modes,
13321		.input_mux = &alc861vd_capture_source,
13322	},
13323	[ALC861VD_LENOVO] = {
13324		.mixers = { alc861vd_lenovo_mixer },
13325		.init_verbs = { alc861vd_volume_init_verbs,
13326				alc861vd_3stack_init_verbs,
13327				alc861vd_eapd_verbs,
13328				alc861vd_lenovo_unsol_verbs },
13329		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13330		.dac_nids = alc660vd_dac_nids,
13331		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13332		.channel_mode = alc861vd_3stack_2ch_modes,
13333		.input_mux = &alc861vd_capture_source,
13334		.unsol_event = alc861vd_lenovo_unsol_event,
13335		.init_hook = alc861vd_lenovo_automute,
13336	},
13337	[ALC861VD_DALLAS] = {
13338		.mixers = { alc861vd_dallas_mixer },
13339		.init_verbs = { alc861vd_dallas_verbs },
13340		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13341		.dac_nids = alc861vd_dac_nids,
13342		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13343		.channel_mode = alc861vd_3stack_2ch_modes,
13344		.input_mux = &alc861vd_dallas_capture_source,
13345		.unsol_event = alc861vd_dallas_unsol_event,
13346		.init_hook = alc861vd_dallas_automute,
13347	},
13348	[ALC861VD_HP] = {
13349		.mixers = { alc861vd_hp_mixer },
13350		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
13351		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13352		.dac_nids = alc861vd_dac_nids,
13353		.dig_out_nid = ALC861VD_DIGOUT_NID,
13354		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13355		.channel_mode = alc861vd_3stack_2ch_modes,
13356		.input_mux = &alc861vd_hp_capture_source,
13357		.unsol_event = alc861vd_dallas_unsol_event,
13358		.init_hook = alc861vd_dallas_automute,
13359	},
13360};
13361
13362/*
13363 * BIOS auto configuration
13364 */
13365static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
13366				hda_nid_t nid, int pin_type, int dac_idx)
13367{
13368	alc_set_pin_output(codec, nid, pin_type);
13369}
13370
13371static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
13372{
13373	struct alc_spec *spec = codec->spec;
13374	int i;
13375
13376	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13377	for (i = 0; i <= HDA_SIDE; i++) {
13378		hda_nid_t nid = spec->autocfg.line_out_pins[i];
13379		int pin_type = get_pin_type(spec->autocfg.line_out_type);
13380		if (nid)
13381			alc861vd_auto_set_output_and_unmute(codec, nid,
13382							    pin_type, i);
13383	}
13384}
13385
13386
13387static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
13388{
13389	struct alc_spec *spec = codec->spec;
13390	hda_nid_t pin;
13391
13392	pin = spec->autocfg.hp_pins[0];
13393	if (pin) /* connect to front and  use dac 0 */
13394		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13395	pin = spec->autocfg.speaker_pins[0];
13396	if (pin)
13397		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13398}
13399
13400#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
13401#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
13402
13403static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
13404{
13405	struct alc_spec *spec = codec->spec;
13406	int i;
13407
13408	for (i = 0; i < AUTO_PIN_LAST; i++) {
13409		hda_nid_t nid = spec->autocfg.input_pins[i];
13410		if (alc861vd_is_input_pin(nid)) {
13411			snd_hda_codec_write(codec, nid, 0,
13412					AC_VERB_SET_PIN_WIDGET_CONTROL,
13413					i <= AUTO_PIN_FRONT_MIC ?
13414							PIN_VREF80 : PIN_IN);
13415			if (nid != ALC861VD_PIN_CD_NID)
13416				snd_hda_codec_write(codec, nid, 0,
13417						AC_VERB_SET_AMP_GAIN_MUTE,
13418						AMP_OUT_MUTE);
13419		}
13420	}
13421}
13422
13423#define alc861vd_auto_init_input_src	alc882_auto_init_input_src
13424
13425#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
13426#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
13427
13428/* add playback controls from the parsed DAC table */
13429/* Based on ALC880 version. But ALC861VD has separate,
13430 * different NIDs for mute/unmute switch and volume control */
13431static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
13432					     const struct auto_pin_cfg *cfg)
13433{
13434	char name[32];
13435	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
13436	hda_nid_t nid_v, nid_s;
13437	int i, err;
13438
13439	for (i = 0; i < cfg->line_outs; i++) {
13440		if (!spec->multiout.dac_nids[i])
13441			continue;
13442		nid_v = alc861vd_idx_to_mixer_vol(
13443				alc880_dac_to_idx(
13444					spec->multiout.dac_nids[i]));
13445		nid_s = alc861vd_idx_to_mixer_switch(
13446				alc880_dac_to_idx(
13447					spec->multiout.dac_nids[i]));
13448
13449		if (i == 2) {
13450			/* Center/LFE */
13451			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13452					  "Center Playback Volume",
13453					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
13454							      HDA_OUTPUT));
13455			if (err < 0)
13456				return err;
13457			err = add_control(spec, ALC_CTL_WIDGET_VOL,
13458					  "LFE Playback Volume",
13459					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
13460							      HDA_OUTPUT));
13461			if (err < 0)
13462				return err;
13463			err = add_control(spec, ALC_CTL_BIND_MUTE,
13464					  "Center Playback Switch",
13465					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
13466							      HDA_INPUT));
13467			if (err < 0)
13468				return err;
13469			err = add_control(spec, ALC_CTL_BIND_MUTE,
13470					  "LFE Playback Switch",
13471					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
13472							      HDA_INPUT));
13473			if (err < 0)
13474				return err;
13475		} else {
13476			sprintf(name, "%s Playback Volume", chname[i]);
13477			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13478					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
13479							      HDA_OUTPUT));
13480			if (err < 0)
13481				return err;
13482			sprintf(name, "%s Playback Switch", chname[i]);
13483			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13484					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
13485							      HDA_INPUT));
13486			if (err < 0)
13487				return err;
13488		}
13489	}
13490	return 0;
13491}
13492
13493/* add playback controls for speaker and HP outputs */
13494/* Based on ALC880 version. But ALC861VD has separate,
13495 * different NIDs for mute/unmute switch and volume control */
13496static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
13497					hda_nid_t pin, const char *pfx)
13498{
13499	hda_nid_t nid_v, nid_s;
13500	int err;
13501	char name[32];
13502
13503	if (!pin)
13504		return 0;
13505
13506	if (alc880_is_fixed_pin(pin)) {
13507		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13508		/* specify the DAC as the extra output */
13509		if (!spec->multiout.hp_nid)
13510			spec->multiout.hp_nid = nid_v;
13511		else
13512			spec->multiout.extra_out_nid[0] = nid_v;
13513		/* control HP volume/switch on the output mixer amp */
13514		nid_v = alc861vd_idx_to_mixer_vol(
13515				alc880_fixed_pin_idx(pin));
13516		nid_s = alc861vd_idx_to_mixer_switch(
13517				alc880_fixed_pin_idx(pin));
13518
13519		sprintf(name, "%s Playback Volume", pfx);
13520		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13521				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
13522		if (err < 0)
13523			return err;
13524		sprintf(name, "%s Playback Switch", pfx);
13525		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13526				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
13527		if (err < 0)
13528			return err;
13529	} else if (alc880_is_multi_pin(pin)) {
13530		/* set manual connection */
13531		/* we have only a switch on HP-out PIN */
13532		sprintf(name, "%s Playback Switch", pfx);
13533		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13534				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13535		if (err < 0)
13536			return err;
13537	}
13538	return 0;
13539}
13540
13541/* parse the BIOS configuration and set up the alc_spec
13542 * return 1 if successful, 0 if the proper config is not found,
13543 * or a negative error code
13544 * Based on ALC880 version - had to change it to override
13545 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
13546static int alc861vd_parse_auto_config(struct hda_codec *codec)
13547{
13548	struct alc_spec *spec = codec->spec;
13549	int err;
13550	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
13551
13552	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13553					   alc861vd_ignore);
13554	if (err < 0)
13555		return err;
13556	if (!spec->autocfg.line_outs)
13557		return 0; /* can't find valid BIOS pin config */
13558
13559	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13560	if (err < 0)
13561		return err;
13562	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
13563	if (err < 0)
13564		return err;
13565	err = alc861vd_auto_create_extra_out(spec,
13566					     spec->autocfg.speaker_pins[0],
13567					     "Speaker");
13568	if (err < 0)
13569		return err;
13570	err = alc861vd_auto_create_extra_out(spec,
13571					     spec->autocfg.hp_pins[0],
13572					     "Headphone");
13573	if (err < 0)
13574		return err;
13575	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
13576	if (err < 0)
13577		return err;
13578
13579	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13580
13581	if (spec->autocfg.dig_out_pin)
13582		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
13583
13584	if (spec->kctl_alloc)
13585		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13586
13587	spec->init_verbs[spec->num_init_verbs++]
13588		= alc861vd_volume_init_verbs;
13589
13590	spec->num_mux_defs = 1;
13591	spec->input_mux = &spec->private_imux;
13592
13593	err = alc_auto_add_mic_boost(codec);
13594	if (err < 0)
13595		return err;
13596
13597	return 1;
13598}
13599
13600/* additional initialization for auto-configuration model */
13601static void alc861vd_auto_init(struct hda_codec *codec)
13602{
13603	struct alc_spec *spec = codec->spec;
13604	alc861vd_auto_init_multi_out(codec);
13605	alc861vd_auto_init_hp_out(codec);
13606	alc861vd_auto_init_analog_input(codec);
13607	alc861vd_auto_init_input_src(codec);
13608	if (spec->unsol_event)
13609		alc_sku_automute(codec);
13610}
13611
13612static int patch_alc861vd(struct hda_codec *codec)
13613{
13614	struct alc_spec *spec;
13615	int err, board_config;
13616
13617	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13618	if (spec == NULL)
13619		return -ENOMEM;
13620
13621	codec->spec = spec;
13622
13623	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
13624						  alc861vd_models,
13625						  alc861vd_cfg_tbl);
13626
13627	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
13628		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
13629			"ALC861VD, trying auto-probe from BIOS...\n");
13630		board_config = ALC861VD_AUTO;
13631	}
13632
13633	if (board_config == ALC861VD_AUTO) {
13634		/* automatic parse from the BIOS config */
13635		err = alc861vd_parse_auto_config(codec);
13636		if (err < 0) {
13637			alc_free(codec);
13638			return err;
13639		} else if (!err) {
13640			printk(KERN_INFO
13641			       "hda_codec: Cannot set up configuration "
13642			       "from BIOS.  Using base mode...\n");
13643			board_config = ALC861VD_3ST;
13644		}
13645	}
13646
13647	if (board_config != ALC861VD_AUTO)
13648		setup_preset(spec, &alc861vd_presets[board_config]);
13649
13650	if (codec->vendor_id == 0x10ec0660) {
13651		spec->stream_name_analog = "ALC660-VD Analog";
13652		spec->stream_name_digital = "ALC660-VD Digital";
13653		/* always turn on EAPD */
13654		spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
13655	} else {
13656		spec->stream_name_analog = "ALC861VD Analog";
13657		spec->stream_name_digital = "ALC861VD Digital";
13658	}
13659
13660	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
13661	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
13662
13663	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
13664	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
13665
13666	spec->adc_nids = alc861vd_adc_nids;
13667	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
13668	spec->capsrc_nids = alc861vd_capsrc_nids;
13669
13670	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
13671	spec->num_mixers++;
13672
13673	spec->vmaster_nid = 0x02;
13674
13675	codec->patch_ops = alc_patch_ops;
13676
13677	if (board_config == ALC861VD_AUTO)
13678		spec->init_hook = alc861vd_auto_init;
13679#ifdef CONFIG_SND_HDA_POWER_SAVE
13680	if (!spec->loopback.amplist)
13681		spec->loopback.amplist = alc861vd_loopbacks;
13682#endif
13683
13684	return 0;
13685}
13686
13687/*
13688 * ALC662 support
13689 *
13690 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
13691 * configuration.  Each pin widget can choose any input DACs and a mixer.
13692 * Each ADC is connected from a mixer of all inputs.  This makes possible
13693 * 6-channel independent captures.
13694 *
13695 * In addition, an independent DAC for the multi-playback (not used in this
13696 * driver yet).
13697 */
13698#define ALC662_DIGOUT_NID	0x06
13699#define ALC662_DIGIN_NID	0x0a
13700
13701static hda_nid_t alc662_dac_nids[4] = {
13702	/* front, rear, clfe, rear_surr */
13703	0x02, 0x03, 0x04
13704};
13705
13706static hda_nid_t alc662_adc_nids[1] = {
13707	/* ADC1-2 */
13708	0x09,
13709};
13710
13711static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
13712
13713/* input MUX */
13714/* FIXME: should be a matrix-type input source selection */
13715static struct hda_input_mux alc662_capture_source = {
13716	.num_items = 4,
13717	.items = {
13718		{ "Mic", 0x0 },
13719		{ "Front Mic", 0x1 },
13720		{ "Line", 0x2 },
13721		{ "CD", 0x4 },
13722	},
13723};
13724
13725static struct hda_input_mux alc662_lenovo_101e_capture_source = {
13726	.num_items = 2,
13727	.items = {
13728		{ "Mic", 0x1 },
13729		{ "Line", 0x2 },
13730	},
13731};
13732
13733static struct hda_input_mux alc662_eeepc_capture_source = {
13734	.num_items = 2,
13735	.items = {
13736		{ "i-Mic", 0x1 },
13737		{ "e-Mic", 0x0 },
13738	},
13739};
13740
13741static struct hda_input_mux alc663_capture_source = {
13742	.num_items = 3,
13743	.items = {
13744		{ "Mic", 0x0 },
13745		{ "Front Mic", 0x1 },
13746		{ "Line", 0x2 },
13747	},
13748};
13749
13750static struct hda_input_mux alc663_m51va_capture_source = {
13751	.num_items = 2,
13752	.items = {
13753		{ "Ext-Mic", 0x0 },
13754		{ "D-Mic", 0x9 },
13755	},
13756};
13757
13758#define alc662_mux_enum_info alc_mux_enum_info
13759#define alc662_mux_enum_get alc_mux_enum_get
13760#define alc662_mux_enum_put alc882_mux_enum_put
13761
13762/*
13763 * 2ch mode
13764 */
13765static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
13766	{ 2, NULL }
13767};
13768
13769/*
13770 * 2ch mode
13771 */
13772static struct hda_verb alc662_3ST_ch2_init[] = {
13773	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
13774	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13775	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
13776	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13777	{ } /* end */
13778};
13779
13780/*
13781 * 6ch mode
13782 */
13783static struct hda_verb alc662_3ST_ch6_init[] = {
13784	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13785	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13786	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
13787	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13788	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13789	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
13790	{ } /* end */
13791};
13792
13793static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
13794	{ 2, alc662_3ST_ch2_init },
13795	{ 6, alc662_3ST_ch6_init },
13796};
13797
13798/*
13799 * 2ch mode
13800 */
13801static struct hda_verb alc662_sixstack_ch6_init[] = {
13802	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13803	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13804	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13805	{ } /* end */
13806};
13807
13808/*
13809 * 6ch mode
13810 */
13811static struct hda_verb alc662_sixstack_ch8_init[] = {
13812	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13813	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13814	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13815	{ } /* end */
13816};
13817
13818static struct hda_channel_mode alc662_5stack_modes[2] = {
13819	{ 2, alc662_sixstack_ch6_init },
13820	{ 6, alc662_sixstack_ch8_init },
13821};
13822
13823/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13824 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13825 */
13826
13827static struct snd_kcontrol_new alc662_base_mixer[] = {
13828	/* output mixer control */
13829	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13830	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13831	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13832	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13833	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13834	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13835	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13836	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13837	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13838
13839	/*Input mixer control */
13840	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
13841	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
13842	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
13843	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
13844	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
13845	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
13846	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
13847	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
13848	{ } /* end */
13849};
13850
13851static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
13852	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13853	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13854	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13855	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13856	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13857	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13858	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13859	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13860	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13861	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13862	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13863	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13864	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13865	{ } /* end */
13866};
13867
13868static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
13869	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13870	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13871	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13872	HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13873	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13874	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13875	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13876	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13877	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13878	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13879	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13880	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13881	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13882	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13883	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13884	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13885	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13886	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13887	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13888	{ } /* end */
13889};
13890
13891static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13892	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13893	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13894	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13895	HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
13896	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13897	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13898	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13899	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13900	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13901	{ } /* end */
13902};
13903
13904static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
13905	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13906
13907	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13908	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13909
13910	HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13911	HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13912	HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13913
13914	HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13915	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13916	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13917	{ } /* end */
13918};
13919
13920static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13921	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13922	HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13923	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13924	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13925	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13926	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13927	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13928	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
13929	HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13930	HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13931	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13932	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13933	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13934	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13935	{ } /* end */
13936};
13937
13938static struct snd_kcontrol_new alc663_m51va_mixer[] = {
13939	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13940	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13941	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13942	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13943	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13944	HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT),
13945	{ } /* end */
13946};
13947
13948static struct snd_kcontrol_new alc663_g71v_mixer[] = {
13949	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13950	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13951	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13952	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13953	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13954
13955	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13956	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13957	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13958	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13959	{ } /* end */
13960};
13961
13962static struct snd_kcontrol_new alc663_g50v_mixer[] = {
13963	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13964	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13965	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13966
13967	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13968	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13969	HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13970	HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13971	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13972	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13973	{ } /* end */
13974};
13975
13976static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13977	{
13978		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13979		.name = "Channel Mode",
13980		.info = alc_ch_mode_info,
13981		.get = alc_ch_mode_get,
13982		.put = alc_ch_mode_put,
13983	},
13984	{ } /* end */
13985};
13986
13987static struct hda_verb alc662_init_verbs[] = {
13988	/* ADC: mute amp left and right */
13989	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13990	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13991	/* Front mixer: unmute input/output amp left and right (volume = 0) */
13992
13993	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13994	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13995	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13996	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13997	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13998
13999	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14000	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14001	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14002	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14003	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14004	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14005
14006	/* Front Pin: output 0 (0x0c) */
14007	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14008	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14009
14010	/* Rear Pin: output 1 (0x0d) */
14011	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14012	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14013
14014	/* CLFE Pin: output 2 (0x0e) */
14015	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14016	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14017
14018	/* Mic (rear) pin: input vref at 80% */
14019	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14020	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14021	/* Front Mic pin: input vref at 80% */
14022	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14023	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14024	/* Line In pin: input */
14025	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14026	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14027	/* Line-2 In: Headphone output (output 0 - 0x0c) */
14028	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14029	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14030	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14031	/* CD pin widget for input */
14032	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14033
14034	/* FIXME: use matrix-type input source selection */
14035	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14036	/* Input mixer */
14037	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14038	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14039	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14040	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14041
14042	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14043	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14044	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14045	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14046
14047	/* always trun on EAPD */
14048	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14049	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14050
14051	{ }
14052};
14053
14054static struct hda_verb alc662_sue_init_verbs[] = {
14055	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14056	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14057	{}
14058};
14059
14060static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14061	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14062	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14063	{}
14064};
14065
14066/* Set Unsolicited Event*/
14067static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14068	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14069	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14070	{}
14071};
14072
14073/*
14074 * generic initialization of ADC, input mixers and output mixers
14075 */
14076static struct hda_verb alc662_auto_init_verbs[] = {
14077	/*
14078	 * Unmute ADC and set the default input to mic-in
14079	 */
14080	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14081	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14082
14083	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14084	 * mixer widget
14085	 * Note: PASD motherboards uses the Line In 2 as the input for front
14086	 * panel mic (mic 2)
14087	 */
14088	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14089	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14090	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14091	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14092	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14093	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14094
14095	/*
14096	 * Set up output mixers (0x0c - 0x0f)
14097	 */
14098	/* set vol=0 to output mixers */
14099	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14100	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14101	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14102
14103	/* set up input amps for analog loopback */
14104	/* Amp Indices: DAC = 0, mixer = 1 */
14105	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14106	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14107	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14108	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14109	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14110	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14111
14112
14113	/* FIXME: use matrix-type input source selection */
14114	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14115	/* Input mixer */
14116	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14117	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14118	{ }
14119};
14120
14121/* additional verbs for ALC663 */
14122static struct hda_verb alc663_auto_init_verbs[] = {
14123	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14124	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14125	{ }
14126};
14127
14128static struct hda_verb alc663_m51va_init_verbs[] = {
14129	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14130	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14131	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14132
14133	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14134
14135	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14136	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14137	{}
14138};
14139
14140static struct hda_verb alc663_g71v_init_verbs[] = {
14141	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14142	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
14143	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
14144
14145	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14146	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14147	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14148
14149	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14150	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
14151	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14152	{}
14153};
14154
14155static struct hda_verb alc663_g50v_init_verbs[] = {
14156	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14157	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14158	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */
14159
14160	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14161	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14162	{}
14163};
14164
14165/* capture mixer elements */
14166static struct snd_kcontrol_new alc662_capture_mixer[] = {
14167	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14168	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14169	{
14170		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14171		/* The multiple "Capture Source" controls confuse alsamixer
14172		 * So call somewhat different..
14173		 */
14174		/* .name = "Capture Source", */
14175		.name = "Input Source",
14176		.count = 1,
14177		.info = alc662_mux_enum_info,
14178		.get = alc662_mux_enum_get,
14179		.put = alc662_mux_enum_put,
14180	},
14181	{ } /* end */
14182};
14183
14184static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
14185{
14186	unsigned int present;
14187	unsigned char bits;
14188
14189	present = snd_hda_codec_read(codec, 0x14, 0,
14190				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14191	bits = present ? HDA_AMP_MUTE : 0;
14192	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14193				 HDA_AMP_MUTE, bits);
14194}
14195
14196static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
14197{
14198	unsigned int present;
14199	unsigned char bits;
14200
14201 	present = snd_hda_codec_read(codec, 0x1b, 0,
14202				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14203	bits = present ? HDA_AMP_MUTE : 0;
14204	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14205				 HDA_AMP_MUTE, bits);
14206	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14207				 HDA_AMP_MUTE, bits);
14208}
14209
14210static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
14211					   unsigned int res)
14212{
14213	if ((res >> 26) == ALC880_HP_EVENT)
14214		alc662_lenovo_101e_all_automute(codec);
14215	if ((res >> 26) == ALC880_FRONT_EVENT)
14216		alc662_lenovo_101e_ispeaker_automute(codec);
14217}
14218
14219static void alc662_eeepc_mic_automute(struct hda_codec *codec)
14220{
14221	unsigned int present;
14222
14223	present = snd_hda_codec_read(codec, 0x18, 0,
14224				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14225	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14226			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14227	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14228			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14229	snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14230			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14231	snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14232			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14233}
14234
14235/* unsolicited event for HP jack sensing */
14236static void alc662_eeepc_unsol_event(struct hda_codec *codec,
14237				     unsigned int res)
14238{
14239	if ((res >> 26) == ALC880_HP_EVENT)
14240		alc262_hippo1_automute( codec );
14241
14242	if ((res >> 26) == ALC880_MIC_EVENT)
14243		alc662_eeepc_mic_automute(codec);
14244}
14245
14246static void alc662_eeepc_inithook(struct hda_codec *codec)
14247{
14248	alc262_hippo1_automute( codec );
14249	alc662_eeepc_mic_automute(codec);
14250}
14251
14252static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
14253{
14254	unsigned int mute;
14255	unsigned int present;
14256
14257	snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
14258	present = snd_hda_codec_read(codec, 0x14, 0,
14259				     AC_VERB_GET_PIN_SENSE, 0);
14260	present = (present & 0x80000000) != 0;
14261	if (present) {
14262		/* mute internal speaker */
14263		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14264					 HDA_AMP_MUTE, HDA_AMP_MUTE);
14265	} else {
14266		/* unmute internal speaker if necessary */
14267		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
14268		snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
14269					 HDA_AMP_MUTE, mute);
14270	}
14271}
14272
14273/* unsolicited event for HP jack sensing */
14274static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
14275					  unsigned int res)
14276{
14277	if ((res >> 26) == ALC880_HP_EVENT)
14278		alc662_eeepc_ep20_automute(codec);
14279}
14280
14281static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
14282{
14283	alc662_eeepc_ep20_automute(codec);
14284}
14285
14286static void alc663_m51va_speaker_automute(struct hda_codec *codec)
14287{
14288	unsigned int present;
14289	unsigned char bits;
14290
14291	present = snd_hda_codec_read(codec, 0x21, 0,
14292				     AC_VERB_GET_PIN_SENSE, 0)
14293		& AC_PINSENSE_PRESENCE;
14294	bits = present ? HDA_AMP_MUTE : 0;
14295	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14296				 HDA_AMP_MUTE, bits);
14297}
14298
14299static void alc663_m51va_mic_automute(struct hda_codec *codec)
14300{
14301	unsigned int present;
14302
14303	present = snd_hda_codec_read(codec, 0x18, 0,
14304				     AC_VERB_GET_PIN_SENSE, 0)
14305		& AC_PINSENSE_PRESENCE;
14306	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14307			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14308	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14309			    0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14310	snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14311			    0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14312	snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14313			    0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
14314}
14315
14316static void alc663_m51va_unsol_event(struct hda_codec *codec,
14317					   unsigned int res)
14318{
14319	switch (res >> 26) {
14320	case ALC880_HP_EVENT:
14321		alc663_m51va_speaker_automute(codec);
14322		break;
14323	case ALC880_MIC_EVENT:
14324		alc663_m51va_mic_automute(codec);
14325		break;
14326	}
14327}
14328
14329static void alc663_m51va_inithook(struct hda_codec *codec)
14330{
14331	alc663_m51va_speaker_automute(codec);
14332	alc663_m51va_mic_automute(codec);
14333}
14334
14335static void alc663_g71v_hp_automute(struct hda_codec *codec)
14336{
14337	unsigned int present;
14338	unsigned char bits;
14339
14340	present = snd_hda_codec_read(codec, 0x21, 0,
14341				     AC_VERB_GET_PIN_SENSE, 0)
14342		& AC_PINSENSE_PRESENCE;
14343	bits = present ? HDA_AMP_MUTE : 0;
14344	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14345				 HDA_AMP_MUTE, bits);
14346	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14347				 HDA_AMP_MUTE, bits);
14348}
14349
14350static void alc663_g71v_front_automute(struct hda_codec *codec)
14351{
14352	unsigned int present;
14353	unsigned char bits;
14354
14355	present = snd_hda_codec_read(codec, 0x15, 0,
14356				     AC_VERB_GET_PIN_SENSE, 0)
14357		& AC_PINSENSE_PRESENCE;
14358	bits = present ? HDA_AMP_MUTE : 0;
14359	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14360				 HDA_AMP_MUTE, bits);
14361}
14362
14363static void alc663_g71v_unsol_event(struct hda_codec *codec,
14364					   unsigned int res)
14365{
14366	switch (res >> 26) {
14367	case ALC880_HP_EVENT:
14368		alc663_g71v_hp_automute(codec);
14369		break;
14370	case ALC880_FRONT_EVENT:
14371		alc663_g71v_front_automute(codec);
14372		break;
14373	case ALC880_MIC_EVENT:
14374		alc662_eeepc_mic_automute(codec);
14375		break;
14376	}
14377}
14378
14379static void alc663_g71v_inithook(struct hda_codec *codec)
14380{
14381	alc663_g71v_front_automute(codec);
14382	alc663_g71v_hp_automute(codec);
14383	alc662_eeepc_mic_automute(codec);
14384}
14385
14386static void alc663_g50v_unsol_event(struct hda_codec *codec,
14387					   unsigned int res)
14388{
14389	switch (res >> 26) {
14390	case ALC880_HP_EVENT:
14391		alc663_m51va_speaker_automute(codec);
14392		break;
14393	case ALC880_MIC_EVENT:
14394		alc662_eeepc_mic_automute(codec);
14395		break;
14396	}
14397}
14398
14399static void alc663_g50v_inithook(struct hda_codec *codec)
14400{
14401	alc663_m51va_speaker_automute(codec);
14402	alc662_eeepc_mic_automute(codec);
14403}
14404
14405#ifdef CONFIG_SND_HDA_POWER_SAVE
14406#define alc662_loopbacks	alc880_loopbacks
14407#endif
14408
14409
14410/* pcm configuration: identiacal with ALC880 */
14411#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
14412#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
14413#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
14414#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
14415
14416/*
14417 * configuration and preset
14418 */
14419static const char *alc662_models[ALC662_MODEL_LAST] = {
14420	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
14421	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
14422	[ALC662_3ST_6ch]	= "3stack-6ch",
14423	[ALC662_5ST_DIG]	= "6stack-dig",
14424	[ALC662_LENOVO_101E]	= "lenovo-101e",
14425	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
14426	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
14427	[ALC663_ASUS_M51VA] = "m51va",
14428	[ALC663_ASUS_G71V] = "g71v",
14429	[ALC663_ASUS_H13] = "h13",
14430	[ALC663_ASUS_G50V] = "g50v",
14431	[ALC662_AUTO]		= "auto",
14432};
14433
14434static struct snd_pci_quirk alc662_cfg_tbl[] = {
14435	SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V),
14436	SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
14437	SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
14438	SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
14439	SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
14440	SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
14441	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
14442	SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
14443	SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
14444	SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
14445	{}
14446};
14447
14448static struct alc_config_preset alc662_presets[] = {
14449	[ALC662_3ST_2ch_DIG] = {
14450		.mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
14451		.init_verbs = { alc662_init_verbs },
14452		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14453		.dac_nids = alc662_dac_nids,
14454		.dig_out_nid = ALC662_DIGOUT_NID,
14455		.dig_in_nid = ALC662_DIGIN_NID,
14456		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14457		.channel_mode = alc662_3ST_2ch_modes,
14458		.input_mux = &alc662_capture_source,
14459	},
14460	[ALC662_3ST_6ch_DIG] = {
14461		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
14462			    alc662_capture_mixer },
14463		.init_verbs = { alc662_init_verbs },
14464		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14465		.dac_nids = alc662_dac_nids,
14466		.dig_out_nid = ALC662_DIGOUT_NID,
14467		.dig_in_nid = ALC662_DIGIN_NID,
14468		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14469		.channel_mode = alc662_3ST_6ch_modes,
14470		.need_dac_fix = 1,
14471		.input_mux = &alc662_capture_source,
14472	},
14473	[ALC662_3ST_6ch] = {
14474		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
14475			    alc662_capture_mixer },
14476		.init_verbs = { alc662_init_verbs },
14477		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14478		.dac_nids = alc662_dac_nids,
14479		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14480		.channel_mode = alc662_3ST_6ch_modes,
14481		.need_dac_fix = 1,
14482		.input_mux = &alc662_capture_source,
14483	},
14484	[ALC662_5ST_DIG] = {
14485		.mixers = { alc662_base_mixer, alc662_chmode_mixer,
14486			    alc662_capture_mixer },
14487		.init_verbs = { alc662_init_verbs },
14488		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14489		.dac_nids = alc662_dac_nids,
14490		.dig_out_nid = ALC662_DIGOUT_NID,
14491		.dig_in_nid = ALC662_DIGIN_NID,
14492		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
14493		.channel_mode = alc662_5stack_modes,
14494		.input_mux = &alc662_capture_source,
14495	},
14496	[ALC662_LENOVO_101E] = {
14497		.mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
14498		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
14499		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14500		.dac_nids = alc662_dac_nids,
14501		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14502		.channel_mode = alc662_3ST_2ch_modes,
14503		.input_mux = &alc662_lenovo_101e_capture_source,
14504		.unsol_event = alc662_lenovo_101e_unsol_event,
14505		.init_hook = alc662_lenovo_101e_all_automute,
14506	},
14507	[ALC662_ASUS_EEEPC_P701] = {
14508		.mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
14509		.init_verbs = { alc662_init_verbs,
14510				alc662_eeepc_sue_init_verbs },
14511		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14512		.dac_nids = alc662_dac_nids,
14513		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14514		.channel_mode = alc662_3ST_2ch_modes,
14515		.input_mux = &alc662_eeepc_capture_source,
14516		.unsol_event = alc662_eeepc_unsol_event,
14517		.init_hook = alc662_eeepc_inithook,
14518	},
14519	[ALC662_ASUS_EEEPC_EP20] = {
14520		.mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
14521			    alc662_chmode_mixer },
14522		.init_verbs = { alc662_init_verbs,
14523				alc662_eeepc_ep20_sue_init_verbs },
14524		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14525		.dac_nids = alc662_dac_nids,
14526		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14527		.channel_mode = alc662_3ST_6ch_modes,
14528		.input_mux = &alc662_lenovo_101e_capture_source,
14529		.unsol_event = alc662_eeepc_ep20_unsol_event,
14530		.init_hook = alc662_eeepc_ep20_inithook,
14531	},
14532	[ALC663_ASUS_M51VA] = {
14533		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14534		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14535		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14536		.dac_nids = alc662_dac_nids,
14537		.dig_out_nid = ALC662_DIGOUT_NID,
14538		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14539		.channel_mode = alc662_3ST_2ch_modes,
14540		.input_mux = &alc663_m51va_capture_source,
14541		.unsol_event = alc663_m51va_unsol_event,
14542		.init_hook = alc663_m51va_inithook,
14543	},
14544	[ALC663_ASUS_G71V] = {
14545		.mixers = { alc663_g71v_mixer, alc662_capture_mixer},
14546		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
14547		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14548		.dac_nids = alc662_dac_nids,
14549		.dig_out_nid = ALC662_DIGOUT_NID,
14550		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14551		.channel_mode = alc662_3ST_2ch_modes,
14552		.input_mux = &alc662_eeepc_capture_source,
14553		.unsol_event = alc663_g71v_unsol_event,
14554		.init_hook = alc663_g71v_inithook,
14555	},
14556	[ALC663_ASUS_H13] = {
14557		.mixers = { alc663_m51va_mixer, alc662_capture_mixer},
14558		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
14559		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14560		.dac_nids = alc662_dac_nids,
14561		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
14562		.channel_mode = alc662_3ST_2ch_modes,
14563		.input_mux = &alc663_m51va_capture_source,
14564		.unsol_event = alc663_m51va_unsol_event,
14565		.init_hook = alc663_m51va_inithook,
14566	},
14567	[ALC663_ASUS_G50V] = {
14568		.mixers = { alc663_g50v_mixer, alc662_capture_mixer},
14569		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
14570		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
14571		.dac_nids = alc662_dac_nids,
14572		.dig_out_nid = ALC662_DIGOUT_NID,
14573		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
14574		.channel_mode = alc662_3ST_6ch_modes,
14575		.input_mux = &alc663_capture_source,
14576		.unsol_event = alc663_g50v_unsol_event,
14577		.init_hook = alc663_g50v_inithook,
14578	},
14579};
14580
14581
14582/*
14583 * BIOS auto configuration
14584 */
14585
14586/* add playback controls from the parsed DAC table */
14587static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
14588					     const struct auto_pin_cfg *cfg)
14589{
14590	char name[32];
14591	static const char *chname[4] = {
14592		"Front", "Surround", NULL /*CLFE*/, "Side"
14593	};
14594	hda_nid_t nid;
14595	int i, err;
14596
14597	for (i = 0; i < cfg->line_outs; i++) {
14598		if (!spec->multiout.dac_nids[i])
14599			continue;
14600		nid = alc880_idx_to_dac(i);
14601		if (i == 2) {
14602			/* Center/LFE */
14603			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14604					  "Center Playback Volume",
14605					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
14606							      HDA_OUTPUT));
14607			if (err < 0)
14608				return err;
14609			err = add_control(spec, ALC_CTL_WIDGET_VOL,
14610					  "LFE Playback Volume",
14611					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14612							      HDA_OUTPUT));
14613			if (err < 0)
14614				return err;
14615			err = add_control(spec, ALC_CTL_BIND_MUTE,
14616					  "Center Playback Switch",
14617					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
14618							      HDA_INPUT));
14619			if (err < 0)
14620				return err;
14621			err = add_control(spec, ALC_CTL_BIND_MUTE,
14622					  "LFE Playback Switch",
14623					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
14624							      HDA_INPUT));
14625			if (err < 0)
14626				return err;
14627		} else {
14628			sprintf(name, "%s Playback Volume", chname[i]);
14629			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14630					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14631							      HDA_OUTPUT));
14632			if (err < 0)
14633				return err;
14634			sprintf(name, "%s Playback Switch", chname[i]);
14635			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14636					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
14637							      HDA_INPUT));
14638			if (err < 0)
14639				return err;
14640		}
14641	}
14642	return 0;
14643}
14644
14645/* add playback controls for speaker and HP outputs */
14646static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
14647					const char *pfx)
14648{
14649	hda_nid_t nid;
14650	int err;
14651	char name[32];
14652
14653	if (!pin)
14654		return 0;
14655
14656	if (pin == 0x17) {
14657		/* ALC663 has a mono output pin on 0x17 */
14658		sprintf(name, "%s Playback Switch", pfx);
14659		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14660				  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
14661		return err;
14662	}
14663
14664	if (alc880_is_fixed_pin(pin)) {
14665		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14666                /* printk("DAC nid=%x\n",nid); */
14667		/* specify the DAC as the extra output */
14668		if (!spec->multiout.hp_nid)
14669			spec->multiout.hp_nid = nid;
14670		else
14671			spec->multiout.extra_out_nid[0] = nid;
14672		/* control HP volume/switch on the output mixer amp */
14673		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14674		sprintf(name, "%s Playback Volume", pfx);
14675		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14676				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
14677		if (err < 0)
14678			return err;
14679		sprintf(name, "%s Playback Switch", pfx);
14680		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14681				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
14682		if (err < 0)
14683			return err;
14684	} else if (alc880_is_multi_pin(pin)) {
14685		/* set manual connection */
14686		/* we have only a switch on HP-out PIN */
14687		sprintf(name, "%s Playback Switch", pfx);
14688		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14689				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14690		if (err < 0)
14691			return err;
14692	}
14693	return 0;
14694}
14695
14696/* create playback/capture controls for input pins */
14697static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
14698						const struct auto_pin_cfg *cfg)
14699{
14700	struct hda_input_mux *imux = &spec->private_imux;
14701	int i, err, idx;
14702
14703	for (i = 0; i < AUTO_PIN_LAST; i++) {
14704		if (alc880_is_input_pin(cfg->input_pins[i])) {
14705			idx = alc880_input_pin_idx(cfg->input_pins[i]);
14706			err = new_analog_input(spec, cfg->input_pins[i],
14707					       auto_pin_cfg_labels[i],
14708					       idx, 0x0b);
14709			if (err < 0)
14710				return err;
14711			imux->items[imux->num_items].label =
14712				auto_pin_cfg_labels[i];
14713			imux->items[imux->num_items].index =
14714				alc880_input_pin_idx(cfg->input_pins[i]);
14715			imux->num_items++;
14716		}
14717	}
14718	return 0;
14719}
14720
14721static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
14722					      hda_nid_t nid, int pin_type,
14723					      int dac_idx)
14724{
14725	alc_set_pin_output(codec, nid, pin_type);
14726	/* need the manual connection? */
14727	if (alc880_is_multi_pin(nid)) {
14728		struct alc_spec *spec = codec->spec;
14729		int idx = alc880_multi_pin_idx(nid);
14730		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
14731				    AC_VERB_SET_CONNECT_SEL,
14732				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
14733	}
14734}
14735
14736static void alc662_auto_init_multi_out(struct hda_codec *codec)
14737{
14738	struct alc_spec *spec = codec->spec;
14739	int i;
14740
14741	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14742	for (i = 0; i <= HDA_SIDE; i++) {
14743		hda_nid_t nid = spec->autocfg.line_out_pins[i];
14744		int pin_type = get_pin_type(spec->autocfg.line_out_type);
14745		if (nid)
14746			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
14747							  i);
14748	}
14749}
14750
14751static void alc662_auto_init_hp_out(struct hda_codec *codec)
14752{
14753	struct alc_spec *spec = codec->spec;
14754	hda_nid_t pin;
14755
14756	pin = spec->autocfg.hp_pins[0];
14757	if (pin) /* connect to front */
14758		/* use dac 0 */
14759		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14760	pin = spec->autocfg.speaker_pins[0];
14761	if (pin)
14762		alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14763}
14764
14765#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
14766#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
14767
14768static void alc662_auto_init_analog_input(struct hda_codec *codec)
14769{
14770	struct alc_spec *spec = codec->spec;
14771	int i;
14772
14773	for (i = 0; i < AUTO_PIN_LAST; i++) {
14774		hda_nid_t nid = spec->autocfg.input_pins[i];
14775		if (alc662_is_input_pin(nid)) {
14776			snd_hda_codec_write(codec, nid, 0,
14777					    AC_VERB_SET_PIN_WIDGET_CONTROL,
14778					    (i <= AUTO_PIN_FRONT_MIC ?
14779					     PIN_VREF80 : PIN_IN));
14780			if (nid != ALC662_PIN_CD_NID)
14781				snd_hda_codec_write(codec, nid, 0,
14782						    AC_VERB_SET_AMP_GAIN_MUTE,
14783						    AMP_OUT_MUTE);
14784		}
14785	}
14786}
14787
14788#define alc662_auto_init_input_src	alc882_auto_init_input_src
14789
14790static int alc662_parse_auto_config(struct hda_codec *codec)
14791{
14792	struct alc_spec *spec = codec->spec;
14793	int err;
14794	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
14795
14796	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14797					   alc662_ignore);
14798	if (err < 0)
14799		return err;
14800	if (!spec->autocfg.line_outs)
14801		return 0; /* can't find valid BIOS pin config */
14802
14803	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14804	if (err < 0)
14805		return err;
14806	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
14807	if (err < 0)
14808		return err;
14809	err = alc662_auto_create_extra_out(spec,
14810					   spec->autocfg.speaker_pins[0],
14811					   "Speaker");
14812	if (err < 0)
14813		return err;
14814	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
14815					   "Headphone");
14816	if (err < 0)
14817		return err;
14818	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
14819	if (err < 0)
14820		return err;
14821
14822	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14823
14824	if (spec->autocfg.dig_out_pin)
14825		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
14826
14827	if (spec->kctl_alloc)
14828		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14829
14830	spec->num_mux_defs = 1;
14831	spec->input_mux = &spec->private_imux;
14832
14833	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
14834	if (codec->vendor_id == 0x10ec0663)
14835		spec->init_verbs[spec->num_init_verbs++] =
14836			alc663_auto_init_verbs;
14837
14838	err = alc_auto_add_mic_boost(codec);
14839	if (err < 0)
14840		return err;
14841
14842	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
14843	spec->num_mixers++;
14844	return 1;
14845}
14846
14847/* additional initialization for auto-configuration model */
14848static void alc662_auto_init(struct hda_codec *codec)
14849{
14850	struct alc_spec *spec = codec->spec;
14851	alc662_auto_init_multi_out(codec);
14852	alc662_auto_init_hp_out(codec);
14853	alc662_auto_init_analog_input(codec);
14854	alc662_auto_init_input_src(codec);
14855	if (spec->unsol_event)
14856		alc_sku_automute(codec);
14857}
14858
14859static int patch_alc662(struct hda_codec *codec)
14860{
14861	struct alc_spec *spec;
14862	int err, board_config;
14863
14864	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14865	if (!spec)
14866		return -ENOMEM;
14867
14868	codec->spec = spec;
14869
14870	alc_fix_pll_init(codec, 0x20, 0x04, 15);
14871
14872	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
14873						  alc662_models,
14874			  	                  alc662_cfg_tbl);
14875	if (board_config < 0) {
14876		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
14877		       "trying auto-probe from BIOS...\n");
14878		board_config = ALC662_AUTO;
14879	}
14880
14881	if (board_config == ALC662_AUTO) {
14882		/* automatic parse from the BIOS config */
14883		err = alc662_parse_auto_config(codec);
14884		if (err < 0) {
14885			alc_free(codec);
14886			return err;
14887		} else if (!err) {
14888			printk(KERN_INFO
14889			       "hda_codec: Cannot set up configuration "
14890			       "from BIOS.  Using base mode...\n");
14891			board_config = ALC662_3ST_2ch_DIG;
14892		}
14893	}
14894
14895	if (board_config != ALC662_AUTO)
14896		setup_preset(spec, &alc662_presets[board_config]);
14897
14898	if (codec->vendor_id == 0x10ec0663) {
14899		spec->stream_name_analog = "ALC663 Analog";
14900		spec->stream_name_digital = "ALC663 Digital";
14901	} else {
14902		spec->stream_name_analog = "ALC662 Analog";
14903		spec->stream_name_digital = "ALC662 Digital";
14904	}
14905
14906	spec->stream_analog_playback = &alc662_pcm_analog_playback;
14907	spec->stream_analog_capture = &alc662_pcm_analog_capture;
14908
14909	spec->stream_digital_playback = &alc662_pcm_digital_playback;
14910	spec->stream_digital_capture = &alc662_pcm_digital_capture;
14911
14912	spec->adc_nids = alc662_adc_nids;
14913	spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
14914	spec->capsrc_nids = alc662_capsrc_nids;
14915
14916	spec->vmaster_nid = 0x02;
14917
14918	codec->patch_ops = alc_patch_ops;
14919	if (board_config == ALC662_AUTO)
14920		spec->init_hook = alc662_auto_init;
14921#ifdef CONFIG_SND_HDA_POWER_SAVE
14922	if (!spec->loopback.amplist)
14923		spec->loopback.amplist = alc662_loopbacks;
14924#endif
14925
14926	return 0;
14927}
14928
14929/*
14930 * patch entries
14931 */
14932struct hda_codec_preset snd_hda_preset_realtek[] = {
14933	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
14934	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
14935	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
14936	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
14937	{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
14938	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
14939	  .patch = patch_alc861 },
14940	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
14941	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
14942	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
14943	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
14944	  .patch = patch_alc883 },
14945	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
14946	  .patch = patch_alc662 },
14947	{ .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
14948	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
14949	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
14950	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
14951	{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
14952	  .patch = patch_alc882 }, /* should be patch_alc883() in future */
14953	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
14954	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
14955	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
14956	{} /* terminator */
14957};
14958