patch_realtek.c revision 625dc0bf4d91d379e8b4d5c3c9e05ad6fa978c51
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 <sound/driver.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pci.h>
31#include <sound/core.h>
32#include "hda_codec.h"
33#include "hda_local.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#ifdef CONFIG_SND_DEBUG
64	ALC880_TEST,
65#endif
66	ALC880_AUTO,
67	ALC880_MODEL_LAST /* last tag */
68};
69
70/* ALC260 models */
71enum {
72	ALC260_BASIC,
73	ALC260_HP,
74	ALC260_HP_3013,
75	ALC260_FUJITSU_S702X,
76	ALC260_ACER,
77	ALC260_WILL,
78	ALC260_REPLACER_672V,
79#ifdef CONFIG_SND_DEBUG
80	ALC260_TEST,
81#endif
82	ALC260_AUTO,
83	ALC260_MODEL_LAST /* last tag */
84};
85
86/* ALC262 models */
87enum {
88	ALC262_BASIC,
89	ALC262_HIPPO,
90	ALC262_HIPPO_1,
91	ALC262_FUJITSU,
92	ALC262_HP_BPC,
93	ALC262_HP_BPC_D7000_WL,
94	ALC262_HP_BPC_D7000_WF,
95	ALC262_BENQ_ED8,
96	ALC262_SONY_ASSAMD,
97	ALC262_BENQ_T31,
98	ALC262_AUTO,
99	ALC262_MODEL_LAST /* last tag */
100};
101
102/* ALC268 models */
103enum {
104	ALC268_3ST,
105	ALC268_AUTO,
106	ALC268_MODEL_LAST /* last tag */
107};
108
109/* ALC861 models */
110enum {
111	ALC861_3ST,
112	ALC660_3ST,
113	ALC861_3ST_DIG,
114	ALC861_6ST_DIG,
115	ALC861_UNIWILL_M31,
116	ALC861_TOSHIBA,
117	ALC861_ASUS,
118	ALC861_ASUS_LAPTOP,
119	ALC861_AUTO,
120	ALC861_MODEL_LAST,
121};
122
123/* ALC861-VD models */
124enum {
125	ALC660VD_3ST,
126	ALC660VD_3ST_DIG,
127	ALC861VD_3ST,
128	ALC861VD_3ST_DIG,
129	ALC861VD_6ST_DIG,
130	ALC861VD_LENOVO,
131	ALC861VD_DALLAS,
132	ALC861VD_AUTO,
133	ALC861VD_MODEL_LAST,
134};
135
136/* ALC662 models */
137enum {
138	ALC662_3ST_2ch_DIG,
139	ALC662_3ST_6ch_DIG,
140	ALC662_3ST_6ch,
141	ALC662_5ST_DIG,
142	ALC662_LENOVO_101E,
143	ALC662_AUTO,
144	ALC662_MODEL_LAST,
145};
146
147/* ALC882 models */
148enum {
149	ALC882_3ST_DIG,
150	ALC882_6ST_DIG,
151	ALC882_ARIMA,
152	ALC882_W2JC,
153	ALC882_TARGA,
154	ALC882_ASUS_A7J,
155	ALC885_MACPRO,
156	ALC885_IMAC24,
157	ALC882_AUTO,
158	ALC882_MODEL_LAST,
159};
160
161/* ALC883 models */
162enum {
163	ALC883_3ST_2ch_DIG,
164	ALC883_3ST_6ch_DIG,
165	ALC883_3ST_6ch,
166	ALC883_6ST_DIG,
167	ALC883_TARGA_DIG,
168	ALC883_TARGA_2ch_DIG,
169	ALC883_ACER,
170	ALC883_MEDION,
171	ALC883_MEDION_MD2,
172	ALC883_LAPTOP_EAPD,
173	ALC883_LENOVO_101E_2ch,
174	ALC883_LENOVO_NB0763,
175	ALC888_LENOVO_MS7195_DIG,
176	ALC888_6ST_HP,
177	ALC888_3ST_HP,
178	ALC883_AUTO,
179	ALC883_MODEL_LAST,
180};
181
182/* for GPIO Poll */
183#define GPIO_MASK	0x03
184
185struct alc_spec {
186	/* codec parameterization */
187	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
188	unsigned int num_mixers;
189
190	const struct hda_verb *init_verbs[5];	/* initialization verbs
191						 * don't forget NULL
192						 * termination!
193						 */
194	unsigned int num_init_verbs;
195
196	char *stream_name_analog;	/* analog PCM stream */
197	struct hda_pcm_stream *stream_analog_playback;
198	struct hda_pcm_stream *stream_analog_capture;
199
200	char *stream_name_digital;	/* digital PCM stream */
201	struct hda_pcm_stream *stream_digital_playback;
202	struct hda_pcm_stream *stream_digital_capture;
203
204	/* playback */
205	struct hda_multi_out multiout;	/* playback set-up
206					 * max_channels, dacs must be set
207					 * dig_out_nid and hp_nid are optional
208					 */
209
210	/* capture */
211	unsigned int num_adc_nids;
212	hda_nid_t *adc_nids;
213	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
214
215	/* capture source */
216	unsigned int num_mux_defs;
217	const struct hda_input_mux *input_mux;
218	unsigned int cur_mux[3];
219
220	/* channel model */
221	const struct hda_channel_mode *channel_mode;
222	int num_channel_mode;
223	int need_dac_fix;
224
225	/* PCM information */
226	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
227
228	/* dynamic controls, init_verbs and input_mux */
229	struct auto_pin_cfg autocfg;
230	unsigned int num_kctl_alloc, num_kctl_used;
231	struct snd_kcontrol_new *kctl_alloc;
232	struct hda_input_mux private_imux;
233	hda_nid_t private_dac_nids[5];
234
235	/* hooks */
236	void (*init_hook)(struct hda_codec *codec);
237	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
238
239	/* for pin sensing */
240	unsigned int sense_updated: 1;
241	unsigned int jack_present: 1;
242};
243
244/*
245 * configuration template - to be copied to the spec instance
246 */
247struct alc_config_preset {
248	struct snd_kcontrol_new *mixers[5]; /* should be identical size
249					     * with spec
250					     */
251	const struct hda_verb *init_verbs[5];
252	unsigned int num_dacs;
253	hda_nid_t *dac_nids;
254	hda_nid_t dig_out_nid;		/* optional */
255	hda_nid_t hp_nid;		/* optional */
256	unsigned int num_adc_nids;
257	hda_nid_t *adc_nids;
258	hda_nid_t dig_in_nid;
259	unsigned int num_channel_mode;
260	const struct hda_channel_mode *channel_mode;
261	int need_dac_fix;
262	unsigned int num_mux_defs;
263	const struct hda_input_mux *input_mux;
264	void (*unsol_event)(struct hda_codec *, unsigned int);
265	void (*init_hook)(struct hda_codec *);
266};
267
268
269/*
270 * input MUX handling
271 */
272static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
273			     struct snd_ctl_elem_info *uinfo)
274{
275	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
276	struct alc_spec *spec = codec->spec;
277	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
278	if (mux_idx >= spec->num_mux_defs)
279		mux_idx = 0;
280	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
281}
282
283static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
284			    struct snd_ctl_elem_value *ucontrol)
285{
286	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
287	struct alc_spec *spec = codec->spec;
288	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
289
290	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
291	return 0;
292}
293
294static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
295			    struct snd_ctl_elem_value *ucontrol)
296{
297	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
298	struct alc_spec *spec = codec->spec;
299	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
300	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
301	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
302				     spec->adc_nids[adc_idx],
303				     &spec->cur_mux[adc_idx]);
304}
305
306
307/*
308 * channel mode setting
309 */
310static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
311			    struct snd_ctl_elem_info *uinfo)
312{
313	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
314	struct alc_spec *spec = codec->spec;
315	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
316				    spec->num_channel_mode);
317}
318
319static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
320			   struct snd_ctl_elem_value *ucontrol)
321{
322	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
323	struct alc_spec *spec = codec->spec;
324	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
325				   spec->num_channel_mode,
326				   spec->multiout.max_channels);
327}
328
329static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
330			   struct snd_ctl_elem_value *ucontrol)
331{
332	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
333	struct alc_spec *spec = codec->spec;
334	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
335				      spec->num_channel_mode,
336				      &spec->multiout.max_channels);
337	if (err >= 0 && spec->need_dac_fix)
338		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
339	return err;
340}
341
342/*
343 * Control the mode of pin widget settings via the mixer.  "pc" is used
344 * instead of "%" to avoid consequences of accidently treating the % as
345 * being part of a format specifier.  Maximum allowed length of a value is
346 * 63 characters plus NULL terminator.
347 *
348 * Note: some retasking pin complexes seem to ignore requests for input
349 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
350 * are requested.  Therefore order this list so that this behaviour will not
351 * cause problems when mixer clients move through the enum sequentially.
352 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
353 * March 2006.
354 */
355static char *alc_pin_mode_names[] = {
356	"Mic 50pc bias", "Mic 80pc bias",
357	"Line in", "Line out", "Headphone out",
358};
359static unsigned char alc_pin_mode_values[] = {
360	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
361};
362/* The control can present all 5 options, or it can limit the options based
363 * in the pin being assumed to be exclusively an input or an output pin.  In
364 * addition, "input" pins may or may not process the mic bias option
365 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
366 * accept requests for bias as of chip versions up to March 2006) and/or
367 * wiring in the computer.
368 */
369#define ALC_PIN_DIR_IN              0x00
370#define ALC_PIN_DIR_OUT             0x01
371#define ALC_PIN_DIR_INOUT           0x02
372#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
373#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
374
375/* Info about the pin modes supported by the different pin direction modes.
376 * For each direction the minimum and maximum values are given.
377 */
378static signed char alc_pin_mode_dir_info[5][2] = {
379	{ 0, 2 },    /* ALC_PIN_DIR_IN */
380	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
381	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
382	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
383	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
384};
385#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
386#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
387#define alc_pin_mode_n_items(_dir) \
388	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
389
390static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
391			     struct snd_ctl_elem_info *uinfo)
392{
393	unsigned int item_num = uinfo->value.enumerated.item;
394	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
395
396	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
397	uinfo->count = 1;
398	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
399
400	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
401		item_num = alc_pin_mode_min(dir);
402	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
403	return 0;
404}
405
406static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
407			    struct snd_ctl_elem_value *ucontrol)
408{
409	unsigned int i;
410	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
411	hda_nid_t nid = kcontrol->private_value & 0xffff;
412	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
413	long *valp = ucontrol->value.integer.value;
414	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
415						 AC_VERB_GET_PIN_WIDGET_CONTROL,
416						 0x00);
417
418	/* Find enumerated value for current pinctl setting */
419	i = alc_pin_mode_min(dir);
420	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
421		i++;
422	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
423	return 0;
424}
425
426static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
427			    struct snd_ctl_elem_value *ucontrol)
428{
429	signed int change;
430	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
431	hda_nid_t nid = kcontrol->private_value & 0xffff;
432	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
433	long val = *ucontrol->value.integer.value;
434	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
435						 AC_VERB_GET_PIN_WIDGET_CONTROL,
436						 0x00);
437
438	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
439		val = alc_pin_mode_min(dir);
440
441	change = pinctl != alc_pin_mode_values[val];
442	if (change) {
443		/* Set pin mode to that requested */
444		snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
445				    alc_pin_mode_values[val]);
446
447		/* Also enable the retasking pin's input/output as required
448		 * for the requested pin mode.  Enum values of 2 or less are
449		 * input modes.
450		 *
451		 * Dynamically switching the input/output buffers probably
452		 * reduces noise slightly (particularly on input) so we'll
453		 * do it.  However, having both input and output buffers
454		 * enabled simultaneously doesn't seem to be problematic if
455		 * this turns out to be necessary in the future.
456		 */
457		if (val <= 2) {
458			snd_hda_codec_write(codec, nid, 0,
459					    AC_VERB_SET_AMP_GAIN_MUTE,
460					    AMP_OUT_MUTE);
461			snd_hda_codec_write(codec, nid, 0,
462					    AC_VERB_SET_AMP_GAIN_MUTE,
463					    AMP_IN_UNMUTE(0));
464		} else {
465			snd_hda_codec_write(codec, nid, 0,
466					    AC_VERB_SET_AMP_GAIN_MUTE,
467					    AMP_IN_MUTE(0));
468			snd_hda_codec_write(codec, nid, 0,
469					    AC_VERB_SET_AMP_GAIN_MUTE,
470					    AMP_OUT_UNMUTE);
471		}
472	}
473	return change;
474}
475
476#define ALC_PIN_MODE(xname, nid, dir) \
477	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
478	  .info = alc_pin_mode_info, \
479	  .get = alc_pin_mode_get, \
480	  .put = alc_pin_mode_put, \
481	  .private_value = nid | (dir<<16) }
482
483/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
484 * together using a mask with more than one bit set.  This control is
485 * currently used only by the ALC260 test model.  At this stage they are not
486 * needed for any "production" models.
487 */
488#ifdef CONFIG_SND_DEBUG
489#define alc_gpio_data_info	snd_ctl_boolean_mono_info
490
491static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
492			     struct snd_ctl_elem_value *ucontrol)
493{
494	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
495	hda_nid_t nid = kcontrol->private_value & 0xffff;
496	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
497	long *valp = ucontrol->value.integer.value;
498	unsigned int val = snd_hda_codec_read(codec, nid, 0,
499					      AC_VERB_GET_GPIO_DATA, 0x00);
500
501	*valp = (val & mask) != 0;
502	return 0;
503}
504static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
505			     struct snd_ctl_elem_value *ucontrol)
506{
507	signed int change;
508	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
509	hda_nid_t nid = kcontrol->private_value & 0xffff;
510	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
511	long val = *ucontrol->value.integer.value;
512	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
513						    AC_VERB_GET_GPIO_DATA,
514						    0x00);
515
516	/* Set/unset the masked GPIO bit(s) as needed */
517	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
518	if (val == 0)
519		gpio_data &= ~mask;
520	else
521		gpio_data |= mask;
522	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
523
524	return change;
525}
526#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
527	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
528	  .info = alc_gpio_data_info, \
529	  .get = alc_gpio_data_get, \
530	  .put = alc_gpio_data_put, \
531	  .private_value = nid | (mask<<16) }
532#endif   /* CONFIG_SND_DEBUG */
533
534/* A switch control to allow the enabling of the digital IO pins on the
535 * ALC260.  This is incredibly simplistic; the intention of this control is
536 * to provide something in the test model allowing digital outputs to be
537 * identified if present.  If models are found which can utilise these
538 * outputs a more complete mixer control can be devised for those models if
539 * necessary.
540 */
541#ifdef CONFIG_SND_DEBUG
542#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
543
544static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
545			      struct snd_ctl_elem_value *ucontrol)
546{
547	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548	hda_nid_t nid = kcontrol->private_value & 0xffff;
549	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
550	long *valp = ucontrol->value.integer.value;
551	unsigned int val = snd_hda_codec_read(codec, nid, 0,
552					      AC_VERB_GET_DIGI_CONVERT, 0x00);
553
554	*valp = (val & mask) != 0;
555	return 0;
556}
557static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
558			      struct snd_ctl_elem_value *ucontrol)
559{
560	signed int change;
561	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
562	hda_nid_t nid = kcontrol->private_value & 0xffff;
563	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
564	long val = *ucontrol->value.integer.value;
565	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
566						    AC_VERB_GET_DIGI_CONVERT,
567						    0x00);
568
569	/* Set/unset the masked control bit(s) as needed */
570	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
571	if (val==0)
572		ctrl_data &= ~mask;
573	else
574		ctrl_data |= mask;
575	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
576			    ctrl_data);
577
578	return change;
579}
580#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
581	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
582	  .info = alc_spdif_ctrl_info, \
583	  .get = alc_spdif_ctrl_get, \
584	  .put = alc_spdif_ctrl_put, \
585	  .private_value = nid | (mask<<16) }
586#endif   /* CONFIG_SND_DEBUG */
587
588/*
589 * set up from the preset table
590 */
591static void setup_preset(struct alc_spec *spec,
592			 const struct alc_config_preset *preset)
593{
594	int i;
595
596	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
597		spec->mixers[spec->num_mixers++] = preset->mixers[i];
598	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
599	     i++)
600		spec->init_verbs[spec->num_init_verbs++] =
601			preset->init_verbs[i];
602
603	spec->channel_mode = preset->channel_mode;
604	spec->num_channel_mode = preset->num_channel_mode;
605	spec->need_dac_fix = preset->need_dac_fix;
606
607	spec->multiout.max_channels = spec->channel_mode[0].channels;
608
609	spec->multiout.num_dacs = preset->num_dacs;
610	spec->multiout.dac_nids = preset->dac_nids;
611	spec->multiout.dig_out_nid = preset->dig_out_nid;
612	spec->multiout.hp_nid = preset->hp_nid;
613
614	spec->num_mux_defs = preset->num_mux_defs;
615	if (!spec->num_mux_defs)
616		spec->num_mux_defs = 1;
617	spec->input_mux = preset->input_mux;
618
619	spec->num_adc_nids = preset->num_adc_nids;
620	spec->adc_nids = preset->adc_nids;
621	spec->dig_in_nid = preset->dig_in_nid;
622
623	spec->unsol_event = preset->unsol_event;
624	spec->init_hook = preset->init_hook;
625}
626
627/* Enable GPIO mask and set output */
628static struct hda_verb alc_gpio1_init_verbs[] = {
629	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
630	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
631	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
632	{ }
633};
634
635static struct hda_verb alc_gpio2_init_verbs[] = {
636	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
637	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
638	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
639	{ }
640};
641
642static struct hda_verb alc_gpio3_init_verbs[] = {
643	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
644	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
645	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
646	{ }
647};
648
649/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
650 *	31 ~ 16 :	Manufacture ID
651 *	15 ~ 8	:	SKU ID
652 *	7  ~ 0	:	Assembly ID
653 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
654 */
655static void alc_subsystem_id(struct hda_codec *codec,
656			     unsigned int porta, unsigned int porte,
657			     unsigned int portd)
658{
659	unsigned int ass, tmp;
660
661	ass = codec->subsystem_id;
662	if (!(ass & 1))
663		return;
664
665	/* Override */
666	tmp = (ass & 0x38) >> 3;	/* external Amp control */
667	switch (tmp) {
668	case 1:
669		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
670		break;
671	case 3:
672		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
673		break;
674	case 7:
675		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
676		break;
677	case 5:
678		switch (codec->vendor_id) {
679		case 0x10ec0862:
680		case 0x10ec0660:
681		case 0x10ec0662:
682		case 0x10ec0267:
683		case 0x10ec0268:
684			snd_hda_codec_write(codec, 0x14, 0,
685					    AC_VERB_SET_EAPD_BTLENABLE, 2);
686			snd_hda_codec_write(codec, 0x15, 0,
687					    AC_VERB_SET_EAPD_BTLENABLE, 2);
688			return;
689		}
690	case 6:
691		if (ass & 4) {	/* bit 2 : 0 = Desktop, 1 = Laptop */
692			hda_nid_t port = 0;
693			tmp = (ass & 0x1800) >> 11;
694			switch (tmp) {
695			case 0: port = porta; break;
696			case 1: port = porte; break;
697			case 2: port = portd; break;
698			}
699			if (port)
700				snd_hda_codec_write(codec, port, 0,
701						    AC_VERB_SET_EAPD_BTLENABLE,
702						    2);
703		}
704		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
705		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
706				    (tmp == 5 ? 0x3040 : 0x3050));
707		break;
708	}
709}
710
711/*
712 * Fix-up pin default configurations
713 */
714
715struct alc_pincfg {
716	hda_nid_t nid;
717	u32 val;
718};
719
720static void alc_fix_pincfg(struct hda_codec *codec,
721			   const struct snd_pci_quirk *quirk,
722			   const struct alc_pincfg **pinfix)
723{
724	const struct alc_pincfg *cfg;
725
726	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
727	if (!quirk)
728		return;
729
730	cfg = pinfix[quirk->value];
731	for (; cfg->nid; cfg++) {
732		int i;
733		u32 val = cfg->val;
734		for (i = 0; i < 4; i++) {
735			snd_hda_codec_write(codec, cfg->nid, 0,
736				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
737				    val & 0xff);
738			val >>= 8;
739		}
740	}
741}
742
743/*
744 * ALC880 3-stack model
745 *
746 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
747 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
748 *                 F-Mic = 0x1b, HP = 0x19
749 */
750
751static hda_nid_t alc880_dac_nids[4] = {
752	/* front, rear, clfe, rear_surr */
753	0x02, 0x05, 0x04, 0x03
754};
755
756static hda_nid_t alc880_adc_nids[3] = {
757	/* ADC0-2 */
758	0x07, 0x08, 0x09,
759};
760
761/* The datasheet says the node 0x07 is connected from inputs,
762 * but it shows zero connection in the real implementation on some devices.
763 * Note: this is a 915GAV bug, fixed on 915GLV
764 */
765static hda_nid_t alc880_adc_nids_alt[2] = {
766	/* ADC1-2 */
767	0x08, 0x09,
768};
769
770#define ALC880_DIGOUT_NID	0x06
771#define ALC880_DIGIN_NID	0x0a
772
773static struct hda_input_mux alc880_capture_source = {
774	.num_items = 4,
775	.items = {
776		{ "Mic", 0x0 },
777		{ "Front Mic", 0x3 },
778		{ "Line", 0x2 },
779		{ "CD", 0x4 },
780	},
781};
782
783/* channel source setting (2/6 channel selection for 3-stack) */
784/* 2ch mode */
785static struct hda_verb alc880_threestack_ch2_init[] = {
786	/* set line-in to input, mute it */
787	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
788	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
789	/* set mic-in to input vref 80%, mute it */
790	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
791	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
792	{ } /* end */
793};
794
795/* 6ch mode */
796static struct hda_verb alc880_threestack_ch6_init[] = {
797	/* set line-in to output, unmute it */
798	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
799	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
800	/* set mic-in to output, unmute it */
801	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
802	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
803	{ } /* end */
804};
805
806static struct hda_channel_mode alc880_threestack_modes[2] = {
807	{ 2, alc880_threestack_ch2_init },
808	{ 6, alc880_threestack_ch6_init },
809};
810
811static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
812	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
813	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
814	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
815	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
816	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
817	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
818	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
819	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
820	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
821	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
822	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
823	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
824	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
825	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
826	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
827	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
828	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
829	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
830	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
831	{
832		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
833		.name = "Channel Mode",
834		.info = alc_ch_mode_info,
835		.get = alc_ch_mode_get,
836		.put = alc_ch_mode_put,
837	},
838	{ } /* end */
839};
840
841/* capture mixer elements */
842static struct snd_kcontrol_new alc880_capture_mixer[] = {
843	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
844	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
845	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
846	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
847	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
848	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
849	{
850		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
851		/* The multiple "Capture Source" controls confuse alsamixer
852		 * So call somewhat different..
853		 * FIXME: the controls appear in the "playback" view!
854		 */
855		/* .name = "Capture Source", */
856		.name = "Input Source",
857		.count = 3,
858		.info = alc_mux_enum_info,
859		.get = alc_mux_enum_get,
860		.put = alc_mux_enum_put,
861	},
862	{ } /* end */
863};
864
865/* capture mixer elements (in case NID 0x07 not available) */
866static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
867	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
868	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
869	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
870	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
871	{
872		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
873		/* The multiple "Capture Source" controls confuse alsamixer
874		 * So call somewhat different..
875		 * FIXME: the controls appear in the "playback" view!
876		 */
877		/* .name = "Capture Source", */
878		.name = "Input Source",
879		.count = 2,
880		.info = alc_mux_enum_info,
881		.get = alc_mux_enum_get,
882		.put = alc_mux_enum_put,
883	},
884	{ } /* end */
885};
886
887
888
889/*
890 * ALC880 5-stack model
891 *
892 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
893 *      Side = 0x02 (0xd)
894 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
895 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
896 */
897
898/* additional mixers to alc880_three_stack_mixer */
899static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
900	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
901	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
902	{ } /* end */
903};
904
905/* channel source setting (6/8 channel selection for 5-stack) */
906/* 6ch mode */
907static struct hda_verb alc880_fivestack_ch6_init[] = {
908	/* set line-in to input, mute it */
909	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
910	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
911	{ } /* end */
912};
913
914/* 8ch mode */
915static struct hda_verb alc880_fivestack_ch8_init[] = {
916	/* set line-in to output, unmute it */
917	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
918	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
919	{ } /* end */
920};
921
922static struct hda_channel_mode alc880_fivestack_modes[2] = {
923	{ 6, alc880_fivestack_ch6_init },
924	{ 8, alc880_fivestack_ch8_init },
925};
926
927
928/*
929 * ALC880 6-stack model
930 *
931 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
932 *      Side = 0x05 (0x0f)
933 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
934 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
935 */
936
937static hda_nid_t alc880_6st_dac_nids[4] = {
938	/* front, rear, clfe, rear_surr */
939	0x02, 0x03, 0x04, 0x05
940};
941
942static struct hda_input_mux alc880_6stack_capture_source = {
943	.num_items = 4,
944	.items = {
945		{ "Mic", 0x0 },
946		{ "Front Mic", 0x1 },
947		{ "Line", 0x2 },
948		{ "CD", 0x4 },
949	},
950};
951
952/* fixed 8-channels */
953static struct hda_channel_mode alc880_sixstack_modes[1] = {
954	{ 8, NULL },
955};
956
957static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
958	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
959	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
960	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
961	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
962	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
963	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
964	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
965	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
966	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
967	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
968	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
969	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
970	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
971	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
972	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
973	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
974	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
975	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
976	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
977	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
978	{
979		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
980		.name = "Channel Mode",
981		.info = alc_ch_mode_info,
982		.get = alc_ch_mode_get,
983		.put = alc_ch_mode_put,
984	},
985	{ } /* end */
986};
987
988
989/*
990 * ALC880 W810 model
991 *
992 * W810 has rear IO for:
993 * Front (DAC 02)
994 * Surround (DAC 03)
995 * Center/LFE (DAC 04)
996 * Digital out (06)
997 *
998 * The system also has a pair of internal speakers, and a headphone jack.
999 * These are both connected to Line2 on the codec, hence to DAC 02.
1000 *
1001 * There is a variable resistor to control the speaker or headphone
1002 * volume. This is a hardware-only device without a software API.
1003 *
1004 * Plugging headphones in will disable the internal speakers. This is
1005 * implemented in hardware, not via the driver using jack sense. In
1006 * a similar fashion, plugging into the rear socket marked "front" will
1007 * disable both the speakers and headphones.
1008 *
1009 * For input, there's a microphone jack, and an "audio in" jack.
1010 * These may not do anything useful with this driver yet, because I
1011 * haven't setup any initialization verbs for these yet...
1012 */
1013
1014static hda_nid_t alc880_w810_dac_nids[3] = {
1015	/* front, rear/surround, clfe */
1016	0x02, 0x03, 0x04
1017};
1018
1019/* fixed 6 channels */
1020static struct hda_channel_mode alc880_w810_modes[1] = {
1021	{ 6, NULL }
1022};
1023
1024/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1025static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1026	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1027	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1028	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1029	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1030	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1031	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1032	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1033	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1034	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1035	{ } /* end */
1036};
1037
1038
1039/*
1040 * Z710V model
1041 *
1042 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1043 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1044 *                 Line = 0x1a
1045 */
1046
1047static hda_nid_t alc880_z71v_dac_nids[1] = {
1048	0x02
1049};
1050#define ALC880_Z71V_HP_DAC	0x03
1051
1052/* fixed 2 channels */
1053static struct hda_channel_mode alc880_2_jack_modes[1] = {
1054	{ 2, NULL }
1055};
1056
1057static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1058	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1059	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1060	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1061	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1062	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1063	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1064	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1065	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1066	{ } /* end */
1067};
1068
1069
1070/* FIXME! */
1071/*
1072 * ALC880 F1734 model
1073 *
1074 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1075 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1076 */
1077
1078static hda_nid_t alc880_f1734_dac_nids[1] = {
1079	0x03
1080};
1081#define ALC880_F1734_HP_DAC	0x02
1082
1083static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1084	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1085	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1086	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1087	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1088	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1089	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1090	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1091	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1092	{ } /* end */
1093};
1094
1095
1096/* FIXME! */
1097/*
1098 * ALC880 ASUS model
1099 *
1100 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1101 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1102 *  Mic = 0x18, Line = 0x1a
1103 */
1104
1105#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1106#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1107
1108static struct snd_kcontrol_new alc880_asus_mixer[] = {
1109	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1110	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1111	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1112	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1113	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1114	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1115	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1116	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1117	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1118	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1119	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1120	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1121	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1122	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1123	{
1124		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1125		.name = "Channel Mode",
1126		.info = alc_ch_mode_info,
1127		.get = alc_ch_mode_get,
1128		.put = alc_ch_mode_put,
1129	},
1130	{ } /* end */
1131};
1132
1133/* FIXME! */
1134/*
1135 * ALC880 ASUS W1V model
1136 *
1137 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1138 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1139 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1140 */
1141
1142/* additional mixers to alc880_asus_mixer */
1143static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1144	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1145	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1146	{ } /* end */
1147};
1148
1149/* additional mixers to alc880_asus_mixer */
1150static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1151	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1152	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1153	{ } /* end */
1154};
1155
1156/* TCL S700 */
1157static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1158	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1159	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1160	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1161	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1162	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1163	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1164	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1165	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1166	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1167	{
1168		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1169		/* The multiple "Capture Source" controls confuse alsamixer
1170		 * So call somewhat different..
1171		 * FIXME: the controls appear in the "playback" view!
1172		 */
1173		/* .name = "Capture Source", */
1174		.name = "Input Source",
1175		.count = 1,
1176		.info = alc_mux_enum_info,
1177		.get = alc_mux_enum_get,
1178		.put = alc_mux_enum_put,
1179	},
1180	{ } /* end */
1181};
1182
1183/* Uniwill */
1184static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1185	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1186	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1187	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1188	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1189	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1190	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1191	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1192	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1193	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1194	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1195	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1196	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1197	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1198	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1199	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1200	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1201	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1202	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1203	{
1204		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1205		.name = "Channel Mode",
1206		.info = alc_ch_mode_info,
1207		.get = alc_ch_mode_get,
1208		.put = alc_ch_mode_put,
1209	},
1210	{ } /* end */
1211};
1212
1213static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1214	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1215	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1216	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1217	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1218	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1219	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1220	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1221	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1222	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1223	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1224	{ } /* end */
1225};
1226
1227static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1228	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1229	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1230	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1231	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1232	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1233	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1234	{ } /* end */
1235};
1236
1237/*
1238 * build control elements
1239 */
1240static int alc_build_controls(struct hda_codec *codec)
1241{
1242	struct alc_spec *spec = codec->spec;
1243	int err;
1244	int i;
1245
1246	for (i = 0; i < spec->num_mixers; i++) {
1247		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1248		if (err < 0)
1249			return err;
1250	}
1251
1252	if (spec->multiout.dig_out_nid) {
1253		err = snd_hda_create_spdif_out_ctls(codec,
1254						    spec->multiout.dig_out_nid);
1255		if (err < 0)
1256			return err;
1257	}
1258	if (spec->dig_in_nid) {
1259		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1260		if (err < 0)
1261			return err;
1262	}
1263	return 0;
1264}
1265
1266
1267/*
1268 * initialize the codec volumes, etc
1269 */
1270
1271/*
1272 * generic initialization of ADC, input mixers and output mixers
1273 */
1274static struct hda_verb alc880_volume_init_verbs[] = {
1275	/*
1276	 * Unmute ADC0-2 and set the default input to mic-in
1277	 */
1278	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1279	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1280	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1281	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1282	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1283	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1284
1285	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1286	 * mixer widget
1287	 * Note: PASD motherboards uses the Line In 2 as the input for front
1288	 * panel mic (mic 2)
1289	 */
1290	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1291	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1292	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1293	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1294	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1295	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1296
1297	/*
1298	 * Set up output mixers (0x0c - 0x0f)
1299	 */
1300	/* set vol=0 to output mixers */
1301	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1302	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1303	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1304	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1305	/* set up input amps for analog loopback */
1306	/* Amp Indices: DAC = 0, mixer = 1 */
1307	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1308	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1309	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1310	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1311	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1312	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1313	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1314	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1315
1316	{ }
1317};
1318
1319/*
1320 * 3-stack pin configuration:
1321 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1322 */
1323static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1324	/*
1325	 * preset connection lists of input pins
1326	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1327	 */
1328	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1329	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1330	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1331
1332	/*
1333	 * Set pin mode and muting
1334	 */
1335	/* set front pin widgets 0x14 for output */
1336	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1337	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1338	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1339	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1340	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1341	/* Mic2 (as headphone out) for HP output */
1342	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1343	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1344	/* Line In pin widget for input */
1345	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1346	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1347	/* Line2 (as front mic) pin widget for input and vref at 80% */
1348	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1349	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1350	/* CD pin widget for input */
1351	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1352
1353	{ }
1354};
1355
1356/*
1357 * 5-stack pin configuration:
1358 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1359 * line-in/side = 0x1a, f-mic = 0x1b
1360 */
1361static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1362	/*
1363	 * preset connection lists of input pins
1364	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1365	 */
1366	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1367	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1368
1369	/*
1370	 * Set pin mode and muting
1371	 */
1372	/* set pin widgets 0x14-0x17 for output */
1373	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1374	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1375	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1377	/* unmute pins for output (no gain on this amp) */
1378	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1379	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1380	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1381	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1382
1383	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1384	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1385	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1386	/* Mic2 (as headphone out) for HP output */
1387	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1388	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1389	/* Line In pin widget for input */
1390	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1391	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1392	/* Line2 (as front mic) pin widget for input and vref at 80% */
1393	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1394	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1395	/* CD pin widget for input */
1396	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1397
1398	{ }
1399};
1400
1401/*
1402 * W810 pin configuration:
1403 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1404 */
1405static struct hda_verb alc880_pin_w810_init_verbs[] = {
1406	/* hphone/speaker input selector: front DAC */
1407	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1408
1409	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1410	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1411	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1412	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1413	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1414	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1415
1416	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1417	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1418
1419	{ }
1420};
1421
1422/*
1423 * Z71V pin configuration:
1424 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1425 */
1426static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1427	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1428	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1429	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1430	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1431
1432	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1433	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1434	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1435	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1436
1437	{ }
1438};
1439
1440/*
1441 * 6-stack pin configuration:
1442 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1443 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1444 */
1445static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1446	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1447
1448	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1449	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1450	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1451	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1452	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1453	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1454	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1455	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1456
1457	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1458	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1459	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1460	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1461	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1462	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1463	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1464	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1466
1467	{ }
1468};
1469
1470/*
1471 * Uniwill pin configuration:
1472 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1473 * line = 0x1a
1474 */
1475static struct hda_verb alc880_uniwill_init_verbs[] = {
1476	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1477
1478	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1479	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1480	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1481	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1482	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1483	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1484	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1485	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1486	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1487	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1488	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1489	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1490	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1491	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1492
1493	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1494	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1495	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1496	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1497	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1498	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1499	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1500	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1501	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1502
1503	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1504	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1505
1506	{ }
1507};
1508
1509/*
1510* Uniwill P53
1511* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1512 */
1513static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1514	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1515
1516	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1517	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1518	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1519	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1520	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1521	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1522	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1523	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1524	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1525	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1526	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1527	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1528
1529	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1530	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1531	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1532	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1533	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1534	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1535
1536	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1537	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1538
1539	{ }
1540};
1541
1542static struct hda_verb alc880_beep_init_verbs[] = {
1543	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1544	{ }
1545};
1546
1547/* toggle speaker-output according to the hp-jack state */
1548static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1549{
1550 	unsigned int present;
1551	unsigned char bits;
1552
1553 	present = snd_hda_codec_read(codec, 0x14, 0,
1554				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1555	bits = present ? 0x80 : 0;
1556	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1557				 0x80, bits);
1558	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1559				 0x80, bits);
1560	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1561				 0x80, bits);
1562	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1563				 0x80, bits);
1564}
1565
1566/* auto-toggle front mic */
1567static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1568{
1569 	unsigned int present;
1570	unsigned char bits;
1571
1572	present = snd_hda_codec_read(codec, 0x18, 0,
1573				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1574	bits = present ? 0x80 : 0;
1575	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
1576				 0x80, bits);
1577	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
1578				 0x80, bits);
1579}
1580
1581static void alc880_uniwill_automute(struct hda_codec *codec)
1582{
1583	alc880_uniwill_hp_automute(codec);
1584	alc880_uniwill_mic_automute(codec);
1585}
1586
1587static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1588				       unsigned int res)
1589{
1590	/* Looks like the unsol event is incompatible with the standard
1591	 * definition.  4bit tag is placed at 28 bit!
1592	 */
1593	switch (res >> 28) {
1594	case ALC880_HP_EVENT:
1595		alc880_uniwill_hp_automute(codec);
1596		break;
1597	case ALC880_MIC_EVENT:
1598		alc880_uniwill_mic_automute(codec);
1599		break;
1600	}
1601}
1602
1603static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1604{
1605 	unsigned int present;
1606	unsigned char bits;
1607
1608 	present = snd_hda_codec_read(codec, 0x14, 0,
1609				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1610	bits = present ? 0x80 : 0;
1611	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1612				 0x80, bits);
1613	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1614				 0x80, bits);
1615}
1616
1617static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1618{
1619	unsigned int present;
1620
1621	present = snd_hda_codec_read(codec, 0x21, 0,
1622				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1623
1624	snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1625				 0x7f, present);
1626	snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1627				 0x7f,  present);
1628
1629	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1630				 0x7f,  present);
1631	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1632				 0x7f, present);
1633
1634}
1635static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1636					   unsigned int res)
1637{
1638	/* Looks like the unsol event is incompatible with the standard
1639	 * definition.  4bit tag is placed at 28 bit!
1640	 */
1641	if ((res >> 28) == ALC880_HP_EVENT)
1642		alc880_uniwill_p53_hp_automute(codec);
1643	if ((res >> 28) == ALC880_DCVOL_EVENT)
1644		alc880_uniwill_p53_dcvol_automute(codec);
1645}
1646
1647/* FIXME! */
1648/*
1649 * F1734 pin configuration:
1650 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1651 */
1652static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1653	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1654	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1655	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1656	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1657
1658	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1659	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1660	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662
1663	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1664	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1665	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1666	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1667	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1668	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1669	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1670	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1672
1673	{ }
1674};
1675
1676/* FIXME! */
1677/*
1678 * ASUS pin configuration:
1679 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1680 */
1681static struct hda_verb alc880_pin_asus_init_verbs[] = {
1682	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1683	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1684	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1685	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1686
1687	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1688	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1690	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1694	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695
1696	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1697	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1698	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1699	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1700	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1701	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1702	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1703	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1705
1706	{ }
1707};
1708
1709/* Enable GPIO mask and set output */
1710#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1711#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1712
1713/* Clevo m520g init */
1714static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1715	/* headphone output */
1716	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1717	/* line-out */
1718	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1719	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1720	/* Line-in */
1721	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1722	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1723	/* CD */
1724	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1725	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726	/* Mic1 (rear panel) */
1727	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1728	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1729	/* Mic2 (front panel) */
1730	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1731	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732	/* headphone */
1733	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1734	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1735        /* change to EAPD mode */
1736	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1737	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1738
1739	{ }
1740};
1741
1742static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1743	/* change to EAPD mode */
1744	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1745	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1746
1747	/* Headphone output */
1748	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1749	/* Front output*/
1750	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1752
1753	/* Line In pin widget for input */
1754	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1755	/* CD pin widget for input */
1756	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1757	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1758	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1759
1760	/* change to EAPD mode */
1761	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1762	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1763
1764	{ }
1765};
1766
1767/*
1768 * LG m1 express dual
1769 *
1770 * Pin assignment:
1771 *   Rear Line-In/Out (blue): 0x14
1772 *   Build-in Mic-In: 0x15
1773 *   Speaker-out: 0x17
1774 *   HP-Out (green): 0x1b
1775 *   Mic-In/Out (red): 0x19
1776 *   SPDIF-Out: 0x1e
1777 */
1778
1779/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1780static hda_nid_t alc880_lg_dac_nids[3] = {
1781	0x05, 0x02, 0x03
1782};
1783
1784/* seems analog CD is not working */
1785static struct hda_input_mux alc880_lg_capture_source = {
1786	.num_items = 3,
1787	.items = {
1788		{ "Mic", 0x1 },
1789		{ "Line", 0x5 },
1790		{ "Internal Mic", 0x6 },
1791	},
1792};
1793
1794/* 2,4,6 channel modes */
1795static struct hda_verb alc880_lg_ch2_init[] = {
1796	/* set line-in and mic-in to input */
1797	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1798	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1799	{ }
1800};
1801
1802static struct hda_verb alc880_lg_ch4_init[] = {
1803	/* set line-in to out and mic-in to input */
1804	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1805	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1806	{ }
1807};
1808
1809static struct hda_verb alc880_lg_ch6_init[] = {
1810	/* set line-in and mic-in to output */
1811	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1812	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1813	{ }
1814};
1815
1816static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1817	{ 2, alc880_lg_ch2_init },
1818	{ 4, alc880_lg_ch4_init },
1819	{ 6, alc880_lg_ch6_init },
1820};
1821
1822static struct snd_kcontrol_new alc880_lg_mixer[] = {
1823	/* FIXME: it's not really "master" but front channels */
1824	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1825	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1826	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1827	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1828	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1829	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1830	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1831	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1832	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1833	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1834	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1835	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1836	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1837	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1838	{
1839		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1840		.name = "Channel Mode",
1841		.info = alc_ch_mode_info,
1842		.get = alc_ch_mode_get,
1843		.put = alc_ch_mode_put,
1844	},
1845	{ } /* end */
1846};
1847
1848static struct hda_verb alc880_lg_init_verbs[] = {
1849	/* set capture source to mic-in */
1850	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1851	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1852	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1853	/* mute all amp mixer inputs */
1854	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1855	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1856	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1857	/* line-in to input */
1858	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1859	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1860	/* built-in mic */
1861	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1862	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863	/* speaker-out */
1864	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1865	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866	/* mic-in to input */
1867	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1868	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1869	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870	/* HP-out */
1871	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1872	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1873	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874	/* jack sense */
1875	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1876	{ }
1877};
1878
1879/* toggle speaker-output according to the hp-jack state */
1880static void alc880_lg_automute(struct hda_codec *codec)
1881{
1882	unsigned int present;
1883	unsigned char bits;
1884
1885	present = snd_hda_codec_read(codec, 0x1b, 0,
1886				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1887	bits = present ? 0x80 : 0;
1888	snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1889				 0x80, bits);
1890	snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1891				 0x80, bits);
1892}
1893
1894static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1895{
1896	/* Looks like the unsol event is incompatible with the standard
1897	 * definition.  4bit tag is placed at 28 bit!
1898	 */
1899	if ((res >> 28) == 0x01)
1900		alc880_lg_automute(codec);
1901}
1902
1903/*
1904 * LG LW20
1905 *
1906 * Pin assignment:
1907 *   Speaker-out: 0x14
1908 *   Mic-In: 0x18
1909 *   Built-in Mic-In: 0x19
1910 *   Line-In: 0x1b
1911 *   HP-Out: 0x1a
1912 *   SPDIF-Out: 0x1e
1913 */
1914
1915static struct hda_input_mux alc880_lg_lw_capture_source = {
1916	.num_items = 3,
1917	.items = {
1918		{ "Mic", 0x0 },
1919		{ "Internal Mic", 0x1 },
1920		{ "Line In", 0x2 },
1921	},
1922};
1923
1924#define alc880_lg_lw_modes alc880_threestack_modes
1925
1926static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1927	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1928	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1929	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1930	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1931	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1932	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1933	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1934	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1935	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1936	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1937	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1938	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1939	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1940	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1941	{
1942		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1943		.name = "Channel Mode",
1944		.info = alc_ch_mode_info,
1945		.get = alc_ch_mode_get,
1946		.put = alc_ch_mode_put,
1947	},
1948	{ } /* end */
1949};
1950
1951static struct hda_verb alc880_lg_lw_init_verbs[] = {
1952	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1953	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1954	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1955
1956	/* set capture source to mic-in */
1957	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1958	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1959	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1960	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1961	/* speaker-out */
1962	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1963	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1964	/* HP-out */
1965	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1966	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1967	/* mic-in to input */
1968	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1969	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1970	/* built-in mic */
1971	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1972	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1973	/* jack sense */
1974	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1975	{ }
1976};
1977
1978/* toggle speaker-output according to the hp-jack state */
1979static void alc880_lg_lw_automute(struct hda_codec *codec)
1980{
1981	unsigned int present;
1982	unsigned char bits;
1983
1984	present = snd_hda_codec_read(codec, 0x1b, 0,
1985				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1986	bits = present ? 0x80 : 0;
1987	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1988				 0x80, bits);
1989	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1990				 0x80, bits);
1991}
1992
1993static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1994{
1995	/* Looks like the unsol event is incompatible with the standard
1996	 * definition.  4bit tag is placed at 28 bit!
1997	 */
1998	if ((res >> 28) == 0x01)
1999		alc880_lg_lw_automute(codec);
2000}
2001
2002/*
2003 * Common callbacks
2004 */
2005
2006static int alc_init(struct hda_codec *codec)
2007{
2008	struct alc_spec *spec = codec->spec;
2009	unsigned int i;
2010
2011	for (i = 0; i < spec->num_init_verbs; i++)
2012		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2013
2014	if (spec->init_hook)
2015		spec->init_hook(codec);
2016
2017	return 0;
2018}
2019
2020static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2021{
2022	struct alc_spec *spec = codec->spec;
2023
2024	if (spec->unsol_event)
2025		spec->unsol_event(codec, res);
2026}
2027
2028#ifdef CONFIG_PM
2029/*
2030 * resume
2031 */
2032static int alc_resume(struct hda_codec *codec)
2033{
2034	struct alc_spec *spec = codec->spec;
2035	int i;
2036
2037	alc_init(codec);
2038	for (i = 0; i < spec->num_mixers; i++)
2039		snd_hda_resume_ctls(codec, spec->mixers[i]);
2040	if (spec->multiout.dig_out_nid)
2041		snd_hda_resume_spdif_out(codec);
2042	if (spec->dig_in_nid)
2043		snd_hda_resume_spdif_in(codec);
2044
2045	return 0;
2046}
2047#endif
2048
2049/*
2050 * Analog playback callbacks
2051 */
2052static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2053				    struct hda_codec *codec,
2054				    struct snd_pcm_substream *substream)
2055{
2056	struct alc_spec *spec = codec->spec;
2057	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2058}
2059
2060static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2061				       struct hda_codec *codec,
2062				       unsigned int stream_tag,
2063				       unsigned int format,
2064				       struct snd_pcm_substream *substream)
2065{
2066	struct alc_spec *spec = codec->spec;
2067	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2068						stream_tag, format, substream);
2069}
2070
2071static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2072				       struct hda_codec *codec,
2073				       struct snd_pcm_substream *substream)
2074{
2075	struct alc_spec *spec = codec->spec;
2076	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2077}
2078
2079/*
2080 * Digital out
2081 */
2082static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2083					struct hda_codec *codec,
2084					struct snd_pcm_substream *substream)
2085{
2086	struct alc_spec *spec = codec->spec;
2087	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2088}
2089
2090static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2091					   struct hda_codec *codec,
2092					   unsigned int stream_tag,
2093					   unsigned int format,
2094					   struct snd_pcm_substream *substream)
2095{
2096	struct alc_spec *spec = codec->spec;
2097	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2098					     stream_tag, format, substream);
2099}
2100
2101static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2102					 struct hda_codec *codec,
2103					 struct snd_pcm_substream *substream)
2104{
2105	struct alc_spec *spec = codec->spec;
2106	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2107}
2108
2109/*
2110 * Analog capture
2111 */
2112static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2113				      struct hda_codec *codec,
2114				      unsigned int stream_tag,
2115				      unsigned int format,
2116				      struct snd_pcm_substream *substream)
2117{
2118	struct alc_spec *spec = codec->spec;
2119
2120	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2121				   stream_tag, 0, format);
2122	return 0;
2123}
2124
2125static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2126				      struct hda_codec *codec,
2127				      struct snd_pcm_substream *substream)
2128{
2129	struct alc_spec *spec = codec->spec;
2130
2131	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2132				   0, 0, 0);
2133	return 0;
2134}
2135
2136
2137/*
2138 */
2139static struct hda_pcm_stream alc880_pcm_analog_playback = {
2140	.substreams = 1,
2141	.channels_min = 2,
2142	.channels_max = 8,
2143	/* NID is set in alc_build_pcms */
2144	.ops = {
2145		.open = alc880_playback_pcm_open,
2146		.prepare = alc880_playback_pcm_prepare,
2147		.cleanup = alc880_playback_pcm_cleanup
2148	},
2149};
2150
2151static struct hda_pcm_stream alc880_pcm_analog_capture = {
2152	.substreams = 2,
2153	.channels_min = 2,
2154	.channels_max = 2,
2155	/* NID is set in alc_build_pcms */
2156	.ops = {
2157		.prepare = alc880_capture_pcm_prepare,
2158		.cleanup = alc880_capture_pcm_cleanup
2159	},
2160};
2161
2162static struct hda_pcm_stream alc880_pcm_digital_playback = {
2163	.substreams = 1,
2164	.channels_min = 2,
2165	.channels_max = 2,
2166	/* NID is set in alc_build_pcms */
2167	.ops = {
2168		.open = alc880_dig_playback_pcm_open,
2169		.close = alc880_dig_playback_pcm_close,
2170		.prepare = alc880_dig_playback_pcm_prepare
2171	},
2172};
2173
2174static struct hda_pcm_stream alc880_pcm_digital_capture = {
2175	.substreams = 1,
2176	.channels_min = 2,
2177	.channels_max = 2,
2178	/* NID is set in alc_build_pcms */
2179};
2180
2181/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2182static struct hda_pcm_stream alc_pcm_null_playback = {
2183	.substreams = 0,
2184	.channels_min = 0,
2185	.channels_max = 0,
2186};
2187
2188static int alc_build_pcms(struct hda_codec *codec)
2189{
2190	struct alc_spec *spec = codec->spec;
2191	struct hda_pcm *info = spec->pcm_rec;
2192	int i;
2193
2194	codec->num_pcms = 1;
2195	codec->pcm_info = info;
2196
2197	info->name = spec->stream_name_analog;
2198	if (spec->stream_analog_playback) {
2199		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2200		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2201		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2202	}
2203	if (spec->stream_analog_capture) {
2204		snd_assert(spec->adc_nids, return -EINVAL);
2205		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2206		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2207	}
2208
2209	if (spec->channel_mode) {
2210		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2211		for (i = 0; i < spec->num_channel_mode; i++) {
2212			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2213				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2214			}
2215		}
2216	}
2217
2218	/* SPDIF for stream index #1 */
2219	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2220		codec->num_pcms = 2;
2221		info = spec->pcm_rec + 1;
2222		info->name = spec->stream_name_digital;
2223		if (spec->multiout.dig_out_nid &&
2224		    spec->stream_digital_playback) {
2225			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2226			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2227		}
2228		if (spec->dig_in_nid &&
2229		    spec->stream_digital_capture) {
2230			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2231			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2232		}
2233	}
2234
2235	/* If the use of more than one ADC is requested for the current
2236	 * model, configure a second analog capture-only PCM.
2237	 */
2238	/* Additional Analaog capture for index #2 */
2239	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2240	    spec->adc_nids) {
2241		codec->num_pcms = 3;
2242		info = spec->pcm_rec + 2;
2243		info->name = spec->stream_name_analog;
2244		/* No playback stream for second PCM */
2245		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2246		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2247		if (spec->stream_analog_capture) {
2248			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2249			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2250		}
2251	}
2252
2253	return 0;
2254}
2255
2256static void alc_free(struct hda_codec *codec)
2257{
2258	struct alc_spec *spec = codec->spec;
2259	unsigned int i;
2260
2261	if (!spec)
2262		return;
2263
2264	if (spec->kctl_alloc) {
2265		for (i = 0; i < spec->num_kctl_used; i++)
2266			kfree(spec->kctl_alloc[i].name);
2267		kfree(spec->kctl_alloc);
2268	}
2269	kfree(spec);
2270}
2271
2272/*
2273 */
2274static struct hda_codec_ops alc_patch_ops = {
2275	.build_controls = alc_build_controls,
2276	.build_pcms = alc_build_pcms,
2277	.init = alc_init,
2278	.free = alc_free,
2279	.unsol_event = alc_unsol_event,
2280#ifdef CONFIG_PM
2281	.resume = alc_resume,
2282#endif
2283};
2284
2285
2286/*
2287 * Test configuration for debugging
2288 *
2289 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2290 * enum controls.
2291 */
2292#ifdef CONFIG_SND_DEBUG
2293static hda_nid_t alc880_test_dac_nids[4] = {
2294	0x02, 0x03, 0x04, 0x05
2295};
2296
2297static struct hda_input_mux alc880_test_capture_source = {
2298	.num_items = 7,
2299	.items = {
2300		{ "In-1", 0x0 },
2301		{ "In-2", 0x1 },
2302		{ "In-3", 0x2 },
2303		{ "In-4", 0x3 },
2304		{ "CD", 0x4 },
2305		{ "Front", 0x5 },
2306		{ "Surround", 0x6 },
2307	},
2308};
2309
2310static struct hda_channel_mode alc880_test_modes[4] = {
2311	{ 2, NULL },
2312	{ 4, NULL },
2313	{ 6, NULL },
2314	{ 8, NULL },
2315};
2316
2317static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2318				 struct snd_ctl_elem_info *uinfo)
2319{
2320	static char *texts[] = {
2321		"N/A", "Line Out", "HP Out",
2322		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2323	};
2324	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2325	uinfo->count = 1;
2326	uinfo->value.enumerated.items = 8;
2327	if (uinfo->value.enumerated.item >= 8)
2328		uinfo->value.enumerated.item = 7;
2329	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2330	return 0;
2331}
2332
2333static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2334				struct snd_ctl_elem_value *ucontrol)
2335{
2336	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2337	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2338	unsigned int pin_ctl, item = 0;
2339
2340	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2341				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2342	if (pin_ctl & AC_PINCTL_OUT_EN) {
2343		if (pin_ctl & AC_PINCTL_HP_EN)
2344			item = 2;
2345		else
2346			item = 1;
2347	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2348		switch (pin_ctl & AC_PINCTL_VREFEN) {
2349		case AC_PINCTL_VREF_HIZ: item = 3; break;
2350		case AC_PINCTL_VREF_50:  item = 4; break;
2351		case AC_PINCTL_VREF_GRD: item = 5; break;
2352		case AC_PINCTL_VREF_80:  item = 6; break;
2353		case AC_PINCTL_VREF_100: item = 7; break;
2354		}
2355	}
2356	ucontrol->value.enumerated.item[0] = item;
2357	return 0;
2358}
2359
2360static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2361				struct snd_ctl_elem_value *ucontrol)
2362{
2363	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2364	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2365	static unsigned int ctls[] = {
2366		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2367		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2368		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2369		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2370		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2371		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2372	};
2373	unsigned int old_ctl, new_ctl;
2374
2375	old_ctl = snd_hda_codec_read(codec, nid, 0,
2376				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2377	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2378	if (old_ctl != new_ctl) {
2379		snd_hda_codec_write(codec, nid, 0,
2380				    AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2381		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2382				    (ucontrol->value.enumerated.item[0] >= 3 ?
2383				     0xb080 : 0xb000));
2384		return 1;
2385	}
2386	return 0;
2387}
2388
2389static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2390				 struct snd_ctl_elem_info *uinfo)
2391{
2392	static char *texts[] = {
2393		"Front", "Surround", "CLFE", "Side"
2394	};
2395	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2396	uinfo->count = 1;
2397	uinfo->value.enumerated.items = 4;
2398	if (uinfo->value.enumerated.item >= 4)
2399		uinfo->value.enumerated.item = 3;
2400	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2401	return 0;
2402}
2403
2404static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2405				struct snd_ctl_elem_value *ucontrol)
2406{
2407	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2408	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2409	unsigned int sel;
2410
2411	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2412	ucontrol->value.enumerated.item[0] = sel & 3;
2413	return 0;
2414}
2415
2416static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2417				struct snd_ctl_elem_value *ucontrol)
2418{
2419	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2420	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2421	unsigned int sel;
2422
2423	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2424	if (ucontrol->value.enumerated.item[0] != sel) {
2425		sel = ucontrol->value.enumerated.item[0] & 3;
2426		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2427		return 1;
2428	}
2429	return 0;
2430}
2431
2432#define PIN_CTL_TEST(xname,nid) {			\
2433		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2434			.name = xname,		       \
2435			.info = alc_test_pin_ctl_info, \
2436			.get = alc_test_pin_ctl_get,   \
2437			.put = alc_test_pin_ctl_put,   \
2438			.private_value = nid	       \
2439			}
2440
2441#define PIN_SRC_TEST(xname,nid) {			\
2442		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2443			.name = xname,		       \
2444			.info = alc_test_pin_src_info, \
2445			.get = alc_test_pin_src_get,   \
2446			.put = alc_test_pin_src_put,   \
2447			.private_value = nid	       \
2448			}
2449
2450static struct snd_kcontrol_new alc880_test_mixer[] = {
2451	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2452	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2453	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2454	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2455	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2456	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2457	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2458	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2459	PIN_CTL_TEST("Front Pin Mode", 0x14),
2460	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2461	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2462	PIN_CTL_TEST("Side Pin Mode", 0x17),
2463	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2464	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2465	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2466	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2467	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2468	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2469	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2470	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2471	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2472	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2473	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2474	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2475	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2476	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2477	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2478	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2479	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2480	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2481	{
2482		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2483		.name = "Channel Mode",
2484		.info = alc_ch_mode_info,
2485		.get = alc_ch_mode_get,
2486		.put = alc_ch_mode_put,
2487	},
2488	{ } /* end */
2489};
2490
2491static struct hda_verb alc880_test_init_verbs[] = {
2492	/* Unmute inputs of 0x0c - 0x0f */
2493	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2494	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2495	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2496	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2497	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2498	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2499	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2500	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2501	/* Vol output for 0x0c-0x0f */
2502	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2503	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2504	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2505	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2506	/* Set output pins 0x14-0x17 */
2507	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2508	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2509	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2510	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2511	/* Unmute output pins 0x14-0x17 */
2512	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2513	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2514	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2515	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2516	/* Set input pins 0x18-0x1c */
2517	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2518	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2519	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2520	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2521	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2522	/* Mute input pins 0x18-0x1b */
2523	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2524	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2525	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2526	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2527	/* ADC set up */
2528	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2529	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2530	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2531	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2532	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2533	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2534	/* Analog input/passthru */
2535	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2536	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2537	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2538	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2539	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2540	{ }
2541};
2542#endif
2543
2544/*
2545 */
2546
2547static const char *alc880_models[ALC880_MODEL_LAST] = {
2548	[ALC880_3ST]		= "3stack",
2549	[ALC880_TCL_S700]	= "tcl",
2550	[ALC880_3ST_DIG]	= "3stack-digout",
2551	[ALC880_CLEVO]		= "clevo",
2552	[ALC880_5ST]		= "5stack",
2553	[ALC880_5ST_DIG]	= "5stack-digout",
2554	[ALC880_W810]		= "w810",
2555	[ALC880_Z71V]		= "z71v",
2556	[ALC880_6ST]		= "6stack",
2557	[ALC880_6ST_DIG]	= "6stack-digout",
2558	[ALC880_ASUS]		= "asus",
2559	[ALC880_ASUS_W1V]	= "asus-w1v",
2560	[ALC880_ASUS_DIG]	= "asus-dig",
2561	[ALC880_ASUS_DIG2]	= "asus-dig2",
2562	[ALC880_UNIWILL_DIG]	= "uniwill",
2563	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2564	[ALC880_FUJITSU]	= "fujitsu",
2565	[ALC880_F1734]		= "F1734",
2566	[ALC880_LG]		= "lg",
2567	[ALC880_LG_LW]		= "lg-lw",
2568#ifdef CONFIG_SND_DEBUG
2569	[ALC880_TEST]		= "test",
2570#endif
2571	[ALC880_AUTO]		= "auto",
2572};
2573
2574static struct snd_pci_quirk alc880_cfg_tbl[] = {
2575	/* Broken BIOS configuration */
2576	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2577	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2578
2579	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2580	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2581	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2582	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2583	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2584	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2585	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2586	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2587	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2588
2589	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2590	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2591
2592	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2593	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2594	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2595	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2596	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2597	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2598	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2599	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2600	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2601	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2602	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2603	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2604	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2605	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2606	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2607
2608	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2609	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2610	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2611	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2612	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2613	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2614	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2615	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2616	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2617	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2618	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2619	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2620	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2621	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2622	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2623	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2624	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2625	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2626
2627	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2628	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2629	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2630	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2631
2632	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2633	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2634	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2635	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2636
2637	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2638	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2639	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2640	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2641
2642	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2643	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2644	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2645	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2646	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2647	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2648	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2649	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2650	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2651	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2652	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2653
2654	{}
2655};
2656
2657/*
2658 * ALC880 codec presets
2659 */
2660static struct alc_config_preset alc880_presets[] = {
2661	[ALC880_3ST] = {
2662		.mixers = { alc880_three_stack_mixer },
2663		.init_verbs = { alc880_volume_init_verbs,
2664				alc880_pin_3stack_init_verbs },
2665		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2666		.dac_nids = alc880_dac_nids,
2667		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2668		.channel_mode = alc880_threestack_modes,
2669		.need_dac_fix = 1,
2670		.input_mux = &alc880_capture_source,
2671	},
2672	[ALC880_3ST_DIG] = {
2673		.mixers = { alc880_three_stack_mixer },
2674		.init_verbs = { alc880_volume_init_verbs,
2675				alc880_pin_3stack_init_verbs },
2676		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2677		.dac_nids = alc880_dac_nids,
2678		.dig_out_nid = ALC880_DIGOUT_NID,
2679		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2680		.channel_mode = alc880_threestack_modes,
2681		.need_dac_fix = 1,
2682		.input_mux = &alc880_capture_source,
2683	},
2684	[ALC880_TCL_S700] = {
2685		.mixers = { alc880_tcl_s700_mixer },
2686		.init_verbs = { alc880_volume_init_verbs,
2687				alc880_pin_tcl_S700_init_verbs,
2688				alc880_gpio2_init_verbs },
2689		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2690		.dac_nids = alc880_dac_nids,
2691		.hp_nid = 0x03,
2692		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2693		.channel_mode = alc880_2_jack_modes,
2694		.input_mux = &alc880_capture_source,
2695	},
2696	[ALC880_5ST] = {
2697		.mixers = { alc880_three_stack_mixer,
2698			    alc880_five_stack_mixer},
2699		.init_verbs = { alc880_volume_init_verbs,
2700				alc880_pin_5stack_init_verbs },
2701		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2702		.dac_nids = alc880_dac_nids,
2703		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2704		.channel_mode = alc880_fivestack_modes,
2705		.input_mux = &alc880_capture_source,
2706	},
2707	[ALC880_5ST_DIG] = {
2708		.mixers = { alc880_three_stack_mixer,
2709			    alc880_five_stack_mixer },
2710		.init_verbs = { alc880_volume_init_verbs,
2711				alc880_pin_5stack_init_verbs },
2712		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2713		.dac_nids = alc880_dac_nids,
2714		.dig_out_nid = ALC880_DIGOUT_NID,
2715		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2716		.channel_mode = alc880_fivestack_modes,
2717		.input_mux = &alc880_capture_source,
2718	},
2719	[ALC880_6ST] = {
2720		.mixers = { alc880_six_stack_mixer },
2721		.init_verbs = { alc880_volume_init_verbs,
2722				alc880_pin_6stack_init_verbs },
2723		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2724		.dac_nids = alc880_6st_dac_nids,
2725		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2726		.channel_mode = alc880_sixstack_modes,
2727		.input_mux = &alc880_6stack_capture_source,
2728	},
2729	[ALC880_6ST_DIG] = {
2730		.mixers = { alc880_six_stack_mixer },
2731		.init_verbs = { alc880_volume_init_verbs,
2732				alc880_pin_6stack_init_verbs },
2733		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2734		.dac_nids = alc880_6st_dac_nids,
2735		.dig_out_nid = ALC880_DIGOUT_NID,
2736		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2737		.channel_mode = alc880_sixstack_modes,
2738		.input_mux = &alc880_6stack_capture_source,
2739	},
2740	[ALC880_W810] = {
2741		.mixers = { alc880_w810_base_mixer },
2742		.init_verbs = { alc880_volume_init_verbs,
2743				alc880_pin_w810_init_verbs,
2744				alc880_gpio2_init_verbs },
2745		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2746		.dac_nids = alc880_w810_dac_nids,
2747		.dig_out_nid = ALC880_DIGOUT_NID,
2748		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2749		.channel_mode = alc880_w810_modes,
2750		.input_mux = &alc880_capture_source,
2751	},
2752	[ALC880_Z71V] = {
2753		.mixers = { alc880_z71v_mixer },
2754		.init_verbs = { alc880_volume_init_verbs,
2755				alc880_pin_z71v_init_verbs },
2756		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2757		.dac_nids = alc880_z71v_dac_nids,
2758		.dig_out_nid = ALC880_DIGOUT_NID,
2759		.hp_nid = 0x03,
2760		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2761		.channel_mode = alc880_2_jack_modes,
2762		.input_mux = &alc880_capture_source,
2763	},
2764	[ALC880_F1734] = {
2765		.mixers = { alc880_f1734_mixer },
2766		.init_verbs = { alc880_volume_init_verbs,
2767				alc880_pin_f1734_init_verbs },
2768		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2769		.dac_nids = alc880_f1734_dac_nids,
2770		.hp_nid = 0x02,
2771		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2772		.channel_mode = alc880_2_jack_modes,
2773		.input_mux = &alc880_capture_source,
2774	},
2775	[ALC880_ASUS] = {
2776		.mixers = { alc880_asus_mixer },
2777		.init_verbs = { alc880_volume_init_verbs,
2778				alc880_pin_asus_init_verbs,
2779				alc880_gpio1_init_verbs },
2780		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2781		.dac_nids = alc880_asus_dac_nids,
2782		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2783		.channel_mode = alc880_asus_modes,
2784		.need_dac_fix = 1,
2785		.input_mux = &alc880_capture_source,
2786	},
2787	[ALC880_ASUS_DIG] = {
2788		.mixers = { alc880_asus_mixer },
2789		.init_verbs = { alc880_volume_init_verbs,
2790				alc880_pin_asus_init_verbs,
2791				alc880_gpio1_init_verbs },
2792		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2793		.dac_nids = alc880_asus_dac_nids,
2794		.dig_out_nid = ALC880_DIGOUT_NID,
2795		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2796		.channel_mode = alc880_asus_modes,
2797		.need_dac_fix = 1,
2798		.input_mux = &alc880_capture_source,
2799	},
2800	[ALC880_ASUS_DIG2] = {
2801		.mixers = { alc880_asus_mixer },
2802		.init_verbs = { alc880_volume_init_verbs,
2803				alc880_pin_asus_init_verbs,
2804				alc880_gpio2_init_verbs }, /* use GPIO2 */
2805		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2806		.dac_nids = alc880_asus_dac_nids,
2807		.dig_out_nid = ALC880_DIGOUT_NID,
2808		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2809		.channel_mode = alc880_asus_modes,
2810		.need_dac_fix = 1,
2811		.input_mux = &alc880_capture_source,
2812	},
2813	[ALC880_ASUS_W1V] = {
2814		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2815		.init_verbs = { alc880_volume_init_verbs,
2816				alc880_pin_asus_init_verbs,
2817				alc880_gpio1_init_verbs },
2818		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2819		.dac_nids = alc880_asus_dac_nids,
2820		.dig_out_nid = ALC880_DIGOUT_NID,
2821		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2822		.channel_mode = alc880_asus_modes,
2823		.need_dac_fix = 1,
2824		.input_mux = &alc880_capture_source,
2825	},
2826	[ALC880_UNIWILL_DIG] = {
2827		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2828		.init_verbs = { alc880_volume_init_verbs,
2829				alc880_pin_asus_init_verbs },
2830		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2831		.dac_nids = alc880_asus_dac_nids,
2832		.dig_out_nid = ALC880_DIGOUT_NID,
2833		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2834		.channel_mode = alc880_asus_modes,
2835		.need_dac_fix = 1,
2836		.input_mux = &alc880_capture_source,
2837	},
2838	[ALC880_UNIWILL] = {
2839		.mixers = { alc880_uniwill_mixer },
2840		.init_verbs = { alc880_volume_init_verbs,
2841				alc880_uniwill_init_verbs },
2842		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2843		.dac_nids = alc880_asus_dac_nids,
2844		.dig_out_nid = ALC880_DIGOUT_NID,
2845		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2846		.channel_mode = alc880_threestack_modes,
2847		.need_dac_fix = 1,
2848		.input_mux = &alc880_capture_source,
2849		.unsol_event = alc880_uniwill_unsol_event,
2850		.init_hook = alc880_uniwill_automute,
2851	},
2852	[ALC880_UNIWILL_P53] = {
2853		.mixers = { alc880_uniwill_p53_mixer },
2854		.init_verbs = { alc880_volume_init_verbs,
2855				alc880_uniwill_p53_init_verbs },
2856		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2857		.dac_nids = alc880_asus_dac_nids,
2858		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2859		.channel_mode = alc880_threestack_modes,
2860		.input_mux = &alc880_capture_source,
2861		.unsol_event = alc880_uniwill_p53_unsol_event,
2862		.init_hook = alc880_uniwill_p53_hp_automute,
2863	},
2864	[ALC880_FUJITSU] = {
2865		.mixers = { alc880_fujitsu_mixer,
2866			    alc880_pcbeep_mixer, },
2867		.init_verbs = { alc880_volume_init_verbs,
2868				alc880_uniwill_p53_init_verbs,
2869	       			alc880_beep_init_verbs },
2870		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2871		.dac_nids = alc880_dac_nids,
2872		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2873		.channel_mode = alc880_2_jack_modes,
2874		.input_mux = &alc880_capture_source,
2875		.unsol_event = alc880_uniwill_p53_unsol_event,
2876		.init_hook = alc880_uniwill_p53_hp_automute,
2877	},
2878	[ALC880_CLEVO] = {
2879		.mixers = { alc880_three_stack_mixer },
2880		.init_verbs = { alc880_volume_init_verbs,
2881				alc880_pin_clevo_init_verbs },
2882		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2883		.dac_nids = alc880_dac_nids,
2884		.hp_nid = 0x03,
2885		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2886		.channel_mode = alc880_threestack_modes,
2887		.need_dac_fix = 1,
2888		.input_mux = &alc880_capture_source,
2889	},
2890	[ALC880_LG] = {
2891		.mixers = { alc880_lg_mixer },
2892		.init_verbs = { alc880_volume_init_verbs,
2893				alc880_lg_init_verbs },
2894		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2895		.dac_nids = alc880_lg_dac_nids,
2896		.dig_out_nid = ALC880_DIGOUT_NID,
2897		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2898		.channel_mode = alc880_lg_ch_modes,
2899		.need_dac_fix = 1,
2900		.input_mux = &alc880_lg_capture_source,
2901		.unsol_event = alc880_lg_unsol_event,
2902		.init_hook = alc880_lg_automute,
2903	},
2904	[ALC880_LG_LW] = {
2905		.mixers = { alc880_lg_lw_mixer },
2906		.init_verbs = { alc880_volume_init_verbs,
2907				alc880_lg_lw_init_verbs },
2908		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2909		.dac_nids = alc880_dac_nids,
2910		.dig_out_nid = ALC880_DIGOUT_NID,
2911		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2912		.channel_mode = alc880_lg_lw_modes,
2913		.input_mux = &alc880_lg_lw_capture_source,
2914		.unsol_event = alc880_lg_lw_unsol_event,
2915		.init_hook = alc880_lg_lw_automute,
2916	},
2917#ifdef CONFIG_SND_DEBUG
2918	[ALC880_TEST] = {
2919		.mixers = { alc880_test_mixer },
2920		.init_verbs = { alc880_test_init_verbs },
2921		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2922		.dac_nids = alc880_test_dac_nids,
2923		.dig_out_nid = ALC880_DIGOUT_NID,
2924		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2925		.channel_mode = alc880_test_modes,
2926		.input_mux = &alc880_test_capture_source,
2927	},
2928#endif
2929};
2930
2931/*
2932 * Automatic parse of I/O pins from the BIOS configuration
2933 */
2934
2935#define NUM_CONTROL_ALLOC	32
2936#define NUM_VERB_ALLOC		32
2937
2938enum {
2939	ALC_CTL_WIDGET_VOL,
2940	ALC_CTL_WIDGET_MUTE,
2941	ALC_CTL_BIND_MUTE,
2942};
2943static struct snd_kcontrol_new alc880_control_templates[] = {
2944	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2945	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2946	HDA_BIND_MUTE(NULL, 0, 0, 0),
2947};
2948
2949/* add dynamic controls */
2950static int add_control(struct alc_spec *spec, int type, const char *name,
2951		       unsigned long val)
2952{
2953	struct snd_kcontrol_new *knew;
2954
2955	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2956		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2957
2958		/* array + terminator */
2959		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2960		if (!knew)
2961			return -ENOMEM;
2962		if (spec->kctl_alloc) {
2963			memcpy(knew, spec->kctl_alloc,
2964			       sizeof(*knew) * spec->num_kctl_alloc);
2965			kfree(spec->kctl_alloc);
2966		}
2967		spec->kctl_alloc = knew;
2968		spec->num_kctl_alloc = num;
2969	}
2970
2971	knew = &spec->kctl_alloc[spec->num_kctl_used];
2972	*knew = alc880_control_templates[type];
2973	knew->name = kstrdup(name, GFP_KERNEL);
2974	if (!knew->name)
2975		return -ENOMEM;
2976	knew->private_value = val;
2977	spec->num_kctl_used++;
2978	return 0;
2979}
2980
2981#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2982#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2983#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2984#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2985#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2986#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2987#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2988#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2989#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2990#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2991#define ALC880_PIN_CD_NID		0x1c
2992
2993/* fill in the dac_nids table from the parsed pin configuration */
2994static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
2995				     const struct auto_pin_cfg *cfg)
2996{
2997	hda_nid_t nid;
2998	int assigned[4];
2999	int i, j;
3000
3001	memset(assigned, 0, sizeof(assigned));
3002	spec->multiout.dac_nids = spec->private_dac_nids;
3003
3004	/* check the pins hardwired to audio widget */
3005	for (i = 0; i < cfg->line_outs; i++) {
3006		nid = cfg->line_out_pins[i];
3007		if (alc880_is_fixed_pin(nid)) {
3008			int idx = alc880_fixed_pin_idx(nid);
3009			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3010			assigned[idx] = 1;
3011		}
3012	}
3013	/* left pins can be connect to any audio widget */
3014	for (i = 0; i < cfg->line_outs; i++) {
3015		nid = cfg->line_out_pins[i];
3016		if (alc880_is_fixed_pin(nid))
3017			continue;
3018		/* search for an empty channel */
3019		for (j = 0; j < cfg->line_outs; j++) {
3020			if (!assigned[j]) {
3021				spec->multiout.dac_nids[i] =
3022					alc880_idx_to_dac(j);
3023				assigned[j] = 1;
3024				break;
3025			}
3026		}
3027	}
3028	spec->multiout.num_dacs = cfg->line_outs;
3029	return 0;
3030}
3031
3032/* add playback controls from the parsed DAC table */
3033static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3034					     const struct auto_pin_cfg *cfg)
3035{
3036	char name[32];
3037	static const char *chname[4] = {
3038		"Front", "Surround", NULL /*CLFE*/, "Side"
3039	};
3040	hda_nid_t nid;
3041	int i, err;
3042
3043	for (i = 0; i < cfg->line_outs; i++) {
3044		if (!spec->multiout.dac_nids[i])
3045			continue;
3046		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3047		if (i == 2) {
3048			/* Center/LFE */
3049			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3050					  "Center Playback Volume",
3051					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3052							      HDA_OUTPUT));
3053			if (err < 0)
3054				return err;
3055			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3056					  "LFE Playback Volume",
3057					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3058							      HDA_OUTPUT));
3059			if (err < 0)
3060				return err;
3061			err = add_control(spec, ALC_CTL_BIND_MUTE,
3062					  "Center Playback Switch",
3063					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3064							      HDA_INPUT));
3065			if (err < 0)
3066				return err;
3067			err = add_control(spec, ALC_CTL_BIND_MUTE,
3068					  "LFE Playback Switch",
3069					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3070							      HDA_INPUT));
3071			if (err < 0)
3072				return err;
3073		} else {
3074			sprintf(name, "%s Playback Volume", chname[i]);
3075			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3076					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3077							      HDA_OUTPUT));
3078			if (err < 0)
3079				return err;
3080			sprintf(name, "%s Playback Switch", chname[i]);
3081			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3082					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3083							      HDA_INPUT));
3084			if (err < 0)
3085				return err;
3086		}
3087	}
3088	return 0;
3089}
3090
3091/* add playback controls for speaker and HP outputs */
3092static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3093					const char *pfx)
3094{
3095	hda_nid_t nid;
3096	int err;
3097	char name[32];
3098
3099	if (!pin)
3100		return 0;
3101
3102	if (alc880_is_fixed_pin(pin)) {
3103		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3104		/* specify the DAC as the extra output */
3105		if (!spec->multiout.hp_nid)
3106			spec->multiout.hp_nid = nid;
3107		else
3108			spec->multiout.extra_out_nid[0] = nid;
3109		/* control HP volume/switch on the output mixer amp */
3110		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3111		sprintf(name, "%s Playback Volume", pfx);
3112		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3113				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3114		if (err < 0)
3115			return err;
3116		sprintf(name, "%s Playback Switch", pfx);
3117		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3118				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3119		if (err < 0)
3120			return err;
3121	} else if (alc880_is_multi_pin(pin)) {
3122		/* set manual connection */
3123		/* we have only a switch on HP-out PIN */
3124		sprintf(name, "%s Playback Switch", pfx);
3125		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3126				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3127		if (err < 0)
3128			return err;
3129	}
3130	return 0;
3131}
3132
3133/* create input playback/capture controls for the given pin */
3134static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3135			    const char *ctlname,
3136			    int idx, hda_nid_t mix_nid)
3137{
3138	char name[32];
3139	int err;
3140
3141	sprintf(name, "%s Playback Volume", ctlname);
3142	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3143			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3144	if (err < 0)
3145		return err;
3146	sprintf(name, "%s Playback Switch", ctlname);
3147	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3148			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3149	if (err < 0)
3150		return err;
3151	return 0;
3152}
3153
3154/* create playback/capture controls for input pins */
3155static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3156						const struct auto_pin_cfg *cfg)
3157{
3158	struct hda_input_mux *imux = &spec->private_imux;
3159	int i, err, idx;
3160
3161	for (i = 0; i < AUTO_PIN_LAST; i++) {
3162		if (alc880_is_input_pin(cfg->input_pins[i])) {
3163			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3164			err = new_analog_input(spec, cfg->input_pins[i],
3165					       auto_pin_cfg_labels[i],
3166					       idx, 0x0b);
3167			if (err < 0)
3168				return err;
3169			imux->items[imux->num_items].label =
3170				auto_pin_cfg_labels[i];
3171			imux->items[imux->num_items].index =
3172				alc880_input_pin_idx(cfg->input_pins[i]);
3173			imux->num_items++;
3174		}
3175	}
3176	return 0;
3177}
3178
3179static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3180					      hda_nid_t nid, int pin_type,
3181					      int dac_idx)
3182{
3183	/* set as output */
3184	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3185			    pin_type);
3186	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3187			    AMP_OUT_UNMUTE);
3188	/* need the manual connection? */
3189	if (alc880_is_multi_pin(nid)) {
3190		struct alc_spec *spec = codec->spec;
3191		int idx = alc880_multi_pin_idx(nid);
3192		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3193				    AC_VERB_SET_CONNECT_SEL,
3194				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3195	}
3196}
3197
3198static int get_pin_type(int line_out_type)
3199{
3200	if (line_out_type == AUTO_PIN_HP_OUT)
3201		return PIN_HP;
3202	else
3203		return PIN_OUT;
3204}
3205
3206static void alc880_auto_init_multi_out(struct hda_codec *codec)
3207{
3208	struct alc_spec *spec = codec->spec;
3209	int i;
3210
3211	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3212	for (i = 0; i < spec->autocfg.line_outs; i++) {
3213		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3214		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3215		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3216	}
3217}
3218
3219static void alc880_auto_init_extra_out(struct hda_codec *codec)
3220{
3221	struct alc_spec *spec = codec->spec;
3222	hda_nid_t pin;
3223
3224	pin = spec->autocfg.speaker_pins[0];
3225	if (pin) /* connect to front */
3226		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3227	pin = spec->autocfg.hp_pins[0];
3228	if (pin) /* connect to front */
3229		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3230}
3231
3232static void alc880_auto_init_analog_input(struct hda_codec *codec)
3233{
3234	struct alc_spec *spec = codec->spec;
3235	int i;
3236
3237	for (i = 0; i < AUTO_PIN_LAST; i++) {
3238		hda_nid_t nid = spec->autocfg.input_pins[i];
3239		if (alc880_is_input_pin(nid)) {
3240			snd_hda_codec_write(codec, nid, 0,
3241					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3242					    i <= AUTO_PIN_FRONT_MIC ?
3243					    PIN_VREF80 : PIN_IN);
3244			if (nid != ALC880_PIN_CD_NID)
3245				snd_hda_codec_write(codec, nid, 0,
3246						    AC_VERB_SET_AMP_GAIN_MUTE,
3247						    AMP_OUT_MUTE);
3248		}
3249	}
3250}
3251
3252/* parse the BIOS configuration and set up the alc_spec */
3253/* return 1 if successful, 0 if the proper config is not found,
3254 * or a negative error code
3255 */
3256static int alc880_parse_auto_config(struct hda_codec *codec)
3257{
3258	struct alc_spec *spec = codec->spec;
3259	int err;
3260	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3261
3262	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3263					   alc880_ignore);
3264	if (err < 0)
3265		return err;
3266	if (!spec->autocfg.line_outs)
3267		return 0; /* can't find valid BIOS pin config */
3268
3269	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3270	if (err < 0)
3271		return err;
3272	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3273	if (err < 0)
3274		return err;
3275	err = alc880_auto_create_extra_out(spec,
3276					   spec->autocfg.speaker_pins[0],
3277					   "Speaker");
3278	if (err < 0)
3279		return err;
3280	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3281					   "Headphone");
3282	if (err < 0)
3283		return err;
3284	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3285	if (err < 0)
3286		return err;
3287
3288	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3289
3290	if (spec->autocfg.dig_out_pin)
3291		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3292	if (spec->autocfg.dig_in_pin)
3293		spec->dig_in_nid = ALC880_DIGIN_NID;
3294
3295	if (spec->kctl_alloc)
3296		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3297
3298	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3299
3300	spec->num_mux_defs = 1;
3301	spec->input_mux = &spec->private_imux;
3302
3303	return 1;
3304}
3305
3306/* additional initialization for auto-configuration model */
3307static void alc880_auto_init(struct hda_codec *codec)
3308{
3309	alc880_auto_init_multi_out(codec);
3310	alc880_auto_init_extra_out(codec);
3311	alc880_auto_init_analog_input(codec);
3312}
3313
3314/*
3315 * OK, here we have finally the patch for ALC880
3316 */
3317
3318static int patch_alc880(struct hda_codec *codec)
3319{
3320	struct alc_spec *spec;
3321	int board_config;
3322	int err;
3323
3324	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3325	if (spec == NULL)
3326		return -ENOMEM;
3327
3328	codec->spec = spec;
3329
3330	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3331						  alc880_models,
3332						  alc880_cfg_tbl);
3333	if (board_config < 0) {
3334		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3335		       "trying auto-probe from BIOS...\n");
3336		board_config = ALC880_AUTO;
3337	}
3338
3339	if (board_config == ALC880_AUTO) {
3340		/* automatic parse from the BIOS config */
3341		err = alc880_parse_auto_config(codec);
3342		if (err < 0) {
3343			alc_free(codec);
3344			return err;
3345		} else if (!err) {
3346			printk(KERN_INFO
3347			       "hda_codec: Cannot set up configuration "
3348			       "from BIOS.  Using 3-stack mode...\n");
3349			board_config = ALC880_3ST;
3350		}
3351	}
3352
3353	if (board_config != ALC880_AUTO)
3354		setup_preset(spec, &alc880_presets[board_config]);
3355
3356	spec->stream_name_analog = "ALC880 Analog";
3357	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3358	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3359
3360	spec->stream_name_digital = "ALC880 Digital";
3361	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3362	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3363
3364	if (!spec->adc_nids && spec->input_mux) {
3365		/* check whether NID 0x07 is valid */
3366		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3367		/* get type */
3368		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3369		if (wcap != AC_WID_AUD_IN) {
3370			spec->adc_nids = alc880_adc_nids_alt;
3371			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3372			spec->mixers[spec->num_mixers] =
3373				alc880_capture_alt_mixer;
3374			spec->num_mixers++;
3375		} else {
3376			spec->adc_nids = alc880_adc_nids;
3377			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3378			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3379			spec->num_mixers++;
3380		}
3381	}
3382
3383	codec->patch_ops = alc_patch_ops;
3384	if (board_config == ALC880_AUTO)
3385		spec->init_hook = alc880_auto_init;
3386
3387	return 0;
3388}
3389
3390
3391/*
3392 * ALC260 support
3393 */
3394
3395static hda_nid_t alc260_dac_nids[1] = {
3396	/* front */
3397	0x02,
3398};
3399
3400static hda_nid_t alc260_adc_nids[1] = {
3401	/* ADC0 */
3402	0x04,
3403};
3404
3405static hda_nid_t alc260_adc_nids_alt[1] = {
3406	/* ADC1 */
3407	0x05,
3408};
3409
3410static hda_nid_t alc260_hp_adc_nids[2] = {
3411	/* ADC1, 0 */
3412	0x05, 0x04
3413};
3414
3415/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3416 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3417 */
3418static hda_nid_t alc260_dual_adc_nids[2] = {
3419	/* ADC0, ADC1 */
3420	0x04, 0x05
3421};
3422
3423#define ALC260_DIGOUT_NID	0x03
3424#define ALC260_DIGIN_NID	0x06
3425
3426static struct hda_input_mux alc260_capture_source = {
3427	.num_items = 4,
3428	.items = {
3429		{ "Mic", 0x0 },
3430		{ "Front Mic", 0x1 },
3431		{ "Line", 0x2 },
3432		{ "CD", 0x4 },
3433	},
3434};
3435
3436/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3437 * headphone jack and the internal CD lines since these are the only pins at
3438 * which audio can appear.  For flexibility, also allow the option of
3439 * recording the mixer output on the second ADC (ADC0 doesn't have a
3440 * connection to the mixer output).
3441 */
3442static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3443	{
3444		.num_items = 3,
3445		.items = {
3446			{ "Mic/Line", 0x0 },
3447			{ "CD", 0x4 },
3448			{ "Headphone", 0x2 },
3449		},
3450	},
3451	{
3452		.num_items = 4,
3453		.items = {
3454			{ "Mic/Line", 0x0 },
3455			{ "CD", 0x4 },
3456			{ "Headphone", 0x2 },
3457			{ "Mixer", 0x5 },
3458		},
3459	},
3460
3461};
3462
3463/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3464 * the Fujitsu S702x, but jacks are marked differently.
3465 */
3466static struct hda_input_mux alc260_acer_capture_sources[2] = {
3467	{
3468		.num_items = 4,
3469		.items = {
3470			{ "Mic", 0x0 },
3471			{ "Line", 0x2 },
3472			{ "CD", 0x4 },
3473			{ "Headphone", 0x5 },
3474		},
3475	},
3476	{
3477		.num_items = 5,
3478		.items = {
3479			{ "Mic", 0x0 },
3480			{ "Line", 0x2 },
3481			{ "CD", 0x4 },
3482			{ "Headphone", 0x6 },
3483			{ "Mixer", 0x5 },
3484		},
3485	},
3486};
3487/*
3488 * This is just place-holder, so there's something for alc_build_pcms to look
3489 * at when it calculates the maximum number of channels. ALC260 has no mixer
3490 * element which allows changing the channel mode, so the verb list is
3491 * never used.
3492 */
3493static struct hda_channel_mode alc260_modes[1] = {
3494	{ 2, NULL },
3495};
3496
3497
3498/* Mixer combinations
3499 *
3500 * basic: base_output + input + pc_beep + capture
3501 * HP: base_output + input + capture_alt
3502 * HP_3013: hp_3013 + input + capture
3503 * fujitsu: fujitsu + capture
3504 * acer: acer + capture
3505 */
3506
3507static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3508	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3509	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3510	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3511	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3512	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3513	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3514	{ } /* end */
3515};
3516
3517static struct snd_kcontrol_new alc260_input_mixer[] = {
3518	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3519	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3520	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3521	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3522	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3523	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3524	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3525	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3526	{ } /* end */
3527};
3528
3529static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3530	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3531	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3532	{ } /* end */
3533};
3534
3535static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3536	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3537	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3538	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3539	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3540	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3541	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3542	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3543	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3544	{ } /* end */
3545};
3546
3547/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3548 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3549 */
3550static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3551	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3552	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3553	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3554	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3555	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3556	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3557	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3558	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3559	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3560	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3561	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3562	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3563	{ } /* end */
3564};
3565
3566/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3567 * versions of the ALC260 don't act on requests to enable mic bias from NID
3568 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3569 * datasheet doesn't mention this restriction.  At this stage it's not clear
3570 * whether this behaviour is intentional or is a hardware bug in chip
3571 * revisions available in early 2006.  Therefore for now allow the
3572 * "Headphone Jack Mode" control to span all choices, but if it turns out
3573 * that the lack of mic bias for this NID is intentional we could change the
3574 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3575 *
3576 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3577 * don't appear to make the mic bias available from the "line" jack, even
3578 * though the NID used for this jack (0x14) can supply it.  The theory is
3579 * that perhaps Acer have included blocking capacitors between the ALC260
3580 * and the output jack.  If this turns out to be the case for all such
3581 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3582 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3583 *
3584 * The C20x Tablet series have a mono internal speaker which is controlled
3585 * via the chip's Mono sum widget and pin complex, so include the necessary
3586 * controls for such models.  On models without a "mono speaker" the control
3587 * won't do anything.
3588 */
3589static struct snd_kcontrol_new alc260_acer_mixer[] = {
3590	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3591	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3592	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3593	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3594			      HDA_OUTPUT),
3595	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3596			   HDA_INPUT),
3597	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3598	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3599	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3600	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3601	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3602	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3603	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3604	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3605	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3606	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3607	{ } /* end */
3608};
3609
3610/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3611 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3612 */
3613static struct snd_kcontrol_new alc260_will_mixer[] = {
3614	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3615	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3616	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3617	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3618	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3619	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3620	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3621	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3622	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3623	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3624	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3625	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3626	{ } /* end */
3627};
3628
3629/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3630 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3631 */
3632static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3633	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3634	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3635	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3636	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3637	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3638	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3639	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3640	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3641	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3642	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3643	{ } /* end */
3644};
3645
3646/* capture mixer elements */
3647static struct snd_kcontrol_new alc260_capture_mixer[] = {
3648	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3649	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3650	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3651	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3652	{
3653		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3654		/* The multiple "Capture Source" controls confuse alsamixer
3655		 * So call somewhat different..
3656		 * FIXME: the controls appear in the "playback" view!
3657		 */
3658		/* .name = "Capture Source", */
3659		.name = "Input Source",
3660		.count = 2,
3661		.info = alc_mux_enum_info,
3662		.get = alc_mux_enum_get,
3663		.put = alc_mux_enum_put,
3664	},
3665	{ } /* end */
3666};
3667
3668static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3669	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3670	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3671	{
3672		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3673		/* The multiple "Capture Source" controls confuse alsamixer
3674		 * So call somewhat different..
3675		 * FIXME: the controls appear in the "playback" view!
3676		 */
3677		/* .name = "Capture Source", */
3678		.name = "Input Source",
3679		.count = 1,
3680		.info = alc_mux_enum_info,
3681		.get = alc_mux_enum_get,
3682		.put = alc_mux_enum_put,
3683	},
3684	{ } /* end */
3685};
3686
3687/*
3688 * initialization verbs
3689 */
3690static struct hda_verb alc260_init_verbs[] = {
3691	/* Line In pin widget for input */
3692	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3693	/* CD pin widget for input */
3694	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3695	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3696	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3697	/* Mic2 (front panel) pin widget for input and vref at 80% */
3698	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3699	/* LINE-2 is used for line-out in rear */
3700	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3701	/* select line-out */
3702	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3703	/* LINE-OUT pin */
3704	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3705	/* enable HP */
3706	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3707	/* enable Mono */
3708	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3709	/* mute capture amp left and right */
3710	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3711	/* set connection select to line in (default select for this ADC) */
3712	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3713	/* mute capture amp left and right */
3714	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3715	/* set connection select to line in (default select for this ADC) */
3716	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3717	/* set vol=0 Line-Out mixer amp left and right */
3718	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3719	/* unmute pin widget amp left and right (no gain on this amp) */
3720	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3721	/* set vol=0 HP mixer amp left and right */
3722	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3723	/* unmute pin widget amp left and right (no gain on this amp) */
3724	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3725	/* set vol=0 Mono mixer amp left and right */
3726	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3727	/* unmute pin widget amp left and right (no gain on this amp) */
3728	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3729	/* unmute LINE-2 out pin */
3730	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3731	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3732	 * Line In 2 = 0x03
3733	 */
3734	/* mute CD */
3735	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3736	/* mute Line In */
3737	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3738	/* mute Mic */
3739	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3740	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3741	/* mute Front out path */
3742	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3743	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3744	/* mute Headphone out path */
3745	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3746	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3747	/* mute Mono out path */
3748	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3749	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3750	{ }
3751};
3752
3753#if 0 /* should be identical with alc260_init_verbs? */
3754static struct hda_verb alc260_hp_init_verbs[] = {
3755	/* Headphone and output */
3756	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3757	/* mono output */
3758	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3759	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3760	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3761	/* Mic2 (front panel) pin widget for input and vref at 80% */
3762	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3763	/* Line In pin widget for input */
3764	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3765	/* Line-2 pin widget for output */
3766	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3767	/* CD pin widget for input */
3768	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3769	/* unmute amp left and right */
3770	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3771	/* set connection select to line in (default select for this ADC) */
3772	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3773	/* unmute Line-Out mixer amp left and right (volume = 0) */
3774	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3775	/* mute pin widget amp left and right (no gain on this amp) */
3776	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3777	/* unmute HP mixer amp left and right (volume = 0) */
3778	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3779	/* mute pin widget amp left and right (no gain on this amp) */
3780	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3781	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3782	 * Line In 2 = 0x03
3783	 */
3784	/* unmute CD */
3785	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3786	/* unmute Line In */
3787	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3788	/* unmute Mic */
3789	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3790	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3791	/* Unmute Front out path */
3792	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3793	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3794	/* Unmute Headphone out path */
3795	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3796	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3797	/* Unmute Mono out path */
3798	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3799	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3800	{ }
3801};
3802#endif
3803
3804static struct hda_verb alc260_hp_3013_init_verbs[] = {
3805	/* Line out and output */
3806	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3807	/* mono output */
3808	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3809	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3810	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3811	/* Mic2 (front panel) pin widget for input and vref at 80% */
3812	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3813	/* Line In pin widget for input */
3814	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3815	/* Headphone pin widget for output */
3816	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3817	/* CD pin widget for input */
3818	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3819	/* unmute amp left and right */
3820	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3821	/* set connection select to line in (default select for this ADC) */
3822	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3823	/* unmute Line-Out mixer amp left and right (volume = 0) */
3824	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3825	/* mute pin widget amp left and right (no gain on this amp) */
3826	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3827	/* unmute HP mixer amp left and right (volume = 0) */
3828	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3829	/* mute pin widget amp left and right (no gain on this amp) */
3830	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3831	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3832	 * Line In 2 = 0x03
3833	 */
3834	/* unmute CD */
3835	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3836	/* unmute Line In */
3837	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3838	/* unmute Mic */
3839	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3840	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3841	/* Unmute Front out path */
3842	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3843	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3844	/* Unmute Headphone out path */
3845	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3846	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3847	/* Unmute Mono out path */
3848	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3849	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3850	{ }
3851};
3852
3853/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3854 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3855 * audio = 0x16, internal speaker = 0x10.
3856 */
3857static struct hda_verb alc260_fujitsu_init_verbs[] = {
3858	/* Disable all GPIOs */
3859	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3860	/* Internal speaker is connected to headphone pin */
3861	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3862	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3863	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3864	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3865	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3866	/* Ensure all other unused pins are disabled and muted. */
3867	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3868	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3869	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3870	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3871	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3872	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3873	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3874	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3875
3876	/* Disable digital (SPDIF) pins */
3877	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3878	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3879
3880	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3881	 * when acting as an output.
3882	 */
3883	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3884
3885	/* Start with output sum widgets muted and their output gains at min */
3886	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3887	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3888	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3889	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3890	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3891	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3892	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3893	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3894	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3895
3896	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3897	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3898	/* Unmute Line1 pin widget output buffer since it starts as an output.
3899	 * If the pin mode is changed by the user the pin mode control will
3900	 * take care of enabling the pin's input/output buffers as needed.
3901	 * Therefore there's no need to enable the input buffer at this
3902	 * stage.
3903	 */
3904	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3905	/* Unmute input buffer of pin widget used for Line-in (no equiv
3906	 * mixer ctrl)
3907	 */
3908	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3909
3910	/* Mute capture amp left and right */
3911	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3912	/* Set ADC connection select to match default mixer setting - line
3913	 * in (on mic1 pin)
3914	 */
3915	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3916
3917	/* Do the same for the second ADC: mute capture input amp and
3918	 * set ADC connection to line in (on mic1 pin)
3919	 */
3920	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3921	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3922
3923	/* Mute all inputs to mixer widget (even unconnected ones) */
3924	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3925	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3926	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3927	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3928	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3929	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3930	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3931	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3932
3933	{ }
3934};
3935
3936/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3937 * similar laptops (adapted from Fujitsu init verbs).
3938 */
3939static struct hda_verb alc260_acer_init_verbs[] = {
3940	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3941	 * the headphone jack.  Turn this on and rely on the standard mute
3942	 * methods whenever the user wants to turn these outputs off.
3943	 */
3944	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3945	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3946	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3947	/* Internal speaker/Headphone jack is connected to Line-out pin */
3948	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3949	/* Internal microphone/Mic jack is connected to Mic1 pin */
3950	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3951	/* Line In jack is connected to Line1 pin */
3952	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3953	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3954	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3955	/* Ensure all other unused pins are disabled and muted. */
3956	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3957	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3958	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3959	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3960	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3961	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3962	/* Disable digital (SPDIF) pins */
3963	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3964	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3965
3966	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3967	 * bus when acting as outputs.
3968	 */
3969	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3970	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3971
3972	/* Start with output sum widgets muted and their output gains at min */
3973	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3974	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3975	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3976	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3977	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3978	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3979	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3980	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3981	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3982
3983	/* Unmute Line-out pin widget amp left and right
3984	 * (no equiv mixer ctrl)
3985	 */
3986	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3987	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3988	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3989	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
3990	 * inputs. If the pin mode is changed by the user the pin mode control
3991	 * will take care of enabling the pin's input/output buffers as needed.
3992	 * Therefore there's no need to enable the input buffer at this
3993	 * stage.
3994	 */
3995	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3996	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3997
3998	/* Mute capture amp left and right */
3999	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4000	/* Set ADC connection select to match default mixer setting - mic
4001	 * (on mic1 pin)
4002	 */
4003	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4004
4005	/* Do similar with the second ADC: mute capture input amp and
4006	 * set ADC connection to mic to match ALSA's default state.
4007	 */
4008	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4009	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4010
4011	/* Mute all inputs to mixer widget (even unconnected ones) */
4012	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4013	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4014	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4015	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4016	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4017	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4018	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4019	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4020
4021	{ }
4022};
4023
4024static struct hda_verb alc260_will_verbs[] = {
4025	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4026	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4027	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4028	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4029	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4030	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4031	{}
4032};
4033
4034static struct hda_verb alc260_replacer_672v_verbs[] = {
4035	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4036	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4037	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4038
4039	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4040	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4041	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4042
4043	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4044	{}
4045};
4046
4047/* toggle speaker-output according to the hp-jack state */
4048static void alc260_replacer_672v_automute(struct hda_codec *codec)
4049{
4050        unsigned int present;
4051
4052	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4053        present = snd_hda_codec_read(codec, 0x0f, 0,
4054                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4055	if (present) {
4056		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1);
4057		snd_hda_codec_write(codec, 0x0f, 0,
4058				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
4059	} else {
4060		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4061		snd_hda_codec_write(codec, 0x0f, 0,
4062				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4063	}
4064}
4065
4066static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4067                                       unsigned int res)
4068{
4069        if ((res >> 26) == ALC880_HP_EVENT)
4070                alc260_replacer_672v_automute(codec);
4071}
4072
4073/* Test configuration for debugging, modelled after the ALC880 test
4074 * configuration.
4075 */
4076#ifdef CONFIG_SND_DEBUG
4077static hda_nid_t alc260_test_dac_nids[1] = {
4078	0x02,
4079};
4080static hda_nid_t alc260_test_adc_nids[2] = {
4081	0x04, 0x05,
4082};
4083/* For testing the ALC260, each input MUX needs its own definition since
4084 * the signal assignments are different.  This assumes that the first ADC
4085 * is NID 0x04.
4086 */
4087static struct hda_input_mux alc260_test_capture_sources[2] = {
4088	{
4089		.num_items = 7,
4090		.items = {
4091			{ "MIC1 pin", 0x0 },
4092			{ "MIC2 pin", 0x1 },
4093			{ "LINE1 pin", 0x2 },
4094			{ "LINE2 pin", 0x3 },
4095			{ "CD pin", 0x4 },
4096			{ "LINE-OUT pin", 0x5 },
4097			{ "HP-OUT pin", 0x6 },
4098		},
4099        },
4100	{
4101		.num_items = 8,
4102		.items = {
4103			{ "MIC1 pin", 0x0 },
4104			{ "MIC2 pin", 0x1 },
4105			{ "LINE1 pin", 0x2 },
4106			{ "LINE2 pin", 0x3 },
4107			{ "CD pin", 0x4 },
4108			{ "Mixer", 0x5 },
4109			{ "LINE-OUT pin", 0x6 },
4110			{ "HP-OUT pin", 0x7 },
4111		},
4112        },
4113};
4114static struct snd_kcontrol_new alc260_test_mixer[] = {
4115	/* Output driver widgets */
4116	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4117	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4118	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4119	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4120	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4121	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4122
4123	/* Modes for retasking pin widgets
4124	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4125         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4126         * mention this restriction.  At this stage it's not clear whether
4127         * this behaviour is intentional or is a hardware bug in chip
4128         * revisions available at least up until early 2006.  Therefore for
4129         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4130         * choices, but if it turns out that the lack of mic bias for these
4131         * NIDs is intentional we could change their modes from
4132         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4133	 */
4134	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4135	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4136	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4137	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4138	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4139	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4140
4141	/* Loopback mixer controls */
4142	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4143	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4144	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4145	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4146	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4147	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4148	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4149	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4150	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4151	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4152	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4153	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4154	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4155	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4156	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4157	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4158
4159	/* Controls for GPIO pins, assuming they are configured as outputs */
4160	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4161	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4162	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4163	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4164
4165	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4166	 * is ambigious as to which NID is which; testing on laptops which
4167	 * make this output available should provide clarification.
4168	 */
4169	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4170	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4171
4172	{ } /* end */
4173};
4174static struct hda_verb alc260_test_init_verbs[] = {
4175	/* Enable all GPIOs as outputs with an initial value of 0 */
4176	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4177	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4178	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4179
4180	/* Enable retasking pins as output, initially without power amp */
4181	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4182	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4183	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4184	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4185	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4186	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4187
4188	/* Disable digital (SPDIF) pins initially, but users can enable
4189	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4190	 * payload also sets the generation to 0, output to be in "consumer"
4191	 * PCM format, copyright asserted, no pre-emphasis and no validity
4192	 * control.
4193	 */
4194	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4195	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4196
4197	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4198	 * OUT1 sum bus when acting as an output.
4199	 */
4200	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4201	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4202	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4203	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4204
4205	/* Start with output sum widgets muted and their output gains at min */
4206	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4207	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4208	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4209	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4210	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4211	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4212	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4213	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4214	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4215
4216	/* Unmute retasking pin widget output buffers since the default
4217	 * state appears to be output.  As the pin mode is changed by the
4218	 * user the pin mode control will take care of enabling the pin's
4219	 * input/output buffers as needed.
4220	 */
4221	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4222	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4223	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4224	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4225	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4226	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4227	/* Also unmute the mono-out pin widget */
4228	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4229
4230	/* Mute capture amp left and right */
4231	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4232	/* Set ADC connection select to match default mixer setting (mic1
4233	 * pin)
4234	 */
4235	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4236
4237	/* Do the same for the second ADC: mute capture input amp and
4238	 * set ADC connection to mic1 pin
4239	 */
4240	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4241	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4242
4243	/* Mute all inputs to mixer widget (even unconnected ones) */
4244	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4245	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4246	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4247	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4248	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4249	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4250	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4251	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4252
4253	{ }
4254};
4255#endif
4256
4257static struct hda_pcm_stream alc260_pcm_analog_playback = {
4258	.substreams = 1,
4259	.channels_min = 2,
4260	.channels_max = 2,
4261};
4262
4263static struct hda_pcm_stream alc260_pcm_analog_capture = {
4264	.substreams = 1,
4265	.channels_min = 2,
4266	.channels_max = 2,
4267};
4268
4269#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4270#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4271
4272/*
4273 * for BIOS auto-configuration
4274 */
4275
4276static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4277					const char *pfx)
4278{
4279	hda_nid_t nid_vol;
4280	unsigned long vol_val, sw_val;
4281	char name[32];
4282	int err;
4283
4284	if (nid >= 0x0f && nid < 0x11) {
4285		nid_vol = nid - 0x7;
4286		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4287		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4288	} else if (nid == 0x11) {
4289		nid_vol = nid - 0x7;
4290		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4291		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4292	} else if (nid >= 0x12 && nid <= 0x15) {
4293		nid_vol = 0x08;
4294		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4295		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4296	} else
4297		return 0; /* N/A */
4298
4299	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4300	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4301	if (err < 0)
4302		return err;
4303	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4304	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4305	if (err < 0)
4306		return err;
4307	return 1;
4308}
4309
4310/* add playback controls from the parsed DAC table */
4311static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4312					     const struct auto_pin_cfg *cfg)
4313{
4314	hda_nid_t nid;
4315	int err;
4316
4317	spec->multiout.num_dacs = 1;
4318	spec->multiout.dac_nids = spec->private_dac_nids;
4319	spec->multiout.dac_nids[0] = 0x02;
4320
4321	nid = cfg->line_out_pins[0];
4322	if (nid) {
4323		err = alc260_add_playback_controls(spec, nid, "Front");
4324		if (err < 0)
4325			return err;
4326	}
4327
4328	nid = cfg->speaker_pins[0];
4329	if (nid) {
4330		err = alc260_add_playback_controls(spec, nid, "Speaker");
4331		if (err < 0)
4332			return err;
4333	}
4334
4335	nid = cfg->hp_pins[0];
4336	if (nid) {
4337		err = alc260_add_playback_controls(spec, nid, "Headphone");
4338		if (err < 0)
4339			return err;
4340	}
4341	return 0;
4342}
4343
4344/* create playback/capture controls for input pins */
4345static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4346						const struct auto_pin_cfg *cfg)
4347{
4348	struct hda_input_mux *imux = &spec->private_imux;
4349	int i, err, idx;
4350
4351	for (i = 0; i < AUTO_PIN_LAST; i++) {
4352		if (cfg->input_pins[i] >= 0x12) {
4353			idx = cfg->input_pins[i] - 0x12;
4354			err = new_analog_input(spec, cfg->input_pins[i],
4355					       auto_pin_cfg_labels[i], idx,
4356					       0x07);
4357			if (err < 0)
4358				return err;
4359			imux->items[imux->num_items].label =
4360				auto_pin_cfg_labels[i];
4361			imux->items[imux->num_items].index = idx;
4362			imux->num_items++;
4363		}
4364		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4365			idx = cfg->input_pins[i] - 0x09;
4366			err = new_analog_input(spec, cfg->input_pins[i],
4367					       auto_pin_cfg_labels[i], idx,
4368					       0x07);
4369			if (err < 0)
4370				return err;
4371			imux->items[imux->num_items].label =
4372				auto_pin_cfg_labels[i];
4373			imux->items[imux->num_items].index = idx;
4374			imux->num_items++;
4375		}
4376	}
4377	return 0;
4378}
4379
4380static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4381					      hda_nid_t nid, int pin_type,
4382					      int sel_idx)
4383{
4384	/* set as output */
4385	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4386			    pin_type);
4387	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4388			    AMP_OUT_UNMUTE);
4389	/* need the manual connection? */
4390	if (nid >= 0x12) {
4391		int idx = nid - 0x12;
4392		snd_hda_codec_write(codec, idx + 0x0b, 0,
4393				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4394	}
4395}
4396
4397static void alc260_auto_init_multi_out(struct hda_codec *codec)
4398{
4399	struct alc_spec *spec = codec->spec;
4400	hda_nid_t nid;
4401
4402	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4403	nid = spec->autocfg.line_out_pins[0];
4404	if (nid) {
4405		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4406		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4407	}
4408
4409	nid = spec->autocfg.speaker_pins[0];
4410	if (nid)
4411		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4412
4413	nid = spec->autocfg.hp_pins[0];
4414	if (nid)
4415		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4416}
4417
4418#define ALC260_PIN_CD_NID		0x16
4419static void alc260_auto_init_analog_input(struct hda_codec *codec)
4420{
4421	struct alc_spec *spec = codec->spec;
4422	int i;
4423
4424	for (i = 0; i < AUTO_PIN_LAST; i++) {
4425		hda_nid_t nid = spec->autocfg.input_pins[i];
4426		if (nid >= 0x12) {
4427			snd_hda_codec_write(codec, nid, 0,
4428					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4429					    i <= AUTO_PIN_FRONT_MIC ?
4430					    PIN_VREF80 : PIN_IN);
4431			if (nid != ALC260_PIN_CD_NID)
4432				snd_hda_codec_write(codec, nid, 0,
4433						    AC_VERB_SET_AMP_GAIN_MUTE,
4434						    AMP_OUT_MUTE);
4435		}
4436	}
4437}
4438
4439/*
4440 * generic initialization of ADC, input mixers and output mixers
4441 */
4442static struct hda_verb alc260_volume_init_verbs[] = {
4443	/*
4444	 * Unmute ADC0-1 and set the default input to mic-in
4445	 */
4446	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4447	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4448	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4449	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4450
4451	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4452	 * mixer widget
4453	 * Note: PASD motherboards uses the Line In 2 as the input for
4454	 * front panel mic (mic 2)
4455	 */
4456	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4457	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4458	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4459	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4460	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4461	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4462
4463	/*
4464	 * Set up output mixers (0x08 - 0x0a)
4465	 */
4466	/* set vol=0 to output mixers */
4467	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4468	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4469	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4470	/* set up input amps for analog loopback */
4471	/* Amp Indices: DAC = 0, mixer = 1 */
4472	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4473	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4474	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4475	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4476	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4477	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4478
4479	{ }
4480};
4481
4482static int alc260_parse_auto_config(struct hda_codec *codec)
4483{
4484	struct alc_spec *spec = codec->spec;
4485	unsigned int wcap;
4486	int err;
4487	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4488
4489	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4490					   alc260_ignore);
4491	if (err < 0)
4492		return err;
4493	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4494	if (err < 0)
4495		return err;
4496	if (!spec->kctl_alloc)
4497		return 0; /* can't find valid BIOS pin config */
4498	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4499	if (err < 0)
4500		return err;
4501
4502	spec->multiout.max_channels = 2;
4503
4504	if (spec->autocfg.dig_out_pin)
4505		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4506	if (spec->kctl_alloc)
4507		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4508
4509	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4510
4511	spec->num_mux_defs = 1;
4512	spec->input_mux = &spec->private_imux;
4513
4514	/* check whether NID 0x04 is valid */
4515	wcap = get_wcaps(codec, 0x04);
4516	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4517	if (wcap != AC_WID_AUD_IN) {
4518		spec->adc_nids = alc260_adc_nids_alt;
4519		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4520		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4521	} else {
4522		spec->adc_nids = alc260_adc_nids;
4523		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4524		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4525	}
4526	spec->num_mixers++;
4527
4528	return 1;
4529}
4530
4531/* additional initialization for auto-configuration model */
4532static void alc260_auto_init(struct hda_codec *codec)
4533{
4534	alc260_auto_init_multi_out(codec);
4535	alc260_auto_init_analog_input(codec);
4536}
4537
4538/*
4539 * ALC260 configurations
4540 */
4541static const char *alc260_models[ALC260_MODEL_LAST] = {
4542	[ALC260_BASIC]		= "basic",
4543	[ALC260_HP]		= "hp",
4544	[ALC260_HP_3013]	= "hp-3013",
4545	[ALC260_FUJITSU_S702X]	= "fujitsu",
4546	[ALC260_ACER]		= "acer",
4547	[ALC260_WILL]		= "will",
4548	[ALC260_REPLACER_672V]	= "replacer",
4549#ifdef CONFIG_SND_DEBUG
4550	[ALC260_TEST]		= "test",
4551#endif
4552	[ALC260_AUTO]		= "auto",
4553};
4554
4555static struct snd_pci_quirk alc260_cfg_tbl[] = {
4556	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4557	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4558	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4559	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4560	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4561	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4562	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4563	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4564	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4565	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4566	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4567	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4568	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4569	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4570	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4571	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4572	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4573	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4574	{}
4575};
4576
4577static struct alc_config_preset alc260_presets[] = {
4578	[ALC260_BASIC] = {
4579		.mixers = { alc260_base_output_mixer,
4580			    alc260_input_mixer,
4581			    alc260_pc_beep_mixer,
4582			    alc260_capture_mixer },
4583		.init_verbs = { alc260_init_verbs },
4584		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4585		.dac_nids = alc260_dac_nids,
4586		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4587		.adc_nids = alc260_adc_nids,
4588		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4589		.channel_mode = alc260_modes,
4590		.input_mux = &alc260_capture_source,
4591	},
4592	[ALC260_HP] = {
4593		.mixers = { alc260_base_output_mixer,
4594			    alc260_input_mixer,
4595			    alc260_capture_alt_mixer },
4596		.init_verbs = { alc260_init_verbs },
4597		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4598		.dac_nids = alc260_dac_nids,
4599		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4600		.adc_nids = alc260_hp_adc_nids,
4601		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4602		.channel_mode = alc260_modes,
4603		.input_mux = &alc260_capture_source,
4604	},
4605	[ALC260_HP_3013] = {
4606		.mixers = { alc260_hp_3013_mixer,
4607			    alc260_input_mixer,
4608			    alc260_capture_alt_mixer },
4609		.init_verbs = { alc260_hp_3013_init_verbs },
4610		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4611		.dac_nids = alc260_dac_nids,
4612		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4613		.adc_nids = alc260_hp_adc_nids,
4614		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4615		.channel_mode = alc260_modes,
4616		.input_mux = &alc260_capture_source,
4617	},
4618	[ALC260_FUJITSU_S702X] = {
4619		.mixers = { alc260_fujitsu_mixer,
4620			    alc260_capture_mixer },
4621		.init_verbs = { alc260_fujitsu_init_verbs },
4622		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4623		.dac_nids = alc260_dac_nids,
4624		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4625		.adc_nids = alc260_dual_adc_nids,
4626		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4627		.channel_mode = alc260_modes,
4628		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4629		.input_mux = alc260_fujitsu_capture_sources,
4630	},
4631	[ALC260_ACER] = {
4632		.mixers = { alc260_acer_mixer,
4633			    alc260_capture_mixer },
4634		.init_verbs = { alc260_acer_init_verbs },
4635		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4636		.dac_nids = alc260_dac_nids,
4637		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4638		.adc_nids = alc260_dual_adc_nids,
4639		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4640		.channel_mode = alc260_modes,
4641		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4642		.input_mux = alc260_acer_capture_sources,
4643	},
4644	[ALC260_WILL] = {
4645		.mixers = { alc260_will_mixer,
4646			    alc260_capture_mixer },
4647		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4648		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4649		.dac_nids = alc260_dac_nids,
4650		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4651		.adc_nids = alc260_adc_nids,
4652		.dig_out_nid = ALC260_DIGOUT_NID,
4653		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4654		.channel_mode = alc260_modes,
4655		.input_mux = &alc260_capture_source,
4656	},
4657	[ALC260_REPLACER_672V] = {
4658		.mixers = { alc260_replacer_672v_mixer,
4659			    alc260_capture_mixer },
4660		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4661		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4662		.dac_nids = alc260_dac_nids,
4663		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4664		.adc_nids = alc260_adc_nids,
4665		.dig_out_nid = ALC260_DIGOUT_NID,
4666		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4667		.channel_mode = alc260_modes,
4668		.input_mux = &alc260_capture_source,
4669		.unsol_event = alc260_replacer_672v_unsol_event,
4670		.init_hook = alc260_replacer_672v_automute,
4671	},
4672#ifdef CONFIG_SND_DEBUG
4673	[ALC260_TEST] = {
4674		.mixers = { alc260_test_mixer,
4675			    alc260_capture_mixer },
4676		.init_verbs = { alc260_test_init_verbs },
4677		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4678		.dac_nids = alc260_test_dac_nids,
4679		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4680		.adc_nids = alc260_test_adc_nids,
4681		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4682		.channel_mode = alc260_modes,
4683		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4684		.input_mux = alc260_test_capture_sources,
4685	},
4686#endif
4687};
4688
4689static int patch_alc260(struct hda_codec *codec)
4690{
4691	struct alc_spec *spec;
4692	int err, board_config;
4693
4694	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4695	if (spec == NULL)
4696		return -ENOMEM;
4697
4698	codec->spec = spec;
4699
4700	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4701						  alc260_models,
4702						  alc260_cfg_tbl);
4703	if (board_config < 0) {
4704		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4705			   "trying auto-probe from BIOS...\n");
4706		board_config = ALC260_AUTO;
4707	}
4708
4709	if (board_config == ALC260_AUTO) {
4710		/* automatic parse from the BIOS config */
4711		err = alc260_parse_auto_config(codec);
4712		if (err < 0) {
4713			alc_free(codec);
4714			return err;
4715		} else if (!err) {
4716			printk(KERN_INFO
4717			       "hda_codec: Cannot set up configuration "
4718			       "from BIOS.  Using base mode...\n");
4719			board_config = ALC260_BASIC;
4720		}
4721	}
4722
4723	if (board_config != ALC260_AUTO)
4724		setup_preset(spec, &alc260_presets[board_config]);
4725
4726	spec->stream_name_analog = "ALC260 Analog";
4727	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4728	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4729
4730	spec->stream_name_digital = "ALC260 Digital";
4731	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4732	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4733
4734	codec->patch_ops = alc_patch_ops;
4735	if (board_config == ALC260_AUTO)
4736		spec->init_hook = alc260_auto_init;
4737
4738	return 0;
4739}
4740
4741
4742/*
4743 * ALC882 support
4744 *
4745 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4746 * configuration.  Each pin widget can choose any input DACs and a mixer.
4747 * Each ADC is connected from a mixer of all inputs.  This makes possible
4748 * 6-channel independent captures.
4749 *
4750 * In addition, an independent DAC for the multi-playback (not used in this
4751 * driver yet).
4752 */
4753#define ALC882_DIGOUT_NID	0x06
4754#define ALC882_DIGIN_NID	0x0a
4755
4756static struct hda_channel_mode alc882_ch_modes[1] = {
4757	{ 8, NULL }
4758};
4759
4760static hda_nid_t alc882_dac_nids[4] = {
4761	/* front, rear, clfe, rear_surr */
4762	0x02, 0x03, 0x04, 0x05
4763};
4764
4765/* identical with ALC880 */
4766#define alc882_adc_nids		alc880_adc_nids
4767#define alc882_adc_nids_alt	alc880_adc_nids_alt
4768
4769/* input MUX */
4770/* FIXME: should be a matrix-type input source selection */
4771
4772static struct hda_input_mux alc882_capture_source = {
4773	.num_items = 4,
4774	.items = {
4775		{ "Mic", 0x0 },
4776		{ "Front Mic", 0x1 },
4777		{ "Line", 0x2 },
4778		{ "CD", 0x4 },
4779	},
4780};
4781#define alc882_mux_enum_info alc_mux_enum_info
4782#define alc882_mux_enum_get alc_mux_enum_get
4783
4784static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4785			       struct snd_ctl_elem_value *ucontrol)
4786{
4787	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4788	struct alc_spec *spec = codec->spec;
4789	const struct hda_input_mux *imux = spec->input_mux;
4790	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4791	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4792	hda_nid_t nid = capture_mixers[adc_idx];
4793	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4794	unsigned int i, idx;
4795
4796	idx = ucontrol->value.enumerated.item[0];
4797	if (idx >= imux->num_items)
4798		idx = imux->num_items - 1;
4799	if (*cur_val == idx && !codec->in_resume)
4800		return 0;
4801	for (i = 0; i < imux->num_items; i++) {
4802		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4803		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4804				    v | (imux->items[i].index << 8));
4805	}
4806	*cur_val = idx;
4807	return 1;
4808}
4809
4810/*
4811 * 2ch mode
4812 */
4813static struct hda_verb alc882_3ST_ch2_init[] = {
4814	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4815	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4816	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4817	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4818	{ } /* end */
4819};
4820
4821/*
4822 * 6ch mode
4823 */
4824static struct hda_verb alc882_3ST_ch6_init[] = {
4825	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4826	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4827	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4828	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4829	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4830	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4831	{ } /* end */
4832};
4833
4834static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4835	{ 2, alc882_3ST_ch2_init },
4836	{ 6, alc882_3ST_ch6_init },
4837};
4838
4839/*
4840 * 6ch mode
4841 */
4842static struct hda_verb alc882_sixstack_ch6_init[] = {
4843	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4844	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4845	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4846	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4847	{ } /* end */
4848};
4849
4850/*
4851 * 8ch mode
4852 */
4853static struct hda_verb alc882_sixstack_ch8_init[] = {
4854	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4855	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4856	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4857	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4858	{ } /* end */
4859};
4860
4861static struct hda_channel_mode alc882_sixstack_modes[2] = {
4862	{ 6, alc882_sixstack_ch6_init },
4863	{ 8, alc882_sixstack_ch8_init },
4864};
4865
4866/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4867 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4868 */
4869static struct snd_kcontrol_new alc882_base_mixer[] = {
4870	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4871	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4872	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4873	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4874	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4875	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4876	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4877	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4878	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4879	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4880	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4881	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4882	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4883	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4884	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4885	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4886	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4887	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4888	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4889	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4890	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4891	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4892	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4893	{ } /* end */
4894};
4895
4896static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4897	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4898	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4899	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4900	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4901	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4902	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4903	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4904	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4905	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4906	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4907	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4908	{ } /* end */
4909};
4910
4911static struct snd_kcontrol_new alc882_targa_mixer[] = {
4912	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4913	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4914	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4915	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4916	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4917	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4918	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4919	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4920	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4921	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4922	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4923	{ } /* end */
4924};
4925
4926/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4927 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4928 */
4929static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
4930	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4931	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4932	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4933	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
4934	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4935	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4936	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4937	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4938	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
4939	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
4940	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4941	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4942	{ } /* end */
4943};
4944
4945static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4946	{
4947		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4948		.name = "Channel Mode",
4949		.info = alc_ch_mode_info,
4950		.get = alc_ch_mode_get,
4951		.put = alc_ch_mode_put,
4952	},
4953	{ } /* end */
4954};
4955
4956static struct hda_verb alc882_init_verbs[] = {
4957	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4958	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4959	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4960	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4961	/* Rear mixer */
4962	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4963	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4964	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4965	/* CLFE mixer */
4966	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4967	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4968	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4969	/* Side mixer */
4970	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4971	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4972	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4973
4974	/* Front Pin: output 0 (0x0c) */
4975	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4976	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4977	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4978	/* Rear Pin: output 1 (0x0d) */
4979	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4980	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4981	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4982	/* CLFE Pin: output 2 (0x0e) */
4983	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4984	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4985	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4986	/* Side Pin: output 3 (0x0f) */
4987	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4988	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4989	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4990	/* Mic (rear) pin: input vref at 80% */
4991	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4992	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4993	/* Front Mic pin: input vref at 80% */
4994	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4995	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4996	/* Line In pin: input */
4997	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4998	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4999	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5000	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5001	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5002	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5003	/* CD pin widget for input */
5004	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5005
5006	/* FIXME: use matrix-type input source selection */
5007	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5008	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5009	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5010	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5011	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5012	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5013	/* Input mixer2 */
5014	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5015	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5016	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5017	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5018	/* Input mixer3 */
5019	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5020	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5021	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5022	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5023	/* ADC1: mute amp left and right */
5024	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5025	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5026	/* ADC2: mute amp left and right */
5027	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5028	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5029	/* ADC3: mute amp left and right */
5030	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5031	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5032
5033	{ }
5034};
5035
5036static struct hda_verb alc882_eapd_verbs[] = {
5037	/* change to EAPD mode */
5038	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5039	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5040	{ }
5041};
5042
5043/* Mac Pro test */
5044static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5045	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5046	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5047	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5048	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5049	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5050	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5051	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5052	{ } /* end */
5053};
5054
5055static struct hda_verb alc882_macpro_init_verbs[] = {
5056	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5057	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5058	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5059	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5060	/* Front Pin: output 0 (0x0c) */
5061	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5062	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5063	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5064	/* Front Mic pin: input vref at 80% */
5065	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5066	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5067	/* Speaker:  output */
5068	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5069	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5070	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5071	/* Headphone output (output 0 - 0x0c) */
5072	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5073	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5074	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5075
5076	/* FIXME: use matrix-type input source selection */
5077	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5078	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5079	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5080	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5081	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5082	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5083	/* Input mixer2 */
5084	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5085	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5086	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5087	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5088	/* Input mixer3 */
5089	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5090	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5091	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5092	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5093	/* ADC1: mute amp left and right */
5094	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5095	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5096	/* ADC2: mute amp left and right */
5097	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5098	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5099	/* ADC3: mute amp left and right */
5100	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5101	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5102
5103	{ }
5104};
5105
5106/* iMac 24 mixer. */
5107static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5108	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5109	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5110	{ } /* end */
5111};
5112
5113/* iMac 24 init verbs. */
5114static struct hda_verb alc885_imac24_init_verbs[] = {
5115	/* Internal speakers: output 0 (0x0c) */
5116	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5117	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5118	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5119	/* Internal speakers: output 0 (0x0c) */
5120	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5121	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5122	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5123	/* Headphone: output 0 (0x0c) */
5124	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5125	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5126	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5127	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5128	/* Front Mic: input vref at 80% */
5129	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5130	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5131	{ }
5132};
5133
5134/* Toggle speaker-output according to the hp-jack state */
5135static void alc885_imac24_automute(struct hda_codec *codec)
5136{
5137 	unsigned int present;
5138
5139 	present = snd_hda_codec_read(codec, 0x14, 0,
5140				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5141	snd_hda_codec_amp_update(codec, 0x18, 0, HDA_OUTPUT, 0,
5142				 0x80, present ? 0x80 : 0);
5143	snd_hda_codec_amp_update(codec, 0x18, 1, HDA_OUTPUT, 0,
5144				 0x80, present ? 0x80 : 0);
5145	snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
5146				 0x80, present ? 0x80 : 0);
5147	snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
5148				 0x80, present ? 0x80 : 0);
5149}
5150
5151/* Processes unsolicited events. */
5152static void alc885_imac24_unsol_event(struct hda_codec *codec,
5153				      unsigned int res)
5154{
5155	/* Headphone insertion or removal. */
5156	if ((res >> 26) == ALC880_HP_EVENT)
5157		alc885_imac24_automute(codec);
5158}
5159
5160static struct hda_verb alc882_targa_verbs[] = {
5161	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5162	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5163
5164	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5165	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5166
5167	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5168	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5169	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5170
5171	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5172	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5173	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5174	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5175	{ } /* end */
5176};
5177
5178/* toggle speaker-output according to the hp-jack state */
5179static void alc882_targa_automute(struct hda_codec *codec)
5180{
5181 	unsigned int present;
5182
5183 	present = snd_hda_codec_read(codec, 0x14, 0,
5184				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5185	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5186				 0x80, present ? 0x80 : 0);
5187	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5188				 0x80, present ? 0x80 : 0);
5189	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5190}
5191
5192static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5193{
5194	/* Looks like the unsol event is incompatible with the standard
5195	 * definition.  4bit tag is placed at 26 bit!
5196	 */
5197	if (((res >> 26) == ALC880_HP_EVENT)) {
5198		alc882_targa_automute(codec);
5199	}
5200}
5201
5202static struct hda_verb alc882_asus_a7j_verbs[] = {
5203	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5204	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5205
5206	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5207	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5208	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5209
5210	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5211	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5212	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5213
5214	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5215	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5216	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5217	{ } /* end */
5218};
5219
5220static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5221{
5222	unsigned int gpiostate, gpiomask, gpiodir;
5223
5224	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5225				       AC_VERB_GET_GPIO_DATA, 0);
5226
5227	if (!muted)
5228		gpiostate |= (1 << pin);
5229	else
5230		gpiostate &= ~(1 << pin);
5231
5232	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5233				      AC_VERB_GET_GPIO_MASK, 0);
5234	gpiomask |= (1 << pin);
5235
5236	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5237				     AC_VERB_GET_GPIO_DIRECTION, 0);
5238	gpiodir |= (1 << pin);
5239
5240
5241	snd_hda_codec_write(codec, codec->afg, 0,
5242			    AC_VERB_SET_GPIO_MASK, gpiomask);
5243	snd_hda_codec_write(codec, codec->afg, 0,
5244			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5245
5246	msleep(1);
5247
5248	snd_hda_codec_write(codec, codec->afg, 0,
5249			    AC_VERB_SET_GPIO_DATA, gpiostate);
5250}
5251
5252/*
5253 * generic initialization of ADC, input mixers and output mixers
5254 */
5255static struct hda_verb alc882_auto_init_verbs[] = {
5256	/*
5257	 * Unmute ADC0-2 and set the default input to mic-in
5258	 */
5259	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5260	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5261	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5262	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5263	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5264	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5265
5266	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5267	 * mixer widget
5268	 * Note: PASD motherboards uses the Line In 2 as the input for
5269	 * front panel mic (mic 2)
5270	 */
5271	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5272	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5273	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5274	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5275	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5276	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5277
5278	/*
5279	 * Set up output mixers (0x0c - 0x0f)
5280	 */
5281	/* set vol=0 to output mixers */
5282	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5283	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5284	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5285	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5286	/* set up input amps for analog loopback */
5287	/* Amp Indices: DAC = 0, mixer = 1 */
5288	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5289	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5290	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5291	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5292	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5293	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5294	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5295	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5296	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5297	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5298
5299	/* FIXME: use matrix-type input source selection */
5300	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5301	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5302	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5303	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5304	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5305	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5306	/* Input mixer2 */
5307	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5308	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5309	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5310	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5311	/* Input mixer3 */
5312	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5313	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5314	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5315	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5316
5317	{ }
5318};
5319
5320/* capture mixer elements */
5321static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5322	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5323	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5324	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5325	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5326	{
5327		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5328		/* The multiple "Capture Source" controls confuse alsamixer
5329		 * So call somewhat different..
5330		 * FIXME: the controls appear in the "playback" view!
5331		 */
5332		/* .name = "Capture Source", */
5333		.name = "Input Source",
5334		.count = 2,
5335		.info = alc882_mux_enum_info,
5336		.get = alc882_mux_enum_get,
5337		.put = alc882_mux_enum_put,
5338	},
5339	{ } /* end */
5340};
5341
5342static struct snd_kcontrol_new alc882_capture_mixer[] = {
5343	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5344	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5345	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5346	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5347	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5348	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5349	{
5350		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5351		/* The multiple "Capture Source" controls confuse alsamixer
5352		 * So call somewhat different..
5353		 * FIXME: the controls appear in the "playback" view!
5354		 */
5355		/* .name = "Capture Source", */
5356		.name = "Input Source",
5357		.count = 3,
5358		.info = alc882_mux_enum_info,
5359		.get = alc882_mux_enum_get,
5360		.put = alc882_mux_enum_put,
5361	},
5362	{ } /* end */
5363};
5364
5365/* pcm configuration: identiacal with ALC880 */
5366#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5367#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5368#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5369#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5370
5371/*
5372 * configuration and preset
5373 */
5374static const char *alc882_models[ALC882_MODEL_LAST] = {
5375	[ALC882_3ST_DIG]	= "3stack-dig",
5376	[ALC882_6ST_DIG]	= "6stack-dig",
5377	[ALC882_ARIMA]		= "arima",
5378	[ALC882_W2JC]		= "w2jc",
5379	[ALC885_MACPRO]		= "macpro",
5380	[ALC885_IMAC24]		= "imac24",
5381	[ALC882_AUTO]		= "auto",
5382};
5383
5384static struct snd_pci_quirk alc882_cfg_tbl[] = {
5385	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5386	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5387	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5388	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5389	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5390	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5391	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5392	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5393	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5394	{}
5395};
5396
5397static struct alc_config_preset alc882_presets[] = {
5398	[ALC882_3ST_DIG] = {
5399		.mixers = { alc882_base_mixer },
5400		.init_verbs = { alc882_init_verbs },
5401		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5402		.dac_nids = alc882_dac_nids,
5403		.dig_out_nid = ALC882_DIGOUT_NID,
5404		.dig_in_nid = ALC882_DIGIN_NID,
5405		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5406		.channel_mode = alc882_ch_modes,
5407		.need_dac_fix = 1,
5408		.input_mux = &alc882_capture_source,
5409	},
5410	[ALC882_6ST_DIG] = {
5411		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5412		.init_verbs = { alc882_init_verbs },
5413		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5414		.dac_nids = alc882_dac_nids,
5415		.dig_out_nid = ALC882_DIGOUT_NID,
5416		.dig_in_nid = ALC882_DIGIN_NID,
5417		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5418		.channel_mode = alc882_sixstack_modes,
5419		.input_mux = &alc882_capture_source,
5420	},
5421	[ALC882_ARIMA] = {
5422		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5423		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5424		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5425		.dac_nids = alc882_dac_nids,
5426		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5427		.channel_mode = alc882_sixstack_modes,
5428		.input_mux = &alc882_capture_source,
5429	},
5430	[ALC882_W2JC] = {
5431		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5432		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5433				alc880_gpio1_init_verbs },
5434		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5435		.dac_nids = alc882_dac_nids,
5436		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5437		.channel_mode = alc880_threestack_modes,
5438		.need_dac_fix = 1,
5439		.input_mux = &alc882_capture_source,
5440		.dig_out_nid = ALC882_DIGOUT_NID,
5441	},
5442	[ALC885_MACPRO] = {
5443		.mixers = { alc882_macpro_mixer },
5444		.init_verbs = { alc882_macpro_init_verbs },
5445		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5446		.dac_nids = alc882_dac_nids,
5447		.dig_out_nid = ALC882_DIGOUT_NID,
5448		.dig_in_nid = ALC882_DIGIN_NID,
5449		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5450		.channel_mode = alc882_ch_modes,
5451		.input_mux = &alc882_capture_source,
5452	},
5453	[ALC885_IMAC24] = {
5454		.mixers = { alc885_imac24_mixer },
5455		.init_verbs = { alc885_imac24_init_verbs },
5456		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5457		.dac_nids = alc882_dac_nids,
5458		.dig_out_nid = ALC882_DIGOUT_NID,
5459		.dig_in_nid = ALC882_DIGIN_NID,
5460		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5461		.channel_mode = alc882_ch_modes,
5462		.input_mux = &alc882_capture_source,
5463		.unsol_event = alc885_imac24_unsol_event,
5464		.init_hook = alc885_imac24_automute,
5465	},
5466	[ALC882_TARGA] = {
5467		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5468			    alc882_capture_mixer },
5469		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5470		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5471		.dac_nids = alc882_dac_nids,
5472		.dig_out_nid = ALC882_DIGOUT_NID,
5473		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5474		.adc_nids = alc882_adc_nids,
5475		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5476		.channel_mode = alc882_3ST_6ch_modes,
5477		.need_dac_fix = 1,
5478		.input_mux = &alc882_capture_source,
5479		.unsol_event = alc882_targa_unsol_event,
5480		.init_hook = alc882_targa_automute,
5481	},
5482	[ALC882_ASUS_A7J] = {
5483		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5484			    alc882_capture_mixer },
5485		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5486		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5487		.dac_nids = alc882_dac_nids,
5488		.dig_out_nid = ALC882_DIGOUT_NID,
5489		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5490		.adc_nids = alc882_adc_nids,
5491		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5492		.channel_mode = alc882_3ST_6ch_modes,
5493		.need_dac_fix = 1,
5494		.input_mux = &alc882_capture_source,
5495	},
5496};
5497
5498
5499/*
5500 * Pin config fixes
5501 */
5502enum {
5503	PINFIX_ABIT_AW9D_MAX
5504};
5505
5506static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5507	{ 0x15, 0x01080104 }, /* side */
5508	{ 0x16, 0x01011012 }, /* rear */
5509	{ 0x17, 0x01016011 }, /* clfe */
5510	{ }
5511};
5512
5513static const struct alc_pincfg *alc882_pin_fixes[] = {
5514	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5515};
5516
5517static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5518	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5519	{}
5520};
5521
5522/*
5523 * BIOS auto configuration
5524 */
5525static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5526					      hda_nid_t nid, int pin_type,
5527					      int dac_idx)
5528{
5529	/* set as output */
5530	struct alc_spec *spec = codec->spec;
5531	int idx;
5532
5533	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5534		idx = 4;
5535	else
5536		idx = spec->multiout.dac_nids[dac_idx] - 2;
5537
5538	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5539			    pin_type);
5540	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5541			    AMP_OUT_UNMUTE);
5542	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5543
5544}
5545
5546static void alc882_auto_init_multi_out(struct hda_codec *codec)
5547{
5548	struct alc_spec *spec = codec->spec;
5549	int i;
5550
5551	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5552	for (i = 0; i <= HDA_SIDE; i++) {
5553		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5554		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5555		if (nid)
5556			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5557							  i);
5558	}
5559}
5560
5561static void alc882_auto_init_hp_out(struct hda_codec *codec)
5562{
5563	struct alc_spec *spec = codec->spec;
5564	hda_nid_t pin;
5565
5566	pin = spec->autocfg.hp_pins[0];
5567	if (pin) /* connect to front */
5568		/* use dac 0 */
5569		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5570}
5571
5572#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
5573#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
5574
5575static void alc882_auto_init_analog_input(struct hda_codec *codec)
5576{
5577	struct alc_spec *spec = codec->spec;
5578	int i;
5579
5580	for (i = 0; i < AUTO_PIN_LAST; i++) {
5581		hda_nid_t nid = spec->autocfg.input_pins[i];
5582		if (alc882_is_input_pin(nid)) {
5583			snd_hda_codec_write(codec, nid, 0,
5584					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5585					    i <= AUTO_PIN_FRONT_MIC ?
5586					    PIN_VREF80 : PIN_IN);
5587			if (nid != ALC882_PIN_CD_NID)
5588				snd_hda_codec_write(codec, nid, 0,
5589						    AC_VERB_SET_AMP_GAIN_MUTE,
5590						    AMP_OUT_MUTE);
5591		}
5592	}
5593}
5594
5595/* almost identical with ALC880 parser... */
5596static int alc882_parse_auto_config(struct hda_codec *codec)
5597{
5598	struct alc_spec *spec = codec->spec;
5599	int err = alc880_parse_auto_config(codec);
5600
5601	if (err < 0)
5602		return err;
5603	else if (err > 0)
5604		/* hack - override the init verbs */
5605		spec->init_verbs[0] = alc882_auto_init_verbs;
5606	return err;
5607}
5608
5609/* additional initialization for auto-configuration model */
5610static void alc882_auto_init(struct hda_codec *codec)
5611{
5612	alc882_auto_init_multi_out(codec);
5613	alc882_auto_init_hp_out(codec);
5614	alc882_auto_init_analog_input(codec);
5615}
5616
5617static int patch_alc882(struct hda_codec *codec)
5618{
5619	struct alc_spec *spec;
5620	int err, board_config;
5621
5622	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5623	if (spec == NULL)
5624		return -ENOMEM;
5625
5626	codec->spec = spec;
5627
5628	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5629						  alc882_models,
5630						  alc882_cfg_tbl);
5631
5632	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5633		/* Pick up systems that don't supply PCI SSID */
5634		switch (codec->subsystem_id) {
5635		case 0x106b0c00: /* Mac Pro */
5636			board_config = ALC885_MACPRO;
5637			break;
5638		case 0x106b1000: /* iMac 24 */
5639			board_config = ALC885_IMAC24;
5640			break;
5641		default:
5642			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5643		       			 "trying auto-probe from BIOS...\n");
5644			board_config = ALC882_AUTO;
5645		}
5646	}
5647
5648	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5649
5650	if (board_config == ALC882_AUTO) {
5651		/* automatic parse from the BIOS config */
5652		err = alc882_parse_auto_config(codec);
5653		if (err < 0) {
5654			alc_free(codec);
5655			return err;
5656		} else if (!err) {
5657			printk(KERN_INFO
5658			       "hda_codec: Cannot set up configuration "
5659			       "from BIOS.  Using base mode...\n");
5660			board_config = ALC882_3ST_DIG;
5661		}
5662	}
5663
5664	if (board_config != ALC882_AUTO)
5665		setup_preset(spec, &alc882_presets[board_config]);
5666
5667	if (board_config == ALC885_MACPRO || board_config == ALC885_IMAC24) {
5668		alc882_gpio_mute(codec, 0, 0);
5669		alc882_gpio_mute(codec, 1, 0);
5670	}
5671
5672	spec->stream_name_analog = "ALC882 Analog";
5673	spec->stream_analog_playback = &alc882_pcm_analog_playback;
5674	spec->stream_analog_capture = &alc882_pcm_analog_capture;
5675
5676	spec->stream_name_digital = "ALC882 Digital";
5677	spec->stream_digital_playback = &alc882_pcm_digital_playback;
5678	spec->stream_digital_capture = &alc882_pcm_digital_capture;
5679
5680	if (!spec->adc_nids && spec->input_mux) {
5681		/* check whether NID 0x07 is valid */
5682		unsigned int wcap = get_wcaps(codec, 0x07);
5683		/* get type */
5684		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5685		if (wcap != AC_WID_AUD_IN) {
5686			spec->adc_nids = alc882_adc_nids_alt;
5687			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5688			spec->mixers[spec->num_mixers] =
5689				alc882_capture_alt_mixer;
5690			spec->num_mixers++;
5691		} else {
5692			spec->adc_nids = alc882_adc_nids;
5693			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5694			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5695			spec->num_mixers++;
5696		}
5697	}
5698
5699	codec->patch_ops = alc_patch_ops;
5700	if (board_config == ALC882_AUTO)
5701		spec->init_hook = alc882_auto_init;
5702
5703	return 0;
5704}
5705
5706/*
5707 * ALC883 support
5708 *
5709 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5710 * configuration.  Each pin widget can choose any input DACs and a mixer.
5711 * Each ADC is connected from a mixer of all inputs.  This makes possible
5712 * 6-channel independent captures.
5713 *
5714 * In addition, an independent DAC for the multi-playback (not used in this
5715 * driver yet).
5716 */
5717#define ALC883_DIGOUT_NID	0x06
5718#define ALC883_DIGIN_NID	0x0a
5719
5720static hda_nid_t alc883_dac_nids[4] = {
5721	/* front, rear, clfe, rear_surr */
5722	0x02, 0x04, 0x03, 0x05
5723};
5724
5725static hda_nid_t alc883_adc_nids[2] = {
5726	/* ADC1-2 */
5727	0x08, 0x09,
5728};
5729
5730/* input MUX */
5731/* FIXME: should be a matrix-type input source selection */
5732
5733static struct hda_input_mux alc883_capture_source = {
5734	.num_items = 4,
5735	.items = {
5736		{ "Mic", 0x0 },
5737		{ "Front Mic", 0x1 },
5738		{ "Line", 0x2 },
5739		{ "CD", 0x4 },
5740	},
5741};
5742
5743static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5744	.num_items = 2,
5745	.items = {
5746		{ "Mic", 0x1 },
5747		{ "Line", 0x2 },
5748	},
5749};
5750
5751static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5752	.num_items = 4,
5753	.items = {
5754		{ "Mic", 0x0 },
5755		{ "iMic", 0x1 },
5756		{ "Line", 0x2 },
5757		{ "CD", 0x4 },
5758	},
5759};
5760
5761#define alc883_mux_enum_info alc_mux_enum_info
5762#define alc883_mux_enum_get alc_mux_enum_get
5763
5764static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5765			       struct snd_ctl_elem_value *ucontrol)
5766{
5767	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5768	struct alc_spec *spec = codec->spec;
5769	const struct hda_input_mux *imux = spec->input_mux;
5770	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5771	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5772	hda_nid_t nid = capture_mixers[adc_idx];
5773	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5774	unsigned int i, idx;
5775
5776	idx = ucontrol->value.enumerated.item[0];
5777	if (idx >= imux->num_items)
5778		idx = imux->num_items - 1;
5779	if (*cur_val == idx && !codec->in_resume)
5780		return 0;
5781	for (i = 0; i < imux->num_items; i++) {
5782		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
5783		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5784				    v | (imux->items[i].index << 8));
5785	}
5786	*cur_val = idx;
5787	return 1;
5788}
5789
5790/*
5791 * 2ch mode
5792 */
5793static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5794	{ 2, NULL }
5795};
5796
5797/*
5798 * 2ch mode
5799 */
5800static struct hda_verb alc883_3ST_ch2_init[] = {
5801	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5802	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5803	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5804	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5805	{ } /* end */
5806};
5807
5808/*
5809 * 6ch mode
5810 */
5811static struct hda_verb alc883_3ST_ch6_init[] = {
5812	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5813	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5814	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5815	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5816	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5817	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5818	{ } /* end */
5819};
5820
5821static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
5822	{ 2, alc883_3ST_ch2_init },
5823	{ 6, alc883_3ST_ch6_init },
5824};
5825
5826/*
5827 * 6ch mode
5828 */
5829static struct hda_verb alc883_sixstack_ch6_init[] = {
5830	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5831	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5832	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5833	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5834	{ } /* end */
5835};
5836
5837/*
5838 * 8ch mode
5839 */
5840static struct hda_verb alc883_sixstack_ch8_init[] = {
5841	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5842	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5843	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5844	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5845	{ } /* end */
5846};
5847
5848static struct hda_channel_mode alc883_sixstack_modes[2] = {
5849	{ 6, alc883_sixstack_ch6_init },
5850	{ 8, alc883_sixstack_ch8_init },
5851};
5852
5853static struct hda_verb alc883_medion_eapd_verbs[] = {
5854        /* eanable EAPD on medion laptop */
5855	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5856	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5857	{ }
5858};
5859
5860/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5861 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5862 */
5863
5864static struct snd_kcontrol_new alc883_base_mixer[] = {
5865	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5866	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5867	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5868	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5869	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5870	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5871	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5872	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5873	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5874	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5875	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5876	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5877	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5878	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5879	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5880	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5881	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5882	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5883	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5884	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5885	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5886	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5887	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5888	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5889	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5890	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5891	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5892	{
5893		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5894		/* .name = "Capture Source", */
5895		.name = "Input Source",
5896		.count = 2,
5897		.info = alc883_mux_enum_info,
5898		.get = alc883_mux_enum_get,
5899		.put = alc883_mux_enum_put,
5900	},
5901	{ } /* end */
5902};
5903
5904static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5905	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5906	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5907	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5908	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5909	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5910	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5911	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5912	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5913	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5914	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5915	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5916	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5917	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5918	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5919	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5920	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5921	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5922	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5923	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5924	{
5925		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5926		/* .name = "Capture Source", */
5927		.name = "Input Source",
5928		.count = 2,
5929		.info = alc883_mux_enum_info,
5930		.get = alc883_mux_enum_get,
5931		.put = alc883_mux_enum_put,
5932	},
5933	{ } /* end */
5934};
5935
5936static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5937	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5938	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5939	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5940	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5941	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5942	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5943	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5944	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5945	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5946	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5947	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5948	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5949	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5950	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5951	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5952	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5953	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5954	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5955	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5956	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5957	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5958	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5959	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5960	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5961	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5962	{
5963		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5964		/* .name = "Capture Source", */
5965		.name = "Input Source",
5966		.count = 2,
5967		.info = alc883_mux_enum_info,
5968		.get = alc883_mux_enum_get,
5969		.put = alc883_mux_enum_put,
5970	},
5971	{ } /* end */
5972};
5973
5974static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5975	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5976	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5977	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5978	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5979	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5980	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5981	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5982	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5983	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5984	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5985	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5986	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5987	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5988	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5989	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5990	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5991	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5992	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5993	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5994	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5995	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5996	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5997	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5998
5999	{
6000		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6001		/* .name = "Capture Source", */
6002		.name = "Input Source",
6003		.count = 1,
6004		.info = alc883_mux_enum_info,
6005		.get = alc883_mux_enum_get,
6006		.put = alc883_mux_enum_put,
6007	},
6008	{ } /* end */
6009};
6010
6011static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6012	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6013	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6014	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6015	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6016	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6017	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6018	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6019	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6020	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6021	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6022	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6023	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6024	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6025	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6026	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6027	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6028	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6029	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6030	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6031	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6032	{
6033		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6034		/* .name = "Capture Source", */
6035		.name = "Input Source",
6036		.count = 2,
6037		.info = alc883_mux_enum_info,
6038		.get = alc883_mux_enum_get,
6039		.put = alc883_mux_enum_put,
6040	},
6041	{ } /* end */
6042};
6043
6044static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6045	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6046	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6047	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6048	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6049	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6050	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6051	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6052	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6053	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6054	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6055	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6056	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6057	{
6058		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6059		/* .name = "Capture Source", */
6060		.name = "Input Source",
6061		.count = 2,
6062		.info = alc883_mux_enum_info,
6063		.get = alc883_mux_enum_get,
6064		.put = alc883_mux_enum_put,
6065	},
6066	{ } /* end */
6067};
6068
6069static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6070	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6071	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6072	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6073	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6074	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6075	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6076	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6077	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6078	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6079	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6080	{
6081		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6082		/* .name = "Capture Source", */
6083		.name = "Input Source",
6084		.count = 1,
6085		.info = alc883_mux_enum_info,
6086		.get = alc883_mux_enum_get,
6087		.put = alc883_mux_enum_put,
6088	},
6089	{ } /* end */
6090};
6091
6092static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6093	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6094	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6095	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6096	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6097	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6098	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6099	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6100	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6101	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6102	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6103	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6104	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6105	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6106	{
6107		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6108		/* .name = "Capture Source", */
6109		.name = "Input Source",
6110		.count = 2,
6111		.info = alc883_mux_enum_info,
6112		.get = alc883_mux_enum_get,
6113		.put = alc883_mux_enum_put,
6114	},
6115	{ } /* end */
6116};
6117
6118static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6119	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6120	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6121	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6122	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6123	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6124	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6125	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6126	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6127	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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		/* .name = "Capture Source", */
6135		.name = "Input Source",
6136		.count = 2,
6137		.info = alc883_mux_enum_info,
6138		.get = alc883_mux_enum_get,
6139		.put = alc883_mux_enum_put,
6140	},
6141	{ } /* end */
6142};
6143
6144static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6145	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6146	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6147	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6148	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6149	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6150	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6151	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6152	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6153	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6154	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6155	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6156	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6157	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6158	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6159	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6160	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6161	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6162	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6163	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6164	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6165	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6166	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6167	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6168	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6169	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6170	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6171	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6172	{
6173		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6174		/* .name = "Capture Source", */
6175		.name = "Input Source",
6176		.count = 2,
6177		.info = alc883_mux_enum_info,
6178		.get = alc883_mux_enum_get,
6179		.put = alc883_mux_enum_put,
6180	},
6181	{ } /* end */
6182};
6183
6184static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6185	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6186	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6187	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6188	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6189	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6190	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6191	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6192	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6193	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6194	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6195	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6196	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6197	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6198	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6199	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6200	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6201	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6202	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6203	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6204	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6205	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6206	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6207	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6208	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6209	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6210	{
6211		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6212		/* .name = "Capture Source", */
6213		.name = "Input Source",
6214		.count = 2,
6215		.info = alc883_mux_enum_info,
6216		.get = alc883_mux_enum_get,
6217		.put = alc883_mux_enum_put,
6218	},
6219	{ } /* end */
6220};
6221
6222static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6223	{
6224		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6225		.name = "Channel Mode",
6226		.info = alc_ch_mode_info,
6227		.get = alc_ch_mode_get,
6228		.put = alc_ch_mode_put,
6229	},
6230	{ } /* end */
6231};
6232
6233static struct hda_verb alc883_init_verbs[] = {
6234	/* ADC1: mute amp left and right */
6235	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6236	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6237	/* ADC2: mute amp left and right */
6238	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6239	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6240	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6241	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6242	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6243	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6244	/* Rear mixer */
6245	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6246	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6247	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6248	/* CLFE mixer */
6249	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6250	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6251	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6252	/* Side mixer */
6253	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6254	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6255	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6256
6257	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6258	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6259	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6260	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6261	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6262
6263	/* Front Pin: output 0 (0x0c) */
6264	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6265	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6266	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6267	/* Rear Pin: output 1 (0x0d) */
6268	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6269	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6270	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6271	/* CLFE Pin: output 2 (0x0e) */
6272	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6273	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6274	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6275	/* Side Pin: output 3 (0x0f) */
6276	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6277	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6278	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6279	/* Mic (rear) pin: input vref at 80% */
6280	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6281	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6282	/* Front Mic pin: input vref at 80% */
6283	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6284	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6285	/* Line In pin: input */
6286	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6287	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6288	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6289	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6290	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6291	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6292	/* CD pin widget for input */
6293	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6294
6295	/* FIXME: use matrix-type input source selection */
6296	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6297	/* Input mixer2 */
6298	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6299	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6300	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6301	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6302	/* Input mixer3 */
6303	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6304	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6305	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6306	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6307	{ }
6308};
6309
6310static struct hda_verb alc883_tagra_verbs[] = {
6311	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6312	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6313
6314	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6315	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6316
6317	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6318	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6319	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6320
6321	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6322	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6323	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6324	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6325
6326	{ } /* end */
6327};
6328
6329static struct hda_verb alc883_lenovo_101e_verbs[] = {
6330	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6331	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6332        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6333	{ } /* end */
6334};
6335
6336static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6337        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6338	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6339        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6340        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6341	{ } /* end */
6342};
6343
6344static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6345	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6346	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6347	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6348	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6349	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6350	{ } /* end */
6351};
6352
6353static struct hda_verb alc888_6st_hp_verbs[] = {
6354	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6355	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},	/* Rear : output 2 (0x0e) */
6356	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* CLFE : output 1 (0x0d) */
6357	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},	/* Side : output 3 (0x0f) */
6358	{ }
6359};
6360
6361static struct hda_verb alc888_3st_hp_verbs[] = {
6362	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6363	{0x18, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
6364	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
6365	{ }
6366};
6367
6368static struct hda_verb alc888_3st_hp_2ch_init[] = {
6369	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6370	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6371	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6372	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6373	{ }
6374};
6375
6376static struct hda_verb alc888_3st_hp_6ch_init[] = {
6377	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6378	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6379	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6380	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6381	{ }
6382};
6383
6384static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6385	{ 2, alc888_3st_hp_2ch_init },
6386	{ 6, alc888_3st_hp_6ch_init },
6387};
6388
6389/* toggle front-jack and RCA according to the hp-jack state */
6390static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6391{
6392 	unsigned int present;
6393
6394 	present = snd_hda_codec_read(codec, 0x1b, 0,
6395				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6396	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6397				 0x80, present ? 0x80 : 0);
6398	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6399				 0x80, present ? 0x80 : 0);
6400	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6401				 0x80, present ? 0x80 : 0);
6402	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6403				 0x80, present ? 0x80 : 0);
6404
6405}
6406
6407/* toggle RCA according to the front-jack state */
6408static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6409{
6410 	unsigned int present;
6411
6412 	present = snd_hda_codec_read(codec, 0x14, 0,
6413				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6414	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6415				 0x80, present ? 0x80 : 0);
6416	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6417				 0x80, present ? 0x80 : 0);
6418
6419}
6420static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6421					     unsigned int res)
6422{
6423	if ((res >> 26) == ALC880_HP_EVENT)
6424		alc888_lenovo_ms7195_front_automute(codec);
6425	if ((res >> 26) == ALC880_FRONT_EVENT)
6426		alc888_lenovo_ms7195_rca_automute(codec);
6427}
6428
6429static struct hda_verb alc883_medion_md2_verbs[] = {
6430	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6431	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6432
6433	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6434
6435	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6436	{ } /* end */
6437};
6438
6439/* toggle speaker-output according to the hp-jack state */
6440static void alc883_medion_md2_automute(struct hda_codec *codec)
6441{
6442 	unsigned int present;
6443
6444 	present = snd_hda_codec_read(codec, 0x14, 0,
6445				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6446	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6447				 0x80, present ? 0x80 : 0);
6448	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6449				 0x80, present ? 0x80 : 0);
6450}
6451
6452static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6453					  unsigned int res)
6454{
6455	if ((res >> 26) == ALC880_HP_EVENT)
6456		alc883_medion_md2_automute(codec);
6457}
6458
6459/* toggle speaker-output according to the hp-jack state */
6460static void alc883_tagra_automute(struct hda_codec *codec)
6461{
6462 	unsigned int present;
6463	unsigned char bits;
6464
6465 	present = snd_hda_codec_read(codec, 0x14, 0,
6466				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6467	bits = present ? 0x80 : 0;
6468	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
6469				 0x80, bits);
6470	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
6471				 0x80, bits);
6472	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6473			    present ? 1 : 3);
6474}
6475
6476static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6477{
6478	if ((res >> 26) == ALC880_HP_EVENT)
6479		alc883_tagra_automute(codec);
6480}
6481
6482static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6483{
6484 	unsigned int present;
6485	unsigned char bits;
6486
6487 	present = snd_hda_codec_read(codec, 0x14, 0,
6488				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6489	bits = present ? 0x80 : 0;
6490	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6491				 0x80, bits);
6492	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6493				 0x80, bits);
6494}
6495
6496static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6497{
6498 	unsigned int present;
6499	unsigned char bits;
6500
6501 	present = snd_hda_codec_read(codec, 0x1b, 0,
6502				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6503	bits = present ? 0x80 : 0;
6504	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6505				 0x80, bits);
6506	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6507				 0x80, bits);
6508	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6509				 0x80, bits);
6510	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6511				 0x80, bits);
6512}
6513
6514static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6515					   unsigned int res)
6516{
6517	if ((res >> 26) == ALC880_HP_EVENT)
6518		alc883_lenovo_101e_all_automute(codec);
6519	if ((res >> 26) == ALC880_FRONT_EVENT)
6520		alc883_lenovo_101e_ispeaker_automute(codec);
6521}
6522
6523/*
6524 * generic initialization of ADC, input mixers and output mixers
6525 */
6526static struct hda_verb alc883_auto_init_verbs[] = {
6527	/*
6528	 * Unmute ADC0-2 and set the default input to mic-in
6529	 */
6530	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6531	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6532	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6533	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6534
6535	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6536	 * mixer widget
6537	 * Note: PASD motherboards uses the Line In 2 as the input for
6538	 * front panel mic (mic 2)
6539	 */
6540	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6541	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6542	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6543	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6544	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6545	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6546
6547	/*
6548	 * Set up output mixers (0x0c - 0x0f)
6549	 */
6550	/* set vol=0 to output mixers */
6551	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6552	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6553	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6554	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6555	/* set up input amps for analog loopback */
6556	/* Amp Indices: DAC = 0, mixer = 1 */
6557	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6558	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6559	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6560	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6561	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6562	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6563	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6564	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6565	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6566	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6567
6568	/* FIXME: use matrix-type input source selection */
6569	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6570	/* Input mixer1 */
6571	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6572	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6573	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6574	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6575	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6576	/* Input mixer2 */
6577	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6578	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6579	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6580	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6581	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6582
6583	{ }
6584};
6585
6586/* capture mixer elements */
6587static struct snd_kcontrol_new alc883_capture_mixer[] = {
6588	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6589	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6590	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6591	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6592	{
6593		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6594		/* The multiple "Capture Source" controls confuse alsamixer
6595		 * So call somewhat different..
6596		 * FIXME: the controls appear in the "playback" view!
6597		 */
6598		/* .name = "Capture Source", */
6599		.name = "Input Source",
6600		.count = 2,
6601		.info = alc882_mux_enum_info,
6602		.get = alc882_mux_enum_get,
6603		.put = alc882_mux_enum_put,
6604	},
6605	{ } /* end */
6606};
6607
6608/* pcm configuration: identiacal with ALC880 */
6609#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
6610#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
6611#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
6612#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
6613
6614/*
6615 * configuration and preset
6616 */
6617static const char *alc883_models[ALC883_MODEL_LAST] = {
6618	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
6619	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
6620	[ALC883_3ST_6ch]	= "3stack-6ch",
6621	[ALC883_6ST_DIG]	= "6stack-dig",
6622	[ALC883_TARGA_DIG]	= "targa-dig",
6623	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
6624	[ALC883_ACER]		= "acer",
6625	[ALC883_MEDION]		= "medion",
6626	[ALC883_MEDION_MD2]	= "medion-md2",
6627	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
6628	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6629	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
6630	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6631	[ALC888_6ST_HP]		= "6stack-hp",
6632	[ALC888_3ST_HP]		= "3stack-hp",
6633	[ALC883_AUTO]		= "auto",
6634};
6635
6636static struct snd_pci_quirk alc883_cfg_tbl[] = {
6637	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6638	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6639	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6640	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6641	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6642	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6643	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6644	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6645	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6646	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6647	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6648	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6649	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6650	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6651	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6652	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6653	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6654	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6655	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6656	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6657	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6658	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6659	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6660	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6661	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6662	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6663	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6664	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6665	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6666	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6667	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6668	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6669	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6670	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6671	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6672	{}
6673};
6674
6675static struct alc_config_preset alc883_presets[] = {
6676	[ALC883_3ST_2ch_DIG] = {
6677		.mixers = { alc883_3ST_2ch_mixer },
6678		.init_verbs = { alc883_init_verbs },
6679		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6680		.dac_nids = alc883_dac_nids,
6681		.dig_out_nid = ALC883_DIGOUT_NID,
6682		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6683		.adc_nids = alc883_adc_nids,
6684		.dig_in_nid = ALC883_DIGIN_NID,
6685		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6686		.channel_mode = alc883_3ST_2ch_modes,
6687		.input_mux = &alc883_capture_source,
6688	},
6689	[ALC883_3ST_6ch_DIG] = {
6690		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6691		.init_verbs = { alc883_init_verbs },
6692		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6693		.dac_nids = alc883_dac_nids,
6694		.dig_out_nid = ALC883_DIGOUT_NID,
6695		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6696		.adc_nids = alc883_adc_nids,
6697		.dig_in_nid = ALC883_DIGIN_NID,
6698		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6699		.channel_mode = alc883_3ST_6ch_modes,
6700		.need_dac_fix = 1,
6701		.input_mux = &alc883_capture_source,
6702	},
6703	[ALC883_3ST_6ch] = {
6704		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6705		.init_verbs = { alc883_init_verbs },
6706		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6707		.dac_nids = alc883_dac_nids,
6708		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6709		.adc_nids = alc883_adc_nids,
6710		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6711		.channel_mode = alc883_3ST_6ch_modes,
6712		.need_dac_fix = 1,
6713		.input_mux = &alc883_capture_source,
6714	},
6715	[ALC883_6ST_DIG] = {
6716		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
6717		.init_verbs = { alc883_init_verbs },
6718		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6719		.dac_nids = alc883_dac_nids,
6720		.dig_out_nid = ALC883_DIGOUT_NID,
6721		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6722		.adc_nids = alc883_adc_nids,
6723		.dig_in_nid = ALC883_DIGIN_NID,
6724		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6725		.channel_mode = alc883_sixstack_modes,
6726		.input_mux = &alc883_capture_source,
6727	},
6728	[ALC883_TARGA_DIG] = {
6729		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6730		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6731		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6732		.dac_nids = alc883_dac_nids,
6733		.dig_out_nid = ALC883_DIGOUT_NID,
6734		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6735		.adc_nids = alc883_adc_nids,
6736		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6737		.channel_mode = alc883_3ST_6ch_modes,
6738		.need_dac_fix = 1,
6739		.input_mux = &alc883_capture_source,
6740		.unsol_event = alc883_tagra_unsol_event,
6741		.init_hook = alc883_tagra_automute,
6742	},
6743	[ALC883_TARGA_2ch_DIG] = {
6744		.mixers = { alc883_tagra_2ch_mixer},
6745		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6746		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6747		.dac_nids = alc883_dac_nids,
6748		.dig_out_nid = ALC883_DIGOUT_NID,
6749		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6750		.adc_nids = alc883_adc_nids,
6751		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6752		.channel_mode = alc883_3ST_2ch_modes,
6753		.input_mux = &alc883_capture_source,
6754		.unsol_event = alc883_tagra_unsol_event,
6755		.init_hook = alc883_tagra_automute,
6756	},
6757	[ALC883_ACER] = {
6758		.mixers = { alc883_base_mixer,
6759			    alc883_chmode_mixer },
6760		/* On TravelMate laptops, GPIO 0 enables the internal speaker
6761		 * and the headphone jack.  Turn this on and rely on the
6762		 * standard mute methods whenever the user wants to turn
6763		 * these outputs off.
6764		 */
6765		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
6766		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6767		.dac_nids = alc883_dac_nids,
6768		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6769		.adc_nids = alc883_adc_nids,
6770		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6771		.channel_mode = alc883_3ST_2ch_modes,
6772		.input_mux = &alc883_capture_source,
6773	},
6774	[ALC883_MEDION] = {
6775		.mixers = { alc883_fivestack_mixer,
6776			    alc883_chmode_mixer },
6777		.init_verbs = { alc883_init_verbs,
6778				alc883_medion_eapd_verbs },
6779		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6780		.dac_nids = alc883_dac_nids,
6781		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6782		.adc_nids = alc883_adc_nids,
6783		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6784		.channel_mode = alc883_sixstack_modes,
6785		.input_mux = &alc883_capture_source,
6786	},
6787	[ALC883_MEDION_MD2] = {
6788		.mixers = { alc883_medion_md2_mixer},
6789		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
6790		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6791		.dac_nids = alc883_dac_nids,
6792		.dig_out_nid = ALC883_DIGOUT_NID,
6793		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6794		.adc_nids = alc883_adc_nids,
6795		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6796		.channel_mode = alc883_3ST_2ch_modes,
6797		.input_mux = &alc883_capture_source,
6798		.unsol_event = alc883_medion_md2_unsol_event,
6799		.init_hook = alc883_medion_md2_automute,
6800	},
6801	[ALC883_LAPTOP_EAPD] = {
6802		.mixers = { alc883_base_mixer,
6803			    alc883_chmode_mixer },
6804		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
6805		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6806		.dac_nids = alc883_dac_nids,
6807		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6808		.adc_nids = alc883_adc_nids,
6809		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6810		.channel_mode = alc883_3ST_2ch_modes,
6811		.input_mux = &alc883_capture_source,
6812	},
6813	[ALC883_LENOVO_101E_2ch] = {
6814		.mixers = { alc883_lenovo_101e_2ch_mixer},
6815		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
6816		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6817		.dac_nids = alc883_dac_nids,
6818		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6819		.adc_nids = alc883_adc_nids,
6820		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6821		.channel_mode = alc883_3ST_2ch_modes,
6822		.input_mux = &alc883_lenovo_101e_capture_source,
6823		.unsol_event = alc883_lenovo_101e_unsol_event,
6824		.init_hook = alc883_lenovo_101e_all_automute,
6825	},
6826	[ALC883_LENOVO_NB0763] = {
6827		.mixers = { alc883_lenovo_nb0763_mixer },
6828		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
6829		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6830		.dac_nids = alc883_dac_nids,
6831		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6832		.adc_nids = alc883_adc_nids,
6833		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6834		.channel_mode = alc883_3ST_2ch_modes,
6835		.need_dac_fix = 1,
6836		.input_mux = &alc883_lenovo_nb0763_capture_source,
6837		.unsol_event = alc883_medion_md2_unsol_event,
6838		.init_hook = alc883_medion_md2_automute,
6839	},
6840	[ALC888_LENOVO_MS7195_DIG] = {
6841		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6842		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
6843		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6844		.dac_nids = alc883_dac_nids,
6845		.dig_out_nid = ALC883_DIGOUT_NID,
6846		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6847		.adc_nids = alc883_adc_nids,
6848		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6849		.channel_mode = alc883_3ST_6ch_modes,
6850		.need_dac_fix = 1,
6851		.input_mux = &alc883_capture_source,
6852		.unsol_event = alc883_lenovo_ms7195_unsol_event,
6853		.init_hook = alc888_lenovo_ms7195_front_automute,
6854	},
6855	[ALC888_6ST_HP] = {
6856		.mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
6857		.init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
6858		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6859		.dac_nids = alc883_dac_nids,
6860		.dig_out_nid = ALC883_DIGOUT_NID,
6861		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6862		.adc_nids = alc883_adc_nids,
6863		.dig_in_nid = ALC883_DIGIN_NID,
6864		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6865		.channel_mode = alc883_sixstack_modes,
6866		.input_mux = &alc883_capture_source,
6867	},
6868	[ALC888_3ST_HP] = {
6869		.mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
6870		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
6871		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6872		.dac_nids = alc883_dac_nids,
6873		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6874		.adc_nids = alc883_adc_nids,
6875		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
6876		.channel_mode = alc888_3st_hp_modes,
6877		.need_dac_fix = 1,
6878		.input_mux = &alc883_capture_source,
6879	},
6880};
6881
6882
6883/*
6884 * BIOS auto configuration
6885 */
6886static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
6887					      hda_nid_t nid, int pin_type,
6888					      int dac_idx)
6889{
6890	/* set as output */
6891	struct alc_spec *spec = codec->spec;
6892	int idx;
6893
6894	if (spec->multiout.dac_nids[dac_idx] == 0x25)
6895		idx = 4;
6896	else
6897		idx = spec->multiout.dac_nids[dac_idx] - 2;
6898
6899	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6900			    pin_type);
6901	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6902			    AMP_OUT_UNMUTE);
6903	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6904
6905}
6906
6907static void alc883_auto_init_multi_out(struct hda_codec *codec)
6908{
6909	struct alc_spec *spec = codec->spec;
6910	int i;
6911
6912	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6913	for (i = 0; i <= HDA_SIDE; i++) {
6914		hda_nid_t nid = spec->autocfg.line_out_pins[i];
6915		int pin_type = get_pin_type(spec->autocfg.line_out_type);
6916		if (nid)
6917			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
6918							  i);
6919	}
6920}
6921
6922static void alc883_auto_init_hp_out(struct hda_codec *codec)
6923{
6924	struct alc_spec *spec = codec->spec;
6925	hda_nid_t pin;
6926
6927	pin = spec->autocfg.hp_pins[0];
6928	if (pin) /* connect to front */
6929		/* use dac 0 */
6930		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6931}
6932
6933#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
6934#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
6935
6936static void alc883_auto_init_analog_input(struct hda_codec *codec)
6937{
6938	struct alc_spec *spec = codec->spec;
6939	int i;
6940
6941	for (i = 0; i < AUTO_PIN_LAST; i++) {
6942		hda_nid_t nid = spec->autocfg.input_pins[i];
6943		if (alc883_is_input_pin(nid)) {
6944			snd_hda_codec_write(codec, nid, 0,
6945					    AC_VERB_SET_PIN_WIDGET_CONTROL,
6946					    (i <= AUTO_PIN_FRONT_MIC ?
6947					     PIN_VREF80 : PIN_IN));
6948			if (nid != ALC883_PIN_CD_NID)
6949				snd_hda_codec_write(codec, nid, 0,
6950						    AC_VERB_SET_AMP_GAIN_MUTE,
6951						    AMP_OUT_MUTE);
6952		}
6953	}
6954}
6955
6956/* almost identical with ALC880 parser... */
6957static int alc883_parse_auto_config(struct hda_codec *codec)
6958{
6959	struct alc_spec *spec = codec->spec;
6960	int err = alc880_parse_auto_config(codec);
6961
6962	if (err < 0)
6963		return err;
6964	else if (err > 0)
6965		/* hack - override the init verbs */
6966		spec->init_verbs[0] = alc883_auto_init_verbs;
6967	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
6968	spec->num_mixers++;
6969	return err;
6970}
6971
6972/* additional initialization for auto-configuration model */
6973static void alc883_auto_init(struct hda_codec *codec)
6974{
6975	alc883_auto_init_multi_out(codec);
6976	alc883_auto_init_hp_out(codec);
6977	alc883_auto_init_analog_input(codec);
6978}
6979
6980static int patch_alc883(struct hda_codec *codec)
6981{
6982	struct alc_spec *spec;
6983	int err, board_config;
6984
6985	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6986	if (spec == NULL)
6987		return -ENOMEM;
6988
6989	codec->spec = spec;
6990
6991	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
6992						  alc883_models,
6993						  alc883_cfg_tbl);
6994	if (board_config < 0) {
6995		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
6996		       "trying auto-probe from BIOS...\n");
6997		board_config = ALC883_AUTO;
6998	}
6999
7000	if (board_config == ALC883_AUTO) {
7001		/* automatic parse from the BIOS config */
7002		err = alc883_parse_auto_config(codec);
7003		if (err < 0) {
7004			alc_free(codec);
7005			return err;
7006		} else if (!err) {
7007			printk(KERN_INFO
7008			       "hda_codec: Cannot set up configuration "
7009			       "from BIOS.  Using base mode...\n");
7010			board_config = ALC883_3ST_2ch_DIG;
7011		}
7012	}
7013
7014	if (board_config != ALC883_AUTO)
7015		setup_preset(spec, &alc883_presets[board_config]);
7016
7017	spec->stream_name_analog = "ALC883 Analog";
7018	spec->stream_analog_playback = &alc883_pcm_analog_playback;
7019	spec->stream_analog_capture = &alc883_pcm_analog_capture;
7020
7021	spec->stream_name_digital = "ALC883 Digital";
7022	spec->stream_digital_playback = &alc883_pcm_digital_playback;
7023	spec->stream_digital_capture = &alc883_pcm_digital_capture;
7024
7025	if (!spec->adc_nids && spec->input_mux) {
7026		spec->adc_nids = alc883_adc_nids;
7027		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7028	}
7029
7030	codec->patch_ops = alc_patch_ops;
7031	if (board_config == ALC883_AUTO)
7032		spec->init_hook = alc883_auto_init;
7033
7034	return 0;
7035}
7036
7037/*
7038 * ALC262 support
7039 */
7040
7041#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
7042#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
7043
7044#define alc262_dac_nids		alc260_dac_nids
7045#define alc262_adc_nids		alc882_adc_nids
7046#define alc262_adc_nids_alt	alc882_adc_nids_alt
7047
7048#define alc262_modes		alc260_modes
7049#define alc262_capture_source	alc882_capture_source
7050
7051static struct snd_kcontrol_new alc262_base_mixer[] = {
7052	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7053	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7054	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7055	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7056	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7057	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7058	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7059	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7060	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7061	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7062	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7063	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7064	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7065	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7066	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7067	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7068	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7069	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7070	{ } /* end */
7071};
7072
7073static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7074	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7075	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7076	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7077	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7078	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7079	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7080	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7081	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7082	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7083	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7084	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7085	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7086	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7087	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7088	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7089	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7090	{ } /* end */
7091};
7092
7093static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7094	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7095	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7096	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7097	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7098	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7099
7100	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7101	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7102	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7103	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7104	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7105	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7106	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7107	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7108	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7109	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7110	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7111	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7112	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7113	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7114	{ } /* end */
7115};
7116
7117static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7118	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7119	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7120	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7121	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7122	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7123	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7124	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7125	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7126	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7127	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7128	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7129	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7130	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7131	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7132	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7133	{ } /* end */
7134};
7135
7136static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7137	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7138	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7139	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7140	{ } /* end */
7141};
7142
7143static struct hda_bind_ctls alc262_sony_bind_sw = {
7144	.ops = &snd_hda_bind_sw,
7145	.values = {
7146		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7147		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7148		0,
7149	},
7150};
7151
7152static struct snd_kcontrol_new alc262_sony_mixer[] = {
7153	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7154	HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7155	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7156	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7157	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7158	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7159	{ } /* end */
7160};
7161
7162static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7163	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7164	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7165	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7166	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7167	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7168	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7169	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7170	{ } /* end */
7171};
7172
7173#define alc262_capture_mixer		alc882_capture_mixer
7174#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
7175
7176/*
7177 * generic initialization of ADC, input mixers and output mixers
7178 */
7179static struct hda_verb alc262_init_verbs[] = {
7180	/*
7181	 * Unmute ADC0-2 and set the default input to mic-in
7182	 */
7183	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7184	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7185	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7186	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7187	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7188	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7189
7190	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7191	 * mixer widget
7192	 * Note: PASD motherboards uses the Line In 2 as the input for
7193	 * front panel mic (mic 2)
7194	 */
7195	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7196	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7197	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7198	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7199	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7200	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7201
7202	/*
7203	 * Set up output mixers (0x0c - 0x0e)
7204	 */
7205	/* set vol=0 to output mixers */
7206	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7207	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7208	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7209	/* set up input amps for analog loopback */
7210	/* Amp Indices: DAC = 0, mixer = 1 */
7211	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7212	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7213	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7214	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7215	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7216	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7217
7218	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7219	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7220	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7221	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7222	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7223	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7224
7225	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7226	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7227	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7228	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7229	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7230
7231	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7232	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7233
7234	/* FIXME: use matrix-type input source selection */
7235	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7236	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7237	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7238	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7239	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7240	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7241	/* Input mixer2 */
7242	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7243	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7244	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7245	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7246	/* Input mixer3 */
7247	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7248	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7249	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7250	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7251
7252	{ }
7253};
7254
7255static struct hda_verb alc262_hippo_unsol_verbs[] = {
7256	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7257	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7258	{}
7259};
7260
7261static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7262	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7263	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7264	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7265
7266	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7267	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7268	{}
7269};
7270
7271static struct hda_verb alc262_sony_unsol_verbs[] = {
7272	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7273	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7274	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
7275
7276	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7277	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7278};
7279
7280/* mute/unmute internal speaker according to the hp jack and mute state */
7281static void alc262_hippo_automute(struct hda_codec *codec)
7282{
7283	struct alc_spec *spec = codec->spec;
7284	unsigned int mute;
7285	unsigned int present;
7286
7287	/* need to execute and sync at first */
7288	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7289	present = snd_hda_codec_read(codec, 0x15, 0,
7290				     AC_VERB_GET_PIN_SENSE, 0);
7291	spec->jack_present = (present & 0x80000000) != 0;
7292	if (spec->jack_present) {
7293		/* mute internal speaker */
7294		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7295					 0x80, 0x80);
7296		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7297					 0x80, 0x80);
7298	} else {
7299		/* unmute internal speaker if necessary */
7300		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7301		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7302					 0x80, mute & 0x80);
7303		mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
7304		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7305					 0x80, mute & 0x80);
7306	}
7307}
7308
7309/* unsolicited event for HP jack sensing */
7310static void alc262_hippo_unsol_event(struct hda_codec *codec,
7311				       unsigned int res)
7312{
7313	if ((res >> 26) != ALC880_HP_EVENT)
7314		return;
7315	alc262_hippo_automute(codec);
7316}
7317
7318static void alc262_hippo1_automute(struct hda_codec *codec)
7319{
7320	unsigned int mute;
7321	unsigned int present;
7322
7323	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7324	present = snd_hda_codec_read(codec, 0x1b, 0,
7325				     AC_VERB_GET_PIN_SENSE, 0);
7326	present = (present & 0x80000000) != 0;
7327	if (present) {
7328		/* mute internal speaker */
7329		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7330					 0x80, 0x80);
7331		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7332					 0x80, 0x80);
7333	} else {
7334		/* unmute internal speaker if necessary */
7335		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7336		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7337					 0x80, mute & 0x80);
7338		mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
7339		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7340					 0x80, mute & 0x80);
7341	}
7342}
7343
7344/* unsolicited event for HP jack sensing */
7345static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7346				       unsigned int res)
7347{
7348	if ((res >> 26) != ALC880_HP_EVENT)
7349		return;
7350	alc262_hippo1_automute(codec);
7351}
7352
7353/*
7354 * fujitsu model
7355 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7356 */
7357
7358#define ALC_HP_EVENT	0x37
7359
7360static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7361	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7362	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7363	{}
7364};
7365
7366static struct hda_input_mux alc262_fujitsu_capture_source = {
7367	.num_items = 2,
7368	.items = {
7369		{ "Mic", 0x0 },
7370		{ "CD", 0x4 },
7371	},
7372};
7373
7374static struct hda_input_mux alc262_HP_capture_source = {
7375	.num_items = 5,
7376	.items = {
7377		{ "Mic", 0x0 },
7378		{ "Front Mic", 0x3 },
7379		{ "Line", 0x2 },
7380		{ "CD", 0x4 },
7381		{ "AUX IN", 0x6 },
7382	},
7383};
7384
7385/* mute/unmute internal speaker according to the hp jack and mute state */
7386static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7387{
7388	struct alc_spec *spec = codec->spec;
7389	unsigned int mute;
7390
7391	if (force || !spec->sense_updated) {
7392		unsigned int present;
7393		/* need to execute and sync at first */
7394		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7395		present = snd_hda_codec_read(codec, 0x14, 0,
7396				    	 AC_VERB_GET_PIN_SENSE, 0);
7397		spec->jack_present = (present & 0x80000000) != 0;
7398		spec->sense_updated = 1;
7399	}
7400	if (spec->jack_present) {
7401		/* mute internal speaker */
7402		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7403					 0x80, 0x80);
7404		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7405					 0x80, 0x80);
7406	} else {
7407		/* unmute internal speaker if necessary */
7408		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7409		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7410					 0x80, mute & 0x80);
7411		mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
7412		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7413					 0x80, mute & 0x80);
7414	}
7415}
7416
7417/* unsolicited event for HP jack sensing */
7418static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7419				       unsigned int res)
7420{
7421	if ((res >> 26) != ALC_HP_EVENT)
7422		return;
7423	alc262_fujitsu_automute(codec, 1);
7424}
7425
7426/* bind volumes of both NID 0x0c and 0x0d */
7427static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
7428					 struct snd_ctl_elem_value *ucontrol)
7429{
7430	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7431	long *valp = ucontrol->value.integer.value;
7432	int change;
7433
7434	change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
7435					  0x7f, valp[0] & 0x7f);
7436	change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
7437					   0x7f, valp[1] & 0x7f);
7438	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
7439				 0x7f, valp[0] & 0x7f);
7440	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
7441				 0x7f, valp[1] & 0x7f);
7442	return change;
7443}
7444
7445/* bind hp and internal speaker mute (with plug check) */
7446static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7447					 struct snd_ctl_elem_value *ucontrol)
7448{
7449	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7450	long *valp = ucontrol->value.integer.value;
7451	int change;
7452
7453	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7454					  0x80, valp[0] ? 0 : 0x80);
7455	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7456					   0x80, valp[1] ? 0 : 0x80);
7457	if (change || codec->in_resume)
7458		alc262_fujitsu_automute(codec, codec->in_resume);
7459	return change;
7460}
7461
7462static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7463	{
7464		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7465		.name = "Master Playback Volume",
7466		.info = snd_hda_mixer_amp_volume_info,
7467		.get = snd_hda_mixer_amp_volume_get,
7468		.put = alc262_fujitsu_master_vol_put,
7469		.tlv = { .c = snd_hda_mixer_amp_tlv },
7470		.private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7471	},
7472	{
7473		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7474		.name = "Master Playback Switch",
7475		.info = snd_hda_mixer_amp_switch_info,
7476		.get = snd_hda_mixer_amp_switch_get,
7477		.put = alc262_fujitsu_master_sw_put,
7478		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7479	},
7480	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7481	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7482	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7483	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7484	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7485	{ } /* end */
7486};
7487
7488/* additional init verbs for Benq laptops */
7489static struct hda_verb alc262_EAPD_verbs[] = {
7490	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7491	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7492	{}
7493};
7494
7495static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7496	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7497	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7498
7499	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7500	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7501	{}
7502};
7503
7504/* add playback controls from the parsed DAC table */
7505static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7506					     const struct auto_pin_cfg *cfg)
7507{
7508	hda_nid_t nid;
7509	int err;
7510
7511	spec->multiout.num_dacs = 1;	/* only use one dac */
7512	spec->multiout.dac_nids = spec->private_dac_nids;
7513	spec->multiout.dac_nids[0] = 2;
7514
7515	nid = cfg->line_out_pins[0];
7516	if (nid) {
7517		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7518				  "Front Playback Volume",
7519				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7520		if (err < 0)
7521			return err;
7522		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7523				  "Front Playback Switch",
7524				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7525		if (err < 0)
7526			return err;
7527	}
7528
7529	nid = cfg->speaker_pins[0];
7530	if (nid) {
7531		if (nid == 0x16) {
7532			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7533					  "Speaker Playback Volume",
7534					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7535							      HDA_OUTPUT));
7536			if (err < 0)
7537				return err;
7538			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7539					  "Speaker Playback Switch",
7540					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7541							      HDA_OUTPUT));
7542			if (err < 0)
7543				return err;
7544		} else {
7545			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7546					  "Speaker Playback Switch",
7547					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7548							      HDA_OUTPUT));
7549			if (err < 0)
7550				return err;
7551		}
7552	}
7553	nid = cfg->hp_pins[0];
7554	if (nid) {
7555		/* spec->multiout.hp_nid = 2; */
7556		if (nid == 0x16) {
7557			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7558					  "Headphone Playback Volume",
7559					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7560							      HDA_OUTPUT));
7561			if (err < 0)
7562				return err;
7563			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7564					  "Headphone Playback Switch",
7565					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7566							      HDA_OUTPUT));
7567			if (err < 0)
7568				return err;
7569		} else {
7570			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7571					  "Headphone Playback Switch",
7572					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7573							      HDA_OUTPUT));
7574			if (err < 0)
7575				return err;
7576		}
7577	}
7578	return 0;
7579}
7580
7581/* identical with ALC880 */
7582#define alc262_auto_create_analog_input_ctls \
7583	alc880_auto_create_analog_input_ctls
7584
7585/*
7586 * generic initialization of ADC, input mixers and output mixers
7587 */
7588static struct hda_verb alc262_volume_init_verbs[] = {
7589	/*
7590	 * Unmute ADC0-2 and set the default input to mic-in
7591	 */
7592	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7593	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7594	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7595	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7596	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7597	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7598
7599	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7600	 * mixer widget
7601	 * Note: PASD motherboards uses the Line In 2 as the input for
7602	 * front panel mic (mic 2)
7603	 */
7604	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7605	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7606	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7607	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7608	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7609	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7610
7611	/*
7612	 * Set up output mixers (0x0c - 0x0f)
7613	 */
7614	/* set vol=0 to output mixers */
7615	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7616	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7617	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7618
7619	/* set up input amps for analog loopback */
7620	/* Amp Indices: DAC = 0, mixer = 1 */
7621	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7622	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7623	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7624	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7625	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7626	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7627
7628	/* FIXME: use matrix-type input source selection */
7629	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7630	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7631	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7632	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7633	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7634	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7635	/* Input mixer2 */
7636	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7637	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7638	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7639	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7640	/* Input mixer3 */
7641	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7642	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7643	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7644	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7645
7646	{ }
7647};
7648
7649static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7650	/*
7651	 * Unmute ADC0-2 and set the default input to mic-in
7652	 */
7653	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7654	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7655	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7656	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7657	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7658	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7659
7660	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7661	 * mixer widget
7662	 * Note: PASD motherboards uses the Line In 2 as the input for
7663	 * front panel mic (mic 2)
7664	 */
7665	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7666	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7667	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7668	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7669	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7670	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7671	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7672        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7673
7674	/*
7675	 * Set up output mixers (0x0c - 0x0e)
7676	 */
7677	/* set vol=0 to output mixers */
7678	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7679	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7680	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7681
7682	/* set up input amps for analog loopback */
7683	/* Amp Indices: DAC = 0, mixer = 1 */
7684	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7685	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7686	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7687	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7688	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7689	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7690
7691	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7692	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7693	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7694
7695	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7696	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7697
7698	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7699	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7700
7701	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7702	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7703        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7704	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7705	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7706
7707	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7708	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7709        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7710	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7711	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7712	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7713
7714
7715	/* FIXME: use matrix-type input source selection */
7716	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7717	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7718	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7719	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7720	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7721	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7722	/* Input mixer2 */
7723	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7724	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7725	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7726	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7727	/* Input mixer3 */
7728	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7729	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7730	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7731	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7732
7733	{ }
7734};
7735
7736static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7737	/*
7738	 * Unmute ADC0-2 and set the default input to mic-in
7739	 */
7740	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7741	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7742	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7743	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7744	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7745	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7746
7747	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7748	 * mixer widget
7749	 * Note: PASD motherboards uses the Line In 2 as the input for front
7750	 * panel mic (mic 2)
7751	 */
7752	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7753	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7754	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7755	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7756	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7757	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7758	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
7759	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
7760	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
7761	/*
7762	 * Set up output mixers (0x0c - 0x0e)
7763	 */
7764	/* set vol=0 to output mixers */
7765	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7766	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7767	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7768
7769	/* set up input amps for analog loopback */
7770	/* Amp Indices: DAC = 0, mixer = 1 */
7771	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7772	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7773	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7774	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7775	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7776	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7777
7778
7779	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
7780	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
7781	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
7782	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
7783	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
7784	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
7785	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
7786
7787	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7788	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7789
7790	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7791	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7792
7793	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7794	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7795	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7796	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7797	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7798	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7799
7800	/* FIXME: use matrix-type input source selection */
7801	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7802	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7803	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7804	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
7805	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
7806	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
7807	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
7808        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
7809	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
7810	/* Input mixer2 */
7811	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7812	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7813	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7814	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7815	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7816        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7817	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7818	/* Input mixer3 */
7819	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7820	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7821	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7822	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7823	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7824        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7825	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
7826
7827	{ }
7828};
7829
7830/* pcm configuration: identiacal with ALC880 */
7831#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
7832#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
7833#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
7834#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
7835
7836/*
7837 * BIOS auto configuration
7838 */
7839static int alc262_parse_auto_config(struct hda_codec *codec)
7840{
7841	struct alc_spec *spec = codec->spec;
7842	int err;
7843	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
7844
7845	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7846					   alc262_ignore);
7847	if (err < 0)
7848		return err;
7849	if (!spec->autocfg.line_outs)
7850		return 0; /* can't find valid BIOS pin config */
7851	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
7852	if (err < 0)
7853		return err;
7854	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
7855	if (err < 0)
7856		return err;
7857
7858	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7859
7860	if (spec->autocfg.dig_out_pin)
7861		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
7862	if (spec->autocfg.dig_in_pin)
7863		spec->dig_in_nid = ALC262_DIGIN_NID;
7864
7865	if (spec->kctl_alloc)
7866		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7867
7868	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
7869	spec->num_mux_defs = 1;
7870	spec->input_mux = &spec->private_imux;
7871
7872	return 1;
7873}
7874
7875#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
7876#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
7877#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
7878
7879
7880/* init callback for auto-configuration model -- overriding the default init */
7881static void alc262_auto_init(struct hda_codec *codec)
7882{
7883	alc262_auto_init_multi_out(codec);
7884	alc262_auto_init_hp_out(codec);
7885	alc262_auto_init_analog_input(codec);
7886}
7887
7888/*
7889 * configuration and preset
7890 */
7891static const char *alc262_models[ALC262_MODEL_LAST] = {
7892	[ALC262_BASIC]		= "basic",
7893	[ALC262_HIPPO]		= "hippo",
7894	[ALC262_HIPPO_1]	= "hippo_1",
7895	[ALC262_FUJITSU]	= "fujitsu",
7896	[ALC262_HP_BPC]		= "hp-bpc",
7897	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
7898	[ALC262_BENQ_ED8]	= "benq",
7899	[ALC262_BENQ_T31]	= "benq-t31",
7900	[ALC262_SONY_ASSAMD]	= "sony-assamd",
7901	[ALC262_AUTO]		= "auto",
7902};
7903
7904static struct snd_pci_quirk alc262_cfg_tbl[] = {
7905	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
7906	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7907	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
7908	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
7909	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
7910	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
7911	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7912	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
7913	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
7914	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
7915	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
7916	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
7917	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
7918	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
7919	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
7920	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
7921	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
7922	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
7923	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
7924	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
7925	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
7926	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
7927	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7928	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
7929	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7930	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
7931	{}
7932};
7933
7934static struct alc_config_preset alc262_presets[] = {
7935	[ALC262_BASIC] = {
7936		.mixers = { alc262_base_mixer },
7937		.init_verbs = { alc262_init_verbs },
7938		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7939		.dac_nids = alc262_dac_nids,
7940		.hp_nid = 0x03,
7941		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7942		.channel_mode = alc262_modes,
7943		.input_mux = &alc262_capture_source,
7944	},
7945	[ALC262_HIPPO] = {
7946		.mixers = { alc262_base_mixer },
7947		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
7948		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7949		.dac_nids = alc262_dac_nids,
7950		.hp_nid = 0x03,
7951		.dig_out_nid = ALC262_DIGOUT_NID,
7952		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7953		.channel_mode = alc262_modes,
7954		.input_mux = &alc262_capture_source,
7955		.unsol_event = alc262_hippo_unsol_event,
7956		.init_hook = alc262_hippo_automute,
7957	},
7958	[ALC262_HIPPO_1] = {
7959		.mixers = { alc262_hippo1_mixer },
7960		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
7961		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7962		.dac_nids = alc262_dac_nids,
7963		.hp_nid = 0x02,
7964		.dig_out_nid = ALC262_DIGOUT_NID,
7965		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7966		.channel_mode = alc262_modes,
7967		.input_mux = &alc262_capture_source,
7968		.unsol_event = alc262_hippo1_unsol_event,
7969		.init_hook = alc262_hippo1_automute,
7970	},
7971	[ALC262_FUJITSU] = {
7972		.mixers = { alc262_fujitsu_mixer },
7973		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
7974		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7975		.dac_nids = alc262_dac_nids,
7976		.hp_nid = 0x03,
7977		.dig_out_nid = ALC262_DIGOUT_NID,
7978		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7979		.channel_mode = alc262_modes,
7980		.input_mux = &alc262_fujitsu_capture_source,
7981		.unsol_event = alc262_fujitsu_unsol_event,
7982	},
7983	[ALC262_HP_BPC] = {
7984		.mixers = { alc262_HP_BPC_mixer },
7985		.init_verbs = { alc262_HP_BPC_init_verbs },
7986		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7987		.dac_nids = alc262_dac_nids,
7988		.hp_nid = 0x03,
7989		.num_channel_mode = ARRAY_SIZE(alc262_modes),
7990		.channel_mode = alc262_modes,
7991		.input_mux = &alc262_HP_capture_source,
7992	},
7993	[ALC262_HP_BPC_D7000_WF] = {
7994		.mixers = { alc262_HP_BPC_WildWest_mixer },
7995		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
7996		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
7997		.dac_nids = alc262_dac_nids,
7998		.hp_nid = 0x03,
7999		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8000		.channel_mode = alc262_modes,
8001		.input_mux = &alc262_HP_capture_source,
8002	},
8003	[ALC262_HP_BPC_D7000_WL] = {
8004		.mixers = { alc262_HP_BPC_WildWest_mixer,
8005			    alc262_HP_BPC_WildWest_option_mixer },
8006		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8007		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8008		.dac_nids = alc262_dac_nids,
8009		.hp_nid = 0x03,
8010		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8011		.channel_mode = alc262_modes,
8012		.input_mux = &alc262_HP_capture_source,
8013	},
8014	[ALC262_BENQ_ED8] = {
8015		.mixers = { alc262_base_mixer },
8016		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8017		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8018		.dac_nids = alc262_dac_nids,
8019		.hp_nid = 0x03,
8020		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8021		.channel_mode = alc262_modes,
8022		.input_mux = &alc262_capture_source,
8023	},
8024	[ALC262_SONY_ASSAMD] = {
8025		.mixers = { alc262_sony_mixer },
8026		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8027		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8028		.dac_nids = alc262_dac_nids,
8029		.hp_nid = 0x02,
8030		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8031		.channel_mode = alc262_modes,
8032		.input_mux = &alc262_capture_source,
8033		.unsol_event = alc262_hippo_unsol_event,
8034		.init_hook = alc262_hippo_automute,
8035	},
8036	[ALC262_BENQ_T31] = {
8037		.mixers = { alc262_benq_t31_mixer },
8038		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8039		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8040		.dac_nids = alc262_dac_nids,
8041		.hp_nid = 0x03,
8042		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8043		.channel_mode = alc262_modes,
8044		.input_mux = &alc262_capture_source,
8045		.unsol_event = alc262_hippo_unsol_event,
8046		.init_hook = alc262_hippo_automute,
8047	},
8048};
8049
8050static int patch_alc262(struct hda_codec *codec)
8051{
8052	struct alc_spec *spec;
8053	int board_config;
8054	int err;
8055
8056	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8057	if (spec == NULL)
8058		return -ENOMEM;
8059
8060	codec->spec = spec;
8061#if 0
8062	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8063	 * under-run
8064	 */
8065	{
8066	int tmp;
8067	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8068	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8069	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8070	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8071	}
8072#endif
8073
8074	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8075						  alc262_models,
8076						  alc262_cfg_tbl);
8077
8078	if (board_config < 0) {
8079		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8080		       "trying auto-probe from BIOS...\n");
8081		board_config = ALC262_AUTO;
8082	}
8083
8084	if (board_config == ALC262_AUTO) {
8085		/* automatic parse from the BIOS config */
8086		err = alc262_parse_auto_config(codec);
8087		if (err < 0) {
8088			alc_free(codec);
8089			return err;
8090		} else if (!err) {
8091			printk(KERN_INFO
8092			       "hda_codec: Cannot set up configuration "
8093			       "from BIOS.  Using base mode...\n");
8094			board_config = ALC262_BASIC;
8095		}
8096	}
8097
8098	if (board_config != ALC262_AUTO)
8099		setup_preset(spec, &alc262_presets[board_config]);
8100
8101	spec->stream_name_analog = "ALC262 Analog";
8102	spec->stream_analog_playback = &alc262_pcm_analog_playback;
8103	spec->stream_analog_capture = &alc262_pcm_analog_capture;
8104
8105	spec->stream_name_digital = "ALC262 Digital";
8106	spec->stream_digital_playback = &alc262_pcm_digital_playback;
8107	spec->stream_digital_capture = &alc262_pcm_digital_capture;
8108
8109	if (!spec->adc_nids && spec->input_mux) {
8110		/* check whether NID 0x07 is valid */
8111		unsigned int wcap = get_wcaps(codec, 0x07);
8112
8113		/* get type */
8114		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8115		if (wcap != AC_WID_AUD_IN) {
8116			spec->adc_nids = alc262_adc_nids_alt;
8117			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8118			spec->mixers[spec->num_mixers] =
8119				alc262_capture_alt_mixer;
8120			spec->num_mixers++;
8121		} else {
8122			spec->adc_nids = alc262_adc_nids;
8123			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8124			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8125			spec->num_mixers++;
8126		}
8127	}
8128
8129	codec->patch_ops = alc_patch_ops;
8130	if (board_config == ALC262_AUTO)
8131		spec->init_hook = alc262_auto_init;
8132
8133	return 0;
8134}
8135
8136/*
8137 *  ALC268 channel source setting (2 channel)
8138 */
8139#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
8140#define alc268_modes		alc260_modes
8141
8142static hda_nid_t alc268_dac_nids[2] = {
8143	/* front, hp */
8144	0x02, 0x03
8145};
8146
8147static hda_nid_t alc268_adc_nids[2] = {
8148	/* ADC0-1 */
8149	0x08, 0x07
8150};
8151
8152static hda_nid_t alc268_adc_nids_alt[1] = {
8153	/* ADC0 */
8154	0x08
8155};
8156
8157static struct snd_kcontrol_new alc268_base_mixer[] = {
8158	/* output mixer control */
8159	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8160	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8161	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8162	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8163	{ }
8164};
8165
8166/*
8167 * generic initialization of ADC, input mixers and output mixers
8168 */
8169static struct hda_verb alc268_base_init_verbs[] = {
8170	/* Unmute DAC0-1 and set vol = 0 */
8171	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8172	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8173	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8174	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8175	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8176	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8177
8178	/*
8179	 * Set up output mixers (0x0c - 0x0e)
8180	 */
8181	/* set vol=0 to output mixers */
8182	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8183	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8184	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8185        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8186
8187	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8188	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8189
8190	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8191	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8192	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8193	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8194	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8195	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8196	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8197	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8198
8199	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8200	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8201	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8202	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8203	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8204	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8205	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8206	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8207
8208	/* FIXME: use matrix-type input source selection */
8209	/* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8210	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8211	/* Input mixer2 */
8212	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8213	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8214	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8215	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8216
8217	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8218	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8219	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8220	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8221	{ }
8222};
8223
8224/*
8225 * generic initialization of ADC, input mixers and output mixers
8226 */
8227static struct hda_verb alc268_volume_init_verbs[] = {
8228	/* set output DAC */
8229	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8230	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8231	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8232	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8233
8234	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8235	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8236	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8237	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8238	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8239
8240	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8241	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8242	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8243	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8244	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8245
8246	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8247	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8248	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8249	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8250
8251	/* set PCBEEP vol = 0 */
8252	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8253
8254	{ }
8255};
8256
8257#define alc268_mux_enum_info alc_mux_enum_info
8258#define alc268_mux_enum_get alc_mux_enum_get
8259
8260static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8261			       struct snd_ctl_elem_value *ucontrol)
8262{
8263	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8264	struct alc_spec *spec = codec->spec;
8265	const struct hda_input_mux *imux = spec->input_mux;
8266	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8267	static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8268	hda_nid_t nid = capture_mixers[adc_idx];
8269	unsigned int *cur_val = &spec->cur_mux[adc_idx];
8270	unsigned int i, idx;
8271
8272	idx = ucontrol->value.enumerated.item[0];
8273	if (idx >= imux->num_items)
8274		idx = imux->num_items - 1;
8275	if (*cur_val == idx && !codec->in_resume)
8276		return 0;
8277	for (i = 0; i < imux->num_items; i++) {
8278		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8279		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8280				    v | (imux->items[i].index << 8));
8281                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
8282				    idx );
8283	}
8284	*cur_val = idx;
8285	return 1;
8286}
8287
8288static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8289	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8290	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8291	{
8292		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8293		/* The multiple "Capture Source" controls confuse alsamixer
8294		 * So call somewhat different..
8295		 * FIXME: the controls appear in the "playback" view!
8296		 */
8297		/* .name = "Capture Source", */
8298		.name = "Input Source",
8299		.count = 1,
8300		.info = alc268_mux_enum_info,
8301		.get = alc268_mux_enum_get,
8302		.put = alc268_mux_enum_put,
8303	},
8304	{ } /* end */
8305};
8306
8307static struct snd_kcontrol_new alc268_capture_mixer[] = {
8308	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8309	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8310	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8311	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8312	{
8313		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8314		/* The multiple "Capture Source" controls confuse alsamixer
8315		 * So call somewhat different..
8316		 * FIXME: the controls appear in the "playback" view!
8317		 */
8318		/* .name = "Capture Source", */
8319		.name = "Input Source",
8320		.count = 2,
8321		.info = alc268_mux_enum_info,
8322		.get = alc268_mux_enum_get,
8323		.put = alc268_mux_enum_put,
8324	},
8325	{ } /* end */
8326};
8327
8328static struct hda_input_mux alc268_capture_source = {
8329	.num_items = 4,
8330	.items = {
8331		{ "Mic", 0x0 },
8332		{ "Front Mic", 0x1 },
8333		{ "Line", 0x2 },
8334		{ "CD", 0x3 },
8335	},
8336};
8337
8338/* create input playback/capture controls for the given pin */
8339static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8340				    const char *ctlname, int idx)
8341{
8342	char name[32];
8343	int err;
8344
8345	sprintf(name, "%s Playback Volume", ctlname);
8346	if (nid == 0x14) {
8347		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8348				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8349						      HDA_OUTPUT));
8350		if (err < 0)
8351			return err;
8352	} else if (nid == 0x15) {
8353		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8354				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8355						      HDA_OUTPUT));
8356		if (err < 0)
8357			return err;
8358	} else
8359		return -1;
8360	sprintf(name, "%s Playback Switch", ctlname);
8361	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8362			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8363	if (err < 0)
8364		return err;
8365	return 0;
8366}
8367
8368/* add playback controls from the parsed DAC table */
8369static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8370					     const struct auto_pin_cfg *cfg)
8371{
8372	hda_nid_t nid;
8373	int err;
8374
8375	spec->multiout.num_dacs = 2;	/* only use one dac */
8376	spec->multiout.dac_nids = spec->private_dac_nids;
8377	spec->multiout.dac_nids[0] = 2;
8378	spec->multiout.dac_nids[1] = 3;
8379
8380	nid = cfg->line_out_pins[0];
8381	if (nid)
8382		alc268_new_analog_output(spec, nid, "Front", 0);
8383
8384	nid = cfg->speaker_pins[0];
8385	if (nid == 0x1d) {
8386		err = add_control(spec, ALC_CTL_WIDGET_VOL,
8387				  "Speaker Playback Volume",
8388				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8389		if (err < 0)
8390			return err;
8391	}
8392	nid = cfg->hp_pins[0];
8393	if (nid)
8394		alc268_new_analog_output(spec, nid, "Headphone", 0);
8395
8396	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8397	if (nid == 0x16) {
8398		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8399				  "Mono Playback Switch",
8400				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8401		if (err < 0)
8402			return err;
8403	}
8404	return 0;
8405}
8406
8407/* create playback/capture controls for input pins */
8408static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8409						const struct auto_pin_cfg *cfg)
8410{
8411	struct hda_input_mux *imux = &spec->private_imux;
8412	int i, idx1;
8413
8414	for (i = 0; i < AUTO_PIN_LAST; i++) {
8415		switch(cfg->input_pins[i]) {
8416		case 0x18:
8417			idx1 = 0;	/* Mic 1 */
8418			break;
8419		case 0x19:
8420			idx1 = 1;	/* Mic 2 */
8421			break;
8422		case 0x1a:
8423			idx1 = 2;	/* Line In */
8424			break;
8425		case 0x1c:
8426			idx1 = 3;	/* CD */
8427			break;
8428		default:
8429			continue;
8430		}
8431		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8432		imux->items[imux->num_items].index = idx1;
8433		imux->num_items++;
8434	}
8435	return 0;
8436}
8437
8438static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8439{
8440	struct alc_spec *spec = codec->spec;
8441	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8442	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8443	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8444	unsigned int	dac_vol1, dac_vol2;
8445
8446	if (speaker_nid) {
8447		snd_hda_codec_write(codec, speaker_nid, 0,
8448				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8449		snd_hda_codec_write(codec, 0x0f, 0,
8450				    AC_VERB_SET_AMP_GAIN_MUTE,
8451				    AMP_IN_UNMUTE(1));
8452		snd_hda_codec_write(codec, 0x10, 0,
8453				    AC_VERB_SET_AMP_GAIN_MUTE,
8454				    AMP_IN_UNMUTE(1));
8455	} else {
8456		snd_hda_codec_write(codec, 0x0f, 0,
8457				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8458		snd_hda_codec_write(codec, 0x10, 0,
8459				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8460	}
8461
8462	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
8463	if (line_nid == 0x14)
8464		dac_vol2 = AMP_OUT_ZERO;
8465	else if (line_nid == 0x15)
8466		dac_vol1 = AMP_OUT_ZERO;
8467	if (hp_nid == 0x14)
8468		dac_vol2 = AMP_OUT_ZERO;
8469	else if (hp_nid == 0x15)
8470		dac_vol1 = AMP_OUT_ZERO;
8471	if (line_nid != 0x16 || hp_nid != 0x16 ||
8472	    spec->autocfg.line_out_pins[1] != 0x16 ||
8473	    spec->autocfg.line_out_pins[2] != 0x16)
8474		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8475
8476	snd_hda_codec_write(codec, 0x02, 0,
8477			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8478	snd_hda_codec_write(codec, 0x03, 0,
8479			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8480}
8481
8482/* pcm configuration: identiacal with ALC880 */
8483#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
8484#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
8485#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
8486
8487/*
8488 * BIOS auto configuration
8489 */
8490static int alc268_parse_auto_config(struct hda_codec *codec)
8491{
8492	struct alc_spec *spec = codec->spec;
8493	int err;
8494	static hda_nid_t alc268_ignore[] = { 0 };
8495
8496	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8497					   alc268_ignore);
8498	if (err < 0)
8499		return err;
8500	if (!spec->autocfg.line_outs)
8501		return 0; /* can't find valid BIOS pin config */
8502
8503	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8504	if (err < 0)
8505		return err;
8506	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8507	if (err < 0)
8508		return err;
8509
8510	spec->multiout.max_channels = 2;
8511
8512	/* digital only support output */
8513	if (spec->autocfg.dig_out_pin)
8514		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8515
8516	if (spec->kctl_alloc)
8517		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8518
8519	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8520	spec->num_mux_defs = 1;
8521	spec->input_mux = &spec->private_imux;
8522
8523	return 1;
8524}
8525
8526#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
8527#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
8528#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
8529
8530/* init callback for auto-configuration model -- overriding the default init */
8531static void alc268_auto_init(struct hda_codec *codec)
8532{
8533	alc268_auto_init_multi_out(codec);
8534	alc268_auto_init_hp_out(codec);
8535	alc268_auto_init_mono_speaker_out(codec);
8536	alc268_auto_init_analog_input(codec);
8537}
8538
8539/*
8540 * configuration and preset
8541 */
8542static const char *alc268_models[ALC268_MODEL_LAST] = {
8543	[ALC268_3ST]		= "3stack",
8544	[ALC268_AUTO]		= "auto",
8545};
8546
8547static struct snd_pci_quirk alc268_cfg_tbl[] = {
8548	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8549	{}
8550};
8551
8552static struct alc_config_preset alc268_presets[] = {
8553	[ALC268_3ST] = {
8554		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8555		.init_verbs = { alc268_base_init_verbs },
8556		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8557		.dac_nids = alc268_dac_nids,
8558                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8559                .adc_nids = alc268_adc_nids_alt,
8560		.hp_nid = 0x03,
8561		.dig_out_nid = ALC268_DIGOUT_NID,
8562		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8563		.channel_mode = alc268_modes,
8564		.input_mux = &alc268_capture_source,
8565	},
8566};
8567
8568static int patch_alc268(struct hda_codec *codec)
8569{
8570	struct alc_spec *spec;
8571	int board_config;
8572	int err;
8573
8574	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8575	if (spec == NULL)
8576		return -ENOMEM;
8577
8578	codec->spec = spec;
8579
8580	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8581						  alc268_models,
8582						  alc268_cfg_tbl);
8583
8584	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8585		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8586		       "trying auto-probe from BIOS...\n");
8587		board_config = ALC268_AUTO;
8588	}
8589
8590	if (board_config == ALC268_AUTO) {
8591		/* automatic parse from the BIOS config */
8592		err = alc268_parse_auto_config(codec);
8593		if (err < 0) {
8594			alc_free(codec);
8595			return err;
8596		} else if (!err) {
8597			printk(KERN_INFO
8598			       "hda_codec: Cannot set up configuration "
8599			       "from BIOS.  Using base mode...\n");
8600			board_config = ALC268_3ST;
8601		}
8602	}
8603
8604	if (board_config != ALC268_AUTO)
8605		setup_preset(spec, &alc268_presets[board_config]);
8606
8607	spec->stream_name_analog = "ALC268 Analog";
8608	spec->stream_analog_playback = &alc268_pcm_analog_playback;
8609	spec->stream_analog_capture = &alc268_pcm_analog_capture;
8610
8611	spec->stream_name_digital = "ALC268 Digital";
8612	spec->stream_digital_playback = &alc268_pcm_digital_playback;
8613
8614	if (board_config == ALC268_AUTO) {
8615		if (!spec->adc_nids && spec->input_mux) {
8616			/* check whether NID 0x07 is valid */
8617			unsigned int wcap = get_wcaps(codec, 0x07);
8618
8619			/* get type */
8620			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8621			if (wcap != AC_WID_AUD_IN) {
8622				spec->adc_nids = alc268_adc_nids_alt;
8623				spec->num_adc_nids =
8624					ARRAY_SIZE(alc268_adc_nids_alt);
8625				spec->mixers[spec->num_mixers] =
8626					alc268_capture_alt_mixer;
8627				spec->num_mixers++;
8628			} else {
8629				spec->adc_nids = alc268_adc_nids;
8630				spec->num_adc_nids =
8631					ARRAY_SIZE(alc268_adc_nids);
8632				spec->mixers[spec->num_mixers] =
8633					alc268_capture_mixer;
8634				spec->num_mixers++;
8635			}
8636		}
8637	}
8638	codec->patch_ops = alc_patch_ops;
8639	if (board_config == ALC268_AUTO)
8640		spec->init_hook = alc268_auto_init;
8641
8642	return 0;
8643}
8644
8645/*
8646 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8647 */
8648
8649/*
8650 * set the path ways for 2 channel output
8651 * need to set the codec line out and mic 1 pin widgets to inputs
8652 */
8653static struct hda_verb alc861_threestack_ch2_init[] = {
8654	/* set pin widget 1Ah (line in) for input */
8655	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8656	/* set pin widget 18h (mic1/2) for input, for mic also enable
8657	 * the vref
8658	 */
8659	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8660
8661	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8662#if 0
8663	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8664	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8665#endif
8666	{ } /* end */
8667};
8668/*
8669 * 6ch mode
8670 * need to set the codec line out and mic 1 pin widgets to outputs
8671 */
8672static struct hda_verb alc861_threestack_ch6_init[] = {
8673	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8674	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8675	/* set pin widget 18h (mic1) for output (CLFE)*/
8676	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8677
8678	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8679	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8680
8681	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8682#if 0
8683	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8684	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8685#endif
8686	{ } /* end */
8687};
8688
8689static struct hda_channel_mode alc861_threestack_modes[2] = {
8690	{ 2, alc861_threestack_ch2_init },
8691	{ 6, alc861_threestack_ch6_init },
8692};
8693/* Set mic1 as input and unmute the mixer */
8694static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
8695	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8696	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8697	{ } /* end */
8698};
8699/* Set mic1 as output and mute mixer */
8700static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
8701	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8702	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8703	{ } /* end */
8704};
8705
8706static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
8707	{ 2, alc861_uniwill_m31_ch2_init },
8708	{ 4, alc861_uniwill_m31_ch4_init },
8709};
8710
8711/* Set mic1 and line-in as input and unmute the mixer */
8712static struct hda_verb alc861_asus_ch2_init[] = {
8713	/* set pin widget 1Ah (line in) for input */
8714	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8715	/* set pin widget 18h (mic1/2) for input, for mic also enable
8716	 * the vref
8717	 */
8718	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8719
8720	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
8721#if 0
8722	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
8723	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
8724#endif
8725	{ } /* end */
8726};
8727/* Set mic1 nad line-in as output and mute mixer */
8728static struct hda_verb alc861_asus_ch6_init[] = {
8729	/* set pin widget 1Ah (line in) for output (Back Surround)*/
8730	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8731	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8732	/* set pin widget 18h (mic1) for output (CLFE)*/
8733	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8734	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8735	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
8736	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
8737
8738	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
8739#if 0
8740	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
8741	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
8742#endif
8743	{ } /* end */
8744};
8745
8746static struct hda_channel_mode alc861_asus_modes[2] = {
8747	{ 2, alc861_asus_ch2_init },
8748	{ 6, alc861_asus_ch6_init },
8749};
8750
8751/* patch-ALC861 */
8752
8753static struct snd_kcontrol_new alc861_base_mixer[] = {
8754        /* output mixer control */
8755	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8756	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8757	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8758	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8759	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8760
8761        /*Input mixer control */
8762	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8763	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8764	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8765	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8766	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8767	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8768	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8769	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8770	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8771	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8772
8773        /* Capture mixer control */
8774	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8775	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8776	{
8777		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8778		.name = "Capture Source",
8779		.count = 1,
8780		.info = alc_mux_enum_info,
8781		.get = alc_mux_enum_get,
8782		.put = alc_mux_enum_put,
8783	},
8784	{ } /* end */
8785};
8786
8787static struct snd_kcontrol_new alc861_3ST_mixer[] = {
8788        /* output mixer control */
8789	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8790	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8791	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8792	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8793	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8794
8795	/* Input mixer control */
8796	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8797	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8798	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8799	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8800	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8801	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8802	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8803	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8804	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8805	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8806
8807	/* Capture mixer control */
8808	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8809	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8810	{
8811		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8812		.name = "Capture Source",
8813		.count = 1,
8814		.info = alc_mux_enum_info,
8815		.get = alc_mux_enum_get,
8816		.put = alc_mux_enum_put,
8817	},
8818	{
8819		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8820		.name = "Channel Mode",
8821		.info = alc_ch_mode_info,
8822		.get = alc_ch_mode_get,
8823		.put = alc_ch_mode_put,
8824                .private_value = ARRAY_SIZE(alc861_threestack_modes),
8825	},
8826	{ } /* end */
8827};
8828
8829static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
8830        /* output mixer control */
8831	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8832	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8833	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8834
8835        /*Capture mixer control */
8836	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8837	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8838	{
8839		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8840		.name = "Capture Source",
8841		.count = 1,
8842		.info = alc_mux_enum_info,
8843		.get = alc_mux_enum_get,
8844		.put = alc_mux_enum_put,
8845	},
8846
8847	{ } /* end */
8848};
8849
8850static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
8851        /* output mixer control */
8852	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8853	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8854	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8855	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8856	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8857
8858	/* Input mixer control */
8859	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8860	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8861	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8862	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8863	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8864	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8865	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8866	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8867	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8868	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
8869
8870	/* Capture mixer control */
8871	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8872	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8873	{
8874		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8875		.name = "Capture Source",
8876		.count = 1,
8877		.info = alc_mux_enum_info,
8878		.get = alc_mux_enum_get,
8879		.put = alc_mux_enum_put,
8880	},
8881	{
8882		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8883		.name = "Channel Mode",
8884		.info = alc_ch_mode_info,
8885		.get = alc_ch_mode_get,
8886		.put = alc_ch_mode_put,
8887                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
8888	},
8889	{ } /* end */
8890};
8891
8892static struct snd_kcontrol_new alc861_asus_mixer[] = {
8893        /* output mixer control */
8894	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
8895	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
8896	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
8897	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
8898	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
8899
8900	/* Input mixer control */
8901	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8902	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8903	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8904	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8905	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
8906	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
8907	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
8908	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
8909	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
8910	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
8911
8912	/* Capture mixer control */
8913	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8914	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8915	{
8916		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8917		.name = "Capture Source",
8918		.count = 1,
8919		.info = alc_mux_enum_info,
8920		.get = alc_mux_enum_get,
8921		.put = alc_mux_enum_put,
8922	},
8923	{
8924		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8925		.name = "Channel Mode",
8926		.info = alc_ch_mode_info,
8927		.get = alc_ch_mode_get,
8928		.put = alc_ch_mode_put,
8929                .private_value = ARRAY_SIZE(alc861_asus_modes),
8930	},
8931	{ }
8932};
8933
8934/* additional mixer */
8935static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
8936	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
8937	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
8938	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
8939	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
8940	{ }
8941};
8942
8943/*
8944 * generic initialization of ADC, input mixers and output mixers
8945 */
8946static struct hda_verb alc861_base_init_verbs[] = {
8947	/*
8948	 * Unmute ADC0 and set the default input to mic-in
8949	 */
8950	/* port-A for surround (rear panel) */
8951	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8952	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
8953	/* port-B for mic-in (rear panel) with vref */
8954	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8955	/* port-C for line-in (rear panel) */
8956	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8957	/* port-D for Front */
8958	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8959	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
8960	/* port-E for HP out (front panel) */
8961	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
8962	/* route front PCM to HP */
8963	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8964	/* port-F for mic-in (front panel) with vref */
8965	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
8966	/* port-G for CLFE (rear panel) */
8967	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8968	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
8969	/* port-H for side (rear panel) */
8970	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
8971	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
8972	/* CD-in */
8973	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
8974	/* route front mic to ADC1*/
8975	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8976	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8977
8978	/* Unmute DAC0~3 & spdif out*/
8979	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8980	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8981	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8982	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8983	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8984
8985	/* Unmute Mixer 14 (mic) 1c (Line in)*/
8986	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8987        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8988	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8989        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8990
8991	/* Unmute Stereo Mixer 15 */
8992	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8993	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8994	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8995	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
8996
8997	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8998	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8999	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9000	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9001	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9002	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9003	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9004	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9005	/* hp used DAC 3 (Front) */
9006	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9007        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9008
9009	{ }
9010};
9011
9012static struct hda_verb alc861_threestack_init_verbs[] = {
9013	/*
9014	 * Unmute ADC0 and set the default input to mic-in
9015	 */
9016	/* port-A for surround (rear panel) */
9017	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9018	/* port-B for mic-in (rear panel) with vref */
9019	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9020	/* port-C for line-in (rear panel) */
9021	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9022	/* port-D for Front */
9023	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9024	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9025	/* port-E for HP out (front panel) */
9026	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9027	/* route front PCM to HP */
9028	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9029	/* port-F for mic-in (front panel) with vref */
9030	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9031	/* port-G for CLFE (rear panel) */
9032	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9033	/* port-H for side (rear panel) */
9034	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9035	/* CD-in */
9036	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9037	/* route front mic to ADC1*/
9038	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9039	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9040	/* Unmute DAC0~3 & spdif out*/
9041	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9042	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9043	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9044	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9045	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9046
9047	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9048	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9049        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9050	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9051        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9052
9053	/* Unmute Stereo Mixer 15 */
9054	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9055	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9056	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9057	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9058
9059	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9060	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9061	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9063	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9065	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9066	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9067	/* hp used DAC 3 (Front) */
9068	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9069        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9070	{ }
9071};
9072
9073static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9074	/*
9075	 * Unmute ADC0 and set the default input to mic-in
9076	 */
9077	/* port-A for surround (rear panel) */
9078	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9079	/* port-B for mic-in (rear panel) with vref */
9080	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9081	/* port-C for line-in (rear panel) */
9082	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9083	/* port-D for Front */
9084	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9085	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9086	/* port-E for HP out (front panel) */
9087	/* this has to be set to VREF80 */
9088	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9089	/* route front PCM to HP */
9090	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9091	/* port-F for mic-in (front panel) with vref */
9092	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9093	/* port-G for CLFE (rear panel) */
9094	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9095	/* port-H for side (rear panel) */
9096	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9097	/* CD-in */
9098	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9099	/* route front mic to ADC1*/
9100	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9101	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9102	/* Unmute DAC0~3 & spdif out*/
9103	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9104	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9105	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9106	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9107	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9108
9109	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9110	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9111        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9112	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9113        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9114
9115	/* Unmute Stereo Mixer 15 */
9116	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9117	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9118	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9119	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9120
9121	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9122	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9123	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9124	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9125	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9126	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9127	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9128	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9129	/* hp used DAC 3 (Front) */
9130	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9131        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9132	{ }
9133};
9134
9135static struct hda_verb alc861_asus_init_verbs[] = {
9136	/*
9137	 * Unmute ADC0 and set the default input to mic-in
9138	 */
9139	/* port-A for surround (rear panel)
9140	 * according to codec#0 this is the HP jack
9141	 */
9142	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9143	/* route front PCM to HP */
9144	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9145	/* port-B for mic-in (rear panel) with vref */
9146	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9147	/* port-C for line-in (rear panel) */
9148	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9149	/* port-D for Front */
9150	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9151	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9152	/* port-E for HP out (front panel) */
9153	/* this has to be set to VREF80 */
9154	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9155	/* route front PCM to HP */
9156	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9157	/* port-F for mic-in (front panel) with vref */
9158	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9159	/* port-G for CLFE (rear panel) */
9160	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9161	/* port-H for side (rear panel) */
9162	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9163	/* CD-in */
9164	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9165	/* route front mic to ADC1*/
9166	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9167	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9168	/* Unmute DAC0~3 & spdif out*/
9169	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9170	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9171	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9172	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9173	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9174	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9175	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9176        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9177	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9178        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9179
9180	/* Unmute Stereo Mixer 15 */
9181	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9182	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9183	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9184	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9185
9186	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9187	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9188	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9189	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9190	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9191	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9192	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9193	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9194	/* hp used DAC 3 (Front) */
9195	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9196	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9197	{ }
9198};
9199
9200/* additional init verbs for ASUS laptops */
9201static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9202	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9203	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9204	{ }
9205};
9206
9207/*
9208 * generic initialization of ADC, input mixers and output mixers
9209 */
9210static struct hda_verb alc861_auto_init_verbs[] = {
9211	/*
9212	 * Unmute ADC0 and set the default input to mic-in
9213	 */
9214	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9215	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9216
9217	/* Unmute DAC0~3 & spdif out*/
9218	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9219	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9220	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9221	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9222	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9223
9224	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9225	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9226	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9227	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9229
9230	/* Unmute Stereo Mixer 15 */
9231	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9232	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9233	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9234	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9235
9236	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9237	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9238	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9239	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9240	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9241	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9242	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9243	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9244
9245	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9246	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9247	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9248	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9249	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9250	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9251	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9252	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9253
9254	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
9255
9256	{ }
9257};
9258
9259static struct hda_verb alc861_toshiba_init_verbs[] = {
9260	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9261
9262	{ }
9263};
9264
9265/* toggle speaker-output according to the hp-jack state */
9266static void alc861_toshiba_automute(struct hda_codec *codec)
9267{
9268	unsigned int present;
9269
9270	present = snd_hda_codec_read(codec, 0x0f, 0,
9271				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9272	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
9273				 0x80, present ? 0x80 : 0);
9274	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
9275				 0x80, present ? 0x80 : 0);
9276	snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
9277				 0x80, present ? 0 : 0x80);
9278	snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
9279				 0x80, present ? 0 : 0x80);
9280}
9281
9282static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9283				       unsigned int res)
9284{
9285	if ((res >> 26) == ALC880_HP_EVENT)
9286		alc861_toshiba_automute(codec);
9287}
9288
9289/* pcm configuration: identiacal with ALC880 */
9290#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
9291#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
9292#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
9293#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
9294
9295
9296#define ALC861_DIGOUT_NID	0x07
9297
9298static struct hda_channel_mode alc861_8ch_modes[1] = {
9299	{ 8, NULL }
9300};
9301
9302static hda_nid_t alc861_dac_nids[4] = {
9303	/* front, surround, clfe, side */
9304	0x03, 0x06, 0x05, 0x04
9305};
9306
9307static hda_nid_t alc660_dac_nids[3] = {
9308	/* front, clfe, surround */
9309	0x03, 0x05, 0x06
9310};
9311
9312static hda_nid_t alc861_adc_nids[1] = {
9313	/* ADC0-2 */
9314	0x08,
9315};
9316
9317static struct hda_input_mux alc861_capture_source = {
9318	.num_items = 5,
9319	.items = {
9320		{ "Mic", 0x0 },
9321		{ "Front Mic", 0x3 },
9322		{ "Line", 0x1 },
9323		{ "CD", 0x4 },
9324		{ "Mixer", 0x5 },
9325	},
9326};
9327
9328/* fill in the dac_nids table from the parsed pin configuration */
9329static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9330				     const struct auto_pin_cfg *cfg)
9331{
9332	int i;
9333	hda_nid_t nid;
9334
9335	spec->multiout.dac_nids = spec->private_dac_nids;
9336	for (i = 0; i < cfg->line_outs; i++) {
9337		nid = cfg->line_out_pins[i];
9338		if (nid) {
9339			if (i >= ARRAY_SIZE(alc861_dac_nids))
9340				continue;
9341			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9342		}
9343	}
9344	spec->multiout.num_dacs = cfg->line_outs;
9345	return 0;
9346}
9347
9348/* add playback controls from the parsed DAC table */
9349static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9350					     const struct auto_pin_cfg *cfg)
9351{
9352	char name[32];
9353	static const char *chname[4] = {
9354		"Front", "Surround", NULL /*CLFE*/, "Side"
9355	};
9356	hda_nid_t nid;
9357	int i, idx, err;
9358
9359	for (i = 0; i < cfg->line_outs; i++) {
9360		nid = spec->multiout.dac_nids[i];
9361		if (!nid)
9362			continue;
9363		if (nid == 0x05) {
9364			/* Center/LFE */
9365			err = add_control(spec, ALC_CTL_BIND_MUTE,
9366					  "Center Playback Switch",
9367					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9368							      HDA_OUTPUT));
9369			if (err < 0)
9370				return err;
9371			err = add_control(spec, ALC_CTL_BIND_MUTE,
9372					  "LFE Playback Switch",
9373					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9374							      HDA_OUTPUT));
9375			if (err < 0)
9376				return err;
9377		} else {
9378			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9379			     idx++)
9380				if (nid == alc861_dac_nids[idx])
9381					break;
9382			sprintf(name, "%s Playback Switch", chname[idx]);
9383			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9384					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9385							      HDA_OUTPUT));
9386			if (err < 0)
9387				return err;
9388		}
9389	}
9390	return 0;
9391}
9392
9393static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9394{
9395	int err;
9396	hda_nid_t nid;
9397
9398	if (!pin)
9399		return 0;
9400
9401	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9402		nid = 0x03;
9403		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9404				  "Headphone Playback Switch",
9405				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9406		if (err < 0)
9407			return err;
9408		spec->multiout.hp_nid = nid;
9409	}
9410	return 0;
9411}
9412
9413/* create playback/capture controls for input pins */
9414static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9415						const struct auto_pin_cfg *cfg)
9416{
9417	struct hda_input_mux *imux = &spec->private_imux;
9418	int i, err, idx, idx1;
9419
9420	for (i = 0; i < AUTO_PIN_LAST; i++) {
9421		switch (cfg->input_pins[i]) {
9422		case 0x0c:
9423			idx1 = 1;
9424			idx = 2;	/* Line In */
9425			break;
9426		case 0x0f:
9427			idx1 = 2;
9428			idx = 2;	/* Line In */
9429			break;
9430		case 0x0d:
9431			idx1 = 0;
9432			idx = 1;	/* Mic In */
9433			break;
9434		case 0x10:
9435			idx1 = 3;
9436			idx = 1;	/* Mic In */
9437			break;
9438		case 0x11:
9439			idx1 = 4;
9440			idx = 0;	/* CD */
9441			break;
9442		default:
9443			continue;
9444		}
9445
9446		err = new_analog_input(spec, cfg->input_pins[i],
9447				       auto_pin_cfg_labels[i], idx, 0x15);
9448		if (err < 0)
9449			return err;
9450
9451		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9452		imux->items[imux->num_items].index = idx1;
9453		imux->num_items++;
9454	}
9455	return 0;
9456}
9457
9458static struct snd_kcontrol_new alc861_capture_mixer[] = {
9459	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9460	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9461
9462	{
9463		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9464		/* The multiple "Capture Source" controls confuse alsamixer
9465		 * So call somewhat different..
9466		 *FIXME: the controls appear in the "playback" view!
9467		 */
9468		/* .name = "Capture Source", */
9469		.name = "Input Source",
9470		.count = 1,
9471		.info = alc_mux_enum_info,
9472		.get = alc_mux_enum_get,
9473		.put = alc_mux_enum_put,
9474	},
9475	{ } /* end */
9476};
9477
9478static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9479					      hda_nid_t nid,
9480					      int pin_type, int dac_idx)
9481{
9482	/* set as output */
9483
9484	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9485			    pin_type);
9486	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9487			    AMP_OUT_UNMUTE);
9488
9489}
9490
9491static void alc861_auto_init_multi_out(struct hda_codec *codec)
9492{
9493	struct alc_spec *spec = codec->spec;
9494	int i;
9495
9496	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9497	for (i = 0; i < spec->autocfg.line_outs; i++) {
9498		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9499		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9500		if (nid)
9501			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9502							  spec->multiout.dac_nids[i]);
9503	}
9504}
9505
9506static void alc861_auto_init_hp_out(struct hda_codec *codec)
9507{
9508	struct alc_spec *spec = codec->spec;
9509	hda_nid_t pin;
9510
9511	pin = spec->autocfg.hp_pins[0];
9512	if (pin) /* connect to front */
9513		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9514						  spec->multiout.dac_nids[0]);
9515}
9516
9517static void alc861_auto_init_analog_input(struct hda_codec *codec)
9518{
9519	struct alc_spec *spec = codec->spec;
9520	int i;
9521
9522	for (i = 0; i < AUTO_PIN_LAST; i++) {
9523		hda_nid_t nid = spec->autocfg.input_pins[i];
9524		if (nid >= 0x0c && nid <= 0x11) {
9525			snd_hda_codec_write(codec, nid, 0,
9526					    AC_VERB_SET_PIN_WIDGET_CONTROL,
9527					    i <= AUTO_PIN_FRONT_MIC ?
9528					    PIN_VREF80 : PIN_IN);
9529		}
9530	}
9531}
9532
9533/* parse the BIOS configuration and set up the alc_spec */
9534/* return 1 if successful, 0 if the proper config is not found,
9535 * or a negative error code
9536 */
9537static int alc861_parse_auto_config(struct hda_codec *codec)
9538{
9539	struct alc_spec *spec = codec->spec;
9540	int err;
9541	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9542
9543	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9544					   alc861_ignore);
9545	if (err < 0)
9546		return err;
9547	if (!spec->autocfg.line_outs)
9548		return 0; /* can't find valid BIOS pin config */
9549
9550	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9551	if (err < 0)
9552		return err;
9553	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9554	if (err < 0)
9555		return err;
9556	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9557	if (err < 0)
9558		return err;
9559	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9560	if (err < 0)
9561		return err;
9562
9563	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9564
9565	if (spec->autocfg.dig_out_pin)
9566		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9567
9568	if (spec->kctl_alloc)
9569		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9570
9571	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9572
9573	spec->num_mux_defs = 1;
9574	spec->input_mux = &spec->private_imux;
9575
9576	spec->adc_nids = alc861_adc_nids;
9577	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9578	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9579	spec->num_mixers++;
9580
9581	return 1;
9582}
9583
9584/* additional initialization for auto-configuration model */
9585static void alc861_auto_init(struct hda_codec *codec)
9586{
9587	alc861_auto_init_multi_out(codec);
9588	alc861_auto_init_hp_out(codec);
9589	alc861_auto_init_analog_input(codec);
9590}
9591
9592
9593/*
9594 * configuration and preset
9595 */
9596static const char *alc861_models[ALC861_MODEL_LAST] = {
9597	[ALC861_3ST]		= "3stack",
9598	[ALC660_3ST]		= "3stack-660",
9599	[ALC861_3ST_DIG]	= "3stack-dig",
9600	[ALC861_6ST_DIG]	= "6stack-dig",
9601	[ALC861_UNIWILL_M31]	= "uniwill-m31",
9602	[ALC861_TOSHIBA]	= "toshiba",
9603	[ALC861_ASUS]		= "asus",
9604	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
9605	[ALC861_AUTO]		= "auto",
9606};
9607
9608static struct snd_pci_quirk alc861_cfg_tbl[] = {
9609	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9610	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9611	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9612	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9613	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9614	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9615	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9616	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9617	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9618	 *        Any other models that need this preset?
9619	 */
9620	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9621	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9622	SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9623	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9624	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9625	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9626	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9627	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9628	{}
9629};
9630
9631static struct alc_config_preset alc861_presets[] = {
9632	[ALC861_3ST] = {
9633		.mixers = { alc861_3ST_mixer },
9634		.init_verbs = { alc861_threestack_init_verbs },
9635		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9636		.dac_nids = alc861_dac_nids,
9637		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9638		.channel_mode = alc861_threestack_modes,
9639		.need_dac_fix = 1,
9640		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9641		.adc_nids = alc861_adc_nids,
9642		.input_mux = &alc861_capture_source,
9643	},
9644	[ALC861_3ST_DIG] = {
9645		.mixers = { alc861_base_mixer },
9646		.init_verbs = { alc861_threestack_init_verbs },
9647		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9648		.dac_nids = alc861_dac_nids,
9649		.dig_out_nid = ALC861_DIGOUT_NID,
9650		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9651		.channel_mode = alc861_threestack_modes,
9652		.need_dac_fix = 1,
9653		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9654		.adc_nids = alc861_adc_nids,
9655		.input_mux = &alc861_capture_source,
9656	},
9657	[ALC861_6ST_DIG] = {
9658		.mixers = { alc861_base_mixer },
9659		.init_verbs = { alc861_base_init_verbs },
9660		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9661		.dac_nids = alc861_dac_nids,
9662		.dig_out_nid = ALC861_DIGOUT_NID,
9663		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
9664		.channel_mode = alc861_8ch_modes,
9665		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9666		.adc_nids = alc861_adc_nids,
9667		.input_mux = &alc861_capture_source,
9668	},
9669	[ALC660_3ST] = {
9670		.mixers = { alc861_3ST_mixer },
9671		.init_verbs = { alc861_threestack_init_verbs },
9672		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
9673		.dac_nids = alc660_dac_nids,
9674		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9675		.channel_mode = alc861_threestack_modes,
9676		.need_dac_fix = 1,
9677		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9678		.adc_nids = alc861_adc_nids,
9679		.input_mux = &alc861_capture_source,
9680	},
9681	[ALC861_UNIWILL_M31] = {
9682		.mixers = { alc861_uniwill_m31_mixer },
9683		.init_verbs = { alc861_uniwill_m31_init_verbs },
9684		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9685		.dac_nids = alc861_dac_nids,
9686		.dig_out_nid = ALC861_DIGOUT_NID,
9687		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
9688		.channel_mode = alc861_uniwill_m31_modes,
9689		.need_dac_fix = 1,
9690		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9691		.adc_nids = alc861_adc_nids,
9692		.input_mux = &alc861_capture_source,
9693	},
9694	[ALC861_TOSHIBA] = {
9695		.mixers = { alc861_toshiba_mixer },
9696		.init_verbs = { alc861_base_init_verbs,
9697				alc861_toshiba_init_verbs },
9698		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9699		.dac_nids = alc861_dac_nids,
9700		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9701		.channel_mode = alc883_3ST_2ch_modes,
9702		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9703		.adc_nids = alc861_adc_nids,
9704		.input_mux = &alc861_capture_source,
9705		.unsol_event = alc861_toshiba_unsol_event,
9706		.init_hook = alc861_toshiba_automute,
9707	},
9708	[ALC861_ASUS] = {
9709		.mixers = { alc861_asus_mixer },
9710		.init_verbs = { alc861_asus_init_verbs },
9711		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9712		.dac_nids = alc861_dac_nids,
9713		.dig_out_nid = ALC861_DIGOUT_NID,
9714		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
9715		.channel_mode = alc861_asus_modes,
9716		.need_dac_fix = 1,
9717		.hp_nid = 0x06,
9718		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9719		.adc_nids = alc861_adc_nids,
9720		.input_mux = &alc861_capture_source,
9721	},
9722	[ALC861_ASUS_LAPTOP] = {
9723		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
9724		.init_verbs = { alc861_asus_init_verbs,
9725				alc861_asus_laptop_init_verbs },
9726		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9727		.dac_nids = alc861_dac_nids,
9728		.dig_out_nid = ALC861_DIGOUT_NID,
9729		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9730		.channel_mode = alc883_3ST_2ch_modes,
9731		.need_dac_fix = 1,
9732		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9733		.adc_nids = alc861_adc_nids,
9734		.input_mux = &alc861_capture_source,
9735	},
9736};
9737
9738
9739static int patch_alc861(struct hda_codec *codec)
9740{
9741	struct alc_spec *spec;
9742	int board_config;
9743	int err;
9744
9745	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9746	if (spec == NULL)
9747		return -ENOMEM;
9748
9749	codec->spec = spec;
9750
9751        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
9752						  alc861_models,
9753						  alc861_cfg_tbl);
9754
9755	if (board_config < 0) {
9756		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
9757		       "trying auto-probe from BIOS...\n");
9758		board_config = ALC861_AUTO;
9759	}
9760
9761	if (board_config == ALC861_AUTO) {
9762		/* automatic parse from the BIOS config */
9763		err = alc861_parse_auto_config(codec);
9764		if (err < 0) {
9765			alc_free(codec);
9766			return err;
9767		} else if (!err) {
9768			printk(KERN_INFO
9769			       "hda_codec: Cannot set up configuration "
9770			       "from BIOS.  Using base mode...\n");
9771		   board_config = ALC861_3ST_DIG;
9772		}
9773	}
9774
9775	if (board_config != ALC861_AUTO)
9776		setup_preset(spec, &alc861_presets[board_config]);
9777
9778	spec->stream_name_analog = "ALC861 Analog";
9779	spec->stream_analog_playback = &alc861_pcm_analog_playback;
9780	spec->stream_analog_capture = &alc861_pcm_analog_capture;
9781
9782	spec->stream_name_digital = "ALC861 Digital";
9783	spec->stream_digital_playback = &alc861_pcm_digital_playback;
9784	spec->stream_digital_capture = &alc861_pcm_digital_capture;
9785
9786	codec->patch_ops = alc_patch_ops;
9787	if (board_config == ALC861_AUTO)
9788		spec->init_hook = alc861_auto_init;
9789
9790	return 0;
9791}
9792
9793/*
9794 * ALC861-VD support
9795 *
9796 * Based on ALC882
9797 *
9798 * In addition, an independent DAC
9799 */
9800#define ALC861VD_DIGOUT_NID	0x06
9801
9802static hda_nid_t alc861vd_dac_nids[4] = {
9803	/* front, surr, clfe, side surr */
9804	0x02, 0x03, 0x04, 0x05
9805};
9806
9807/* dac_nids for ALC660vd are in a different order - according to
9808 * Realtek's driver.
9809 * This should probably tesult in a different mixer for 6stack models
9810 * of ALC660vd codecs, but for now there is only 3stack mixer
9811 * - and it is the same as in 861vd.
9812 * adc_nids in ALC660vd are (is) the same as in 861vd
9813 */
9814static hda_nid_t alc660vd_dac_nids[3] = {
9815	/* front, rear, clfe, rear_surr */
9816	0x02, 0x04, 0x03
9817};
9818
9819static hda_nid_t alc861vd_adc_nids[1] = {
9820	/* ADC0 */
9821	0x09,
9822};
9823
9824/* input MUX */
9825/* FIXME: should be a matrix-type input source selection */
9826static struct hda_input_mux alc861vd_capture_source = {
9827	.num_items = 4,
9828	.items = {
9829		{ "Mic", 0x0 },
9830		{ "Front Mic", 0x1 },
9831		{ "Line", 0x2 },
9832		{ "CD", 0x4 },
9833	},
9834};
9835
9836static struct hda_input_mux alc861vd_dallas_capture_source = {
9837	.num_items = 3,
9838	.items = {
9839		{ "Front Mic", 0x0 },
9840		{ "ATAPI Mic", 0x1 },
9841		{ "Line In", 0x5 },
9842	},
9843};
9844
9845#define alc861vd_mux_enum_info alc_mux_enum_info
9846#define alc861vd_mux_enum_get alc_mux_enum_get
9847
9848static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
9849				struct snd_ctl_elem_value *ucontrol)
9850{
9851	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9852	struct alc_spec *spec = codec->spec;
9853	const struct hda_input_mux *imux = spec->input_mux;
9854	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9855	static hda_nid_t capture_mixers[1] = { 0x22 };
9856	hda_nid_t nid = capture_mixers[adc_idx];
9857	unsigned int *cur_val = &spec->cur_mux[adc_idx];
9858	unsigned int i, idx;
9859
9860	idx = ucontrol->value.enumerated.item[0];
9861	if (idx >= imux->num_items)
9862		idx = imux->num_items - 1;
9863	if (*cur_val == idx && !codec->in_resume)
9864		return 0;
9865	for (i = 0; i < imux->num_items; i++) {
9866		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
9867		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9868				    v | (imux->items[i].index << 8));
9869	}
9870	*cur_val = idx;
9871	return 1;
9872}
9873
9874/*
9875 * 2ch mode
9876 */
9877static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
9878	{ 2, NULL }
9879};
9880
9881/*
9882 * 6ch mode
9883 */
9884static struct hda_verb alc861vd_6stack_ch6_init[] = {
9885	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9886	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9887	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9888	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9889	{ } /* end */
9890};
9891
9892/*
9893 * 8ch mode
9894 */
9895static struct hda_verb alc861vd_6stack_ch8_init[] = {
9896	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9897	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9898	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9899	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9900	{ } /* end */
9901};
9902
9903static struct hda_channel_mode alc861vd_6stack_modes[2] = {
9904	{ 6, alc861vd_6stack_ch6_init },
9905	{ 8, alc861vd_6stack_ch8_init },
9906};
9907
9908static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
9909	{
9910		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9911		.name = "Channel Mode",
9912		.info = alc_ch_mode_info,
9913		.get = alc_ch_mode_get,
9914		.put = alc_ch_mode_put,
9915	},
9916	{ } /* end */
9917};
9918
9919static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
9920	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9921	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9922
9923	{
9924		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9925		/* The multiple "Capture Source" controls confuse alsamixer
9926		 * So call somewhat different..
9927		 *FIXME: the controls appear in the "playback" view!
9928		 */
9929		/* .name = "Capture Source", */
9930		.name = "Input Source",
9931		.count = 1,
9932		.info = alc861vd_mux_enum_info,
9933		.get = alc861vd_mux_enum_get,
9934		.put = alc861vd_mux_enum_put,
9935	},
9936	{ } /* end */
9937};
9938
9939/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9940 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9941 */
9942static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
9943	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9944	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9945
9946	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9947	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9948
9949	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9950				HDA_OUTPUT),
9951	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9952				HDA_OUTPUT),
9953	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9954	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9955
9956	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
9957	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9958
9959	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9960
9961	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9962	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9963	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9964
9965	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9966	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9967	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9968
9969	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9970	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9971
9972	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9973	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9974
9975	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
9976	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
9977
9978	{ } /* end */
9979};
9980
9981static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
9982	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9983	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9984
9985	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9986
9987	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9988	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9989	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9990
9991	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9992	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9993	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9994
9995	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9996	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9997
9998	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9999	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10000
10001	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10002	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10003
10004	{ } /* end */
10005};
10006
10007static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10008	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10009	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10010	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10011
10012	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10013
10014	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10015	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10016	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10017
10018	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10019	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10020	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10021
10022	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10023	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10024
10025	{ } /* end */
10026};
10027
10028/* Pin assignment: Front=0x14, HP = 0x15,
10029 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10030 */
10031static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10032	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10033	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10034	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10035	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10036	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10037	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10038	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10039	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10040	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10041	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10042	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10043	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10044	{
10045		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10046		/* .name = "Capture Source", */
10047		.name = "Input Source",
10048		.count = 1,
10049		.info = alc882_mux_enum_info,
10050		.get = alc882_mux_enum_get,
10051		.put = alc882_mux_enum_put,
10052	},
10053	{ } /* end */
10054};
10055
10056/*
10057 * generic initialization of ADC, input mixers and output mixers
10058 */
10059static struct hda_verb alc861vd_volume_init_verbs[] = {
10060	/*
10061	 * Unmute ADC0 and set the default input to mic-in
10062	 */
10063	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10064	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10065
10066	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10067	 * the analog-loopback mixer widget
10068	 */
10069	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10070	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10071	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10072	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10073	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10074	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10075
10076	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10077	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10078	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10079	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10080	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10081
10082	/*
10083	 * Set up output mixers (0x02 - 0x05)
10084	 */
10085	/* set vol=0 to output mixers */
10086	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10087	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10088	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10089	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10090
10091	/* set up input amps for analog loopback */
10092	/* Amp Indices: DAC = 0, mixer = 1 */
10093	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10094	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10095	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10096	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10097	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10098	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10099	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10100	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10101
10102	{ }
10103};
10104
10105/*
10106 * 3-stack pin configuration:
10107 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10108 */
10109static struct hda_verb alc861vd_3stack_init_verbs[] = {
10110	/*
10111	 * Set pin mode and muting
10112	 */
10113	/* set front pin widgets 0x14 for output */
10114	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10115	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10116	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10117
10118	/* Mic (rear) pin: input vref at 80% */
10119	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10120	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10121	/* Front Mic pin: input vref at 80% */
10122	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10123	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10124	/* Line In pin: input */
10125	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10126	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10127	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10128	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10129	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10130	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10131	/* CD pin widget for input */
10132	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10133
10134	{ }
10135};
10136
10137/*
10138 * 6-stack pin configuration:
10139 */
10140static struct hda_verb alc861vd_6stack_init_verbs[] = {
10141	/*
10142	 * Set pin mode and muting
10143	 */
10144	/* set front pin widgets 0x14 for output */
10145	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10146	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10147	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10148
10149	/* Rear Pin: output 1 (0x0d) */
10150	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10151	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10152	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10153	/* CLFE Pin: output 2 (0x0e) */
10154	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10155	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10156	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10157	/* Side Pin: output 3 (0x0f) */
10158	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10159	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10160	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10161
10162	/* Mic (rear) pin: input vref at 80% */
10163	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10164	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10165	/* Front Mic pin: input vref at 80% */
10166	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10167	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10168	/* Line In pin: input */
10169	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10170	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10171	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10172	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10173	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10174	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10175	/* CD pin widget for input */
10176	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10177
10178	{ }
10179};
10180
10181static struct hda_verb alc861vd_eapd_verbs[] = {
10182	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10183	{ }
10184};
10185
10186static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10187	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10188	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10189	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10190	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10191	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10192	{}
10193};
10194
10195/* toggle speaker-output according to the hp-jack state */
10196static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10197{
10198	unsigned int present;
10199	unsigned char bits;
10200
10201	present = snd_hda_codec_read(codec, 0x1b, 0,
10202				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10203	bits = present ? 0x80 : 0;
10204	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10205				 0x80, bits);
10206	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10207				 0x80, bits);
10208}
10209
10210static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10211{
10212	unsigned int present;
10213	unsigned char bits;
10214
10215	present = snd_hda_codec_read(codec, 0x18, 0,
10216				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10217	bits = present ? 0x80 : 0;
10218	snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1,
10219				 0x80, bits);
10220	snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1,
10221				 0x80, bits);
10222}
10223
10224static void alc861vd_lenovo_automute(struct hda_codec *codec)
10225{
10226	alc861vd_lenovo_hp_automute(codec);
10227	alc861vd_lenovo_mic_automute(codec);
10228}
10229
10230static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10231					unsigned int res)
10232{
10233	switch (res >> 26) {
10234	case ALC880_HP_EVENT:
10235		alc861vd_lenovo_hp_automute(codec);
10236		break;
10237	case ALC880_MIC_EVENT:
10238		alc861vd_lenovo_mic_automute(codec);
10239		break;
10240	}
10241}
10242
10243static struct hda_verb alc861vd_dallas_verbs[] = {
10244	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10245	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10246	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10247	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10248
10249	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10250	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10251	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10252	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10253	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10254	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10255	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10256	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10257
10258	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10259	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10260	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10261	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10262	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10263	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10264	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10265	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10266
10267	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10268	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10269	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10270	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10271	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10272	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10273	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10274	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10275
10276	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10277	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10278	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10279	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10280
10281	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10282	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10283	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10284
10285	{ } /* end */
10286};
10287
10288/* toggle speaker-output according to the hp-jack state */
10289static void alc861vd_dallas_automute(struct hda_codec *codec)
10290{
10291	unsigned int present;
10292
10293	present = snd_hda_codec_read(codec, 0x15, 0,
10294				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10295	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10296				 0x80, present ? 0x80 : 0);
10297	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10298				 0x80, present ? 0x80 : 0);
10299}
10300
10301static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10302{
10303	if ((res >> 26) == ALC880_HP_EVENT)
10304		alc861vd_dallas_automute(codec);
10305}
10306
10307/* pcm configuration: identiacal with ALC880 */
10308#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
10309#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
10310#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
10311#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
10312
10313/*
10314 * configuration and preset
10315 */
10316static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10317	[ALC660VD_3ST]		= "3stack-660",
10318	[ALC660VD_3ST_DIG]= "3stack-660-digout",
10319	[ALC861VD_3ST]		= "3stack",
10320	[ALC861VD_3ST_DIG]	= "3stack-digout",
10321	[ALC861VD_6ST_DIG]	= "6stack-digout",
10322	[ALC861VD_LENOVO]	= "lenovo",
10323	[ALC861VD_DALLAS]	= "dallas",
10324	[ALC861VD_AUTO]		= "auto",
10325};
10326
10327static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10328	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10329	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10330	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10331	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10332	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10333
10334	SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
10335	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10336	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10337	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10338	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10339	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
10340	{}
10341};
10342
10343static struct alc_config_preset alc861vd_presets[] = {
10344	[ALC660VD_3ST] = {
10345		.mixers = { alc861vd_3st_mixer },
10346		.init_verbs = { alc861vd_volume_init_verbs,
10347				 alc861vd_3stack_init_verbs },
10348		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10349		.dac_nids = alc660vd_dac_nids,
10350		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10351		.adc_nids = alc861vd_adc_nids,
10352		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10353		.channel_mode = alc861vd_3stack_2ch_modes,
10354		.input_mux = &alc861vd_capture_source,
10355	},
10356	[ALC660VD_3ST_DIG] = {
10357		.mixers = { alc861vd_3st_mixer },
10358		.init_verbs = { alc861vd_volume_init_verbs,
10359				 alc861vd_3stack_init_verbs },
10360		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10361		.dac_nids = alc660vd_dac_nids,
10362		.dig_out_nid = ALC861VD_DIGOUT_NID,
10363		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10364		.adc_nids = alc861vd_adc_nids,
10365		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10366		.channel_mode = alc861vd_3stack_2ch_modes,
10367		.input_mux = &alc861vd_capture_source,
10368	},
10369	[ALC861VD_3ST] = {
10370		.mixers = { alc861vd_3st_mixer },
10371		.init_verbs = { alc861vd_volume_init_verbs,
10372				 alc861vd_3stack_init_verbs },
10373		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10374		.dac_nids = alc861vd_dac_nids,
10375		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10376		.channel_mode = alc861vd_3stack_2ch_modes,
10377		.input_mux = &alc861vd_capture_source,
10378	},
10379	[ALC861VD_3ST_DIG] = {
10380		.mixers = { alc861vd_3st_mixer },
10381		.init_verbs = { alc861vd_volume_init_verbs,
10382		 		 alc861vd_3stack_init_verbs },
10383		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10384		.dac_nids = alc861vd_dac_nids,
10385		.dig_out_nid = ALC861VD_DIGOUT_NID,
10386		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10387		.channel_mode = alc861vd_3stack_2ch_modes,
10388		.input_mux = &alc861vd_capture_source,
10389	},
10390	[ALC861VD_6ST_DIG] = {
10391		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10392		.init_verbs = { alc861vd_volume_init_verbs,
10393				alc861vd_6stack_init_verbs },
10394		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10395		.dac_nids = alc861vd_dac_nids,
10396		.dig_out_nid = ALC861VD_DIGOUT_NID,
10397		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10398		.channel_mode = alc861vd_6stack_modes,
10399		.input_mux = &alc861vd_capture_source,
10400	},
10401	[ALC861VD_LENOVO] = {
10402		.mixers = { alc861vd_lenovo_mixer },
10403		.init_verbs = { alc861vd_volume_init_verbs,
10404				alc861vd_3stack_init_verbs,
10405				alc861vd_eapd_verbs,
10406				alc861vd_lenovo_unsol_verbs },
10407		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10408		.dac_nids = alc660vd_dac_nids,
10409		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10410		.adc_nids = alc861vd_adc_nids,
10411		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10412		.channel_mode = alc861vd_3stack_2ch_modes,
10413		.input_mux = &alc861vd_capture_source,
10414		.unsol_event = alc861vd_lenovo_unsol_event,
10415		.init_hook = alc861vd_lenovo_automute,
10416	},
10417	[ALC861VD_DALLAS] = {
10418		.mixers = { alc861vd_dallas_mixer },
10419		.init_verbs = { alc861vd_dallas_verbs },
10420		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10421		.dac_nids = alc861vd_dac_nids,
10422		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10423		.adc_nids = alc861vd_adc_nids,
10424		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10425		.channel_mode = alc861vd_3stack_2ch_modes,
10426		.input_mux = &alc861vd_dallas_capture_source,
10427		.unsol_event = alc861vd_dallas_unsol_event,
10428		.init_hook = alc861vd_dallas_automute,
10429	},
10430};
10431
10432/*
10433 * BIOS auto configuration
10434 */
10435static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10436				hda_nid_t nid, int pin_type, int dac_idx)
10437{
10438	/* set as output */
10439	snd_hda_codec_write(codec, nid, 0,
10440				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10441	snd_hda_codec_write(codec, nid, 0,
10442				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10443}
10444
10445static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10446{
10447	struct alc_spec *spec = codec->spec;
10448	int i;
10449
10450	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10451	for (i = 0; i <= HDA_SIDE; i++) {
10452		hda_nid_t nid = spec->autocfg.line_out_pins[i];
10453		int pin_type = get_pin_type(spec->autocfg.line_out_type);
10454		if (nid)
10455			alc861vd_auto_set_output_and_unmute(codec, nid,
10456							    pin_type, i);
10457	}
10458}
10459
10460
10461static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10462{
10463	struct alc_spec *spec = codec->spec;
10464	hda_nid_t pin;
10465
10466	pin = spec->autocfg.hp_pins[0];
10467	if (pin) /* connect to front and  use dac 0 */
10468		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10469}
10470
10471#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
10472#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
10473
10474static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10475{
10476	struct alc_spec *spec = codec->spec;
10477	int i;
10478
10479	for (i = 0; i < AUTO_PIN_LAST; i++) {
10480		hda_nid_t nid = spec->autocfg.input_pins[i];
10481		if (alc861vd_is_input_pin(nid)) {
10482			snd_hda_codec_write(codec, nid, 0,
10483					AC_VERB_SET_PIN_WIDGET_CONTROL,
10484					i <= AUTO_PIN_FRONT_MIC ?
10485							PIN_VREF80 : PIN_IN);
10486			if (nid != ALC861VD_PIN_CD_NID)
10487				snd_hda_codec_write(codec, nid, 0,
10488						AC_VERB_SET_AMP_GAIN_MUTE,
10489						AMP_OUT_MUTE);
10490		}
10491	}
10492}
10493
10494#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
10495#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
10496
10497/* add playback controls from the parsed DAC table */
10498/* Based on ALC880 version. But ALC861VD has separate,
10499 * different NIDs for mute/unmute switch and volume control */
10500static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10501					     const struct auto_pin_cfg *cfg)
10502{
10503	char name[32];
10504	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10505	hda_nid_t nid_v, nid_s;
10506	int i, err;
10507
10508	for (i = 0; i < cfg->line_outs; i++) {
10509		if (!spec->multiout.dac_nids[i])
10510			continue;
10511		nid_v = alc861vd_idx_to_mixer_vol(
10512				alc880_dac_to_idx(
10513					spec->multiout.dac_nids[i]));
10514		nid_s = alc861vd_idx_to_mixer_switch(
10515				alc880_dac_to_idx(
10516					spec->multiout.dac_nids[i]));
10517
10518		if (i == 2) {
10519			/* Center/LFE */
10520			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10521					  "Center Playback Volume",
10522					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10523							      HDA_OUTPUT));
10524			if (err < 0)
10525				return err;
10526			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10527					  "LFE Playback Volume",
10528					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10529							      HDA_OUTPUT));
10530			if (err < 0)
10531				return err;
10532			err = add_control(spec, ALC_CTL_BIND_MUTE,
10533					  "Center Playback Switch",
10534					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10535							      HDA_INPUT));
10536			if (err < 0)
10537				return err;
10538			err = add_control(spec, ALC_CTL_BIND_MUTE,
10539					  "LFE Playback Switch",
10540					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10541							      HDA_INPUT));
10542			if (err < 0)
10543				return err;
10544		} else {
10545			sprintf(name, "%s Playback Volume", chname[i]);
10546			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10547					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10548							      HDA_OUTPUT));
10549			if (err < 0)
10550				return err;
10551			sprintf(name, "%s Playback Switch", chname[i]);
10552			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10553					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10554							      HDA_INPUT));
10555			if (err < 0)
10556				return err;
10557		}
10558	}
10559	return 0;
10560}
10561
10562/* add playback controls for speaker and HP outputs */
10563/* Based on ALC880 version. But ALC861VD has separate,
10564 * different NIDs for mute/unmute switch and volume control */
10565static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10566					hda_nid_t pin, const char *pfx)
10567{
10568	hda_nid_t nid_v, nid_s;
10569	int err;
10570	char name[32];
10571
10572	if (!pin)
10573		return 0;
10574
10575	if (alc880_is_fixed_pin(pin)) {
10576		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10577		/* specify the DAC as the extra output */
10578		if (!spec->multiout.hp_nid)
10579			spec->multiout.hp_nid = nid_v;
10580		else
10581			spec->multiout.extra_out_nid[0] = nid_v;
10582		/* control HP volume/switch on the output mixer amp */
10583		nid_v = alc861vd_idx_to_mixer_vol(
10584				alc880_fixed_pin_idx(pin));
10585		nid_s = alc861vd_idx_to_mixer_switch(
10586				alc880_fixed_pin_idx(pin));
10587
10588		sprintf(name, "%s Playback Volume", pfx);
10589		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10590				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10591		if (err < 0)
10592			return err;
10593		sprintf(name, "%s Playback Switch", pfx);
10594		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10595				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10596		if (err < 0)
10597			return err;
10598	} else if (alc880_is_multi_pin(pin)) {
10599		/* set manual connection */
10600		/* we have only a switch on HP-out PIN */
10601		sprintf(name, "%s Playback Switch", pfx);
10602		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10603				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10604		if (err < 0)
10605			return err;
10606	}
10607	return 0;
10608}
10609
10610/* parse the BIOS configuration and set up the alc_spec
10611 * return 1 if successful, 0 if the proper config is not found,
10612 * or a negative error code
10613 * Based on ALC880 version - had to change it to override
10614 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10615static int alc861vd_parse_auto_config(struct hda_codec *codec)
10616{
10617	struct alc_spec *spec = codec->spec;
10618	int err;
10619	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
10620
10621	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10622					   alc861vd_ignore);
10623	if (err < 0)
10624		return err;
10625	if (!spec->autocfg.line_outs)
10626		return 0; /* can't find valid BIOS pin config */
10627
10628	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10629	if (err < 0)
10630		return err;
10631	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10632	if (err < 0)
10633		return err;
10634	err = alc861vd_auto_create_extra_out(spec,
10635					     spec->autocfg.speaker_pins[0],
10636					     "Speaker");
10637	if (err < 0)
10638		return err;
10639	err = alc861vd_auto_create_extra_out(spec,
10640					     spec->autocfg.hp_pins[0],
10641					     "Headphone");
10642	if (err < 0)
10643		return err;
10644	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
10645	if (err < 0)
10646		return err;
10647
10648	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10649
10650	if (spec->autocfg.dig_out_pin)
10651		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
10652
10653	if (spec->kctl_alloc)
10654		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10655
10656	spec->init_verbs[spec->num_init_verbs++]
10657		= alc861vd_volume_init_verbs;
10658
10659	spec->num_mux_defs = 1;
10660	spec->input_mux = &spec->private_imux;
10661
10662	return 1;
10663}
10664
10665/* additional initialization for auto-configuration model */
10666static void alc861vd_auto_init(struct hda_codec *codec)
10667{
10668	alc861vd_auto_init_multi_out(codec);
10669	alc861vd_auto_init_hp_out(codec);
10670	alc861vd_auto_init_analog_input(codec);
10671}
10672
10673static int patch_alc861vd(struct hda_codec *codec)
10674{
10675	struct alc_spec *spec;
10676	int err, board_config;
10677
10678	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10679	if (spec == NULL)
10680		return -ENOMEM;
10681
10682	codec->spec = spec;
10683
10684	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
10685						  alc861vd_models,
10686						  alc861vd_cfg_tbl);
10687
10688	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
10689		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
10690			"ALC861VD, trying auto-probe from BIOS...\n");
10691		board_config = ALC861VD_AUTO;
10692	}
10693
10694	if (board_config == ALC861VD_AUTO) {
10695		/* automatic parse from the BIOS config */
10696		err = alc861vd_parse_auto_config(codec);
10697		if (err < 0) {
10698			alc_free(codec);
10699			return err;
10700		} else if (!err) {
10701			printk(KERN_INFO
10702			       "hda_codec: Cannot set up configuration "
10703			       "from BIOS.  Using base mode...\n");
10704			board_config = ALC861VD_3ST;
10705		}
10706	}
10707
10708	if (board_config != ALC861VD_AUTO)
10709		setup_preset(spec, &alc861vd_presets[board_config]);
10710
10711	spec->stream_name_analog = "ALC861VD Analog";
10712	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
10713	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
10714
10715	spec->stream_name_digital = "ALC861VD Digital";
10716	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
10717	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
10718
10719	spec->adc_nids = alc861vd_adc_nids;
10720	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
10721
10722	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
10723	spec->num_mixers++;
10724
10725	codec->patch_ops = alc_patch_ops;
10726
10727	if (board_config == ALC861VD_AUTO)
10728		spec->init_hook = alc861vd_auto_init;
10729
10730	return 0;
10731}
10732
10733/*
10734 * ALC662 support
10735 *
10736 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10737 * configuration.  Each pin widget can choose any input DACs and a mixer.
10738 * Each ADC is connected from a mixer of all inputs.  This makes possible
10739 * 6-channel independent captures.
10740 *
10741 * In addition, an independent DAC for the multi-playback (not used in this
10742 * driver yet).
10743 */
10744#define ALC662_DIGOUT_NID	0x06
10745#define ALC662_DIGIN_NID	0x0a
10746
10747static hda_nid_t alc662_dac_nids[4] = {
10748	/* front, rear, clfe, rear_surr */
10749	0x02, 0x03, 0x04
10750};
10751
10752static hda_nid_t alc662_adc_nids[1] = {
10753	/* ADC1-2 */
10754	0x09,
10755};
10756/* input MUX */
10757/* FIXME: should be a matrix-type input source selection */
10758
10759static struct hda_input_mux alc662_capture_source = {
10760	.num_items = 4,
10761	.items = {
10762		{ "Mic", 0x0 },
10763		{ "Front Mic", 0x1 },
10764		{ "Line", 0x2 },
10765		{ "CD", 0x4 },
10766	},
10767};
10768
10769static struct hda_input_mux alc662_lenovo_101e_capture_source = {
10770	.num_items = 2,
10771	.items = {
10772		{ "Mic", 0x1 },
10773		{ "Line", 0x2 },
10774	},
10775};
10776#define alc662_mux_enum_info alc_mux_enum_info
10777#define alc662_mux_enum_get alc_mux_enum_get
10778
10779static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
10780			       struct snd_ctl_elem_value *ucontrol)
10781{
10782	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10783	struct alc_spec *spec = codec->spec;
10784	const struct hda_input_mux *imux = spec->input_mux;
10785	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10786	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
10787	hda_nid_t nid = capture_mixers[adc_idx];
10788	unsigned int *cur_val = &spec->cur_mux[adc_idx];
10789	unsigned int i, idx;
10790
10791	idx = ucontrol->value.enumerated.item[0];
10792	if (idx >= imux->num_items)
10793		idx = imux->num_items - 1;
10794	if (*cur_val == idx && !codec->in_resume)
10795		return 0;
10796	for (i = 0; i < imux->num_items; i++) {
10797		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
10798		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10799				    v | (imux->items[i].index << 8));
10800	}
10801	*cur_val = idx;
10802	return 1;
10803}
10804/*
10805 * 2ch mode
10806 */
10807static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
10808	{ 2, NULL }
10809};
10810
10811/*
10812 * 2ch mode
10813 */
10814static struct hda_verb alc662_3ST_ch2_init[] = {
10815	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
10816	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10817	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
10818	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
10819	{ } /* end */
10820};
10821
10822/*
10823 * 6ch mode
10824 */
10825static struct hda_verb alc662_3ST_ch6_init[] = {
10826	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10827	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10828	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
10829	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10830	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10831	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
10832	{ } /* end */
10833};
10834
10835static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
10836	{ 2, alc662_3ST_ch2_init },
10837	{ 6, alc662_3ST_ch6_init },
10838};
10839
10840/*
10841 * 2ch mode
10842 */
10843static struct hda_verb alc662_sixstack_ch6_init[] = {
10844	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10845	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10846	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10847	{ } /* end */
10848};
10849
10850/*
10851 * 6ch mode
10852 */
10853static struct hda_verb alc662_sixstack_ch8_init[] = {
10854	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10855	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10856	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10857	{ } /* end */
10858};
10859
10860static struct hda_channel_mode alc662_5stack_modes[2] = {
10861	{ 2, alc662_sixstack_ch6_init },
10862	{ 6, alc662_sixstack_ch8_init },
10863};
10864
10865/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10866 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10867 */
10868
10869static struct snd_kcontrol_new alc662_base_mixer[] = {
10870	/* output mixer control */
10871	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10872	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
10873	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10874	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10875	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10876	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10877	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10878	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10879	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10880
10881	/*Input mixer control */
10882	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
10883	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
10884	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
10885	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
10886	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
10887	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
10888	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
10889	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
10890
10891	/* Capture mixer control */
10892	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10893	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10894	{
10895		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10896		.name = "Capture Source",
10897		.count = 1,
10898		.info = alc_mux_enum_info,
10899		.get = alc_mux_enum_get,
10900		.put = alc_mux_enum_put,
10901	},
10902	{ } /* end */
10903};
10904
10905static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
10906	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10907	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10908	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10909	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10910	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10911	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10912	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10913	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10914	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10915	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10916	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10917	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10918	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10919	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10920	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10921	{
10922		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10923		/* .name = "Capture Source", */
10924		.name = "Input Source",
10925		.count = 1,
10926		.info = alc662_mux_enum_info,
10927		.get = alc662_mux_enum_get,
10928		.put = alc662_mux_enum_put,
10929	},
10930	{ } /* end */
10931};
10932
10933static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
10934	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10935	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10936	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10937	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
10938	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
10939	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
10940	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
10941	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
10942	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10943	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10944	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10945	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10946	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10947	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10948	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10949	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10950	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10951	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10952	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10953	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10954	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10955	{
10956		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10957		/* .name = "Capture Source", */
10958		.name = "Input Source",
10959		.count = 1,
10960		.info = alc662_mux_enum_info,
10961		.get = alc662_mux_enum_get,
10962		.put = alc662_mux_enum_put,
10963	},
10964	{ } /* end */
10965};
10966
10967static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
10968	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10969	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
10970	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10971	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
10972	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10973	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10974	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10975	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10976	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10977	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10978	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10979	{
10980		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10981		/* .name = "Capture Source", */
10982		.name = "Input Source",
10983		.count = 1,
10984		.info = alc662_mux_enum_info,
10985		.get = alc662_mux_enum_get,
10986		.put = alc662_mux_enum_put,
10987	},
10988	{ } /* end */
10989};
10990
10991static struct snd_kcontrol_new alc662_chmode_mixer[] = {
10992	{
10993		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10994		.name = "Channel Mode",
10995		.info = alc_ch_mode_info,
10996		.get = alc_ch_mode_get,
10997		.put = alc_ch_mode_put,
10998	},
10999	{ } /* end */
11000};
11001
11002static struct hda_verb alc662_init_verbs[] = {
11003	/* ADC: mute amp left and right */
11004	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11005	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11006	/* Front mixer: unmute input/output amp left and right (volume = 0) */
11007
11008	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11009	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11010	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11011	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11012	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11013
11014	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11015	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11016	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11017	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11018	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11019	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11020
11021	/* Front Pin: output 0 (0x0c) */
11022	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11023	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11024
11025	/* Rear Pin: output 1 (0x0d) */
11026	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11027	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11028
11029	/* CLFE Pin: output 2 (0x0e) */
11030	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11031	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11032
11033	/* Mic (rear) pin: input vref at 80% */
11034	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11035	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11036	/* Front Mic pin: input vref at 80% */
11037	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11038	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11039	/* Line In pin: input */
11040	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11041	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11042	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11043	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11044	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11045	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11046	/* CD pin widget for input */
11047	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11048
11049	/* FIXME: use matrix-type input source selection */
11050	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11051	/* Input mixer */
11052	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11053	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11054	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11055	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11056	{ }
11057};
11058
11059static struct hda_verb alc662_sue_init_verbs[] = {
11060	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11061	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11062        {}
11063};
11064
11065/*
11066 * generic initialization of ADC, input mixers and output mixers
11067 */
11068static struct hda_verb alc662_auto_init_verbs[] = {
11069	/*
11070	 * Unmute ADC and set the default input to mic-in
11071	 */
11072	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11073	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11074
11075	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11076	 * mixer widget
11077	 * Note: PASD motherboards uses the Line In 2 as the input for front
11078	 * panel mic (mic 2)
11079	 */
11080	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11081	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11082	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11083	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11084	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11085	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11086
11087	/*
11088	 * Set up output mixers (0x0c - 0x0f)
11089	 */
11090	/* set vol=0 to output mixers */
11091	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11092	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11093	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11094
11095	/* set up input amps for analog loopback */
11096	/* Amp Indices: DAC = 0, mixer = 1 */
11097	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11098	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11099	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11100	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11101	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11102	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11103
11104
11105	/* FIXME: use matrix-type input source selection */
11106	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11107	/* Input mixer */
11108	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11109	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11110	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11111	/*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
11112	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11113
11114	{ }
11115};
11116
11117/* capture mixer elements */
11118static struct snd_kcontrol_new alc662_capture_mixer[] = {
11119	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11120	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11121	{
11122		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11123		/* The multiple "Capture Source" controls confuse alsamixer
11124		 * So call somewhat different..
11125		 * FIXME: the controls appear in the "playback" view!
11126		 */
11127		/* .name = "Capture Source", */
11128		.name = "Input Source",
11129		.count = 1,
11130		.info = alc882_mux_enum_info,
11131		.get = alc882_mux_enum_get,
11132		.put = alc882_mux_enum_put,
11133	},
11134	{ } /* end */
11135};
11136
11137static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11138{
11139	unsigned int present;
11140	unsigned char bits;
11141
11142	present = snd_hda_codec_read(codec, 0x14, 0,
11143				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11144	bits = present ? 0x80 : 0;
11145	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11146				 0x80, bits);
11147	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11148				 0x80, bits);
11149}
11150
11151static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11152{
11153	unsigned int present;
11154	unsigned char bits;
11155
11156 	present = snd_hda_codec_read(codec, 0x1b, 0,
11157				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11158	bits = present ? 0x80 : 0;
11159	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
11160				 0x80, bits);
11161	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
11162				 0x80, bits);
11163	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11164				 0x80, bits);
11165	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11166				 0x80, bits);
11167}
11168
11169static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11170					   unsigned int res)
11171{
11172	if ((res >> 26) == ALC880_HP_EVENT)
11173		alc662_lenovo_101e_all_automute(codec);
11174	if ((res >> 26) == ALC880_FRONT_EVENT)
11175		alc662_lenovo_101e_ispeaker_automute(codec);
11176}
11177
11178
11179/* pcm configuration: identiacal with ALC880 */
11180#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
11181#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
11182#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
11183#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
11184
11185/*
11186 * configuration and preset
11187 */
11188static const char *alc662_models[ALC662_MODEL_LAST] = {
11189	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
11190	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
11191	[ALC662_3ST_6ch]	= "3stack-6ch",
11192	[ALC662_5ST_DIG]	= "6stack-dig",
11193	[ALC662_LENOVO_101E]	= "lenovo-101e",
11194	[ALC662_AUTO]		= "auto",
11195};
11196
11197static struct snd_pci_quirk alc662_cfg_tbl[] = {
11198	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11199	{}
11200};
11201
11202static struct alc_config_preset alc662_presets[] = {
11203	[ALC662_3ST_2ch_DIG] = {
11204		.mixers = { alc662_3ST_2ch_mixer },
11205		.init_verbs = { alc662_init_verbs },
11206		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11207		.dac_nids = alc662_dac_nids,
11208		.dig_out_nid = ALC662_DIGOUT_NID,
11209		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11210		.adc_nids = alc662_adc_nids,
11211		.dig_in_nid = ALC662_DIGIN_NID,
11212		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11213		.channel_mode = alc662_3ST_2ch_modes,
11214		.input_mux = &alc662_capture_source,
11215	},
11216	[ALC662_3ST_6ch_DIG] = {
11217		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11218		.init_verbs = { alc662_init_verbs },
11219		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11220		.dac_nids = alc662_dac_nids,
11221		.dig_out_nid = ALC662_DIGOUT_NID,
11222		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11223		.adc_nids = alc662_adc_nids,
11224		.dig_in_nid = ALC662_DIGIN_NID,
11225		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11226		.channel_mode = alc662_3ST_6ch_modes,
11227		.need_dac_fix = 1,
11228		.input_mux = &alc662_capture_source,
11229	},
11230	[ALC662_3ST_6ch] = {
11231		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11232		.init_verbs = { alc662_init_verbs },
11233		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11234		.dac_nids = alc662_dac_nids,
11235		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11236		.adc_nids = alc662_adc_nids,
11237		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11238		.channel_mode = alc662_3ST_6ch_modes,
11239		.need_dac_fix = 1,
11240		.input_mux = &alc662_capture_source,
11241	},
11242	[ALC662_5ST_DIG] = {
11243		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
11244		.init_verbs = { alc662_init_verbs },
11245		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11246		.dac_nids = alc662_dac_nids,
11247		.dig_out_nid = ALC662_DIGOUT_NID,
11248		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11249		.adc_nids = alc662_adc_nids,
11250		.dig_in_nid = ALC662_DIGIN_NID,
11251		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11252		.channel_mode = alc662_5stack_modes,
11253		.input_mux = &alc662_capture_source,
11254	},
11255	[ALC662_LENOVO_101E] = {
11256		.mixers = { alc662_lenovo_101e_mixer },
11257		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11258		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11259		.dac_nids = alc662_dac_nids,
11260		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11261		.adc_nids = alc662_adc_nids,
11262		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11263		.channel_mode = alc662_3ST_2ch_modes,
11264		.input_mux = &alc662_lenovo_101e_capture_source,
11265		.unsol_event = alc662_lenovo_101e_unsol_event,
11266		.init_hook = alc662_lenovo_101e_all_automute,
11267	},
11268
11269};
11270
11271
11272/*
11273 * BIOS auto configuration
11274 */
11275
11276/* add playback controls from the parsed DAC table */
11277static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11278					     const struct auto_pin_cfg *cfg)
11279{
11280	char name[32];
11281	static const char *chname[4] = {
11282		"Front", "Surround", NULL /*CLFE*/, "Side"
11283	};
11284	hda_nid_t nid;
11285	int i, err;
11286
11287	for (i = 0; i < cfg->line_outs; i++) {
11288		if (!spec->multiout.dac_nids[i])
11289			continue;
11290		nid = alc880_idx_to_mixer(i);
11291		if (i == 2) {
11292			/* Center/LFE */
11293			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11294					  "Center Playback Volume",
11295					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11296							      HDA_OUTPUT));
11297			if (err < 0)
11298				return err;
11299			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11300					  "LFE Playback Volume",
11301					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11302							      HDA_OUTPUT));
11303			if (err < 0)
11304				return err;
11305			err = add_control(spec, ALC_CTL_BIND_MUTE,
11306					  "Center Playback Switch",
11307					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11308							      HDA_INPUT));
11309			if (err < 0)
11310				return err;
11311			err = add_control(spec, ALC_CTL_BIND_MUTE,
11312					  "LFE Playback Switch",
11313					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11314							      HDA_INPUT));
11315			if (err < 0)
11316				return err;
11317		} else {
11318			sprintf(name, "%s Playback Volume", chname[i]);
11319			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11320					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11321							      HDA_OUTPUT));
11322			if (err < 0)
11323				return err;
11324			sprintf(name, "%s Playback Switch", chname[i]);
11325			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11326					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11327							      HDA_INPUT));
11328			if (err < 0)
11329				return err;
11330		}
11331	}
11332	return 0;
11333}
11334
11335/* add playback controls for speaker and HP outputs */
11336static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11337					const char *pfx)
11338{
11339	hda_nid_t nid;
11340	int err;
11341	char name[32];
11342
11343	if (!pin)
11344		return 0;
11345
11346	if (alc880_is_fixed_pin(pin)) {
11347		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11348                /* printk("DAC nid=%x\n",nid); */
11349		/* specify the DAC as the extra output */
11350		if (!spec->multiout.hp_nid)
11351			spec->multiout.hp_nid = nid;
11352		else
11353			spec->multiout.extra_out_nid[0] = nid;
11354		/* control HP volume/switch on the output mixer amp */
11355		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11356		sprintf(name, "%s Playback Volume", pfx);
11357		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11358				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11359		if (err < 0)
11360			return err;
11361		sprintf(name, "%s Playback Switch", pfx);
11362		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11363				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11364		if (err < 0)
11365			return err;
11366	} else if (alc880_is_multi_pin(pin)) {
11367		/* set manual connection */
11368		/* we have only a switch on HP-out PIN */
11369		sprintf(name, "%s Playback Switch", pfx);
11370		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11371				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11372		if (err < 0)
11373			return err;
11374	}
11375	return 0;
11376}
11377
11378/* create playback/capture controls for input pins */
11379static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11380						const struct auto_pin_cfg *cfg)
11381{
11382	struct hda_input_mux *imux = &spec->private_imux;
11383	int i, err, idx;
11384
11385	for (i = 0; i < AUTO_PIN_LAST; i++) {
11386		if (alc880_is_input_pin(cfg->input_pins[i])) {
11387			idx = alc880_input_pin_idx(cfg->input_pins[i]);
11388			err = new_analog_input(spec, cfg->input_pins[i],
11389					       auto_pin_cfg_labels[i],
11390					       idx, 0x0b);
11391			if (err < 0)
11392				return err;
11393			imux->items[imux->num_items].label =
11394				auto_pin_cfg_labels[i];
11395			imux->items[imux->num_items].index =
11396				alc880_input_pin_idx(cfg->input_pins[i]);
11397			imux->num_items++;
11398		}
11399	}
11400	return 0;
11401}
11402
11403static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11404					      hda_nid_t nid, int pin_type,
11405					      int dac_idx)
11406{
11407	/* set as output */
11408	snd_hda_codec_write(codec, nid, 0,
11409			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11410	snd_hda_codec_write(codec, nid, 0,
11411			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11412	/* need the manual connection? */
11413	if (alc880_is_multi_pin(nid)) {
11414		struct alc_spec *spec = codec->spec;
11415		int idx = alc880_multi_pin_idx(nid);
11416		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11417				    AC_VERB_SET_CONNECT_SEL,
11418				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11419	}
11420}
11421
11422static void alc662_auto_init_multi_out(struct hda_codec *codec)
11423{
11424	struct alc_spec *spec = codec->spec;
11425	int i;
11426
11427	for (i = 0; i <= HDA_SIDE; i++) {
11428		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11429		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11430		if (nid)
11431			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11432							  i);
11433	}
11434}
11435
11436static void alc662_auto_init_hp_out(struct hda_codec *codec)
11437{
11438	struct alc_spec *spec = codec->spec;
11439	hda_nid_t pin;
11440
11441	pin = spec->autocfg.hp_pins[0];
11442	if (pin) /* connect to front */
11443		/* use dac 0 */
11444		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11445}
11446
11447#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
11448#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
11449
11450static void alc662_auto_init_analog_input(struct hda_codec *codec)
11451{
11452	struct alc_spec *spec = codec->spec;
11453	int i;
11454
11455	for (i = 0; i < AUTO_PIN_LAST; i++) {
11456		hda_nid_t nid = spec->autocfg.input_pins[i];
11457		if (alc662_is_input_pin(nid)) {
11458			snd_hda_codec_write(codec, nid, 0,
11459					    AC_VERB_SET_PIN_WIDGET_CONTROL,
11460					    (i <= AUTO_PIN_FRONT_MIC ?
11461					     PIN_VREF80 : PIN_IN));
11462			if (nid != ALC662_PIN_CD_NID)
11463				snd_hda_codec_write(codec, nid, 0,
11464						    AC_VERB_SET_AMP_GAIN_MUTE,
11465						    AMP_OUT_MUTE);
11466		}
11467	}
11468}
11469
11470static int alc662_parse_auto_config(struct hda_codec *codec)
11471{
11472	struct alc_spec *spec = codec->spec;
11473	int err;
11474	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11475
11476	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11477					   alc662_ignore);
11478	if (err < 0)
11479		return err;
11480	if (!spec->autocfg.line_outs)
11481		return 0; /* can't find valid BIOS pin config */
11482
11483	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11484	if (err < 0)
11485		return err;
11486	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11487	if (err < 0)
11488		return err;
11489	err = alc662_auto_create_extra_out(spec,
11490					   spec->autocfg.speaker_pins[0],
11491					   "Speaker");
11492	if (err < 0)
11493		return err;
11494	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11495					   "Headphone");
11496	if (err < 0)
11497		return err;
11498	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11499	if (err < 0)
11500		return err;
11501
11502	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11503
11504	if (spec->autocfg.dig_out_pin)
11505		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11506
11507	if (spec->kctl_alloc)
11508		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11509
11510	spec->num_mux_defs = 1;
11511	spec->input_mux = &spec->private_imux;
11512
11513	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11514	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11515	spec->num_mixers++;
11516	return 1;
11517}
11518
11519/* additional initialization for auto-configuration model */
11520static void alc662_auto_init(struct hda_codec *codec)
11521{
11522	alc662_auto_init_multi_out(codec);
11523	alc662_auto_init_hp_out(codec);
11524	alc662_auto_init_analog_input(codec);
11525}
11526
11527static int patch_alc662(struct hda_codec *codec)
11528{
11529	struct alc_spec *spec;
11530	int err, board_config;
11531
11532	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11533	if (!spec)
11534		return -ENOMEM;
11535
11536	codec->spec = spec;
11537
11538	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11539						  alc662_models,
11540			  	                  alc662_cfg_tbl);
11541	if (board_config < 0) {
11542		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11543		       "trying auto-probe from BIOS...\n");
11544		board_config = ALC662_AUTO;
11545	}
11546
11547	if (board_config == ALC662_AUTO) {
11548		/* automatic parse from the BIOS config */
11549		err = alc662_parse_auto_config(codec);
11550		if (err < 0) {
11551			alc_free(codec);
11552			return err;
11553		} else if (!err) {
11554			printk(KERN_INFO
11555			       "hda_codec: Cannot set up configuration "
11556			       "from BIOS.  Using base mode...\n");
11557			board_config = ALC662_3ST_2ch_DIG;
11558		}
11559	}
11560
11561	if (board_config != ALC662_AUTO)
11562		setup_preset(spec, &alc662_presets[board_config]);
11563
11564	spec->stream_name_analog = "ALC662 Analog";
11565	spec->stream_analog_playback = &alc662_pcm_analog_playback;
11566	spec->stream_analog_capture = &alc662_pcm_analog_capture;
11567
11568	spec->stream_name_digital = "ALC662 Digital";
11569	spec->stream_digital_playback = &alc662_pcm_digital_playback;
11570	spec->stream_digital_capture = &alc662_pcm_digital_capture;
11571
11572	if (!spec->adc_nids && spec->input_mux) {
11573		spec->adc_nids = alc662_adc_nids;
11574		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11575	}
11576
11577	codec->patch_ops = alc_patch_ops;
11578	if (board_config == ALC662_AUTO)
11579		spec->init_hook = alc662_auto_init;
11580
11581	return 0;
11582}
11583
11584/*
11585 * patch entries
11586 */
11587struct hda_codec_preset snd_hda_preset_realtek[] = {
11588	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11589	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11590	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11591	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11592	  .patch = patch_alc861 },
11593	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11594	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11595	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11596	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11597	  .patch = patch_alc883 },
11598	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11599	  .patch = patch_alc662 },
11600	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11601	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11602	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11603	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11604	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11605	{} /* terminator */
11606};
11607