patch_realtek.c revision f5fcc13c2fc62da6f75d80189a51c2492afb39c0
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_UNIWILL_DIG,
56	ALC880_UNIWILL,
57	ALC880_UNIWILL_P53,
58	ALC880_CLEVO,
59	ALC880_TCL_S700,
60	ALC880_LG,
61	ALC880_LG_LW,
62#ifdef CONFIG_SND_DEBUG
63	ALC880_TEST,
64#endif
65	ALC880_AUTO,
66	ALC880_MODEL_LAST /* last tag */
67};
68
69/* ALC260 models */
70enum {
71	ALC260_BASIC,
72	ALC260_HP,
73	ALC260_HP_3013,
74	ALC260_FUJITSU_S702X,
75	ALC260_ACER,
76#ifdef CONFIG_SND_DEBUG
77	ALC260_TEST,
78#endif
79	ALC260_AUTO,
80	ALC260_MODEL_LAST /* last tag */
81};
82
83/* ALC262 models */
84enum {
85	ALC262_BASIC,
86	ALC262_HIPPO,
87	ALC262_HIPPO_1,
88	ALC262_FUJITSU,
89	ALC262_HP_BPC,
90	ALC262_BENQ_ED8,
91	ALC262_AUTO,
92	ALC262_MODEL_LAST /* last tag */
93};
94
95/* ALC861 models */
96enum {
97	ALC861_3ST,
98	ALC660_3ST,
99	ALC861_3ST_DIG,
100	ALC861_6ST_DIG,
101	ALC861_UNIWILL_M31,
102	ALC861_TOSHIBA,
103	ALC861_ASUS,
104	ALC861_ASUS_LAPTOP,
105	ALC861_AUTO,
106	ALC861_MODEL_LAST,
107};
108
109/* ALC882 models */
110enum {
111	ALC882_3ST_DIG,
112	ALC882_6ST_DIG,
113	ALC882_ARIMA,
114	ALC882_AUTO,
115	ALC882_MODEL_LAST,
116};
117
118/* ALC883 models */
119enum {
120	ALC883_3ST_2ch_DIG,
121	ALC883_3ST_6ch_DIG,
122	ALC883_3ST_6ch,
123	ALC883_6ST_DIG,
124	ALC883_TARGA_DIG,
125	ALC883_TARGA_2ch_DIG,
126	ALC888_DEMO_BOARD,
127	ALC883_ACER,
128	ALC883_MEDION,
129	ALC883_LAPTOP_EAPD,
130	ALC883_AUTO,
131	ALC883_MODEL_LAST,
132};
133
134/* for GPIO Poll */
135#define GPIO_MASK	0x03
136
137struct alc_spec {
138	/* codec parameterization */
139	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
140	unsigned int num_mixers;
141
142	const struct hda_verb *init_verbs[5];	/* initialization verbs
143						 * don't forget NULL
144						 * termination!
145						 */
146	unsigned int num_init_verbs;
147
148	char *stream_name_analog;	/* analog PCM stream */
149	struct hda_pcm_stream *stream_analog_playback;
150	struct hda_pcm_stream *stream_analog_capture;
151
152	char *stream_name_digital;	/* digital PCM stream */
153	struct hda_pcm_stream *stream_digital_playback;
154	struct hda_pcm_stream *stream_digital_capture;
155
156	/* playback */
157	struct hda_multi_out multiout;	/* playback set-up
158					 * max_channels, dacs must be set
159					 * dig_out_nid and hp_nid are optional
160					 */
161
162	/* capture */
163	unsigned int num_adc_nids;
164	hda_nid_t *adc_nids;
165	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
166
167	/* capture source */
168	unsigned int num_mux_defs;
169	const struct hda_input_mux *input_mux;
170	unsigned int cur_mux[3];
171
172	/* channel model */
173	const struct hda_channel_mode *channel_mode;
174	int num_channel_mode;
175	int need_dac_fix;
176
177	/* PCM information */
178	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
179
180	/* dynamic controls, init_verbs and input_mux */
181	struct auto_pin_cfg autocfg;
182	unsigned int num_kctl_alloc, num_kctl_used;
183	struct snd_kcontrol_new *kctl_alloc;
184	struct hda_input_mux private_imux;
185	hda_nid_t private_dac_nids[5];
186
187	/* hooks */
188	void (*init_hook)(struct hda_codec *codec);
189	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
190
191	/* for pin sensing */
192	unsigned int sense_updated: 1;
193	unsigned int jack_present: 1;
194};
195
196/*
197 * configuration template - to be copied to the spec instance
198 */
199struct alc_config_preset {
200	struct snd_kcontrol_new *mixers[5]; /* should be identical size
201					     * with spec
202					     */
203	const struct hda_verb *init_verbs[5];
204	unsigned int num_dacs;
205	hda_nid_t *dac_nids;
206	hda_nid_t dig_out_nid;		/* optional */
207	hda_nid_t hp_nid;		/* optional */
208	unsigned int num_adc_nids;
209	hda_nid_t *adc_nids;
210	hda_nid_t dig_in_nid;
211	unsigned int num_channel_mode;
212	const struct hda_channel_mode *channel_mode;
213	int need_dac_fix;
214	unsigned int num_mux_defs;
215	const struct hda_input_mux *input_mux;
216	void (*unsol_event)(struct hda_codec *, unsigned int);
217	void (*init_hook)(struct hda_codec *);
218};
219
220
221/*
222 * input MUX handling
223 */
224static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
225			     struct snd_ctl_elem_info *uinfo)
226{
227	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
228	struct alc_spec *spec = codec->spec;
229	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
230	if (mux_idx >= spec->num_mux_defs)
231		mux_idx = 0;
232	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
233}
234
235static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
236			    struct snd_ctl_elem_value *ucontrol)
237{
238	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
239	struct alc_spec *spec = codec->spec;
240	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
241
242	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
243	return 0;
244}
245
246static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
247			    struct snd_ctl_elem_value *ucontrol)
248{
249	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
250	struct alc_spec *spec = codec->spec;
251	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
252	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
253	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
254				     spec->adc_nids[adc_idx],
255				     &spec->cur_mux[adc_idx]);
256}
257
258
259/*
260 * channel mode setting
261 */
262static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
263			    struct snd_ctl_elem_info *uinfo)
264{
265	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
266	struct alc_spec *spec = codec->spec;
267	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
268				    spec->num_channel_mode);
269}
270
271static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
272			   struct snd_ctl_elem_value *ucontrol)
273{
274	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
275	struct alc_spec *spec = codec->spec;
276	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
277				   spec->num_channel_mode,
278				   spec->multiout.max_channels);
279}
280
281static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
282			   struct snd_ctl_elem_value *ucontrol)
283{
284	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
285	struct alc_spec *spec = codec->spec;
286	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
287				      spec->num_channel_mode,
288				      &spec->multiout.max_channels);
289	if (err >= 0 && spec->need_dac_fix)
290		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
291	return err;
292}
293
294/*
295 * Control the mode of pin widget settings via the mixer.  "pc" is used
296 * instead of "%" to avoid consequences of accidently treating the % as
297 * being part of a format specifier.  Maximum allowed length of a value is
298 * 63 characters plus NULL terminator.
299 *
300 * Note: some retasking pin complexes seem to ignore requests for input
301 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
302 * are requested.  Therefore order this list so that this behaviour will not
303 * cause problems when mixer clients move through the enum sequentially.
304 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
305 * March 2006.
306 */
307static char *alc_pin_mode_names[] = {
308	"Mic 50pc bias", "Mic 80pc bias",
309	"Line in", "Line out", "Headphone out",
310};
311static unsigned char alc_pin_mode_values[] = {
312	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
313};
314/* The control can present all 5 options, or it can limit the options based
315 * in the pin being assumed to be exclusively an input or an output pin.  In
316 * addition, "input" pins may or may not process the mic bias option
317 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
318 * accept requests for bias as of chip versions up to March 2006) and/or
319 * wiring in the computer.
320 */
321#define ALC_PIN_DIR_IN              0x00
322#define ALC_PIN_DIR_OUT             0x01
323#define ALC_PIN_DIR_INOUT           0x02
324#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
325#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
326
327/* Info about the pin modes supported by the different pin direction modes.
328 * For each direction the minimum and maximum values are given.
329 */
330static signed char alc_pin_mode_dir_info[5][2] = {
331	{ 0, 2 },    /* ALC_PIN_DIR_IN */
332	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
333	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
334	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
335	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
336};
337#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
338#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
339#define alc_pin_mode_n_items(_dir) \
340	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
341
342static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
343			     struct snd_ctl_elem_info *uinfo)
344{
345	unsigned int item_num = uinfo->value.enumerated.item;
346	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
347
348	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
349	uinfo->count = 1;
350	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
351
352	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
353		item_num = alc_pin_mode_min(dir);
354	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
355	return 0;
356}
357
358static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
359			    struct snd_ctl_elem_value *ucontrol)
360{
361	unsigned int i;
362	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
363	hda_nid_t nid = kcontrol->private_value & 0xffff;
364	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
365	long *valp = ucontrol->value.integer.value;
366	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
367						 AC_VERB_GET_PIN_WIDGET_CONTROL,
368						 0x00);
369
370	/* Find enumerated value for current pinctl setting */
371	i = alc_pin_mode_min(dir);
372	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
373		i++;
374	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
375	return 0;
376}
377
378static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
379			    struct snd_ctl_elem_value *ucontrol)
380{
381	signed int change;
382	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
383	hda_nid_t nid = kcontrol->private_value & 0xffff;
384	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
385	long val = *ucontrol->value.integer.value;
386	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
387						 AC_VERB_GET_PIN_WIDGET_CONTROL,
388						 0x00);
389
390	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
391		val = alc_pin_mode_min(dir);
392
393	change = pinctl != alc_pin_mode_values[val];
394	if (change) {
395		/* Set pin mode to that requested */
396		snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
397				    alc_pin_mode_values[val]);
398
399		/* Also enable the retasking pin's input/output as required
400		 * for the requested pin mode.  Enum values of 2 or less are
401		 * input modes.
402		 *
403		 * Dynamically switching the input/output buffers probably
404		 * reduces noise slightly (particularly on input) so we'll
405		 * do it.  However, having both input and output buffers
406		 * enabled simultaneously doesn't seem to be problematic if
407		 * this turns out to be necessary in the future.
408		 */
409		if (val <= 2) {
410			snd_hda_codec_write(codec, nid, 0,
411					    AC_VERB_SET_AMP_GAIN_MUTE,
412					    AMP_OUT_MUTE);
413			snd_hda_codec_write(codec, nid, 0,
414					    AC_VERB_SET_AMP_GAIN_MUTE,
415					    AMP_IN_UNMUTE(0));
416		} else {
417			snd_hda_codec_write(codec, nid, 0,
418					    AC_VERB_SET_AMP_GAIN_MUTE,
419					    AMP_IN_MUTE(0));
420			snd_hda_codec_write(codec, nid, 0,
421					    AC_VERB_SET_AMP_GAIN_MUTE,
422					    AMP_OUT_UNMUTE);
423		}
424	}
425	return change;
426}
427
428#define ALC_PIN_MODE(xname, nid, dir) \
429	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
430	  .info = alc_pin_mode_info, \
431	  .get = alc_pin_mode_get, \
432	  .put = alc_pin_mode_put, \
433	  .private_value = nid | (dir<<16) }
434
435/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
436 * together using a mask with more than one bit set.  This control is
437 * currently used only by the ALC260 test model.  At this stage they are not
438 * needed for any "production" models.
439 */
440#ifdef CONFIG_SND_DEBUG
441static int alc_gpio_data_info(struct snd_kcontrol *kcontrol,
442			      struct snd_ctl_elem_info *uinfo)
443{
444	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
445	uinfo->count = 1;
446	uinfo->value.integer.min = 0;
447	uinfo->value.integer.max = 1;
448	return 0;
449}
450static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
451			     struct snd_ctl_elem_value *ucontrol)
452{
453	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
454	hda_nid_t nid = kcontrol->private_value & 0xffff;
455	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
456	long *valp = ucontrol->value.integer.value;
457	unsigned int val = snd_hda_codec_read(codec, nid, 0,
458					      AC_VERB_GET_GPIO_DATA, 0x00);
459
460	*valp = (val & mask) != 0;
461	return 0;
462}
463static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
464			     struct snd_ctl_elem_value *ucontrol)
465{
466	signed int change;
467	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
468	hda_nid_t nid = kcontrol->private_value & 0xffff;
469	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
470	long val = *ucontrol->value.integer.value;
471	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
472						    AC_VERB_GET_GPIO_DATA,
473						    0x00);
474
475	/* Set/unset the masked GPIO bit(s) as needed */
476	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
477	if (val == 0)
478		gpio_data &= ~mask;
479	else
480		gpio_data |= mask;
481	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
482
483	return change;
484}
485#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
486	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
487	  .info = alc_gpio_data_info, \
488	  .get = alc_gpio_data_get, \
489	  .put = alc_gpio_data_put, \
490	  .private_value = nid | (mask<<16) }
491#endif   /* CONFIG_SND_DEBUG */
492
493/* A switch control to allow the enabling of the digital IO pins on the
494 * ALC260.  This is incredibly simplistic; the intention of this control is
495 * to provide something in the test model allowing digital outputs to be
496 * identified if present.  If models are found which can utilise these
497 * outputs a more complete mixer control can be devised for those models if
498 * necessary.
499 */
500#ifdef CONFIG_SND_DEBUG
501static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
502			       struct snd_ctl_elem_info *uinfo)
503{
504	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
505	uinfo->count = 1;
506	uinfo->value.integer.min = 0;
507	uinfo->value.integer.max = 1;
508	return 0;
509}
510static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
511			      struct snd_ctl_elem_value *ucontrol)
512{
513	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
514	hda_nid_t nid = kcontrol->private_value & 0xffff;
515	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
516	long *valp = ucontrol->value.integer.value;
517	unsigned int val = snd_hda_codec_read(codec, nid, 0,
518					      AC_VERB_GET_DIGI_CONVERT, 0x00);
519
520	*valp = (val & mask) != 0;
521	return 0;
522}
523static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
524			      struct snd_ctl_elem_value *ucontrol)
525{
526	signed int change;
527	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
528	hda_nid_t nid = kcontrol->private_value & 0xffff;
529	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
530	long val = *ucontrol->value.integer.value;
531	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
532						    AC_VERB_GET_DIGI_CONVERT,
533						    0x00);
534
535	/* Set/unset the masked control bit(s) as needed */
536	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
537	if (val==0)
538		ctrl_data &= ~mask;
539	else
540		ctrl_data |= mask;
541	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
542			    ctrl_data);
543
544	return change;
545}
546#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
547	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
548	  .info = alc_spdif_ctrl_info, \
549	  .get = alc_spdif_ctrl_get, \
550	  .put = alc_spdif_ctrl_put, \
551	  .private_value = nid | (mask<<16) }
552#endif   /* CONFIG_SND_DEBUG */
553
554/*
555 * set up from the preset table
556 */
557static void setup_preset(struct alc_spec *spec,
558			 const struct alc_config_preset *preset)
559{
560	int i;
561
562	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
563		spec->mixers[spec->num_mixers++] = preset->mixers[i];
564	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
565	     i++)
566		spec->init_verbs[spec->num_init_verbs++] =
567			preset->init_verbs[i];
568
569	spec->channel_mode = preset->channel_mode;
570	spec->num_channel_mode = preset->num_channel_mode;
571	spec->need_dac_fix = preset->need_dac_fix;
572
573	spec->multiout.max_channels = spec->channel_mode[0].channels;
574
575	spec->multiout.num_dacs = preset->num_dacs;
576	spec->multiout.dac_nids = preset->dac_nids;
577	spec->multiout.dig_out_nid = preset->dig_out_nid;
578	spec->multiout.hp_nid = preset->hp_nid;
579
580	spec->num_mux_defs = preset->num_mux_defs;
581	if (! spec->num_mux_defs)
582		spec->num_mux_defs = 1;
583	spec->input_mux = preset->input_mux;
584
585	spec->num_adc_nids = preset->num_adc_nids;
586	spec->adc_nids = preset->adc_nids;
587	spec->dig_in_nid = preset->dig_in_nid;
588
589	spec->unsol_event = preset->unsol_event;
590	spec->init_hook = preset->init_hook;
591}
592
593/*
594 * ALC880 3-stack model
595 *
596 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
597 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
598 *                 F-Mic = 0x1b, HP = 0x19
599 */
600
601static hda_nid_t alc880_dac_nids[4] = {
602	/* front, rear, clfe, rear_surr */
603	0x02, 0x05, 0x04, 0x03
604};
605
606static hda_nid_t alc880_adc_nids[3] = {
607	/* ADC0-2 */
608	0x07, 0x08, 0x09,
609};
610
611/* The datasheet says the node 0x07 is connected from inputs,
612 * but it shows zero connection in the real implementation on some devices.
613 * Note: this is a 915GAV bug, fixed on 915GLV
614 */
615static hda_nid_t alc880_adc_nids_alt[2] = {
616	/* ADC1-2 */
617	0x08, 0x09,
618};
619
620#define ALC880_DIGOUT_NID	0x06
621#define ALC880_DIGIN_NID	0x0a
622
623static struct hda_input_mux alc880_capture_source = {
624	.num_items = 4,
625	.items = {
626		{ "Mic", 0x0 },
627		{ "Front Mic", 0x3 },
628		{ "Line", 0x2 },
629		{ "CD", 0x4 },
630	},
631};
632
633/* channel source setting (2/6 channel selection for 3-stack) */
634/* 2ch mode */
635static struct hda_verb alc880_threestack_ch2_init[] = {
636	/* set line-in to input, mute it */
637	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
638	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
639	/* set mic-in to input vref 80%, mute it */
640	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
641	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
642	{ } /* end */
643};
644
645/* 6ch mode */
646static struct hda_verb alc880_threestack_ch6_init[] = {
647	/* set line-in to output, unmute it */
648	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
649	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
650	/* set mic-in to output, unmute it */
651	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
652	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
653	{ } /* end */
654};
655
656static struct hda_channel_mode alc880_threestack_modes[2] = {
657	{ 2, alc880_threestack_ch2_init },
658	{ 6, alc880_threestack_ch6_init },
659};
660
661static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
662	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
663	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
664	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
665	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
666	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
667	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
668	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
669	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
670	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
671	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
672	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
673	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
674	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
675	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
676	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
677	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
678	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
679	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
680	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
681	{
682		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
683		.name = "Channel Mode",
684		.info = alc_ch_mode_info,
685		.get = alc_ch_mode_get,
686		.put = alc_ch_mode_put,
687	},
688	{ } /* end */
689};
690
691/* capture mixer elements */
692static struct snd_kcontrol_new alc880_capture_mixer[] = {
693	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
694	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
695	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
696	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
697	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
698	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
699	{
700		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
701		/* The multiple "Capture Source" controls confuse alsamixer
702		 * So call somewhat different..
703		 * FIXME: the controls appear in the "playback" view!
704		 */
705		/* .name = "Capture Source", */
706		.name = "Input Source",
707		.count = 3,
708		.info = alc_mux_enum_info,
709		.get = alc_mux_enum_get,
710		.put = alc_mux_enum_put,
711	},
712	{ } /* end */
713};
714
715/* capture mixer elements (in case NID 0x07 not available) */
716static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
717	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
718	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
719	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
720	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
721	{
722		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
723		/* The multiple "Capture Source" controls confuse alsamixer
724		 * So call somewhat different..
725		 * FIXME: the controls appear in the "playback" view!
726		 */
727		/* .name = "Capture Source", */
728		.name = "Input Source",
729		.count = 2,
730		.info = alc_mux_enum_info,
731		.get = alc_mux_enum_get,
732		.put = alc_mux_enum_put,
733	},
734	{ } /* end */
735};
736
737
738
739/*
740 * ALC880 5-stack model
741 *
742 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
743 *      Side = 0x02 (0xd)
744 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
745 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
746 */
747
748/* additional mixers to alc880_three_stack_mixer */
749static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
750	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
751	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
752	{ } /* end */
753};
754
755/* channel source setting (6/8 channel selection for 5-stack) */
756/* 6ch mode */
757static struct hda_verb alc880_fivestack_ch6_init[] = {
758	/* set line-in to input, mute it */
759	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
760	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
761	{ } /* end */
762};
763
764/* 8ch mode */
765static struct hda_verb alc880_fivestack_ch8_init[] = {
766	/* set line-in to output, unmute it */
767	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
768	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
769	{ } /* end */
770};
771
772static struct hda_channel_mode alc880_fivestack_modes[2] = {
773	{ 6, alc880_fivestack_ch6_init },
774	{ 8, alc880_fivestack_ch8_init },
775};
776
777
778/*
779 * ALC880 6-stack model
780 *
781 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
782 *      Side = 0x05 (0x0f)
783 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
784 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
785 */
786
787static hda_nid_t alc880_6st_dac_nids[4] = {
788	/* front, rear, clfe, rear_surr */
789	0x02, 0x03, 0x04, 0x05
790};
791
792static struct hda_input_mux alc880_6stack_capture_source = {
793	.num_items = 4,
794	.items = {
795		{ "Mic", 0x0 },
796		{ "Front Mic", 0x1 },
797		{ "Line", 0x2 },
798		{ "CD", 0x4 },
799	},
800};
801
802/* fixed 8-channels */
803static struct hda_channel_mode alc880_sixstack_modes[1] = {
804	{ 8, NULL },
805};
806
807static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
808	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
809	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
810	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
811	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
812	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
813	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
814	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
815	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
816	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
817	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
818	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
819	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
820	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
821	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
822	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
823	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
824	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
825	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
826	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
827	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
828	{
829		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
830		.name = "Channel Mode",
831		.info = alc_ch_mode_info,
832		.get = alc_ch_mode_get,
833		.put = alc_ch_mode_put,
834	},
835	{ } /* end */
836};
837
838
839/*
840 * ALC880 W810 model
841 *
842 * W810 has rear IO for:
843 * Front (DAC 02)
844 * Surround (DAC 03)
845 * Center/LFE (DAC 04)
846 * Digital out (06)
847 *
848 * The system also has a pair of internal speakers, and a headphone jack.
849 * These are both connected to Line2 on the codec, hence to DAC 02.
850 *
851 * There is a variable resistor to control the speaker or headphone
852 * volume. This is a hardware-only device without a software API.
853 *
854 * Plugging headphones in will disable the internal speakers. This is
855 * implemented in hardware, not via the driver using jack sense. In
856 * a similar fashion, plugging into the rear socket marked "front" will
857 * disable both the speakers and headphones.
858 *
859 * For input, there's a microphone jack, and an "audio in" jack.
860 * These may not do anything useful with this driver yet, because I
861 * haven't setup any initialization verbs for these yet...
862 */
863
864static hda_nid_t alc880_w810_dac_nids[3] = {
865	/* front, rear/surround, clfe */
866	0x02, 0x03, 0x04
867};
868
869/* fixed 6 channels */
870static struct hda_channel_mode alc880_w810_modes[1] = {
871	{ 6, NULL }
872};
873
874/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
875static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
876	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
877	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
878	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
879	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
880	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
881	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
882	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
883	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
884	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
885	{ } /* end */
886};
887
888
889/*
890 * Z710V model
891 *
892 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
893 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
894 *                 Line = 0x1a
895 */
896
897static hda_nid_t alc880_z71v_dac_nids[1] = {
898	0x02
899};
900#define ALC880_Z71V_HP_DAC	0x03
901
902/* fixed 2 channels */
903static struct hda_channel_mode alc880_2_jack_modes[1] = {
904	{ 2, NULL }
905};
906
907static struct snd_kcontrol_new alc880_z71v_mixer[] = {
908	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
909	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
910	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
911	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
912	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
913	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
914	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
915	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
916	{ } /* end */
917};
918
919
920/* FIXME! */
921/*
922 * ALC880 F1734 model
923 *
924 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
925 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
926 */
927
928static hda_nid_t alc880_f1734_dac_nids[1] = {
929	0x03
930};
931#define ALC880_F1734_HP_DAC	0x02
932
933static struct snd_kcontrol_new alc880_f1734_mixer[] = {
934	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
935	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
936	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
937	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
938	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
939	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
940	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
941	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
942	{ } /* end */
943};
944
945
946/* FIXME! */
947/*
948 * ALC880 ASUS model
949 *
950 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
951 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
952 *  Mic = 0x18, Line = 0x1a
953 */
954
955#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
956#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
957
958static struct snd_kcontrol_new alc880_asus_mixer[] = {
959	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
960	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
961	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
962	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
963	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
964	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
965	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
966	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
967	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
968	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
969	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
970	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
971	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
972	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
973	{
974		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
975		.name = "Channel Mode",
976		.info = alc_ch_mode_info,
977		.get = alc_ch_mode_get,
978		.put = alc_ch_mode_put,
979	},
980	{ } /* end */
981};
982
983/* FIXME! */
984/*
985 * ALC880 ASUS W1V model
986 *
987 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
988 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
989 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
990 */
991
992/* additional mixers to alc880_asus_mixer */
993static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
994	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
995	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
996	{ } /* end */
997};
998
999/* additional mixers to alc880_asus_mixer */
1000static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1001	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1002	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1003	{ } /* end */
1004};
1005
1006/* TCL S700 */
1007static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1008	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1009	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1010	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1011	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1012	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1013	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1014	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1015	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1016	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1017	{
1018		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1019		/* The multiple "Capture Source" controls confuse alsamixer
1020		 * So call somewhat different..
1021		 * FIXME: the controls appear in the "playback" view!
1022		 */
1023		/* .name = "Capture Source", */
1024		.name = "Input Source",
1025		.count = 1,
1026		.info = alc_mux_enum_info,
1027		.get = alc_mux_enum_get,
1028		.put = alc_mux_enum_put,
1029	},
1030	{ } /* end */
1031};
1032
1033/* Uniwill */
1034static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1035	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1036	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1037	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1038	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1039	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1040	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1041	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1042	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1043	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1044	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1045	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1046	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1047	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1048	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1049	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1050	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1051	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1052	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1053	{
1054		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1055		.name = "Channel Mode",
1056		.info = alc_ch_mode_info,
1057		.get = alc_ch_mode_get,
1058		.put = alc_ch_mode_put,
1059	},
1060	{ } /* end */
1061};
1062
1063static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1064	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1065	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1066	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1067	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1068	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1069	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1070	{ } /* end */
1071};
1072
1073/*
1074 * build control elements
1075 */
1076static int alc_build_controls(struct hda_codec *codec)
1077{
1078	struct alc_spec *spec = codec->spec;
1079	int err;
1080	int i;
1081
1082	for (i = 0; i < spec->num_mixers; i++) {
1083		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1084		if (err < 0)
1085			return err;
1086	}
1087
1088	if (spec->multiout.dig_out_nid) {
1089		err = snd_hda_create_spdif_out_ctls(codec,
1090						    spec->multiout.dig_out_nid);
1091		if (err < 0)
1092			return err;
1093	}
1094	if (spec->dig_in_nid) {
1095		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1096		if (err < 0)
1097			return err;
1098	}
1099	return 0;
1100}
1101
1102
1103/*
1104 * initialize the codec volumes, etc
1105 */
1106
1107/*
1108 * generic initialization of ADC, input mixers and output mixers
1109 */
1110static struct hda_verb alc880_volume_init_verbs[] = {
1111	/*
1112	 * Unmute ADC0-2 and set the default input to mic-in
1113	 */
1114	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1115	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1116	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1117	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1118	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1119	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1120
1121	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1122	 * mixer widget
1123	 * Note: PASD motherboards uses the Line In 2 as the input for front
1124	 * panel mic (mic 2)
1125	 */
1126	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1127	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1128	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1129	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1130	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1131	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1132
1133	/*
1134	 * Set up output mixers (0x0c - 0x0f)
1135	 */
1136	/* set vol=0 to output mixers */
1137	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1138	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1139	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1140	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1141	/* set up input amps for analog loopback */
1142	/* Amp Indices: DAC = 0, mixer = 1 */
1143	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1144	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1145	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1146	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1147	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1148	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1149	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1150	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1151
1152	{ }
1153};
1154
1155/*
1156 * 3-stack pin configuration:
1157 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1158 */
1159static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1160	/*
1161	 * preset connection lists of input pins
1162	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1163	 */
1164	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1165	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1166	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1167
1168	/*
1169	 * Set pin mode and muting
1170	 */
1171	/* set front pin widgets 0x14 for output */
1172	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1173	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1174	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1175	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1176	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1177	/* Mic2 (as headphone out) for HP output */
1178	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1179	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1180	/* Line In pin widget for input */
1181	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1182	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1183	/* Line2 (as front mic) pin widget for input and vref at 80% */
1184	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1185	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1186	/* CD pin widget for input */
1187	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1188
1189	{ }
1190};
1191
1192/*
1193 * 5-stack pin configuration:
1194 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1195 * line-in/side = 0x1a, f-mic = 0x1b
1196 */
1197static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1198	/*
1199	 * preset connection lists of input pins
1200	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1201	 */
1202	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1203	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1204
1205	/*
1206	 * Set pin mode and muting
1207	 */
1208	/* set pin widgets 0x14-0x17 for output */
1209	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1210	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1211	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1212	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1213	/* unmute pins for output (no gain on this amp) */
1214	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1215	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1216	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1217	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1218
1219	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1220	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1221	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1222	/* Mic2 (as headphone out) for HP output */
1223	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1224	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1225	/* Line In pin widget for input */
1226	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1227	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1228	/* Line2 (as front mic) pin widget for input and vref at 80% */
1229	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1230	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1231	/* CD pin widget for input */
1232	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1233
1234	{ }
1235};
1236
1237/*
1238 * W810 pin configuration:
1239 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1240 */
1241static struct hda_verb alc880_pin_w810_init_verbs[] = {
1242	/* hphone/speaker input selector: front DAC */
1243	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1244
1245	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1246	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1247	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1248	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1249	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1250	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1251
1252	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1253	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1254
1255	{ }
1256};
1257
1258/*
1259 * Z71V pin configuration:
1260 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1261 */
1262static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1263	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1264	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1265	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1266	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1267
1268	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1269	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1270	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1271	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1272
1273	{ }
1274};
1275
1276/*
1277 * 6-stack pin configuration:
1278 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1279 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1280 */
1281static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1282	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1283
1284	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1285	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1286	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1287	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1288	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1289	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1290	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1291	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1292
1293	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1294	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1295	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1296	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1297	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1298	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1299	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1300	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1301	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1302
1303	{ }
1304};
1305
1306/*
1307 * Uniwill pin configuration:
1308 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1309 * line = 0x1a
1310 */
1311static struct hda_verb alc880_uniwill_init_verbs[] = {
1312	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1313
1314	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1315	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1316	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1317	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1318	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1319	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1320	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1321	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1322	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1324	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1325	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1326	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1327	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1328
1329	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1330	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1331	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1332	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1333	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1334	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1335	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1336	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1337	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1338
1339	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1340	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1341
1342	{ }
1343};
1344
1345/*
1346* Uniwill P53
1347* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1348 */
1349static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1350	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1351
1352	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1353	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1354	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1355	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1356	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1357	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1358	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1359	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1360	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1361	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1362	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1363	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1364
1365	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1366	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1367	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1368	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1369	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1370	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1371
1372	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1373	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1374
1375	{ }
1376};
1377
1378/* toggle speaker-output according to the hp-jack state */
1379static void alc880_uniwill_automute(struct hda_codec *codec)
1380{
1381 	unsigned int present;
1382
1383 	present = snd_hda_codec_read(codec, 0x14, 0,
1384				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1385	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1386				 0x80, present ? 0x80 : 0);
1387	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1388				 0x80, present ? 0x80 : 0);
1389	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1390				 0x80, present ? 0x80 : 0);
1391	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1392				 0x80, present ? 0x80 : 0);
1393
1394	present = snd_hda_codec_read(codec, 0x18, 0,
1395				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1396	snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1397			    0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
1398}
1399
1400static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1401				       unsigned int res)
1402{
1403	/* Looks like the unsol event is incompatible with the standard
1404	 * definition.  4bit tag is placed at 28 bit!
1405	 */
1406	if ((res >> 28) == ALC880_HP_EVENT ||
1407	    (res >> 28) == ALC880_MIC_EVENT)
1408		alc880_uniwill_automute(codec);
1409}
1410
1411static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1412{
1413 	unsigned int present;
1414
1415 	present = snd_hda_codec_read(codec, 0x14, 0,
1416				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1417
1418	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1419				 0x80, present ? 0x80 : 0);
1420	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1421				 0x80, present ? 0x80 : 0);
1422}
1423
1424static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1425{
1426	unsigned int present;
1427
1428	present = snd_hda_codec_read(codec, 0x21, 0,
1429				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1430
1431	snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1432				 0x7f, present);
1433	snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1434				 0x7f,  present);
1435
1436	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1437				 0x7f,  present);
1438	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1439				 0x7f, present);
1440
1441}
1442static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1443					   unsigned int res)
1444{
1445	/* Looks like the unsol event is incompatible with the standard
1446	 * definition.  4bit tag is placed at 28 bit!
1447	 */
1448	if ((res >> 28) == ALC880_HP_EVENT)
1449		alc880_uniwill_p53_hp_automute(codec);
1450	if ((res >> 28) == ALC880_DCVOL_EVENT)
1451		alc880_uniwill_p53_dcvol_automute(codec);
1452}
1453
1454/* FIXME! */
1455/*
1456 * F1734 pin configuration:
1457 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1458 */
1459static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1460	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1461	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1462	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1463	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1464
1465	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1466	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1468	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469
1470	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1471	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1472	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1473	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1474	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1475	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1476	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1477	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1478	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1479
1480	{ }
1481};
1482
1483/* FIXME! */
1484/*
1485 * ASUS pin configuration:
1486 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1487 */
1488static struct hda_verb alc880_pin_asus_init_verbs[] = {
1489	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1490	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1491	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1492	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1493
1494	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1495	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1496	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1497	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1499	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1500	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1501	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1502
1503	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1504	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1505	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1506	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1507	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1508	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1509	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1510	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1511	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1512
1513	{ }
1514};
1515
1516/* Enable GPIO mask and set output */
1517static struct hda_verb alc880_gpio1_init_verbs[] = {
1518	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1519	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1520	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1521
1522	{ }
1523};
1524
1525/* Enable GPIO mask and set output */
1526static struct hda_verb alc880_gpio2_init_verbs[] = {
1527	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1528	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1529	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1530
1531	{ }
1532};
1533
1534/* Clevo m520g init */
1535static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1536	/* headphone output */
1537	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1538	/* line-out */
1539	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1540	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1541	/* Line-in */
1542	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1543	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1544	/* CD */
1545	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1546	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1547	/* Mic1 (rear panel) */
1548	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1549	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1550	/* Mic2 (front panel) */
1551	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1552	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1553	/* headphone */
1554	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1555	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1556        /* change to EAPD mode */
1557	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1558	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1559
1560	{ }
1561};
1562
1563static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1564	/* change to EAPD mode */
1565	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1566	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1567
1568	/* Headphone output */
1569	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1570	/* Front output*/
1571	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1572	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1573
1574	/* Line In pin widget for input */
1575	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1576	/* CD pin widget for input */
1577	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1578	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1579	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1580
1581	/* change to EAPD mode */
1582	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1583	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1584
1585	{ }
1586};
1587
1588/*
1589 * LG m1 express dual
1590 *
1591 * Pin assignment:
1592 *   Rear Line-In/Out (blue): 0x14
1593 *   Build-in Mic-In: 0x15
1594 *   Speaker-out: 0x17
1595 *   HP-Out (green): 0x1b
1596 *   Mic-In/Out (red): 0x19
1597 *   SPDIF-Out: 0x1e
1598 */
1599
1600/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1601static hda_nid_t alc880_lg_dac_nids[3] = {
1602	0x05, 0x02, 0x03
1603};
1604
1605/* seems analog CD is not working */
1606static struct hda_input_mux alc880_lg_capture_source = {
1607	.num_items = 3,
1608	.items = {
1609		{ "Mic", 0x1 },
1610		{ "Line", 0x5 },
1611		{ "Internal Mic", 0x6 },
1612	},
1613};
1614
1615/* 2,4,6 channel modes */
1616static struct hda_verb alc880_lg_ch2_init[] = {
1617	/* set line-in and mic-in to input */
1618	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1619	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1620	{ }
1621};
1622
1623static struct hda_verb alc880_lg_ch4_init[] = {
1624	/* set line-in to out and mic-in to input */
1625	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1626	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1627	{ }
1628};
1629
1630static struct hda_verb alc880_lg_ch6_init[] = {
1631	/* set line-in and mic-in to output */
1632	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1633	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1634	{ }
1635};
1636
1637static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1638	{ 2, alc880_lg_ch2_init },
1639	{ 4, alc880_lg_ch4_init },
1640	{ 6, alc880_lg_ch6_init },
1641};
1642
1643static struct snd_kcontrol_new alc880_lg_mixer[] = {
1644	/* FIXME: it's not really "master" but front channels */
1645	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1646	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1647	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1648	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1649	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1650	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1651	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1652	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1653	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1654	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1655	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1656	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1657	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1658	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1659	{
1660		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1661		.name = "Channel Mode",
1662		.info = alc_ch_mode_info,
1663		.get = alc_ch_mode_get,
1664		.put = alc_ch_mode_put,
1665	},
1666	{ } /* end */
1667};
1668
1669static struct hda_verb alc880_lg_init_verbs[] = {
1670	/* set capture source to mic-in */
1671	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1672	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1673	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1674	/* mute all amp mixer inputs */
1675	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1676	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1677	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1678	/* line-in to input */
1679	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1680	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1681	/* built-in mic */
1682	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1683	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1684	/* speaker-out */
1685	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1686	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1687	/* mic-in to input */
1688	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1689	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1690	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691	/* HP-out */
1692	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1693	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1694	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695	/* jack sense */
1696	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1697	{ }
1698};
1699
1700/* toggle speaker-output according to the hp-jack state */
1701static void alc880_lg_automute(struct hda_codec *codec)
1702{
1703	unsigned int present;
1704
1705	present = snd_hda_codec_read(codec, 0x1b, 0,
1706				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1707	snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1708				 0x80, present ? 0x80 : 0);
1709	snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1710				 0x80, present ? 0x80 : 0);
1711}
1712
1713static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1714{
1715	/* Looks like the unsol event is incompatible with the standard
1716	 * definition.  4bit tag is placed at 28 bit!
1717	 */
1718	if ((res >> 28) == 0x01)
1719		alc880_lg_automute(codec);
1720}
1721
1722/*
1723 * LG LW20
1724 *
1725 * Pin assignment:
1726 *   Speaker-out: 0x14
1727 *   Mic-In: 0x18
1728 *   Built-in Mic-In: 0x19 (?)
1729 *   HP-Out: 0x1b
1730 *   SPDIF-Out: 0x1e
1731 */
1732
1733/* seems analog CD is not working */
1734static struct hda_input_mux alc880_lg_lw_capture_source = {
1735	.num_items = 2,
1736	.items = {
1737		{ "Mic", 0x0 },
1738		{ "Internal Mic", 0x1 },
1739	},
1740};
1741
1742static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1743	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1744	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1745	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1746	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1747	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1748	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1749	{ } /* end */
1750};
1751
1752static struct hda_verb alc880_lg_lw_init_verbs[] = {
1753	/* set capture source to mic-in */
1754	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1755	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1756	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1757	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1758	/* speaker-out */
1759	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1760	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1761	/* HP-out */
1762	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1763	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1764	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1765	/* mic-in to input */
1766	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1767	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1768	/* built-in mic */
1769	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1770	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1771	/* jack sense */
1772	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1773	{ }
1774};
1775
1776/* toggle speaker-output according to the hp-jack state */
1777static void alc880_lg_lw_automute(struct hda_codec *codec)
1778{
1779	unsigned int present;
1780
1781	present = snd_hda_codec_read(codec, 0x1b, 0,
1782				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1783	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1784				 0x80, present ? 0x80 : 0);
1785	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1786				 0x80, present ? 0x80 : 0);
1787}
1788
1789static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1790{
1791	/* Looks like the unsol event is incompatible with the standard
1792	 * definition.  4bit tag is placed at 28 bit!
1793	 */
1794	if ((res >> 28) == 0x01)
1795		alc880_lg_lw_automute(codec);
1796}
1797
1798/*
1799 * Common callbacks
1800 */
1801
1802static int alc_init(struct hda_codec *codec)
1803{
1804	struct alc_spec *spec = codec->spec;
1805	unsigned int i;
1806
1807	for (i = 0; i < spec->num_init_verbs; i++)
1808		snd_hda_sequence_write(codec, spec->init_verbs[i]);
1809
1810	if (spec->init_hook)
1811		spec->init_hook(codec);
1812
1813	return 0;
1814}
1815
1816static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1817{
1818	struct alc_spec *spec = codec->spec;
1819
1820	if (spec->unsol_event)
1821		spec->unsol_event(codec, res);
1822}
1823
1824#ifdef CONFIG_PM
1825/*
1826 * resume
1827 */
1828static int alc_resume(struct hda_codec *codec)
1829{
1830	struct alc_spec *spec = codec->spec;
1831	int i;
1832
1833	alc_init(codec);
1834	for (i = 0; i < spec->num_mixers; i++)
1835		snd_hda_resume_ctls(codec, spec->mixers[i]);
1836	if (spec->multiout.dig_out_nid)
1837		snd_hda_resume_spdif_out(codec);
1838	if (spec->dig_in_nid)
1839		snd_hda_resume_spdif_in(codec);
1840
1841	return 0;
1842}
1843#endif
1844
1845/*
1846 * Analog playback callbacks
1847 */
1848static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
1849				    struct hda_codec *codec,
1850				    struct snd_pcm_substream *substream)
1851{
1852	struct alc_spec *spec = codec->spec;
1853	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1854}
1855
1856static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1857				       struct hda_codec *codec,
1858				       unsigned int stream_tag,
1859				       unsigned int format,
1860				       struct snd_pcm_substream *substream)
1861{
1862	struct alc_spec *spec = codec->spec;
1863	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
1864						stream_tag, format, substream);
1865}
1866
1867static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1868				       struct hda_codec *codec,
1869				       struct snd_pcm_substream *substream)
1870{
1871	struct alc_spec *spec = codec->spec;
1872	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1873}
1874
1875/*
1876 * Digital out
1877 */
1878static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1879					struct hda_codec *codec,
1880					struct snd_pcm_substream *substream)
1881{
1882	struct alc_spec *spec = codec->spec;
1883	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1884}
1885
1886static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1887					 struct hda_codec *codec,
1888					 struct snd_pcm_substream *substream)
1889{
1890	struct alc_spec *spec = codec->spec;
1891	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1892}
1893
1894/*
1895 * Analog capture
1896 */
1897static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1898				      struct hda_codec *codec,
1899				      unsigned int stream_tag,
1900				      unsigned int format,
1901				      struct snd_pcm_substream *substream)
1902{
1903	struct alc_spec *spec = codec->spec;
1904
1905	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1906				   stream_tag, 0, format);
1907	return 0;
1908}
1909
1910static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1911				      struct hda_codec *codec,
1912				      struct snd_pcm_substream *substream)
1913{
1914	struct alc_spec *spec = codec->spec;
1915
1916	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1917				   0, 0, 0);
1918	return 0;
1919}
1920
1921
1922/*
1923 */
1924static struct hda_pcm_stream alc880_pcm_analog_playback = {
1925	.substreams = 1,
1926	.channels_min = 2,
1927	.channels_max = 8,
1928	/* NID is set in alc_build_pcms */
1929	.ops = {
1930		.open = alc880_playback_pcm_open,
1931		.prepare = alc880_playback_pcm_prepare,
1932		.cleanup = alc880_playback_pcm_cleanup
1933	},
1934};
1935
1936static struct hda_pcm_stream alc880_pcm_analog_capture = {
1937	.substreams = 2,
1938	.channels_min = 2,
1939	.channels_max = 2,
1940	/* NID is set in alc_build_pcms */
1941	.ops = {
1942		.prepare = alc880_capture_pcm_prepare,
1943		.cleanup = alc880_capture_pcm_cleanup
1944	},
1945};
1946
1947static struct hda_pcm_stream alc880_pcm_digital_playback = {
1948	.substreams = 1,
1949	.channels_min = 2,
1950	.channels_max = 2,
1951	/* NID is set in alc_build_pcms */
1952	.ops = {
1953		.open = alc880_dig_playback_pcm_open,
1954		.close = alc880_dig_playback_pcm_close
1955	},
1956};
1957
1958static struct hda_pcm_stream alc880_pcm_digital_capture = {
1959	.substreams = 1,
1960	.channels_min = 2,
1961	.channels_max = 2,
1962	/* NID is set in alc_build_pcms */
1963};
1964
1965/* Used by alc_build_pcms to flag that a PCM has no playback stream */
1966static struct hda_pcm_stream alc_pcm_null_playback = {
1967	.substreams = 0,
1968	.channels_min = 0,
1969	.channels_max = 0,
1970};
1971
1972static int alc_build_pcms(struct hda_codec *codec)
1973{
1974	struct alc_spec *spec = codec->spec;
1975	struct hda_pcm *info = spec->pcm_rec;
1976	int i;
1977
1978	codec->num_pcms = 1;
1979	codec->pcm_info = info;
1980
1981	info->name = spec->stream_name_analog;
1982	if (spec->stream_analog_playback) {
1983		snd_assert(spec->multiout.dac_nids, return -EINVAL);
1984		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1985		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
1986	}
1987	if (spec->stream_analog_capture) {
1988		snd_assert(spec->adc_nids, return -EINVAL);
1989		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1990		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1991	}
1992
1993	if (spec->channel_mode) {
1994		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1995		for (i = 0; i < spec->num_channel_mode; i++) {
1996			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1997				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1998			}
1999		}
2000	}
2001
2002	/* SPDIF for stream index #1 */
2003	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2004		codec->num_pcms = 2;
2005		info = spec->pcm_rec + 1;
2006		info->name = spec->stream_name_digital;
2007		if (spec->multiout.dig_out_nid &&
2008		    spec->stream_digital_playback) {
2009			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2010			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2011		}
2012		if (spec->dig_in_nid &&
2013		    spec->stream_digital_capture) {
2014			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2015			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2016		}
2017	}
2018
2019	/* If the use of more than one ADC is requested for the current
2020	 * model, configure a second analog capture-only PCM.
2021	 */
2022	/* Additional Analaog capture for index #2 */
2023	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2024	    spec->adc_nids) {
2025		codec->num_pcms = 3;
2026		info = spec->pcm_rec + 2;
2027		info->name = spec->stream_name_analog;
2028		/* No playback stream for second PCM */
2029		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2030		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2031		if (spec->stream_analog_capture) {
2032			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2033			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2034		}
2035	}
2036
2037	return 0;
2038}
2039
2040static void alc_free(struct hda_codec *codec)
2041{
2042	struct alc_spec *spec = codec->spec;
2043	unsigned int i;
2044
2045	if (! spec)
2046		return;
2047
2048	if (spec->kctl_alloc) {
2049		for (i = 0; i < spec->num_kctl_used; i++)
2050			kfree(spec->kctl_alloc[i].name);
2051		kfree(spec->kctl_alloc);
2052	}
2053	kfree(spec);
2054}
2055
2056/*
2057 */
2058static struct hda_codec_ops alc_patch_ops = {
2059	.build_controls = alc_build_controls,
2060	.build_pcms = alc_build_pcms,
2061	.init = alc_init,
2062	.free = alc_free,
2063	.unsol_event = alc_unsol_event,
2064#ifdef CONFIG_PM
2065	.resume = alc_resume,
2066#endif
2067};
2068
2069
2070/*
2071 * Test configuration for debugging
2072 *
2073 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2074 * enum controls.
2075 */
2076#ifdef CONFIG_SND_DEBUG
2077static hda_nid_t alc880_test_dac_nids[4] = {
2078	0x02, 0x03, 0x04, 0x05
2079};
2080
2081static struct hda_input_mux alc880_test_capture_source = {
2082	.num_items = 7,
2083	.items = {
2084		{ "In-1", 0x0 },
2085		{ "In-2", 0x1 },
2086		{ "In-3", 0x2 },
2087		{ "In-4", 0x3 },
2088		{ "CD", 0x4 },
2089		{ "Front", 0x5 },
2090		{ "Surround", 0x6 },
2091	},
2092};
2093
2094static struct hda_channel_mode alc880_test_modes[4] = {
2095	{ 2, NULL },
2096	{ 4, NULL },
2097	{ 6, NULL },
2098	{ 8, NULL },
2099};
2100
2101static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2102				 struct snd_ctl_elem_info *uinfo)
2103{
2104	static char *texts[] = {
2105		"N/A", "Line Out", "HP Out",
2106		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2107	};
2108	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2109	uinfo->count = 1;
2110	uinfo->value.enumerated.items = 8;
2111	if (uinfo->value.enumerated.item >= 8)
2112		uinfo->value.enumerated.item = 7;
2113	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2114	return 0;
2115}
2116
2117static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2118				struct snd_ctl_elem_value *ucontrol)
2119{
2120	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2121	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2122	unsigned int pin_ctl, item = 0;
2123
2124	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2125				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2126	if (pin_ctl & AC_PINCTL_OUT_EN) {
2127		if (pin_ctl & AC_PINCTL_HP_EN)
2128			item = 2;
2129		else
2130			item = 1;
2131	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2132		switch (pin_ctl & AC_PINCTL_VREFEN) {
2133		case AC_PINCTL_VREF_HIZ: item = 3; break;
2134		case AC_PINCTL_VREF_50:  item = 4; break;
2135		case AC_PINCTL_VREF_GRD: item = 5; break;
2136		case AC_PINCTL_VREF_80:  item = 6; break;
2137		case AC_PINCTL_VREF_100: item = 7; break;
2138		}
2139	}
2140	ucontrol->value.enumerated.item[0] = item;
2141	return 0;
2142}
2143
2144static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2145				struct snd_ctl_elem_value *ucontrol)
2146{
2147	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2148	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2149	static unsigned int ctls[] = {
2150		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2151		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2152		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2153		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2154		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2155		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2156	};
2157	unsigned int old_ctl, new_ctl;
2158
2159	old_ctl = snd_hda_codec_read(codec, nid, 0,
2160				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2161	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2162	if (old_ctl != new_ctl) {
2163		snd_hda_codec_write(codec, nid, 0,
2164				    AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
2165		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2166				    (ucontrol->value.enumerated.item[0] >= 3 ?
2167				     0xb080 : 0xb000));
2168		return 1;
2169	}
2170	return 0;
2171}
2172
2173static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2174				 struct snd_ctl_elem_info *uinfo)
2175{
2176	static char *texts[] = {
2177		"Front", "Surround", "CLFE", "Side"
2178	};
2179	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2180	uinfo->count = 1;
2181	uinfo->value.enumerated.items = 4;
2182	if (uinfo->value.enumerated.item >= 4)
2183		uinfo->value.enumerated.item = 3;
2184	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2185	return 0;
2186}
2187
2188static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2189				struct snd_ctl_elem_value *ucontrol)
2190{
2191	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2192	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2193	unsigned int sel;
2194
2195	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2196	ucontrol->value.enumerated.item[0] = sel & 3;
2197	return 0;
2198}
2199
2200static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2201				struct snd_ctl_elem_value *ucontrol)
2202{
2203	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2204	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2205	unsigned int sel;
2206
2207	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2208	if (ucontrol->value.enumerated.item[0] != sel) {
2209		sel = ucontrol->value.enumerated.item[0] & 3;
2210		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
2211		return 1;
2212	}
2213	return 0;
2214}
2215
2216#define PIN_CTL_TEST(xname,nid) {			\
2217		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2218			.name = xname,		       \
2219			.info = alc_test_pin_ctl_info, \
2220			.get = alc_test_pin_ctl_get,   \
2221			.put = alc_test_pin_ctl_put,   \
2222			.private_value = nid	       \
2223			}
2224
2225#define PIN_SRC_TEST(xname,nid) {			\
2226		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2227			.name = xname,		       \
2228			.info = alc_test_pin_src_info, \
2229			.get = alc_test_pin_src_get,   \
2230			.put = alc_test_pin_src_put,   \
2231			.private_value = nid	       \
2232			}
2233
2234static struct snd_kcontrol_new alc880_test_mixer[] = {
2235	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2236	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2237	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2238	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2239	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2240	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2241	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2242	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2243	PIN_CTL_TEST("Front Pin Mode", 0x14),
2244	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2245	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2246	PIN_CTL_TEST("Side Pin Mode", 0x17),
2247	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2248	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2249	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2250	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2251	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2252	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2253	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2254	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2255	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2256	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2257	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2258	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2259	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2260	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2261	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2262	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2263	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2264	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2265	{
2266		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2267		.name = "Channel Mode",
2268		.info = alc_ch_mode_info,
2269		.get = alc_ch_mode_get,
2270		.put = alc_ch_mode_put,
2271	},
2272	{ } /* end */
2273};
2274
2275static struct hda_verb alc880_test_init_verbs[] = {
2276	/* Unmute inputs of 0x0c - 0x0f */
2277	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2278	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2279	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2280	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2281	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2282	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2283	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2284	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2285	/* Vol output for 0x0c-0x0f */
2286	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2287	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2288	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2289	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2290	/* Set output pins 0x14-0x17 */
2291	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2292	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2293	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2294	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2295	/* Unmute output pins 0x14-0x17 */
2296	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2297	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2298	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2299	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300	/* Set input pins 0x18-0x1c */
2301	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2302	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2303	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2304	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2305	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2306	/* Mute input pins 0x18-0x1b */
2307	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2308	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2309	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2310	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2311	/* ADC set up */
2312	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2313	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2314	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2315	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2316	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2317	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2318	/* Analog input/passthru */
2319	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2320	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2321	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2322	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2323	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2324	{ }
2325};
2326#endif
2327
2328/*
2329 */
2330
2331static const char *alc880_models[ALC880_MODEL_LAST] = {
2332	[ALC880_3ST]		= "3stack",
2333	[ALC880_TCL_S700]	= "tcl",
2334	[ALC880_3ST_DIG]	= "3stack-digout",
2335	[ALC880_CLEVO]		= "clevo",
2336	[ALC880_5ST]		= "5stack",
2337	[ALC880_5ST_DIG]	= "5stack-digout",
2338	[ALC880_W810]		= "w810",
2339	[ALC880_Z71V]		= "z71v",
2340	[ALC880_6ST]		= "6stack",
2341	[ALC880_6ST_DIG]	= "6stack-digout",
2342	[ALC880_ASUS]		= "asus",
2343	[ALC880_ASUS_W1V]	= "asus-w1v",
2344	[ALC880_ASUS_DIG]	= "asus-dig",
2345	[ALC880_ASUS_DIG2]	= "asus-dig2",
2346	[ALC880_UNIWILL_DIG]	= "uniwill",
2347	[ALC880_F1734]		= "F1734",
2348	[ALC880_LG]		= "lg",
2349	[ALC880_LG_LW]		= "lg-lw",
2350#ifdef CONFIG_SND_DEBUG
2351	[ALC880_TEST]		= "test",
2352#endif
2353	[ALC880_AUTO]		= "auto",
2354};
2355
2356static struct snd_pci_quirk alc880_cfg_tbl[] = {
2357	/* Broken BIOS configuration */
2358	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2359	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2360
2361	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2362	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2363	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2364	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2365	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2366	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2367	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2368	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2369
2370	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2371	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2372
2373	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2374	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2375	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2376	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2377	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2378	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2379	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2380	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2381	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2382	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2383	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_5ST),
2384	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2385	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2386	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2387	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2388
2389	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2390	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2391	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2392	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2393	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2394	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2395	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2396	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2397	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2398	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2399	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2400	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2401	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2402	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2403	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2404	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2405	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2406	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2407
2408	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2409	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2410	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2411	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2412
2413	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2414	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2415	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2416
2417	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2418	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2419	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2420	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2421
2422	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2423	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2424	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2425	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2426	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2427	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2428	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2429	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2430	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2431	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2432	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2433
2434	{}
2435};
2436
2437/*
2438 * ALC880 codec presets
2439 */
2440static struct alc_config_preset alc880_presets[] = {
2441	[ALC880_3ST] = {
2442		.mixers = { alc880_three_stack_mixer },
2443		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2444		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2445		.dac_nids = alc880_dac_nids,
2446		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2447		.channel_mode = alc880_threestack_modes,
2448		.need_dac_fix = 1,
2449		.input_mux = &alc880_capture_source,
2450	},
2451	[ALC880_3ST_DIG] = {
2452		.mixers = { alc880_three_stack_mixer },
2453		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2454		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2455		.dac_nids = alc880_dac_nids,
2456		.dig_out_nid = ALC880_DIGOUT_NID,
2457		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2458		.channel_mode = alc880_threestack_modes,
2459		.need_dac_fix = 1,
2460		.input_mux = &alc880_capture_source,
2461	},
2462	[ALC880_TCL_S700] = {
2463		.mixers = { alc880_tcl_s700_mixer },
2464		.init_verbs = { alc880_volume_init_verbs,
2465				alc880_pin_tcl_S700_init_verbs,
2466				alc880_gpio2_init_verbs },
2467		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2468		.dac_nids = alc880_dac_nids,
2469		.hp_nid = 0x03,
2470		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2471		.channel_mode = alc880_2_jack_modes,
2472		.input_mux = &alc880_capture_source,
2473	},
2474	[ALC880_5ST] = {
2475		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
2476		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2477		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2478		.dac_nids = alc880_dac_nids,
2479		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2480		.channel_mode = alc880_fivestack_modes,
2481		.input_mux = &alc880_capture_source,
2482	},
2483	[ALC880_5ST_DIG] = {
2484		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
2485		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2486		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2487		.dac_nids = alc880_dac_nids,
2488		.dig_out_nid = ALC880_DIGOUT_NID,
2489		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2490		.channel_mode = alc880_fivestack_modes,
2491		.input_mux = &alc880_capture_source,
2492	},
2493	[ALC880_6ST] = {
2494		.mixers = { alc880_six_stack_mixer },
2495		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2496		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2497		.dac_nids = alc880_6st_dac_nids,
2498		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2499		.channel_mode = alc880_sixstack_modes,
2500		.input_mux = &alc880_6stack_capture_source,
2501	},
2502	[ALC880_6ST_DIG] = {
2503		.mixers = { alc880_six_stack_mixer },
2504		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2505		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2506		.dac_nids = alc880_6st_dac_nids,
2507		.dig_out_nid = ALC880_DIGOUT_NID,
2508		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2509		.channel_mode = alc880_sixstack_modes,
2510		.input_mux = &alc880_6stack_capture_source,
2511	},
2512	[ALC880_W810] = {
2513		.mixers = { alc880_w810_base_mixer },
2514		.init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
2515				alc880_gpio2_init_verbs },
2516		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2517		.dac_nids = alc880_w810_dac_nids,
2518		.dig_out_nid = ALC880_DIGOUT_NID,
2519		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2520		.channel_mode = alc880_w810_modes,
2521		.input_mux = &alc880_capture_source,
2522	},
2523	[ALC880_Z71V] = {
2524		.mixers = { alc880_z71v_mixer },
2525		.init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
2526		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2527		.dac_nids = alc880_z71v_dac_nids,
2528		.dig_out_nid = ALC880_DIGOUT_NID,
2529		.hp_nid = 0x03,
2530		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2531		.channel_mode = alc880_2_jack_modes,
2532		.input_mux = &alc880_capture_source,
2533	},
2534	[ALC880_F1734] = {
2535		.mixers = { alc880_f1734_mixer },
2536		.init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
2537		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2538		.dac_nids = alc880_f1734_dac_nids,
2539		.hp_nid = 0x02,
2540		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2541		.channel_mode = alc880_2_jack_modes,
2542		.input_mux = &alc880_capture_source,
2543	},
2544	[ALC880_ASUS] = {
2545		.mixers = { alc880_asus_mixer },
2546		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2547				alc880_gpio1_init_verbs },
2548		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2549		.dac_nids = alc880_asus_dac_nids,
2550		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2551		.channel_mode = alc880_asus_modes,
2552		.need_dac_fix = 1,
2553		.input_mux = &alc880_capture_source,
2554	},
2555	[ALC880_ASUS_DIG] = {
2556		.mixers = { alc880_asus_mixer },
2557		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2558				alc880_gpio1_init_verbs },
2559		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2560		.dac_nids = alc880_asus_dac_nids,
2561		.dig_out_nid = ALC880_DIGOUT_NID,
2562		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2563		.channel_mode = alc880_asus_modes,
2564		.need_dac_fix = 1,
2565		.input_mux = &alc880_capture_source,
2566	},
2567	[ALC880_ASUS_DIG2] = {
2568		.mixers = { alc880_asus_mixer },
2569		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2570				alc880_gpio2_init_verbs }, /* use GPIO2 */
2571		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2572		.dac_nids = alc880_asus_dac_nids,
2573		.dig_out_nid = ALC880_DIGOUT_NID,
2574		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2575		.channel_mode = alc880_asus_modes,
2576		.need_dac_fix = 1,
2577		.input_mux = &alc880_capture_source,
2578	},
2579	[ALC880_ASUS_W1V] = {
2580		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2581		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2582				alc880_gpio1_init_verbs },
2583		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2584		.dac_nids = alc880_asus_dac_nids,
2585		.dig_out_nid = ALC880_DIGOUT_NID,
2586		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2587		.channel_mode = alc880_asus_modes,
2588		.need_dac_fix = 1,
2589		.input_mux = &alc880_capture_source,
2590	},
2591	[ALC880_UNIWILL_DIG] = {
2592		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2593		.init_verbs = { alc880_volume_init_verbs,
2594				alc880_pin_asus_init_verbs },
2595		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2596		.dac_nids = alc880_asus_dac_nids,
2597		.dig_out_nid = ALC880_DIGOUT_NID,
2598		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2599		.channel_mode = alc880_asus_modes,
2600		.need_dac_fix = 1,
2601		.input_mux = &alc880_capture_source,
2602	},
2603	[ALC880_UNIWILL] = {
2604		.mixers = { alc880_uniwill_mixer },
2605		.init_verbs = { alc880_volume_init_verbs,
2606				alc880_uniwill_init_verbs },
2607		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2608		.dac_nids = alc880_asus_dac_nids,
2609		.dig_out_nid = ALC880_DIGOUT_NID,
2610		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2611		.channel_mode = alc880_threestack_modes,
2612		.need_dac_fix = 1,
2613		.input_mux = &alc880_capture_source,
2614		.unsol_event = alc880_uniwill_unsol_event,
2615		.init_hook = alc880_uniwill_automute,
2616	},
2617	[ALC880_UNIWILL_P53] = {
2618		.mixers = { alc880_uniwill_p53_mixer },
2619		.init_verbs = { alc880_volume_init_verbs,
2620				alc880_uniwill_p53_init_verbs },
2621		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2622		.dac_nids = alc880_asus_dac_nids,
2623		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2624		.channel_mode = alc880_w810_modes,
2625		.input_mux = &alc880_capture_source,
2626		.unsol_event = alc880_uniwill_p53_unsol_event,
2627		.init_hook = alc880_uniwill_p53_hp_automute,
2628	},
2629	[ALC880_CLEVO] = {
2630		.mixers = { alc880_three_stack_mixer },
2631		.init_verbs = { alc880_volume_init_verbs,
2632				alc880_pin_clevo_init_verbs },
2633		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2634		.dac_nids = alc880_dac_nids,
2635		.hp_nid = 0x03,
2636		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2637		.channel_mode = alc880_threestack_modes,
2638		.need_dac_fix = 1,
2639		.input_mux = &alc880_capture_source,
2640	},
2641	[ALC880_LG] = {
2642		.mixers = { alc880_lg_mixer },
2643		.init_verbs = { alc880_volume_init_verbs,
2644				alc880_lg_init_verbs },
2645		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2646		.dac_nids = alc880_lg_dac_nids,
2647		.dig_out_nid = ALC880_DIGOUT_NID,
2648		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2649		.channel_mode = alc880_lg_ch_modes,
2650		.need_dac_fix = 1,
2651		.input_mux = &alc880_lg_capture_source,
2652		.unsol_event = alc880_lg_unsol_event,
2653		.init_hook = alc880_lg_automute,
2654	},
2655	[ALC880_LG_LW] = {
2656		.mixers = { alc880_lg_lw_mixer },
2657		.init_verbs = { alc880_volume_init_verbs,
2658				alc880_lg_lw_init_verbs },
2659		.num_dacs = 1,
2660		.dac_nids = alc880_dac_nids,
2661		.dig_out_nid = ALC880_DIGOUT_NID,
2662		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2663		.channel_mode = alc880_2_jack_modes,
2664		.input_mux = &alc880_lg_lw_capture_source,
2665		.unsol_event = alc880_lg_lw_unsol_event,
2666		.init_hook = alc880_lg_lw_automute,
2667	},
2668#ifdef CONFIG_SND_DEBUG
2669	[ALC880_TEST] = {
2670		.mixers = { alc880_test_mixer },
2671		.init_verbs = { alc880_test_init_verbs },
2672		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2673		.dac_nids = alc880_test_dac_nids,
2674		.dig_out_nid = ALC880_DIGOUT_NID,
2675		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2676		.channel_mode = alc880_test_modes,
2677		.input_mux = &alc880_test_capture_source,
2678	},
2679#endif
2680};
2681
2682/*
2683 * Automatic parse of I/O pins from the BIOS configuration
2684 */
2685
2686#define NUM_CONTROL_ALLOC	32
2687#define NUM_VERB_ALLOC		32
2688
2689enum {
2690	ALC_CTL_WIDGET_VOL,
2691	ALC_CTL_WIDGET_MUTE,
2692	ALC_CTL_BIND_MUTE,
2693};
2694static struct snd_kcontrol_new alc880_control_templates[] = {
2695	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2696	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2697	HDA_BIND_MUTE(NULL, 0, 0, 0),
2698};
2699
2700/* add dynamic controls */
2701static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
2702{
2703	struct snd_kcontrol_new *knew;
2704
2705	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2706		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2707
2708		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2709		if (! knew)
2710			return -ENOMEM;
2711		if (spec->kctl_alloc) {
2712			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2713			kfree(spec->kctl_alloc);
2714		}
2715		spec->kctl_alloc = knew;
2716		spec->num_kctl_alloc = num;
2717	}
2718
2719	knew = &spec->kctl_alloc[spec->num_kctl_used];
2720	*knew = alc880_control_templates[type];
2721	knew->name = kstrdup(name, GFP_KERNEL);
2722	if (! knew->name)
2723		return -ENOMEM;
2724	knew->private_value = val;
2725	spec->num_kctl_used++;
2726	return 0;
2727}
2728
2729#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2730#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2731#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2732#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2733#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2734#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2735#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2736#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2737#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2738#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2739#define ALC880_PIN_CD_NID		0x1c
2740
2741/* fill in the dac_nids table from the parsed pin configuration */
2742static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
2743{
2744	hda_nid_t nid;
2745	int assigned[4];
2746	int i, j;
2747
2748	memset(assigned, 0, sizeof(assigned));
2749	spec->multiout.dac_nids = spec->private_dac_nids;
2750
2751	/* check the pins hardwired to audio widget */
2752	for (i = 0; i < cfg->line_outs; i++) {
2753		nid = cfg->line_out_pins[i];
2754		if (alc880_is_fixed_pin(nid)) {
2755			int idx = alc880_fixed_pin_idx(nid);
2756			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2757			assigned[idx] = 1;
2758		}
2759	}
2760	/* left pins can be connect to any audio widget */
2761	for (i = 0; i < cfg->line_outs; i++) {
2762		nid = cfg->line_out_pins[i];
2763		if (alc880_is_fixed_pin(nid))
2764			continue;
2765		/* search for an empty channel */
2766		for (j = 0; j < cfg->line_outs; j++) {
2767			if (! assigned[j]) {
2768				spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
2769				assigned[j] = 1;
2770				break;
2771			}
2772		}
2773	}
2774	spec->multiout.num_dacs = cfg->line_outs;
2775	return 0;
2776}
2777
2778/* add playback controls from the parsed DAC table */
2779static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
2780					     const struct auto_pin_cfg *cfg)
2781{
2782	char name[32];
2783	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2784	hda_nid_t nid;
2785	int i, err;
2786
2787	for (i = 0; i < cfg->line_outs; i++) {
2788		if (! spec->multiout.dac_nids[i])
2789			continue;
2790		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
2791		if (i == 2) {
2792			/* Center/LFE */
2793			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
2794					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
2795				return err;
2796			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
2797					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
2798				return err;
2799			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
2800					       HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
2801				return err;
2802			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
2803					       HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
2804				return err;
2805		} else {
2806			sprintf(name, "%s Playback Volume", chname[i]);
2807			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2808					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2809				return err;
2810			sprintf(name, "%s Playback Switch", chname[i]);
2811			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2812					       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2813				return err;
2814		}
2815	}
2816	return 0;
2817}
2818
2819/* add playback controls for speaker and HP outputs */
2820static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
2821					const char *pfx)
2822{
2823	hda_nid_t nid;
2824	int err;
2825	char name[32];
2826
2827	if (! pin)
2828		return 0;
2829
2830	if (alc880_is_fixed_pin(pin)) {
2831		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
2832		/* specify the DAC as the extra output */
2833		if (! spec->multiout.hp_nid)
2834			spec->multiout.hp_nid = nid;
2835		else
2836			spec->multiout.extra_out_nid[0] = nid;
2837		/* control HP volume/switch on the output mixer amp */
2838		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
2839		sprintf(name, "%s Playback Volume", pfx);
2840		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2841				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2842			return err;
2843		sprintf(name, "%s Playback Switch", pfx);
2844		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2845				       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2846			return err;
2847	} else if (alc880_is_multi_pin(pin)) {
2848		/* set manual connection */
2849		/* we have only a switch on HP-out PIN */
2850		sprintf(name, "%s Playback Switch", pfx);
2851		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2852				       HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
2853			return err;
2854	}
2855	return 0;
2856}
2857
2858/* create input playback/capture controls for the given pin */
2859static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
2860			    int idx, hda_nid_t mix_nid)
2861{
2862	char name[32];
2863	int err;
2864
2865	sprintf(name, "%s Playback Volume", ctlname);
2866	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2867			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2868		return err;
2869	sprintf(name, "%s Playback Switch", ctlname);
2870	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2871			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2872		return err;
2873	return 0;
2874}
2875
2876/* create playback/capture controls for input pins */
2877static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
2878						const struct auto_pin_cfg *cfg)
2879{
2880	struct hda_input_mux *imux = &spec->private_imux;
2881	int i, err, idx;
2882
2883	for (i = 0; i < AUTO_PIN_LAST; i++) {
2884		if (alc880_is_input_pin(cfg->input_pins[i])) {
2885			idx = alc880_input_pin_idx(cfg->input_pins[i]);
2886			err = new_analog_input(spec, cfg->input_pins[i],
2887					       auto_pin_cfg_labels[i],
2888					       idx, 0x0b);
2889			if (err < 0)
2890				return err;
2891			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2892			imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
2893			imux->num_items++;
2894		}
2895	}
2896	return 0;
2897}
2898
2899static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
2900					      hda_nid_t nid, int pin_type,
2901					      int dac_idx)
2902{
2903	/* set as output */
2904	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2905	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2906	/* need the manual connection? */
2907	if (alc880_is_multi_pin(nid)) {
2908		struct alc_spec *spec = codec->spec;
2909		int idx = alc880_multi_pin_idx(nid);
2910		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
2911				    AC_VERB_SET_CONNECT_SEL,
2912				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
2913	}
2914}
2915
2916static void alc880_auto_init_multi_out(struct hda_codec *codec)
2917{
2918	struct alc_spec *spec = codec->spec;
2919	int i;
2920
2921	for (i = 0; i < spec->autocfg.line_outs; i++) {
2922		hda_nid_t nid = spec->autocfg.line_out_pins[i];
2923		alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2924	}
2925}
2926
2927static void alc880_auto_init_extra_out(struct hda_codec *codec)
2928{
2929	struct alc_spec *spec = codec->spec;
2930	hda_nid_t pin;
2931
2932	pin = spec->autocfg.speaker_pins[0];
2933	if (pin) /* connect to front */
2934		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2935	pin = spec->autocfg.hp_pins[0];
2936	if (pin) /* connect to front */
2937		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2938}
2939
2940static void alc880_auto_init_analog_input(struct hda_codec *codec)
2941{
2942	struct alc_spec *spec = codec->spec;
2943	int i;
2944
2945	for (i = 0; i < AUTO_PIN_LAST; i++) {
2946		hda_nid_t nid = spec->autocfg.input_pins[i];
2947		if (alc880_is_input_pin(nid)) {
2948			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2949					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2950			if (nid != ALC880_PIN_CD_NID)
2951				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2952						    AMP_OUT_MUTE);
2953		}
2954	}
2955}
2956
2957/* parse the BIOS configuration and set up the alc_spec */
2958/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2959static int alc880_parse_auto_config(struct hda_codec *codec)
2960{
2961	struct alc_spec *spec = codec->spec;
2962	int err;
2963	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
2964
2965	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
2966						alc880_ignore)) < 0)
2967		return err;
2968	if (! spec->autocfg.line_outs)
2969		return 0; /* can't find valid BIOS pin config */
2970
2971	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
2972	    (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2973	    (err = alc880_auto_create_extra_out(spec,
2974						spec->autocfg.speaker_pins[0],
2975						"Speaker")) < 0 ||
2976	    (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
2977						"Headphone")) < 0 ||
2978	    (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2979		return err;
2980
2981	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2982
2983	if (spec->autocfg.dig_out_pin)
2984		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
2985	if (spec->autocfg.dig_in_pin)
2986		spec->dig_in_nid = ALC880_DIGIN_NID;
2987
2988	if (spec->kctl_alloc)
2989		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2990
2991	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
2992
2993	spec->num_mux_defs = 1;
2994	spec->input_mux = &spec->private_imux;
2995
2996	return 1;
2997}
2998
2999/* additional initialization for auto-configuration model */
3000static void alc880_auto_init(struct hda_codec *codec)
3001{
3002	alc880_auto_init_multi_out(codec);
3003	alc880_auto_init_extra_out(codec);
3004	alc880_auto_init_analog_input(codec);
3005}
3006
3007/*
3008 * OK, here we have finally the patch for ALC880
3009 */
3010
3011static int patch_alc880(struct hda_codec *codec)
3012{
3013	struct alc_spec *spec;
3014	int board_config;
3015	int err;
3016
3017	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3018	if (spec == NULL)
3019		return -ENOMEM;
3020
3021	codec->spec = spec;
3022
3023	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3024						  alc880_models,
3025						  alc880_cfg_tbl);
3026	if (board_config < 0) {
3027		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3028		       "trying auto-probe from BIOS...\n");
3029		board_config = ALC880_AUTO;
3030	}
3031
3032	if (board_config == ALC880_AUTO) {
3033		/* automatic parse from the BIOS config */
3034		err = alc880_parse_auto_config(codec);
3035		if (err < 0) {
3036			alc_free(codec);
3037			return err;
3038		} else if (! err) {
3039			printk(KERN_INFO
3040			       "hda_codec: Cannot set up configuration "
3041			       "from BIOS.  Using 3-stack mode...\n");
3042			board_config = ALC880_3ST;
3043		}
3044	}
3045
3046	if (board_config != ALC880_AUTO)
3047		setup_preset(spec, &alc880_presets[board_config]);
3048
3049	spec->stream_name_analog = "ALC880 Analog";
3050	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3051	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3052
3053	spec->stream_name_digital = "ALC880 Digital";
3054	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3055	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3056
3057	if (! spec->adc_nids && spec->input_mux) {
3058		/* check whether NID 0x07 is valid */
3059		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3060		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
3061		if (wcap != AC_WID_AUD_IN) {
3062			spec->adc_nids = alc880_adc_nids_alt;
3063			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3064			spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
3065			spec->num_mixers++;
3066		} else {
3067			spec->adc_nids = alc880_adc_nids;
3068			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3069			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3070			spec->num_mixers++;
3071		}
3072	}
3073
3074	codec->patch_ops = alc_patch_ops;
3075	if (board_config == ALC880_AUTO)
3076		spec->init_hook = alc880_auto_init;
3077
3078	return 0;
3079}
3080
3081
3082/*
3083 * ALC260 support
3084 */
3085
3086static hda_nid_t alc260_dac_nids[1] = {
3087	/* front */
3088	0x02,
3089};
3090
3091static hda_nid_t alc260_adc_nids[1] = {
3092	/* ADC0 */
3093	0x04,
3094};
3095
3096static hda_nid_t alc260_adc_nids_alt[1] = {
3097	/* ADC1 */
3098	0x05,
3099};
3100
3101static hda_nid_t alc260_hp_adc_nids[2] = {
3102	/* ADC1, 0 */
3103	0x05, 0x04
3104};
3105
3106/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3107 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3108 */
3109static hda_nid_t alc260_dual_adc_nids[2] = {
3110	/* ADC0, ADC1 */
3111	0x04, 0x05
3112};
3113
3114#define ALC260_DIGOUT_NID	0x03
3115#define ALC260_DIGIN_NID	0x06
3116
3117static struct hda_input_mux alc260_capture_source = {
3118	.num_items = 4,
3119	.items = {
3120		{ "Mic", 0x0 },
3121		{ "Front Mic", 0x1 },
3122		{ "Line", 0x2 },
3123		{ "CD", 0x4 },
3124	},
3125};
3126
3127/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3128 * headphone jack and the internal CD lines since these are the only pins at
3129 * which audio can appear.  For flexibility, also allow the option of
3130 * recording the mixer output on the second ADC (ADC0 doesn't have a
3131 * connection to the mixer output).
3132 */
3133static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3134	{
3135		.num_items = 3,
3136		.items = {
3137			{ "Mic/Line", 0x0 },
3138			{ "CD", 0x4 },
3139			{ "Headphone", 0x2 },
3140		},
3141	},
3142	{
3143		.num_items = 4,
3144		.items = {
3145			{ "Mic/Line", 0x0 },
3146			{ "CD", 0x4 },
3147			{ "Headphone", 0x2 },
3148			{ "Mixer", 0x5 },
3149		},
3150	},
3151
3152};
3153
3154/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3155 * the Fujitsu S702x, but jacks are marked differently.
3156 */
3157static struct hda_input_mux alc260_acer_capture_sources[2] = {
3158	{
3159		.num_items = 4,
3160		.items = {
3161			{ "Mic", 0x0 },
3162			{ "Line", 0x2 },
3163			{ "CD", 0x4 },
3164			{ "Headphone", 0x5 },
3165		},
3166	},
3167	{
3168		.num_items = 5,
3169		.items = {
3170			{ "Mic", 0x0 },
3171			{ "Line", 0x2 },
3172			{ "CD", 0x4 },
3173			{ "Headphone", 0x6 },
3174			{ "Mixer", 0x5 },
3175		},
3176	},
3177};
3178/*
3179 * This is just place-holder, so there's something for alc_build_pcms to look
3180 * at when it calculates the maximum number of channels. ALC260 has no mixer
3181 * element which allows changing the channel mode, so the verb list is
3182 * never used.
3183 */
3184static struct hda_channel_mode alc260_modes[1] = {
3185	{ 2, NULL },
3186};
3187
3188
3189/* Mixer combinations
3190 *
3191 * basic: base_output + input + pc_beep + capture
3192 * HP: base_output + input + capture_alt
3193 * HP_3013: hp_3013 + input + capture
3194 * fujitsu: fujitsu + capture
3195 * acer: acer + capture
3196 */
3197
3198static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3199	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3200	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3201	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3202	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3203	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3204	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3205	{ } /* end */
3206};
3207
3208static struct snd_kcontrol_new alc260_input_mixer[] = {
3209	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3210	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3211	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3212	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3213	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3214	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3215	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3216	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3217	{ } /* end */
3218};
3219
3220static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3221	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3222	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3223	{ } /* end */
3224};
3225
3226static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3227	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3228	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3229	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3230	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3231	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3232	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3233	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3234	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3235	{ } /* end */
3236};
3237
3238/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3239 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3240 */
3241static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3242	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3243	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3244	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3245	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3246	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3247	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3248	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3249	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3250	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3251	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3252	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3253	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3254	{ } /* end */
3255};
3256
3257/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3258 * versions of the ALC260 don't act on requests to enable mic bias from NID
3259 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3260 * datasheet doesn't mention this restriction.  At this stage it's not clear
3261 * whether this behaviour is intentional or is a hardware bug in chip
3262 * revisions available in early 2006.  Therefore for now allow the
3263 * "Headphone Jack Mode" control to span all choices, but if it turns out
3264 * that the lack of mic bias for this NID is intentional we could change the
3265 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3266 *
3267 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3268 * don't appear to make the mic bias available from the "line" jack, even
3269 * though the NID used for this jack (0x14) can supply it.  The theory is
3270 * that perhaps Acer have included blocking capacitors between the ALC260
3271 * and the output jack.  If this turns out to be the case for all such
3272 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3273 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3274 */
3275static struct snd_kcontrol_new alc260_acer_mixer[] = {
3276	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3277	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3278	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3279	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3280	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3281	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3282	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3283	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3284	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3285	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3286	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3287	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3288	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3289	{ } /* end */
3290};
3291
3292/* capture mixer elements */
3293static struct snd_kcontrol_new alc260_capture_mixer[] = {
3294	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3295	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3296	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3297	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3298	{
3299		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3300		/* The multiple "Capture Source" controls confuse alsamixer
3301		 * So call somewhat different..
3302		 * FIXME: the controls appear in the "playback" view!
3303		 */
3304		/* .name = "Capture Source", */
3305		.name = "Input Source",
3306		.count = 2,
3307		.info = alc_mux_enum_info,
3308		.get = alc_mux_enum_get,
3309		.put = alc_mux_enum_put,
3310	},
3311	{ } /* end */
3312};
3313
3314static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3315	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3316	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3317	{
3318		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3319		/* The multiple "Capture Source" controls confuse alsamixer
3320		 * So call somewhat different..
3321		 * FIXME: the controls appear in the "playback" view!
3322		 */
3323		/* .name = "Capture Source", */
3324		.name = "Input Source",
3325		.count = 1,
3326		.info = alc_mux_enum_info,
3327		.get = alc_mux_enum_get,
3328		.put = alc_mux_enum_put,
3329	},
3330	{ } /* end */
3331};
3332
3333/*
3334 * initialization verbs
3335 */
3336static struct hda_verb alc260_init_verbs[] = {
3337	/* Line In pin widget for input */
3338	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3339	/* CD pin widget for input */
3340	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3341	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3342	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3343	/* Mic2 (front panel) pin widget for input and vref at 80% */
3344	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3345	/* LINE-2 is used for line-out in rear */
3346	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3347	/* select line-out */
3348	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3349	/* LINE-OUT pin */
3350	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3351	/* enable HP */
3352	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3353	/* enable Mono */
3354	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3355	/* mute capture amp left and right */
3356	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3357	/* set connection select to line in (default select for this ADC) */
3358	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3359	/* mute capture amp left and right */
3360	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3361	/* set connection select to line in (default select for this ADC) */
3362	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3363	/* set vol=0 Line-Out mixer amp left and right */
3364	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3365	/* unmute pin widget amp left and right (no gain on this amp) */
3366	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3367	/* set vol=0 HP mixer amp left and right */
3368	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3369	/* unmute pin widget amp left and right (no gain on this amp) */
3370	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3371	/* set vol=0 Mono mixer amp left and right */
3372	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3373	/* unmute pin widget amp left and right (no gain on this amp) */
3374	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3375	/* unmute LINE-2 out pin */
3376	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3377	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3378	/* mute CD */
3379	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3380	/* mute Line In */
3381	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3382	/* mute Mic */
3383	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3384	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3385	/* mute Front out path */
3386	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3387	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3388	/* mute Headphone out path */
3389	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3390	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3391	/* mute Mono out path */
3392	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3393	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3394	{ }
3395};
3396
3397#if 0 /* should be identical with alc260_init_verbs? */
3398static struct hda_verb alc260_hp_init_verbs[] = {
3399	/* Headphone and output */
3400	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3401	/* mono output */
3402	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3403	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3404	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3405	/* Mic2 (front panel) pin widget for input and vref at 80% */
3406	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3407	/* Line In pin widget for input */
3408	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3409	/* Line-2 pin widget for output */
3410	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3411	/* CD pin widget for input */
3412	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3413	/* unmute amp left and right */
3414	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3415	/* set connection select to line in (default select for this ADC) */
3416	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3417	/* unmute Line-Out mixer amp left and right (volume = 0) */
3418	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3419	/* mute pin widget amp left and right (no gain on this amp) */
3420	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3421	/* unmute HP mixer amp left and right (volume = 0) */
3422	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3423	/* mute pin widget amp left and right (no gain on this amp) */
3424	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3425	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3426	/* unmute CD */
3427	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3428	/* unmute Line In */
3429	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3430	/* unmute Mic */
3431	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3432	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3433	/* Unmute Front out path */
3434	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3435	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3436	/* Unmute Headphone out path */
3437	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3438	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3439	/* Unmute Mono out path */
3440	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3441	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3442	{ }
3443};
3444#endif
3445
3446static struct hda_verb alc260_hp_3013_init_verbs[] = {
3447	/* Line out and output */
3448	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3449	/* mono output */
3450	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3451	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3452	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3453	/* Mic2 (front panel) pin widget for input and vref at 80% */
3454	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3455	/* Line In pin widget for input */
3456	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3457	/* Headphone pin widget for output */
3458	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3459	/* CD pin widget for input */
3460	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3461	/* unmute amp left and right */
3462	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3463	/* set connection select to line in (default select for this ADC) */
3464	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3465	/* unmute Line-Out mixer amp left and right (volume = 0) */
3466	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3467	/* mute pin widget amp left and right (no gain on this amp) */
3468	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3469	/* unmute HP mixer amp left and right (volume = 0) */
3470	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3471	/* mute pin widget amp left and right (no gain on this amp) */
3472	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3473	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3474	/* unmute CD */
3475	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3476	/* unmute Line In */
3477	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3478	/* unmute Mic */
3479	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3480	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3481	/* Unmute Front out path */
3482	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3483	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3484	/* Unmute Headphone out path */
3485	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3486	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3487	/* Unmute Mono out path */
3488	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3489	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3490	{ }
3491};
3492
3493/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3494 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3495 * audio = 0x16, internal speaker = 0x10.
3496 */
3497static struct hda_verb alc260_fujitsu_init_verbs[] = {
3498	/* Disable all GPIOs */
3499	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3500	/* Internal speaker is connected to headphone pin */
3501	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3502	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3503	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3504	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3505	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3506	/* Ensure all other unused pins are disabled and muted. */
3507	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3508	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3509	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3510	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3511	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3512	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3513	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3514	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3515
3516	/* Disable digital (SPDIF) pins */
3517	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3518	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3519
3520	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3521	 * when acting as an output.
3522	 */
3523	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3524
3525	/* Start with output sum widgets muted and their output gains at min */
3526	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3527	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3528	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3529	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3530	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3531	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3532	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3533	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3534	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3535
3536	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3537	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3538	/* Unmute Line1 pin widget output buffer since it starts as an output.
3539	 * If the pin mode is changed by the user the pin mode control will
3540	 * take care of enabling the pin's input/output buffers as needed.
3541	 * Therefore there's no need to enable the input buffer at this
3542	 * stage.
3543	 */
3544	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3545	/* Unmute input buffer of pin widget used for Line-in (no equiv
3546	 * mixer ctrl)
3547	 */
3548	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3549
3550	/* Mute capture amp left and right */
3551	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3552	/* Set ADC connection select to match default mixer setting - line
3553	 * in (on mic1 pin)
3554	 */
3555	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3556
3557	/* Do the same for the second ADC: mute capture input amp and
3558	 * set ADC connection to line in (on mic1 pin)
3559	 */
3560	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3561	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3562
3563	/* Mute all inputs to mixer widget (even unconnected ones) */
3564	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3565	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3566	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3567	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3568	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3569	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3570	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3571	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3572
3573	{ }
3574};
3575
3576/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3577 * similar laptops (adapted from Fujitsu init verbs).
3578 */
3579static struct hda_verb alc260_acer_init_verbs[] = {
3580	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3581	 * the headphone jack.  Turn this on and rely on the standard mute
3582	 * methods whenever the user wants to turn these outputs off.
3583	 */
3584	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3585	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3586	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3587	/* Internal speaker/Headphone jack is connected to Line-out pin */
3588	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3589	/* Internal microphone/Mic jack is connected to Mic1 pin */
3590	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3591	/* Line In jack is connected to Line1 pin */
3592	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3593	/* Ensure all other unused pins are disabled and muted. */
3594	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3595	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3596	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3597	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3598	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3599	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3600	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3601	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3602	/* Disable digital (SPDIF) pins */
3603	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3604	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3605
3606	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3607	 * bus when acting as outputs.
3608	 */
3609	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3610	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3611
3612	/* Start with output sum widgets muted and their output gains at min */
3613	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3614	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3615	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3616	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3617	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3618	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3619	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3620	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3621	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3622
3623	/* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
3624	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3625	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
3626	 * inputs. If the pin mode is changed by the user the pin mode control
3627	 * will take care of enabling the pin's input/output buffers as needed.
3628	 * Therefore there's no need to enable the input buffer at this
3629	 * stage.
3630	 */
3631	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3632	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3633
3634	/* Mute capture amp left and right */
3635	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3636	/* Set ADC connection select to match default mixer setting - mic
3637	 * (on mic1 pin)
3638	 */
3639	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3640
3641	/* Do similar with the second ADC: mute capture input amp and
3642	 * set ADC connection to mic to match ALSA's default state.
3643	 */
3644	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3645	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3646
3647	/* Mute all inputs to mixer widget (even unconnected ones) */
3648	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3649	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3650	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3651	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3652	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3653	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3654	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3655	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3656
3657	{ }
3658};
3659
3660/* Test configuration for debugging, modelled after the ALC880 test
3661 * configuration.
3662 */
3663#ifdef CONFIG_SND_DEBUG
3664static hda_nid_t alc260_test_dac_nids[1] = {
3665	0x02,
3666};
3667static hda_nid_t alc260_test_adc_nids[2] = {
3668	0x04, 0x05,
3669};
3670/* For testing the ALC260, each input MUX needs its own definition since
3671 * the signal assignments are different.  This assumes that the first ADC
3672 * is NID 0x04.
3673 */
3674static struct hda_input_mux alc260_test_capture_sources[2] = {
3675	{
3676		.num_items = 7,
3677		.items = {
3678			{ "MIC1 pin", 0x0 },
3679			{ "MIC2 pin", 0x1 },
3680			{ "LINE1 pin", 0x2 },
3681			{ "LINE2 pin", 0x3 },
3682			{ "CD pin", 0x4 },
3683			{ "LINE-OUT pin", 0x5 },
3684			{ "HP-OUT pin", 0x6 },
3685		},
3686        },
3687	{
3688		.num_items = 8,
3689		.items = {
3690			{ "MIC1 pin", 0x0 },
3691			{ "MIC2 pin", 0x1 },
3692			{ "LINE1 pin", 0x2 },
3693			{ "LINE2 pin", 0x3 },
3694			{ "CD pin", 0x4 },
3695			{ "Mixer", 0x5 },
3696			{ "LINE-OUT pin", 0x6 },
3697			{ "HP-OUT pin", 0x7 },
3698		},
3699        },
3700};
3701static struct snd_kcontrol_new alc260_test_mixer[] = {
3702	/* Output driver widgets */
3703	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3704	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3705	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3706	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
3707	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3708	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
3709
3710	/* Modes for retasking pin widgets
3711	 * Note: the ALC260 doesn't seem to act on requests to enable mic
3712         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
3713         * mention this restriction.  At this stage it's not clear whether
3714         * this behaviour is intentional or is a hardware bug in chip
3715         * revisions available at least up until early 2006.  Therefore for
3716         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
3717         * choices, but if it turns out that the lack of mic bias for these
3718         * NIDs is intentional we could change their modes from
3719         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3720	 */
3721	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
3722	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
3723	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
3724	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
3725	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
3726	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
3727
3728	/* Loopback mixer controls */
3729	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
3730	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
3731	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
3732	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
3733	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
3734	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
3735	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
3736	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
3737	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3738	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3739	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3740	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3741	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
3742	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
3743	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
3744	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
3745
3746	/* Controls for GPIO pins, assuming they are configured as outputs */
3747	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
3748	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
3749	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
3750	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
3751
3752	/* Switches to allow the digital IO pins to be enabled.  The datasheet
3753	 * is ambigious as to which NID is which; testing on laptops which
3754	 * make this output available should provide clarification.
3755	 */
3756	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
3757	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
3758
3759	{ } /* end */
3760};
3761static struct hda_verb alc260_test_init_verbs[] = {
3762	/* Enable all GPIOs as outputs with an initial value of 0 */
3763	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
3764	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
3765	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
3766
3767	/* Enable retasking pins as output, initially without power amp */
3768	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3769	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3770	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3771	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3772	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3773	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3774
3775	/* Disable digital (SPDIF) pins initially, but users can enable
3776	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
3777	 * payload also sets the generation to 0, output to be in "consumer"
3778	 * PCM format, copyright asserted, no pre-emphasis and no validity
3779	 * control.
3780	 */
3781	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3782	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3783
3784	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
3785	 * OUT1 sum bus when acting as an output.
3786	 */
3787	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3788	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
3789	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3790	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
3791
3792	/* Start with output sum widgets muted and their output gains at min */
3793	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3794	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3795	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3796	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3797	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3798	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3799	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3800	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3801	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3802
3803	/* Unmute retasking pin widget output buffers since the default
3804	 * state appears to be output.  As the pin mode is changed by the
3805	 * user the pin mode control will take care of enabling the pin's
3806	 * input/output buffers as needed.
3807	 */
3808	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3809	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3810	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3811	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3813	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3814	/* Also unmute the mono-out pin widget */
3815	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3816
3817	/* Mute capture amp left and right */
3818	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3819	/* Set ADC connection select to match default mixer setting (mic1
3820	 * pin)
3821	 */
3822	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3823
3824	/* Do the same for the second ADC: mute capture input amp and
3825	 * set ADC connection to mic1 pin
3826	 */
3827	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3828	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3829
3830	/* Mute all inputs to mixer widget (even unconnected ones) */
3831	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3832	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3833	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3834	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3835	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3836	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3837	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3838	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3839
3840	{ }
3841};
3842#endif
3843
3844static struct hda_pcm_stream alc260_pcm_analog_playback = {
3845	.substreams = 1,
3846	.channels_min = 2,
3847	.channels_max = 2,
3848};
3849
3850static struct hda_pcm_stream alc260_pcm_analog_capture = {
3851	.substreams = 1,
3852	.channels_min = 2,
3853	.channels_max = 2,
3854};
3855
3856#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
3857#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
3858
3859/*
3860 * for BIOS auto-configuration
3861 */
3862
3863static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
3864					const char *pfx)
3865{
3866	hda_nid_t nid_vol;
3867	unsigned long vol_val, sw_val;
3868	char name[32];
3869	int err;
3870
3871	if (nid >= 0x0f && nid < 0x11) {
3872		nid_vol = nid - 0x7;
3873		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3874		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3875	} else if (nid == 0x11) {
3876		nid_vol = nid - 0x7;
3877		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
3878		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
3879	} else if (nid >= 0x12 && nid <= 0x15) {
3880		nid_vol = 0x08;
3881		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3882		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3883	} else
3884		return 0; /* N/A */
3885
3886	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
3887	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
3888		return err;
3889	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
3890	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
3891		return err;
3892	return 1;
3893}
3894
3895/* add playback controls from the parsed DAC table */
3896static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
3897					     const struct auto_pin_cfg *cfg)
3898{
3899	hda_nid_t nid;
3900	int err;
3901
3902	spec->multiout.num_dacs = 1;
3903	spec->multiout.dac_nids = spec->private_dac_nids;
3904	spec->multiout.dac_nids[0] = 0x02;
3905
3906	nid = cfg->line_out_pins[0];
3907	if (nid) {
3908		err = alc260_add_playback_controls(spec, nid, "Front");
3909		if (err < 0)
3910			return err;
3911	}
3912
3913	nid = cfg->speaker_pins[0];
3914	if (nid) {
3915		err = alc260_add_playback_controls(spec, nid, "Speaker");
3916		if (err < 0)
3917			return err;
3918	}
3919
3920	nid = cfg->hp_pins[0];
3921	if (nid) {
3922		err = alc260_add_playback_controls(spec, nid, "Headphone");
3923		if (err < 0)
3924			return err;
3925	}
3926	return 0;
3927}
3928
3929/* create playback/capture controls for input pins */
3930static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
3931						const struct auto_pin_cfg *cfg)
3932{
3933	struct hda_input_mux *imux = &spec->private_imux;
3934	int i, err, idx;
3935
3936	for (i = 0; i < AUTO_PIN_LAST; i++) {
3937		if (cfg->input_pins[i] >= 0x12) {
3938			idx = cfg->input_pins[i] - 0x12;
3939			err = new_analog_input(spec, cfg->input_pins[i],
3940					       auto_pin_cfg_labels[i], idx, 0x07);
3941			if (err < 0)
3942				return err;
3943			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3944			imux->items[imux->num_items].index = idx;
3945			imux->num_items++;
3946		}
3947		if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
3948			idx = cfg->input_pins[i] - 0x09;
3949			err = new_analog_input(spec, cfg->input_pins[i],
3950					       auto_pin_cfg_labels[i], idx, 0x07);
3951			if (err < 0)
3952				return err;
3953			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3954			imux->items[imux->num_items].index = idx;
3955			imux->num_items++;
3956		}
3957	}
3958	return 0;
3959}
3960
3961static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
3962					      hda_nid_t nid, int pin_type,
3963					      int sel_idx)
3964{
3965	/* set as output */
3966	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
3967	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3968	/* need the manual connection? */
3969	if (nid >= 0x12) {
3970		int idx = nid - 0x12;
3971		snd_hda_codec_write(codec, idx + 0x0b, 0,
3972				    AC_VERB_SET_CONNECT_SEL, sel_idx);
3973
3974	}
3975}
3976
3977static void alc260_auto_init_multi_out(struct hda_codec *codec)
3978{
3979	struct alc_spec *spec = codec->spec;
3980	hda_nid_t nid;
3981
3982	nid = spec->autocfg.line_out_pins[0];
3983	if (nid)
3984		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3985
3986	nid = spec->autocfg.speaker_pins[0];
3987	if (nid)
3988		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3989
3990	nid = spec->autocfg.hp_pins[0];
3991	if (nid)
3992		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3993}
3994
3995#define ALC260_PIN_CD_NID		0x16
3996static void alc260_auto_init_analog_input(struct hda_codec *codec)
3997{
3998	struct alc_spec *spec = codec->spec;
3999	int i;
4000
4001	for (i = 0; i < AUTO_PIN_LAST; i++) {
4002		hda_nid_t nid = spec->autocfg.input_pins[i];
4003		if (nid >= 0x12) {
4004			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4005					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4006			if (nid != ALC260_PIN_CD_NID)
4007				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4008						    AMP_OUT_MUTE);
4009		}
4010	}
4011}
4012
4013/*
4014 * generic initialization of ADC, input mixers and output mixers
4015 */
4016static struct hda_verb alc260_volume_init_verbs[] = {
4017	/*
4018	 * Unmute ADC0-1 and set the default input to mic-in
4019	 */
4020	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4021	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4022	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4023	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4024
4025	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4026	 * mixer widget
4027	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4028	 * mic (mic 2)
4029	 */
4030	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4031	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4032	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4033	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4034	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4035	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4036
4037	/*
4038	 * Set up output mixers (0x08 - 0x0a)
4039	 */
4040	/* set vol=0 to output mixers */
4041	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4042	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4043	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4044	/* set up input amps for analog loopback */
4045	/* Amp Indices: DAC = 0, mixer = 1 */
4046	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4047	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4048	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4049	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4050	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4051	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4052
4053	{ }
4054};
4055
4056static int alc260_parse_auto_config(struct hda_codec *codec)
4057{
4058	struct alc_spec *spec = codec->spec;
4059	unsigned int wcap;
4060	int err;
4061	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4062
4063	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4064						alc260_ignore)) < 0)
4065		return err;
4066	if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
4067		return err;
4068	if (! spec->kctl_alloc)
4069		return 0; /* can't find valid BIOS pin config */
4070	if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
4071		return err;
4072
4073	spec->multiout.max_channels = 2;
4074
4075	if (spec->autocfg.dig_out_pin)
4076		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4077	if (spec->kctl_alloc)
4078		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4079
4080	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4081
4082	spec->num_mux_defs = 1;
4083	spec->input_mux = &spec->private_imux;
4084
4085	/* check whether NID 0x04 is valid */
4086	wcap = get_wcaps(codec, 0x04);
4087	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4088	if (wcap != AC_WID_AUD_IN) {
4089		spec->adc_nids = alc260_adc_nids_alt;
4090		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4091		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4092	} else {
4093		spec->adc_nids = alc260_adc_nids;
4094		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4095		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4096	}
4097	spec->num_mixers++;
4098
4099	return 1;
4100}
4101
4102/* additional initialization for auto-configuration model */
4103static void alc260_auto_init(struct hda_codec *codec)
4104{
4105	alc260_auto_init_multi_out(codec);
4106	alc260_auto_init_analog_input(codec);
4107}
4108
4109/*
4110 * ALC260 configurations
4111 */
4112static const char *alc260_models[ALC260_MODEL_LAST] = {
4113	[ALC260_BASIC]		= "basic",
4114	[ALC260_HP]		= "hp",
4115	[ALC260_HP_3013]	= "hp-3013",
4116	[ALC260_FUJITSU_S702X]	= "fujitsu",
4117	[ALC260_ACER]		= "acer",
4118#ifdef CONFIG_SND_DEBUG
4119	[ALC260_TEST]		= "test",
4120#endif
4121	[ALC260_AUTO]		= "auto",
4122};
4123
4124static struct snd_pci_quirk alc260_cfg_tbl[] = {
4125	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4126	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4127	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4128	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4129	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4130	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4131	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4132	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4133	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4134	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4135	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4136	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4137	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4138	{}
4139};
4140
4141static struct alc_config_preset alc260_presets[] = {
4142	[ALC260_BASIC] = {
4143		.mixers = { alc260_base_output_mixer,
4144			    alc260_input_mixer,
4145			    alc260_pc_beep_mixer,
4146			    alc260_capture_mixer },
4147		.init_verbs = { alc260_init_verbs },
4148		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4149		.dac_nids = alc260_dac_nids,
4150		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4151		.adc_nids = alc260_adc_nids,
4152		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4153		.channel_mode = alc260_modes,
4154		.input_mux = &alc260_capture_source,
4155	},
4156	[ALC260_HP] = {
4157		.mixers = { alc260_base_output_mixer,
4158			    alc260_input_mixer,
4159			    alc260_capture_alt_mixer },
4160		.init_verbs = { alc260_init_verbs },
4161		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4162		.dac_nids = alc260_dac_nids,
4163		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4164		.adc_nids = alc260_hp_adc_nids,
4165		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4166		.channel_mode = alc260_modes,
4167		.input_mux = &alc260_capture_source,
4168	},
4169	[ALC260_HP_3013] = {
4170		.mixers = { alc260_hp_3013_mixer,
4171			    alc260_input_mixer,
4172			    alc260_capture_alt_mixer },
4173		.init_verbs = { alc260_hp_3013_init_verbs },
4174		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4175		.dac_nids = alc260_dac_nids,
4176		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4177		.adc_nids = alc260_hp_adc_nids,
4178		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4179		.channel_mode = alc260_modes,
4180		.input_mux = &alc260_capture_source,
4181	},
4182	[ALC260_FUJITSU_S702X] = {
4183		.mixers = { alc260_fujitsu_mixer,
4184			    alc260_capture_mixer },
4185		.init_verbs = { alc260_fujitsu_init_verbs },
4186		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4187		.dac_nids = alc260_dac_nids,
4188		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4189		.adc_nids = alc260_dual_adc_nids,
4190		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4191		.channel_mode = alc260_modes,
4192		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4193		.input_mux = alc260_fujitsu_capture_sources,
4194	},
4195	[ALC260_ACER] = {
4196		.mixers = { alc260_acer_mixer,
4197			    alc260_capture_mixer },
4198		.init_verbs = { alc260_acer_init_verbs },
4199		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4200		.dac_nids = alc260_dac_nids,
4201		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4202		.adc_nids = alc260_dual_adc_nids,
4203		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4204		.channel_mode = alc260_modes,
4205		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4206		.input_mux = alc260_acer_capture_sources,
4207	},
4208#ifdef CONFIG_SND_DEBUG
4209	[ALC260_TEST] = {
4210		.mixers = { alc260_test_mixer,
4211			    alc260_capture_mixer },
4212		.init_verbs = { alc260_test_init_verbs },
4213		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4214		.dac_nids = alc260_test_dac_nids,
4215		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4216		.adc_nids = alc260_test_adc_nids,
4217		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4218		.channel_mode = alc260_modes,
4219		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4220		.input_mux = alc260_test_capture_sources,
4221	},
4222#endif
4223};
4224
4225static int patch_alc260(struct hda_codec *codec)
4226{
4227	struct alc_spec *spec;
4228	int err, board_config;
4229
4230	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4231	if (spec == NULL)
4232		return -ENOMEM;
4233
4234	codec->spec = spec;
4235
4236	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4237						  alc260_models,
4238						  alc260_cfg_tbl);
4239	if (board_config < 0) {
4240		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4241			   "trying auto-probe from BIOS...\n");
4242		board_config = ALC260_AUTO;
4243	}
4244
4245	if (board_config == ALC260_AUTO) {
4246		/* automatic parse from the BIOS config */
4247		err = alc260_parse_auto_config(codec);
4248		if (err < 0) {
4249			alc_free(codec);
4250			return err;
4251		} else if (! err) {
4252			printk(KERN_INFO
4253			       "hda_codec: Cannot set up configuration "
4254			       "from BIOS.  Using base mode...\n");
4255			board_config = ALC260_BASIC;
4256		}
4257	}
4258
4259	if (board_config != ALC260_AUTO)
4260		setup_preset(spec, &alc260_presets[board_config]);
4261
4262	spec->stream_name_analog = "ALC260 Analog";
4263	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4264	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4265
4266	spec->stream_name_digital = "ALC260 Digital";
4267	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4268	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4269
4270	codec->patch_ops = alc_patch_ops;
4271	if (board_config == ALC260_AUTO)
4272		spec->init_hook = alc260_auto_init;
4273
4274	return 0;
4275}
4276
4277
4278/*
4279 * ALC882 support
4280 *
4281 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4282 * configuration.  Each pin widget can choose any input DACs and a mixer.
4283 * Each ADC is connected from a mixer of all inputs.  This makes possible
4284 * 6-channel independent captures.
4285 *
4286 * In addition, an independent DAC for the multi-playback (not used in this
4287 * driver yet).
4288 */
4289#define ALC882_DIGOUT_NID	0x06
4290#define ALC882_DIGIN_NID	0x0a
4291
4292static struct hda_channel_mode alc882_ch_modes[1] = {
4293	{ 8, NULL }
4294};
4295
4296static hda_nid_t alc882_dac_nids[4] = {
4297	/* front, rear, clfe, rear_surr */
4298	0x02, 0x03, 0x04, 0x05
4299};
4300
4301/* identical with ALC880 */
4302#define alc882_adc_nids		alc880_adc_nids
4303#define alc882_adc_nids_alt	alc880_adc_nids_alt
4304
4305/* input MUX */
4306/* FIXME: should be a matrix-type input source selection */
4307
4308static struct hda_input_mux alc882_capture_source = {
4309	.num_items = 4,
4310	.items = {
4311		{ "Mic", 0x0 },
4312		{ "Front Mic", 0x1 },
4313		{ "Line", 0x2 },
4314		{ "CD", 0x4 },
4315	},
4316};
4317#define alc882_mux_enum_info alc_mux_enum_info
4318#define alc882_mux_enum_get alc_mux_enum_get
4319
4320static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
4321{
4322	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4323	struct alc_spec *spec = codec->spec;
4324	const struct hda_input_mux *imux = spec->input_mux;
4325	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4326	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4327	hda_nid_t nid = capture_mixers[adc_idx];
4328	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4329	unsigned int i, idx;
4330
4331	idx = ucontrol->value.enumerated.item[0];
4332	if (idx >= imux->num_items)
4333		idx = imux->num_items - 1;
4334	if (*cur_val == idx && ! codec->in_resume)
4335		return 0;
4336	for (i = 0; i < imux->num_items; i++) {
4337		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4338		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4339				    v | (imux->items[i].index << 8));
4340	}
4341	*cur_val = idx;
4342	return 1;
4343}
4344
4345/*
4346 * 6ch mode
4347 */
4348static struct hda_verb alc882_sixstack_ch6_init[] = {
4349	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4350	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4351	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4352	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4353	{ } /* end */
4354};
4355
4356/*
4357 * 8ch mode
4358 */
4359static struct hda_verb alc882_sixstack_ch8_init[] = {
4360	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4361	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4362	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4363	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4364	{ } /* end */
4365};
4366
4367static struct hda_channel_mode alc882_sixstack_modes[2] = {
4368	{ 6, alc882_sixstack_ch6_init },
4369	{ 8, alc882_sixstack_ch8_init },
4370};
4371
4372/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4373 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4374 */
4375static struct snd_kcontrol_new alc882_base_mixer[] = {
4376	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4377	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4378	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4379	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4380	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4381	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4382	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4383	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4384	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4385	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4386	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4387	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4388	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4389	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4390	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4391	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4392	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4393	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4394	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4395	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4396	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4397	{ } /* end */
4398};
4399
4400static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4401	{
4402		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4403		.name = "Channel Mode",
4404		.info = alc_ch_mode_info,
4405		.get = alc_ch_mode_get,
4406		.put = alc_ch_mode_put,
4407	},
4408	{ } /* end */
4409};
4410
4411static struct hda_verb alc882_init_verbs[] = {
4412	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4413	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4414	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4415	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4416	/* Rear mixer */
4417	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4418	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4419	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4420	/* CLFE mixer */
4421	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4422	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4423	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4424	/* Side mixer */
4425	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4426	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4427	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4428
4429	/* Front Pin: output 0 (0x0c) */
4430	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4431	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4432	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4433	/* Rear Pin: output 1 (0x0d) */
4434	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4435	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4436	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4437	/* CLFE Pin: output 2 (0x0e) */
4438	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4439	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4440	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4441	/* Side Pin: output 3 (0x0f) */
4442	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4443	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4444	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4445	/* Mic (rear) pin: input vref at 80% */
4446	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4447	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4448	/* Front Mic pin: input vref at 80% */
4449	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4450	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4451	/* Line In pin: input */
4452	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4453	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4454	/* Line-2 In: Headphone output (output 0 - 0x0c) */
4455	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4456	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4457	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4458	/* CD pin widget for input */
4459	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4460
4461	/* FIXME: use matrix-type input source selection */
4462	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4463	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4464	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4465	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4466	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4467	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4468	/* Input mixer2 */
4469	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4470	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4471	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4472	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4473	/* Input mixer3 */
4474	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4475	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4476	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4477	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4478	/* ADC1: mute amp left and right */
4479	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4480	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4481	/* ADC2: mute amp left and right */
4482	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4483	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4484	/* ADC3: mute amp left and right */
4485	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4486	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4487
4488	{ }
4489};
4490
4491static struct hda_verb alc882_eapd_verbs[] = {
4492	/* change to EAPD mode */
4493	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4494	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4495	{ }
4496};
4497
4498/*
4499 * generic initialization of ADC, input mixers and output mixers
4500 */
4501static struct hda_verb alc882_auto_init_verbs[] = {
4502	/*
4503	 * Unmute ADC0-2 and set the default input to mic-in
4504	 */
4505	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4506	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4507	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4508	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4509	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4510	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4511
4512	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4513	 * mixer widget
4514	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4515	 * mic (mic 2)
4516	 */
4517	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4518	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4519	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4520	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4521	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4522	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4523
4524	/*
4525	 * Set up output mixers (0x0c - 0x0f)
4526	 */
4527	/* set vol=0 to output mixers */
4528	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4529	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4530	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4531	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4532	/* set up input amps for analog loopback */
4533	/* Amp Indices: DAC = 0, mixer = 1 */
4534	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4535	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4536	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4537	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4538	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4539	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4540	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4541	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4542	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4543	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4544
4545	/* FIXME: use matrix-type input source selection */
4546	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4547	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4548	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4549	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4550	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4551	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4552	/* Input mixer2 */
4553	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4554	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4555	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4556	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4557	/* Input mixer3 */
4558	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4559	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4560	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4561	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4562
4563	{ }
4564};
4565
4566/* capture mixer elements */
4567static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
4568	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4569	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4570	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
4571	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
4572	{
4573		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4574		/* The multiple "Capture Source" controls confuse alsamixer
4575		 * So call somewhat different..
4576		 * FIXME: the controls appear in the "playback" view!
4577		 */
4578		/* .name = "Capture Source", */
4579		.name = "Input Source",
4580		.count = 2,
4581		.info = alc882_mux_enum_info,
4582		.get = alc882_mux_enum_get,
4583		.put = alc882_mux_enum_put,
4584	},
4585	{ } /* end */
4586};
4587
4588static struct snd_kcontrol_new alc882_capture_mixer[] = {
4589	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
4590	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
4591	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
4592	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
4593	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
4594	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
4595	{
4596		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4597		/* The multiple "Capture Source" controls confuse alsamixer
4598		 * So call somewhat different..
4599		 * FIXME: the controls appear in the "playback" view!
4600		 */
4601		/* .name = "Capture Source", */
4602		.name = "Input Source",
4603		.count = 3,
4604		.info = alc882_mux_enum_info,
4605		.get = alc882_mux_enum_get,
4606		.put = alc882_mux_enum_put,
4607	},
4608	{ } /* end */
4609};
4610
4611/* pcm configuration: identiacal with ALC880 */
4612#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
4613#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
4614#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
4615#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
4616
4617/*
4618 * configuration and preset
4619 */
4620static const char *alc882_models[ALC882_MODEL_LAST] = {
4621	[ALC882_3ST_DIG]	= "3stack-dig",
4622	[ALC882_6ST_DIG]	= "6stack-dig",
4623	[ALC882_ARIMA]		= "arima",
4624	[ALC882_AUTO]		= "auto",
4625};
4626
4627static struct snd_pci_quirk alc882_cfg_tbl[] = {
4628	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
4629	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4630	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
4631	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
4632	{}
4633};
4634
4635static struct alc_config_preset alc882_presets[] = {
4636	[ALC882_3ST_DIG] = {
4637		.mixers = { alc882_base_mixer },
4638		.init_verbs = { alc882_init_verbs },
4639		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4640		.dac_nids = alc882_dac_nids,
4641		.dig_out_nid = ALC882_DIGOUT_NID,
4642		.dig_in_nid = ALC882_DIGIN_NID,
4643		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
4644		.channel_mode = alc882_ch_modes,
4645		.need_dac_fix = 1,
4646		.input_mux = &alc882_capture_source,
4647	},
4648	[ALC882_6ST_DIG] = {
4649		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
4650		.init_verbs = { alc882_init_verbs },
4651		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4652		.dac_nids = alc882_dac_nids,
4653		.dig_out_nid = ALC882_DIGOUT_NID,
4654		.dig_in_nid = ALC882_DIGIN_NID,
4655		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4656		.channel_mode = alc882_sixstack_modes,
4657		.input_mux = &alc882_capture_source,
4658	},
4659	[ALC882_ARIMA] = {
4660		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
4661		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
4662		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4663		.dac_nids = alc882_dac_nids,
4664		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4665		.channel_mode = alc882_sixstack_modes,
4666		.input_mux = &alc882_capture_source,
4667	},
4668};
4669
4670
4671/*
4672 * BIOS auto configuration
4673 */
4674static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
4675					      hda_nid_t nid, int pin_type,
4676					      int dac_idx)
4677{
4678	/* set as output */
4679	struct alc_spec *spec = codec->spec;
4680	int idx;
4681
4682	if (spec->multiout.dac_nids[dac_idx] == 0x25)
4683		idx = 4;
4684	else
4685		idx = spec->multiout.dac_nids[dac_idx] - 2;
4686
4687	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4688	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4689	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
4690
4691}
4692
4693static void alc882_auto_init_multi_out(struct hda_codec *codec)
4694{
4695	struct alc_spec *spec = codec->spec;
4696	int i;
4697
4698	for (i = 0; i <= HDA_SIDE; i++) {
4699		hda_nid_t nid = spec->autocfg.line_out_pins[i];
4700		if (nid)
4701			alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
4702	}
4703}
4704
4705static void alc882_auto_init_hp_out(struct hda_codec *codec)
4706{
4707	struct alc_spec *spec = codec->spec;
4708	hda_nid_t pin;
4709
4710	pin = spec->autocfg.hp_pins[0];
4711	if (pin) /* connect to front */
4712		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
4713}
4714
4715#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
4716#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
4717
4718static void alc882_auto_init_analog_input(struct hda_codec *codec)
4719{
4720	struct alc_spec *spec = codec->spec;
4721	int i;
4722
4723	for (i = 0; i < AUTO_PIN_LAST; i++) {
4724		hda_nid_t nid = spec->autocfg.input_pins[i];
4725		if (alc882_is_input_pin(nid)) {
4726			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4727					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4728			if (nid != ALC882_PIN_CD_NID)
4729				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4730						    AMP_OUT_MUTE);
4731		}
4732	}
4733}
4734
4735/* almost identical with ALC880 parser... */
4736static int alc882_parse_auto_config(struct hda_codec *codec)
4737{
4738	struct alc_spec *spec = codec->spec;
4739	int err = alc880_parse_auto_config(codec);
4740
4741	if (err < 0)
4742		return err;
4743	else if (err > 0)
4744		/* hack - override the init verbs */
4745		spec->init_verbs[0] = alc882_auto_init_verbs;
4746	return err;
4747}
4748
4749/* additional initialization for auto-configuration model */
4750static void alc882_auto_init(struct hda_codec *codec)
4751{
4752	alc882_auto_init_multi_out(codec);
4753	alc882_auto_init_hp_out(codec);
4754	alc882_auto_init_analog_input(codec);
4755}
4756
4757static int patch_alc882(struct hda_codec *codec)
4758{
4759	struct alc_spec *spec;
4760	int err, board_config;
4761
4762	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4763	if (spec == NULL)
4764		return -ENOMEM;
4765
4766	codec->spec = spec;
4767
4768	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
4769						  alc882_models,
4770						  alc882_cfg_tbl);
4771
4772	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
4773		printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
4774		       "trying auto-probe from BIOS...\n");
4775		board_config = ALC882_AUTO;
4776	}
4777
4778	if (board_config == ALC882_AUTO) {
4779		/* automatic parse from the BIOS config */
4780		err = alc882_parse_auto_config(codec);
4781		if (err < 0) {
4782			alc_free(codec);
4783			return err;
4784		} else if (! err) {
4785			printk(KERN_INFO
4786			       "hda_codec: Cannot set up configuration "
4787			       "from BIOS.  Using base mode...\n");
4788			board_config = ALC882_3ST_DIG;
4789		}
4790	}
4791
4792	if (board_config != ALC882_AUTO)
4793		setup_preset(spec, &alc882_presets[board_config]);
4794
4795	spec->stream_name_analog = "ALC882 Analog";
4796	spec->stream_analog_playback = &alc882_pcm_analog_playback;
4797	spec->stream_analog_capture = &alc882_pcm_analog_capture;
4798
4799	spec->stream_name_digital = "ALC882 Digital";
4800	spec->stream_digital_playback = &alc882_pcm_digital_playback;
4801	spec->stream_digital_capture = &alc882_pcm_digital_capture;
4802
4803	if (! spec->adc_nids && spec->input_mux) {
4804		/* check whether NID 0x07 is valid */
4805		unsigned int wcap = get_wcaps(codec, 0x07);
4806		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4807		if (wcap != AC_WID_AUD_IN) {
4808			spec->adc_nids = alc882_adc_nids_alt;
4809			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
4810			spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
4811			spec->num_mixers++;
4812		} else {
4813			spec->adc_nids = alc882_adc_nids;
4814			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
4815			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
4816			spec->num_mixers++;
4817		}
4818	}
4819
4820	codec->patch_ops = alc_patch_ops;
4821	if (board_config == ALC882_AUTO)
4822		spec->init_hook = alc882_auto_init;
4823
4824	return 0;
4825}
4826
4827/*
4828 * ALC883 support
4829 *
4830 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
4831 * configuration.  Each pin widget can choose any input DACs and a mixer.
4832 * Each ADC is connected from a mixer of all inputs.  This makes possible
4833 * 6-channel independent captures.
4834 *
4835 * In addition, an independent DAC for the multi-playback (not used in this
4836 * driver yet).
4837 */
4838#define ALC883_DIGOUT_NID	0x06
4839#define ALC883_DIGIN_NID	0x0a
4840
4841static hda_nid_t alc883_dac_nids[4] = {
4842	/* front, rear, clfe, rear_surr */
4843	0x02, 0x04, 0x03, 0x05
4844};
4845
4846static hda_nid_t alc883_adc_nids[2] = {
4847	/* ADC1-2 */
4848	0x08, 0x09,
4849};
4850/* input MUX */
4851/* FIXME: should be a matrix-type input source selection */
4852
4853static struct hda_input_mux alc883_capture_source = {
4854	.num_items = 4,
4855	.items = {
4856		{ "Mic", 0x0 },
4857		{ "Front Mic", 0x1 },
4858		{ "Line", 0x2 },
4859		{ "CD", 0x4 },
4860	},
4861};
4862#define alc883_mux_enum_info alc_mux_enum_info
4863#define alc883_mux_enum_get alc_mux_enum_get
4864
4865static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
4866			       struct snd_ctl_elem_value *ucontrol)
4867{
4868	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4869	struct alc_spec *spec = codec->spec;
4870	const struct hda_input_mux *imux = spec->input_mux;
4871	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4872	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4873	hda_nid_t nid = capture_mixers[adc_idx];
4874	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4875	unsigned int i, idx;
4876
4877	idx = ucontrol->value.enumerated.item[0];
4878	if (idx >= imux->num_items)
4879		idx = imux->num_items - 1;
4880	if (*cur_val == idx && ! codec->in_resume)
4881		return 0;
4882	for (i = 0; i < imux->num_items; i++) {
4883		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4884		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4885				    v | (imux->items[i].index << 8));
4886	}
4887	*cur_val = idx;
4888	return 1;
4889}
4890/*
4891 * 2ch mode
4892 */
4893static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4894	{ 2, NULL }
4895};
4896
4897/*
4898 * 2ch mode
4899 */
4900static struct hda_verb alc883_3ST_ch2_init[] = {
4901	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4902	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4903	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4904	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4905	{ } /* end */
4906};
4907
4908/*
4909 * 6ch mode
4910 */
4911static struct hda_verb alc883_3ST_ch6_init[] = {
4912	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4913	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4914	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4915	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4916	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4917	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4918	{ } /* end */
4919};
4920
4921static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
4922	{ 2, alc883_3ST_ch2_init },
4923	{ 6, alc883_3ST_ch6_init },
4924};
4925
4926/*
4927 * 6ch mode
4928 */
4929static struct hda_verb alc883_sixstack_ch6_init[] = {
4930	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4931	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4932	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4933	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4934	{ } /* end */
4935};
4936
4937/*
4938 * 8ch mode
4939 */
4940static struct hda_verb alc883_sixstack_ch8_init[] = {
4941	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4942	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4943	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4944	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4945	{ } /* end */
4946};
4947
4948static struct hda_channel_mode alc883_sixstack_modes[2] = {
4949	{ 6, alc883_sixstack_ch6_init },
4950	{ 8, alc883_sixstack_ch8_init },
4951};
4952
4953static struct hda_verb alc883_medion_eapd_verbs[] = {
4954        /* eanable EAPD on medion laptop */
4955	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4956	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
4957	{ }
4958};
4959
4960/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4961 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4962 */
4963
4964static struct snd_kcontrol_new alc883_base_mixer[] = {
4965	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4966	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4967	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4968	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4969	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4970	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4971	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4972	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4973	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4974	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4975	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4976	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4977	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4978	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4979	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4980	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4981	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4982	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4983	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4984	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4985	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4986	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4987	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4988	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
4989	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
4990	{
4991		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4992		/* .name = "Capture Source", */
4993		.name = "Input Source",
4994		.count = 2,
4995		.info = alc883_mux_enum_info,
4996		.get = alc883_mux_enum_get,
4997		.put = alc883_mux_enum_put,
4998	},
4999	{ } /* end */
5000};
5001
5002static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5003	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5004	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5005	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5006	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5007	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5008	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5009	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5010	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5011	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5012	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5013	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5014	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5015	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5016	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5017	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5018	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5019	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5020	{
5021		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5022		/* .name = "Capture Source", */
5023		.name = "Input Source",
5024		.count = 2,
5025		.info = alc883_mux_enum_info,
5026		.get = alc883_mux_enum_get,
5027		.put = alc883_mux_enum_put,
5028	},
5029	{ } /* end */
5030};
5031
5032static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5033	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5034	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5035	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5036	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5037	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5038	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5039	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5040	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5041	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5042	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5043	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5044	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5045	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5046	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5047	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5048	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5049	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5050	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5051	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5052	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5053	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5054	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5055	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5056	{
5057		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5058		/* .name = "Capture Source", */
5059		.name = "Input Source",
5060		.count = 2,
5061		.info = alc883_mux_enum_info,
5062		.get = alc883_mux_enum_get,
5063		.put = alc883_mux_enum_put,
5064	},
5065	{ } /* end */
5066};
5067
5068static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5069	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5070	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5071	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5072	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5073	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5074	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5075	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5076	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5077	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5078	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5079	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5080	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5081	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5082	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5083	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5084	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5085	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5086	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5087	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5088	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5089	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5090
5091	{
5092		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5093		/* .name = "Capture Source", */
5094		.name = "Input Source",
5095		.count = 1,
5096		.info = alc883_mux_enum_info,
5097		.get = alc883_mux_enum_get,
5098		.put = alc883_mux_enum_put,
5099	},
5100	{ } /* end */
5101};
5102
5103static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5104	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5105	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5106	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5107	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5108	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5109	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5110	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5111	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5112	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5113	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5114	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5115	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5116	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5117	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5118	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5119	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5120	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5121	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5122	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5123	{
5124		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5125		/* .name = "Capture Source", */
5126		.name = "Input Source",
5127		.count = 2,
5128		.info = alc883_mux_enum_info,
5129		.get = alc883_mux_enum_get,
5130		.put = alc883_mux_enum_put,
5131	},
5132	{ } /* end */
5133};
5134
5135static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5136	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5137	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5138	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5139	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5140	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5141	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5142	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5143	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5144	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5145	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5146	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5147	{
5148		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5149		/* .name = "Capture Source", */
5150		.name = "Input Source",
5151		.count = 2,
5152		.info = alc883_mux_enum_info,
5153		.get = alc883_mux_enum_get,
5154		.put = alc883_mux_enum_put,
5155	},
5156	{ } /* end */
5157};
5158
5159static struct snd_kcontrol_new alc883_chmode_mixer[] = {
5160	{
5161		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5162		.name = "Channel Mode",
5163		.info = alc_ch_mode_info,
5164		.get = alc_ch_mode_get,
5165		.put = alc_ch_mode_put,
5166	},
5167	{ } /* end */
5168};
5169
5170static struct hda_verb alc883_init_verbs[] = {
5171	/* ADC1: mute amp left and right */
5172	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5173	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5174	/* ADC2: mute amp left and right */
5175	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5176	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5177	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5178	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5179	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5180	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5181	/* Rear mixer */
5182	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5183	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5184	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5185	/* CLFE mixer */
5186	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5187	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5188	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5189	/* Side mixer */
5190	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5191	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5192	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5193
5194	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5195	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5196	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5197	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5198	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5199
5200	/* Front Pin: output 0 (0x0c) */
5201	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5202	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5203	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5204	/* Rear Pin: output 1 (0x0d) */
5205	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5206	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5207	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5208	/* CLFE Pin: output 2 (0x0e) */
5209	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5210	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5211	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5212	/* Side Pin: output 3 (0x0f) */
5213	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5214	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5215	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5216	/* Mic (rear) pin: input vref at 80% */
5217	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5218	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5219	/* Front Mic pin: input vref at 80% */
5220	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5221	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5222	/* Line In pin: input */
5223	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5224	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5225	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5226	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5227	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5228	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5229	/* CD pin widget for input */
5230	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5231
5232	/* FIXME: use matrix-type input source selection */
5233	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5234	/* Input mixer2 */
5235	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5236	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5237	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5238	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5239	/* Input mixer3 */
5240	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5241	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5242	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5243	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5244	{ }
5245};
5246
5247static struct hda_verb alc883_tagra_verbs[] = {
5248	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5249	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5250
5251	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5252	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5253
5254	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5255	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5256	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5257
5258	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5259	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5260	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5261	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5262
5263	{ } /* end */
5264};
5265
5266/* toggle speaker-output according to the hp-jack state */
5267static void alc883_tagra_automute(struct hda_codec *codec)
5268{
5269 	unsigned int present;
5270
5271 	present = snd_hda_codec_read(codec, 0x14, 0,
5272				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5273	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5274				 0x80, present ? 0x80 : 0);
5275	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5276				 0x80, present ? 0x80 : 0);
5277	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5278}
5279
5280static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
5281{
5282	if ((res >> 26) == ALC880_HP_EVENT)
5283		alc883_tagra_automute(codec);
5284}
5285
5286/*
5287 * generic initialization of ADC, input mixers and output mixers
5288 */
5289static struct hda_verb alc883_auto_init_verbs[] = {
5290	/*
5291	 * Unmute ADC0-2 and set the default input to mic-in
5292	 */
5293	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5294	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5295	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5296	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5297
5298	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5299	 * mixer widget
5300	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
5301	 * mic (mic 2)
5302	 */
5303	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5304	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5305	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5306	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5307	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5308	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5309
5310	/*
5311	 * Set up output mixers (0x0c - 0x0f)
5312	 */
5313	/* set vol=0 to output mixers */
5314	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5315	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5316	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5317	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5318	/* set up input amps for analog loopback */
5319	/* Amp Indices: DAC = 0, mixer = 1 */
5320	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5321	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5322	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5323	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5324	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5325	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5326	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5327	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5328	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5329	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5330
5331	/* FIXME: use matrix-type input source selection */
5332	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5333	/* Input mixer1 */
5334	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5335	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5336	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5337	//{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5338	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5339	/* Input mixer2 */
5340	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5341	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5342	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5343	//{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5344	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5345
5346	{ }
5347};
5348
5349/* capture mixer elements */
5350static struct snd_kcontrol_new alc883_capture_mixer[] = {
5351	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5352	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5353	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5354	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5355	{
5356		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5357		/* The multiple "Capture Source" controls confuse alsamixer
5358		 * So call somewhat different..
5359		 * FIXME: the controls appear in the "playback" view!
5360		 */
5361		/* .name = "Capture Source", */
5362		.name = "Input Source",
5363		.count = 2,
5364		.info = alc882_mux_enum_info,
5365		.get = alc882_mux_enum_get,
5366		.put = alc882_mux_enum_put,
5367	},
5368	{ } /* end */
5369};
5370
5371/* pcm configuration: identiacal with ALC880 */
5372#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
5373#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
5374#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
5375#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
5376
5377/*
5378 * configuration and preset
5379 */
5380static const char *alc883_models[ALC883_MODEL_LAST] = {
5381	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
5382	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
5383	[ALC883_3ST_6ch]	= "3stack-6ch",
5384	[ALC883_6ST_DIG]	= "6stack-dig",
5385	[ALC883_TARGA_DIG]	= "targa-dig",
5386	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
5387	[ALC888_DEMO_BOARD]	= "6stack-dig-demo",
5388	[ALC883_ACER]		= "acer",
5389	[ALC883_MEDION]		= "medion",
5390	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
5391	[ALC883_AUTO]		= "auto",
5392};
5393
5394static struct snd_pci_quirk alc883_cfg_tbl[] = {
5395	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
5396	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
5397	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
5398	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
5399	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
5400	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
5401	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
5402	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
5403	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
5404	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
5405	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
5406	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
5407	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
5408	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
5409	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
5410	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
5411	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
5412	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
5413	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
5414	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
5415	{}
5416};
5417
5418static struct alc_config_preset alc883_presets[] = {
5419	[ALC883_3ST_2ch_DIG] = {
5420		.mixers = { alc883_3ST_2ch_mixer },
5421		.init_verbs = { alc883_init_verbs },
5422		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5423		.dac_nids = alc883_dac_nids,
5424		.dig_out_nid = ALC883_DIGOUT_NID,
5425		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5426		.adc_nids = alc883_adc_nids,
5427		.dig_in_nid = ALC883_DIGIN_NID,
5428		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5429		.channel_mode = alc883_3ST_2ch_modes,
5430		.input_mux = &alc883_capture_source,
5431	},
5432	[ALC883_3ST_6ch_DIG] = {
5433		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
5434		.init_verbs = { alc883_init_verbs },
5435		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5436		.dac_nids = alc883_dac_nids,
5437		.dig_out_nid = ALC883_DIGOUT_NID,
5438		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5439		.adc_nids = alc883_adc_nids,
5440		.dig_in_nid = ALC883_DIGIN_NID,
5441		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5442		.channel_mode = alc883_3ST_6ch_modes,
5443		.need_dac_fix = 1,
5444		.input_mux = &alc883_capture_source,
5445	},
5446	[ALC883_3ST_6ch] = {
5447		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
5448		.init_verbs = { alc883_init_verbs },
5449		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5450		.dac_nids = alc883_dac_nids,
5451		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5452		.adc_nids = alc883_adc_nids,
5453		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5454		.channel_mode = alc883_3ST_6ch_modes,
5455		.need_dac_fix = 1,
5456		.input_mux = &alc883_capture_source,
5457	},
5458	[ALC883_6ST_DIG] = {
5459		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
5460		.init_verbs = { alc883_init_verbs },
5461		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5462		.dac_nids = alc883_dac_nids,
5463		.dig_out_nid = ALC883_DIGOUT_NID,
5464		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5465		.adc_nids = alc883_adc_nids,
5466		.dig_in_nid = ALC883_DIGIN_NID,
5467		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5468		.channel_mode = alc883_sixstack_modes,
5469		.input_mux = &alc883_capture_source,
5470	},
5471	[ALC883_TARGA_DIG] = {
5472		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
5473		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5474		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5475		.dac_nids = alc883_dac_nids,
5476		.dig_out_nid = ALC883_DIGOUT_NID,
5477		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5478		.adc_nids = alc883_adc_nids,
5479		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5480		.channel_mode = alc883_3ST_6ch_modes,
5481		.need_dac_fix = 1,
5482		.input_mux = &alc883_capture_source,
5483		.unsol_event = alc883_tagra_unsol_event,
5484		.init_hook = alc883_tagra_automute,
5485	},
5486	[ALC883_TARGA_2ch_DIG] = {
5487		.mixers = { alc883_tagra_2ch_mixer},
5488		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5489		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5490		.dac_nids = alc883_dac_nids,
5491		.dig_out_nid = ALC883_DIGOUT_NID,
5492		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5493		.adc_nids = alc883_adc_nids,
5494		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5495		.channel_mode = alc883_3ST_2ch_modes,
5496		.input_mux = &alc883_capture_source,
5497		.unsol_event = alc883_tagra_unsol_event,
5498		.init_hook = alc883_tagra_automute,
5499	},
5500	[ALC888_DEMO_BOARD] = {
5501		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
5502		.init_verbs = { alc883_init_verbs },
5503		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5504		.dac_nids = alc883_dac_nids,
5505		.dig_out_nid = ALC883_DIGOUT_NID,
5506		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5507		.adc_nids = alc883_adc_nids,
5508		.dig_in_nid = ALC883_DIGIN_NID,
5509		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5510		.channel_mode = alc883_sixstack_modes,
5511		.input_mux = &alc883_capture_source,
5512	},
5513	[ALC883_ACER] = {
5514		.mixers = { alc883_base_mixer,
5515			    alc883_chmode_mixer },
5516		/* On TravelMate laptops, GPIO 0 enables the internal speaker
5517		 * and the headphone jack.  Turn this on and rely on the
5518		 * standard mute methods whenever the user wants to turn
5519		 * these outputs off.
5520		 */
5521		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
5522		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5523		.dac_nids = alc883_dac_nids,
5524		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5525		.adc_nids = alc883_adc_nids,
5526		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5527		.channel_mode = alc883_3ST_2ch_modes,
5528		.input_mux = &alc883_capture_source,
5529	},
5530	[ALC883_MEDION] = {
5531		.mixers = { alc883_fivestack_mixer,
5532			    alc883_chmode_mixer },
5533		.init_verbs = { alc883_init_verbs,
5534				alc883_medion_eapd_verbs },
5535		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5536		.dac_nids = alc883_dac_nids,
5537		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5538		.adc_nids = alc883_adc_nids,
5539		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5540		.channel_mode = alc883_sixstack_modes,
5541		.input_mux = &alc883_capture_source,
5542	},
5543	[ALC883_LAPTOP_EAPD] = {
5544		.mixers = { alc883_base_mixer,
5545			    alc883_chmode_mixer },
5546		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
5547		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5548		.dac_nids = alc883_dac_nids,
5549		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5550		.adc_nids = alc883_adc_nids,
5551		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5552		.channel_mode = alc883_3ST_2ch_modes,
5553		.input_mux = &alc883_capture_source,
5554	},
5555};
5556
5557
5558/*
5559 * BIOS auto configuration
5560 */
5561static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
5562					      hda_nid_t nid, int pin_type,
5563					      int dac_idx)
5564{
5565	/* set as output */
5566	struct alc_spec *spec = codec->spec;
5567	int idx;
5568
5569	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5570		idx = 4;
5571	else
5572		idx = spec->multiout.dac_nids[dac_idx] - 2;
5573
5574	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5575			    pin_type);
5576	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5577			    AMP_OUT_UNMUTE);
5578	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5579
5580}
5581
5582static void alc883_auto_init_multi_out(struct hda_codec *codec)
5583{
5584	struct alc_spec *spec = codec->spec;
5585	int i;
5586
5587	for (i = 0; i <= HDA_SIDE; i++) {
5588		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5589		if (nid)
5590			alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
5591	}
5592}
5593
5594static void alc883_auto_init_hp_out(struct hda_codec *codec)
5595{
5596	struct alc_spec *spec = codec->spec;
5597	hda_nid_t pin;
5598
5599	pin = spec->autocfg.hp_pins[0];
5600	if (pin) /* connect to front */
5601		/* use dac 0 */
5602		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5603}
5604
5605#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
5606#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
5607
5608static void alc883_auto_init_analog_input(struct hda_codec *codec)
5609{
5610	struct alc_spec *spec = codec->spec;
5611	int i;
5612
5613	for (i = 0; i < AUTO_PIN_LAST; i++) {
5614		hda_nid_t nid = spec->autocfg.input_pins[i];
5615		if (alc883_is_input_pin(nid)) {
5616			snd_hda_codec_write(codec, nid, 0,
5617					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5618					    (i <= AUTO_PIN_FRONT_MIC ?
5619					     PIN_VREF80 : PIN_IN));
5620			if (nid != ALC883_PIN_CD_NID)
5621				snd_hda_codec_write(codec, nid, 0,
5622						    AC_VERB_SET_AMP_GAIN_MUTE,
5623						    AMP_OUT_MUTE);
5624		}
5625	}
5626}
5627
5628/* almost identical with ALC880 parser... */
5629static int alc883_parse_auto_config(struct hda_codec *codec)
5630{
5631	struct alc_spec *spec = codec->spec;
5632	int err = alc880_parse_auto_config(codec);
5633
5634	if (err < 0)
5635		return err;
5636	else if (err > 0)
5637		/* hack - override the init verbs */
5638		spec->init_verbs[0] = alc883_auto_init_verbs;
5639                spec->mixers[spec->num_mixers] = alc883_capture_mixer;
5640		spec->num_mixers++;
5641	return err;
5642}
5643
5644/* additional initialization for auto-configuration model */
5645static void alc883_auto_init(struct hda_codec *codec)
5646{
5647	alc883_auto_init_multi_out(codec);
5648	alc883_auto_init_hp_out(codec);
5649	alc883_auto_init_analog_input(codec);
5650}
5651
5652static int patch_alc883(struct hda_codec *codec)
5653{
5654	struct alc_spec *spec;
5655	int err, board_config;
5656
5657	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5658	if (spec == NULL)
5659		return -ENOMEM;
5660
5661	codec->spec = spec;
5662
5663	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
5664						  alc883_models,
5665						  alc883_cfg_tbl);
5666	if (board_config < 0) {
5667		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
5668		       "trying auto-probe from BIOS...\n");
5669		board_config = ALC883_AUTO;
5670	}
5671
5672	if (board_config == ALC883_AUTO) {
5673		/* automatic parse from the BIOS config */
5674		err = alc883_parse_auto_config(codec);
5675		if (err < 0) {
5676			alc_free(codec);
5677			return err;
5678		} else if (! err) {
5679			printk(KERN_INFO
5680			       "hda_codec: Cannot set up configuration "
5681			       "from BIOS.  Using base mode...\n");
5682			board_config = ALC883_3ST_2ch_DIG;
5683		}
5684	}
5685
5686	if (board_config != ALC883_AUTO)
5687		setup_preset(spec, &alc883_presets[board_config]);
5688
5689	spec->stream_name_analog = "ALC883 Analog";
5690	spec->stream_analog_playback = &alc883_pcm_analog_playback;
5691	spec->stream_analog_capture = &alc883_pcm_analog_capture;
5692
5693	spec->stream_name_digital = "ALC883 Digital";
5694	spec->stream_digital_playback = &alc883_pcm_digital_playback;
5695	spec->stream_digital_capture = &alc883_pcm_digital_capture;
5696
5697	if (! spec->adc_nids && spec->input_mux) {
5698		spec->adc_nids = alc883_adc_nids;
5699		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
5700	}
5701
5702	codec->patch_ops = alc_patch_ops;
5703	if (board_config == ALC883_AUTO)
5704		spec->init_hook = alc883_auto_init;
5705
5706	return 0;
5707}
5708
5709/*
5710 * ALC262 support
5711 */
5712
5713#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
5714#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
5715
5716#define alc262_dac_nids		alc260_dac_nids
5717#define alc262_adc_nids		alc882_adc_nids
5718#define alc262_adc_nids_alt	alc882_adc_nids_alt
5719
5720#define alc262_modes		alc260_modes
5721#define alc262_capture_source	alc882_capture_source
5722
5723static struct snd_kcontrol_new alc262_base_mixer[] = {
5724	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5725	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5726	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5727	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5728	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5729	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5730	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5731	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5732	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5733	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5734	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5735	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5736	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
5737	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5738	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5739	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5740	{ } /* end */
5741};
5742
5743static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
5744	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5745	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5746	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5747	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5748	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5749	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5750	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5751	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5752	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5753	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5754	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5755	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5756	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
5757	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5758	{ } /* end */
5759};
5760
5761static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
5762	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5763	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5764	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5765	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5766	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5767
5768	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5769	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5770	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5771	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5772	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5773	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5774	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5775	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5776	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5777	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
5778	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
5779	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
5780	{ } /* end */
5781};
5782
5783#define alc262_capture_mixer		alc882_capture_mixer
5784#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
5785
5786/*
5787 * generic initialization of ADC, input mixers and output mixers
5788 */
5789static struct hda_verb alc262_init_verbs[] = {
5790	/*
5791	 * Unmute ADC0-2 and set the default input to mic-in
5792	 */
5793	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5794	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5795	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5796	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5797	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5798	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5799
5800	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5801	 * mixer widget
5802	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
5803	 * mic (mic 2)
5804	 */
5805	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5806	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5807	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5808	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5809	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5810	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5811
5812	/*
5813	 * Set up output mixers (0x0c - 0x0e)
5814	 */
5815	/* set vol=0 to output mixers */
5816	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5817	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5818	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5819	/* set up input amps for analog loopback */
5820	/* Amp Indices: DAC = 0, mixer = 1 */
5821	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5822	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5823	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5824	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5825	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5826	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5827
5828	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5829	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5830	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5831	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5832	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5833	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5834
5835	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5836	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5837	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5838	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5839	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5840
5841	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5842	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5843
5844	/* FIXME: use matrix-type input source selection */
5845	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5846	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5847	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5848	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5849	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5850	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5851	/* Input mixer2 */
5852	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5853	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5854	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5855	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5856	/* Input mixer3 */
5857	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5858	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5859	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5860	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5861
5862	{ }
5863};
5864
5865static struct hda_verb alc262_hippo_unsol_verbs[] = {
5866	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5867	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5868	{}
5869};
5870
5871static struct hda_verb alc262_hippo1_unsol_verbs[] = {
5872	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5873	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5874	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5875
5876	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5877	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5878	{}
5879};
5880
5881/* mute/unmute internal speaker according to the hp jack and mute state */
5882static void alc262_hippo_automute(struct hda_codec *codec, int force)
5883{
5884	struct alc_spec *spec = codec->spec;
5885	unsigned int mute;
5886
5887	if (force || ! spec->sense_updated) {
5888		unsigned int present;
5889		/* need to execute and sync at first */
5890		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
5891		present = snd_hda_codec_read(codec, 0x15, 0,
5892				    	 AC_VERB_GET_PIN_SENSE, 0);
5893		spec->jack_present = (present & 0x80000000) != 0;
5894		spec->sense_updated = 1;
5895	}
5896	if (spec->jack_present) {
5897		/* mute internal speaker */
5898		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5899					 0x80, 0x80);
5900		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5901					 0x80, 0x80);
5902	} else {
5903		/* unmute internal speaker if necessary */
5904		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
5905		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5906					 0x80, mute & 0x80);
5907		mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
5908		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5909					 0x80, mute & 0x80);
5910	}
5911}
5912
5913/* unsolicited event for HP jack sensing */
5914static void alc262_hippo_unsol_event(struct hda_codec *codec,
5915				       unsigned int res)
5916{
5917	if ((res >> 26) != ALC880_HP_EVENT)
5918		return;
5919	alc262_hippo_automute(codec, 1);
5920}
5921
5922static void alc262_hippo1_automute(struct hda_codec *codec, int force)
5923{
5924	struct alc_spec *spec = codec->spec;
5925	unsigned int mute;
5926
5927	if (force || ! spec->sense_updated) {
5928		unsigned int present;
5929		/* need to execute and sync at first */
5930		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
5931		present = snd_hda_codec_read(codec, 0x1b, 0,
5932				    	 AC_VERB_GET_PIN_SENSE, 0);
5933		spec->jack_present = (present & 0x80000000) != 0;
5934		spec->sense_updated = 1;
5935	}
5936	if (spec->jack_present) {
5937		/* mute internal speaker */
5938		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5939					 0x80, 0x80);
5940		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5941					 0x80, 0x80);
5942	} else {
5943		/* unmute internal speaker if necessary */
5944		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
5945		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5946					 0x80, mute & 0x80);
5947		mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
5948		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5949					 0x80, mute & 0x80);
5950	}
5951}
5952
5953/* unsolicited event for HP jack sensing */
5954static void alc262_hippo1_unsol_event(struct hda_codec *codec,
5955				       unsigned int res)
5956{
5957	if ((res >> 26) != ALC880_HP_EVENT)
5958		return;
5959	alc262_hippo1_automute(codec, 1);
5960}
5961
5962/*
5963 * fujitsu model
5964 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
5965 */
5966
5967#define ALC_HP_EVENT	0x37
5968
5969static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
5970	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
5971	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5972	{}
5973};
5974
5975static struct hda_input_mux alc262_fujitsu_capture_source = {
5976	.num_items = 2,
5977	.items = {
5978		{ "Mic", 0x0 },
5979		{ "CD", 0x4 },
5980	},
5981};
5982
5983static struct hda_input_mux alc262_HP_capture_source = {
5984	.num_items = 5,
5985	.items = {
5986		{ "Mic", 0x0 },
5987		{ "Front Mic", 0x3 },
5988		{ "Line", 0x2 },
5989		{ "CD", 0x4 },
5990		{ "AUX IN", 0x6 },
5991	},
5992};
5993
5994/* mute/unmute internal speaker according to the hp jack and mute state */
5995static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
5996{
5997	struct alc_spec *spec = codec->spec;
5998	unsigned int mute;
5999
6000	if (force || ! spec->sense_updated) {
6001		unsigned int present;
6002		/* need to execute and sync at first */
6003		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
6004		present = snd_hda_codec_read(codec, 0x14, 0,
6005				    	 AC_VERB_GET_PIN_SENSE, 0);
6006		spec->jack_present = (present & 0x80000000) != 0;
6007		spec->sense_updated = 1;
6008	}
6009	if (spec->jack_present) {
6010		/* mute internal speaker */
6011		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6012					 0x80, 0x80);
6013		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6014					 0x80, 0x80);
6015	} else {
6016		/* unmute internal speaker if necessary */
6017		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
6018		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6019					 0x80, mute & 0x80);
6020		mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
6021		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6022					 0x80, mute & 0x80);
6023	}
6024}
6025
6026/* unsolicited event for HP jack sensing */
6027static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
6028				       unsigned int res)
6029{
6030	if ((res >> 26) != ALC_HP_EVENT)
6031		return;
6032	alc262_fujitsu_automute(codec, 1);
6033}
6034
6035/* bind volumes of both NID 0x0c and 0x0d */
6036static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
6037					 struct snd_ctl_elem_value *ucontrol)
6038{
6039	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6040	long *valp = ucontrol->value.integer.value;
6041	int change;
6042
6043	change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
6044					  0x7f, valp[0] & 0x7f);
6045	change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
6046					   0x7f, valp[1] & 0x7f);
6047	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
6048				 0x7f, valp[0] & 0x7f);
6049	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
6050				 0x7f, valp[1] & 0x7f);
6051	return change;
6052}
6053
6054/* bind hp and internal speaker mute (with plug check) */
6055static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
6056					 struct snd_ctl_elem_value *ucontrol)
6057{
6058	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6059	long *valp = ucontrol->value.integer.value;
6060	int change;
6061
6062	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6063					  0x80, valp[0] ? 0 : 0x80);
6064	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6065					   0x80, valp[1] ? 0 : 0x80);
6066	if (change || codec->in_resume)
6067		alc262_fujitsu_automute(codec, codec->in_resume);
6068	return change;
6069}
6070
6071static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
6072	{
6073		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6074		.name = "Master Playback Volume",
6075		.info = snd_hda_mixer_amp_volume_info,
6076		.get = snd_hda_mixer_amp_volume_get,
6077		.put = alc262_fujitsu_master_vol_put,
6078		.tlv = { .c = snd_hda_mixer_amp_tlv },
6079		.private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
6080	},
6081	{
6082		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6083		.name = "Master Playback Switch",
6084		.info = snd_hda_mixer_amp_switch_info,
6085		.get = snd_hda_mixer_amp_switch_get,
6086		.put = alc262_fujitsu_master_sw_put,
6087		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
6088	},
6089	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6090	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6091	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6092	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6093	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6094	{ } /* end */
6095};
6096
6097/* additional init verbs for Benq laptops */
6098static struct hda_verb alc262_EAPD_verbs[] = {
6099	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6100	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
6101	{}
6102};
6103
6104/* add playback controls from the parsed DAC table */
6105static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
6106{
6107	hda_nid_t nid;
6108	int err;
6109
6110	spec->multiout.num_dacs = 1;	/* only use one dac */
6111	spec->multiout.dac_nids = spec->private_dac_nids;
6112	spec->multiout.dac_nids[0] = 2;
6113
6114	nid = cfg->line_out_pins[0];
6115	if (nid) {
6116		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
6117				       HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
6118			return err;
6119		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
6120				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6121			return err;
6122	}
6123
6124	nid = cfg->speaker_pins[0];
6125	if (nid) {
6126		if (nid == 0x16) {
6127			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
6128					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
6129				return err;
6130			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
6131					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
6132				return err;
6133		} else {
6134			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
6135					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6136				return err;
6137		}
6138	}
6139	nid = cfg->hp_pins[0];
6140	if (nid) {
6141		/* spec->multiout.hp_nid = 2; */
6142		if (nid == 0x16) {
6143			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
6144					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
6145				return err;
6146			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
6147					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
6148				return err;
6149		} else {
6150			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
6151					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6152				return err;
6153		}
6154	}
6155	return 0;
6156}
6157
6158/* identical with ALC880 */
6159#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
6160
6161/*
6162 * generic initialization of ADC, input mixers and output mixers
6163 */
6164static struct hda_verb alc262_volume_init_verbs[] = {
6165	/*
6166	 * Unmute ADC0-2 and set the default input to mic-in
6167	 */
6168	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6169	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6170	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6171	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6172	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6173	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6174
6175	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6176	 * mixer widget
6177	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
6178	 * mic (mic 2)
6179	 */
6180	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6181	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6182	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6183	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6184	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6185	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6186
6187	/*
6188	 * Set up output mixers (0x0c - 0x0f)
6189	 */
6190	/* set vol=0 to output mixers */
6191	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6192	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6193	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6194
6195	/* set up input amps for analog loopback */
6196	/* Amp Indices: DAC = 0, mixer = 1 */
6197	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6198	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6199	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6200	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6201	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6202	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6203
6204	/* FIXME: use matrix-type input source selection */
6205	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6206	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6207	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6208	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6209	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6210	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6211	/* Input mixer2 */
6212	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6213	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6214	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6215	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6216	/* Input mixer3 */
6217	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6218	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6219	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6220	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6221
6222	{ }
6223};
6224
6225static struct hda_verb alc262_HP_BPC_init_verbs[] = {
6226	/*
6227	 * Unmute ADC0-2 and set the default input to mic-in
6228	 */
6229	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6230	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6231	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6232	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6233	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6234	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6235
6236	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6237	 * mixer widget
6238	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
6239	 * mic (mic 2)
6240	 */
6241	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6242	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6243	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6244	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6245	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6246	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6247	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
6248        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
6249
6250	/*
6251	 * Set up output mixers (0x0c - 0x0e)
6252	 */
6253	/* set vol=0 to output mixers */
6254	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6255	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6256	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6257
6258	/* set up input amps for analog loopback */
6259	/* Amp Indices: DAC = 0, mixer = 1 */
6260	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6261	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6262	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6263	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6264	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6265	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6266
6267	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6268	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6269	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6270
6271	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6272	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6273
6274	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6275	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6276
6277	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6278	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6279        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6280	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6281	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6282
6283	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
6284	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6285        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6286	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
6287	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6288	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6289
6290
6291	/* FIXME: use matrix-type input source selection */
6292	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6293	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6294	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6295	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6296	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6297	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6298	/* Input mixer2 */
6299	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6300	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6301	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6302	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6303	/* Input mixer3 */
6304	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6305	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6306	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6307	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6308
6309	{ }
6310};
6311
6312/* pcm configuration: identiacal with ALC880 */
6313#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
6314#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
6315#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
6316#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
6317
6318/*
6319 * BIOS auto configuration
6320 */
6321static int alc262_parse_auto_config(struct hda_codec *codec)
6322{
6323	struct alc_spec *spec = codec->spec;
6324	int err;
6325	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
6326
6327	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6328						alc262_ignore)) < 0)
6329		return err;
6330	if (! spec->autocfg.line_outs)
6331		return 0; /* can't find valid BIOS pin config */
6332	if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
6333	    (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
6334		return err;
6335
6336	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6337
6338	if (spec->autocfg.dig_out_pin)
6339		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
6340	if (spec->autocfg.dig_in_pin)
6341		spec->dig_in_nid = ALC262_DIGIN_NID;
6342
6343	if (spec->kctl_alloc)
6344		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
6345
6346	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
6347	spec->num_mux_defs = 1;
6348	spec->input_mux = &spec->private_imux;
6349
6350	return 1;
6351}
6352
6353#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
6354#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
6355#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
6356
6357
6358/* init callback for auto-configuration model -- overriding the default init */
6359static void alc262_auto_init(struct hda_codec *codec)
6360{
6361	alc262_auto_init_multi_out(codec);
6362	alc262_auto_init_hp_out(codec);
6363	alc262_auto_init_analog_input(codec);
6364}
6365
6366/*
6367 * configuration and preset
6368 */
6369static const char *alc262_models[ALC262_MODEL_LAST] = {
6370	[ALC262_BASIC]		= "basic",
6371	[ALC262_HIPPO]		= "hippo",
6372	[ALC262_HIPPO_1]	= "hippo_1",
6373	[ALC262_FUJITSU]	= "fujitsu",
6374	[ALC262_HP_BPC]		= "hp-bpc",
6375	[ALC262_BENQ_ED8]	= "benq",
6376	[ALC262_AUTO]		= "auto",
6377};
6378
6379static struct snd_pci_quirk alc262_cfg_tbl[] = {
6380	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
6381	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
6382	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
6383	SND_PCI_QUIRK(0x103c, 0x2801, "HP q954", ALC262_HP_BPC),
6384	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
6385	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
6386	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
6387	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
6388	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
6389	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
6390	{}
6391};
6392
6393static struct alc_config_preset alc262_presets[] = {
6394	[ALC262_BASIC] = {
6395		.mixers = { alc262_base_mixer },
6396		.init_verbs = { alc262_init_verbs },
6397		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6398		.dac_nids = alc262_dac_nids,
6399		.hp_nid = 0x03,
6400		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6401		.channel_mode = alc262_modes,
6402		.input_mux = &alc262_capture_source,
6403	},
6404	[ALC262_HIPPO] = {
6405		.mixers = { alc262_base_mixer },
6406		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
6407		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6408		.dac_nids = alc262_dac_nids,
6409		.hp_nid = 0x03,
6410		.dig_out_nid = ALC262_DIGOUT_NID,
6411		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6412		.channel_mode = alc262_modes,
6413		.input_mux = &alc262_capture_source,
6414		.unsol_event = alc262_hippo_unsol_event,
6415	},
6416	[ALC262_HIPPO_1] = {
6417		.mixers = { alc262_hippo1_mixer },
6418		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
6419		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6420		.dac_nids = alc262_dac_nids,
6421		.hp_nid = 0x02,
6422		.dig_out_nid = ALC262_DIGOUT_NID,
6423		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6424		.channel_mode = alc262_modes,
6425		.input_mux = &alc262_capture_source,
6426		.unsol_event = alc262_hippo1_unsol_event,
6427	},
6428	[ALC262_FUJITSU] = {
6429		.mixers = { alc262_fujitsu_mixer },
6430		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
6431		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6432		.dac_nids = alc262_dac_nids,
6433		.hp_nid = 0x03,
6434		.dig_out_nid = ALC262_DIGOUT_NID,
6435		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6436		.channel_mode = alc262_modes,
6437		.input_mux = &alc262_fujitsu_capture_source,
6438		.unsol_event = alc262_fujitsu_unsol_event,
6439	},
6440	[ALC262_HP_BPC] = {
6441		.mixers = { alc262_HP_BPC_mixer },
6442		.init_verbs = { alc262_HP_BPC_init_verbs },
6443		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6444		.dac_nids = alc262_dac_nids,
6445		.hp_nid = 0x03,
6446		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6447		.channel_mode = alc262_modes,
6448		.input_mux = &alc262_HP_capture_source,
6449	},
6450	[ALC262_BENQ_ED8] = {
6451		.mixers = { alc262_base_mixer },
6452		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
6453		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6454		.dac_nids = alc262_dac_nids,
6455		.hp_nid = 0x03,
6456		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6457		.channel_mode = alc262_modes,
6458		.input_mux = &alc262_capture_source,
6459	},
6460};
6461
6462static int patch_alc262(struct hda_codec *codec)
6463{
6464	struct alc_spec *spec;
6465	int board_config;
6466	int err;
6467
6468	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
6469	if (spec == NULL)
6470		return -ENOMEM;
6471
6472	codec->spec = spec;
6473#if 0
6474	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
6475	{
6476	int tmp;
6477	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
6478	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
6479	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
6480	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
6481	}
6482#endif
6483
6484	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
6485						  alc262_models,
6486						  alc262_cfg_tbl);
6487
6488	if (board_config < 0) {
6489		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
6490		       "trying auto-probe from BIOS...\n");
6491		board_config = ALC262_AUTO;
6492	}
6493
6494	if (board_config == ALC262_AUTO) {
6495		/* automatic parse from the BIOS config */
6496		err = alc262_parse_auto_config(codec);
6497		if (err < 0) {
6498			alc_free(codec);
6499			return err;
6500		} else if (! err) {
6501			printk(KERN_INFO
6502			       "hda_codec: Cannot set up configuration "
6503			       "from BIOS.  Using base mode...\n");
6504			board_config = ALC262_BASIC;
6505		}
6506	}
6507
6508	if (board_config != ALC262_AUTO)
6509		setup_preset(spec, &alc262_presets[board_config]);
6510
6511	spec->stream_name_analog = "ALC262 Analog";
6512	spec->stream_analog_playback = &alc262_pcm_analog_playback;
6513	spec->stream_analog_capture = &alc262_pcm_analog_capture;
6514
6515	spec->stream_name_digital = "ALC262 Digital";
6516	spec->stream_digital_playback = &alc262_pcm_digital_playback;
6517	spec->stream_digital_capture = &alc262_pcm_digital_capture;
6518
6519	if (! spec->adc_nids && spec->input_mux) {
6520		/* check whether NID 0x07 is valid */
6521		unsigned int wcap = get_wcaps(codec, 0x07);
6522
6523		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
6524		if (wcap != AC_WID_AUD_IN) {
6525			spec->adc_nids = alc262_adc_nids_alt;
6526			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
6527			spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
6528			spec->num_mixers++;
6529		} else {
6530			spec->adc_nids = alc262_adc_nids;
6531			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
6532			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
6533			spec->num_mixers++;
6534		}
6535	}
6536
6537	codec->patch_ops = alc_patch_ops;
6538	if (board_config == ALC262_AUTO)
6539		spec->init_hook = alc262_auto_init;
6540
6541	return 0;
6542}
6543
6544/*
6545 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
6546 */
6547
6548/*
6549 * set the path ways for 2 channel output
6550 * need to set the codec line out and mic 1 pin widgets to inputs
6551 */
6552static struct hda_verb alc861_threestack_ch2_init[] = {
6553	/* set pin widget 1Ah (line in) for input */
6554	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6555	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
6556	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6557
6558	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
6559#if 0
6560	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6561	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
6562#endif
6563	{ } /* end */
6564};
6565/*
6566 * 6ch mode
6567 * need to set the codec line out and mic 1 pin widgets to outputs
6568 */
6569static struct hda_verb alc861_threestack_ch6_init[] = {
6570	/* set pin widget 1Ah (line in) for output (Back Surround)*/
6571	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6572	/* set pin widget 18h (mic1) for output (CLFE)*/
6573	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6574
6575	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
6576	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
6577
6578	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
6579#if 0
6580	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6581	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
6582#endif
6583	{ } /* end */
6584};
6585
6586static struct hda_channel_mode alc861_threestack_modes[2] = {
6587	{ 2, alc861_threestack_ch2_init },
6588	{ 6, alc861_threestack_ch6_init },
6589};
6590/* Set mic1 as input and unmute the mixer */
6591static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
6592	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6593	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6594	{ } /* end */
6595};
6596/* Set mic1 as output and mute mixer */
6597static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
6598	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6599	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6600	{ } /* end */
6601};
6602
6603static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
6604	{ 2, alc861_uniwill_m31_ch2_init },
6605	{ 4, alc861_uniwill_m31_ch4_init },
6606};
6607
6608/* Set mic1 and line-in as input and unmute the mixer */
6609static struct hda_verb alc861_asus_ch2_init[] = {
6610	/* set pin widget 1Ah (line in) for input */
6611	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6612	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
6613	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6614
6615	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
6616#if 0
6617	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6618	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
6619#endif
6620	{ } /* end */
6621};
6622/* Set mic1 nad line-in as output and mute mixer */
6623static struct hda_verb alc861_asus_ch6_init[] = {
6624	/* set pin widget 1Ah (line in) for output (Back Surround)*/
6625	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6626	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6627	/* set pin widget 18h (mic1) for output (CLFE)*/
6628	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6629	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6630	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
6631	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
6632
6633	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
6634#if 0
6635	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6636	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
6637#endif
6638	{ } /* end */
6639};
6640
6641static struct hda_channel_mode alc861_asus_modes[2] = {
6642	{ 2, alc861_asus_ch2_init },
6643	{ 6, alc861_asus_ch6_init },
6644};
6645
6646/* patch-ALC861 */
6647
6648static struct snd_kcontrol_new alc861_base_mixer[] = {
6649        /* output mixer control */
6650	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6651	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6652	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6653	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6654	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
6655
6656        /*Input mixer control */
6657	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6658	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6659	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6660	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6661	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6662	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6663	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6664	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6665	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6666	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6667
6668        /* Capture mixer control */
6669	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6670	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6671	{
6672		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6673		.name = "Capture Source",
6674		.count = 1,
6675		.info = alc_mux_enum_info,
6676		.get = alc_mux_enum_get,
6677		.put = alc_mux_enum_put,
6678	},
6679	{ } /* end */
6680};
6681
6682static struct snd_kcontrol_new alc861_3ST_mixer[] = {
6683        /* output mixer control */
6684	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6685	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6686	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6687	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6688	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
6689
6690	/* Input mixer control */
6691	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6692	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6693	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6694	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6695	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6696	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6697	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6698	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6699	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6700	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6701
6702	/* Capture mixer control */
6703	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6704	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6705	{
6706		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6707		.name = "Capture Source",
6708		.count = 1,
6709		.info = alc_mux_enum_info,
6710		.get = alc_mux_enum_get,
6711		.put = alc_mux_enum_put,
6712	},
6713	{
6714		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6715		.name = "Channel Mode",
6716		.info = alc_ch_mode_info,
6717		.get = alc_ch_mode_get,
6718		.put = alc_ch_mode_put,
6719                .private_value = ARRAY_SIZE(alc861_threestack_modes),
6720	},
6721	{ } /* end */
6722};
6723
6724static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
6725        /* output mixer control */
6726	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6727	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6728	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6729
6730        /*Capture mixer control */
6731	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6732	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6733	{
6734		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6735		.name = "Capture Source",
6736		.count = 1,
6737		.info = alc_mux_enum_info,
6738		.get = alc_mux_enum_get,
6739		.put = alc_mux_enum_put,
6740	},
6741
6742	{ } /* end */
6743};
6744
6745static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
6746        /* output mixer control */
6747	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6748	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6749	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6750	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6751	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
6752
6753	/* Input mixer control */
6754	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6755	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6756	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6757	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6758	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6759	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6760	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6761	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6762	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6763	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6764
6765	/* Capture mixer control */
6766	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6767	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6768	{
6769		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6770		.name = "Capture Source",
6771		.count = 1,
6772		.info = alc_mux_enum_info,
6773		.get = alc_mux_enum_get,
6774		.put = alc_mux_enum_put,
6775	},
6776	{
6777		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6778		.name = "Channel Mode",
6779		.info = alc_ch_mode_info,
6780		.get = alc_ch_mode_get,
6781		.put = alc_ch_mode_put,
6782                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
6783	},
6784	{ } /* end */
6785};
6786
6787static struct snd_kcontrol_new alc861_asus_mixer[] = {
6788        /* output mixer control */
6789	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6790	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6791	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6792	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6793	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
6794
6795	/* Input mixer control */
6796	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6797	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6798	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6799	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6800	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6801	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6802	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6803	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6804	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6805	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */
6806
6807	/* Capture mixer control */
6808	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6809	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6810	{
6811		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6812		.name = "Capture Source",
6813		.count = 1,
6814		.info = alc_mux_enum_info,
6815		.get = alc_mux_enum_get,
6816		.put = alc_mux_enum_put,
6817	},
6818	{
6819		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6820		.name = "Channel Mode",
6821		.info = alc_ch_mode_info,
6822		.get = alc_ch_mode_get,
6823		.put = alc_ch_mode_put,
6824                .private_value = ARRAY_SIZE(alc861_asus_modes),
6825	},
6826	{ }
6827};
6828
6829/* additional mixer */
6830static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
6831	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6832	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6833	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
6834	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
6835	{ }
6836};
6837
6838/*
6839 * generic initialization of ADC, input mixers and output mixers
6840 */
6841static struct hda_verb alc861_base_init_verbs[] = {
6842	/*
6843	 * Unmute ADC0 and set the default input to mic-in
6844	 */
6845	/* port-A for surround (rear panel) */
6846	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6847	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
6848	/* port-B for mic-in (rear panel) with vref */
6849	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6850	/* port-C for line-in (rear panel) */
6851	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6852	/* port-D for Front */
6853	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6854	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
6855	/* port-E for HP out (front panel) */
6856	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6857	/* route front PCM to HP */
6858	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6859	/* port-F for mic-in (front panel) with vref */
6860	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6861	/* port-G for CLFE (rear panel) */
6862	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6863	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6864	/* port-H for side (rear panel) */
6865	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6866	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
6867	/* CD-in */
6868	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6869	/* route front mic to ADC1*/
6870	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6871	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6872
6873	/* Unmute DAC0~3 & spdif out*/
6874	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6875	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6876	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6877	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6878	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6879
6880	/* Unmute Mixer 14 (mic) 1c (Line in)*/
6881	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6882        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6883	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6884        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6885
6886	/* Unmute Stereo Mixer 15 */
6887	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6888	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6889	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6890	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
6891
6892	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6893	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6894	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6895	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6896	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6897	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6898	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6899	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6900	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
6901        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6902
6903	{ }
6904};
6905
6906static struct hda_verb alc861_threestack_init_verbs[] = {
6907	/*
6908	 * Unmute ADC0 and set the default input to mic-in
6909	 */
6910	/* port-A for surround (rear panel) */
6911	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6912	/* port-B for mic-in (rear panel) with vref */
6913	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6914	/* port-C for line-in (rear panel) */
6915	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6916	/* port-D for Front */
6917	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6918	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
6919	/* port-E for HP out (front panel) */
6920	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6921	/* route front PCM to HP */
6922	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6923	/* port-F for mic-in (front panel) with vref */
6924	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6925	/* port-G for CLFE (rear panel) */
6926	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6927	/* port-H for side (rear panel) */
6928	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6929	/* CD-in */
6930	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6931	/* route front mic to ADC1*/
6932	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6933	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6934	/* Unmute DAC0~3 & spdif out*/
6935	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6936	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6937	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6938	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6939	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6940
6941	/* Unmute Mixer 14 (mic) 1c (Line in)*/
6942	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6943        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6944	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6945        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6946
6947	/* Unmute Stereo Mixer 15 */
6948	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6949	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6950	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6951	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
6952
6953	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6954	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6955	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6956	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6957	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6958	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6959	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6960	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6961	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
6962        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6963	{ }
6964};
6965
6966static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
6967	/*
6968	 * Unmute ADC0 and set the default input to mic-in
6969	 */
6970	/* port-A for surround (rear panel) */
6971	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6972	/* port-B for mic-in (rear panel) with vref */
6973	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6974	/* port-C for line-in (rear panel) */
6975	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6976	/* port-D for Front */
6977	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6978	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
6979	/* port-E for HP out (front panel) */
6980	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80
6981	/* route front PCM to HP */
6982	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6983	/* port-F for mic-in (front panel) with vref */
6984	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6985	/* port-G for CLFE (rear panel) */
6986	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6987	/* port-H for side (rear panel) */
6988	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6989	/* CD-in */
6990	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6991	/* route front mic to ADC1*/
6992	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6993	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6994	/* Unmute DAC0~3 & spdif out*/
6995	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6996	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6997	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6998	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6999	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7000
7001	/* Unmute Mixer 14 (mic) 1c (Line in)*/
7002	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7003        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7004	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7005        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7006
7007	/* Unmute Stereo Mixer 15 */
7008	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7009	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7010	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7011	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
7012
7013	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7014	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7015	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7016	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7017	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7018	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7019	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7020	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7021	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
7022        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7023	{ }
7024};
7025
7026static struct hda_verb alc861_asus_init_verbs[] = {
7027	/*
7028	 * Unmute ADC0 and set the default input to mic-in
7029	 */
7030	/* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/
7031	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
7032	/* route front PCM to HP */
7033	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
7034	/* port-B for mic-in (rear panel) with vref */
7035	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7036	/* port-C for line-in (rear panel) */
7037	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7038	/* port-D for Front */
7039	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7040	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
7041	/* port-E for HP out (front panel) */
7042	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */
7043	/* route front PCM to HP */
7044	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7045	/* port-F for mic-in (front panel) with vref */
7046	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7047	/* port-G for CLFE (rear panel) */
7048	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7049	/* port-H for side (rear panel) */
7050	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7051	/* CD-in */
7052	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7053	/* route front mic to ADC1*/
7054	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7055	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7056	/* Unmute DAC0~3 & spdif out*/
7057	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7058	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7059	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7060	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7061	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7062	/* Unmute Mixer 14 (mic) 1c (Line in)*/
7063	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7064        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7065	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7066        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7067
7068	/* Unmute Stereo Mixer 15 */
7069	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7070	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7071	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7072	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, /* Output 0~12 step */
7073
7074	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7075	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7076	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7077	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7078	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7079	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7080	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7081	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7082	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */
7083	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7084	{ }
7085};
7086
7087/* additional init verbs for ASUS laptops */
7088static struct hda_verb alc861_asus_laptop_init_verbs[] = {
7089	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
7090	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
7091	{ }
7092};
7093
7094/*
7095 * generic initialization of ADC, input mixers and output mixers
7096 */
7097static struct hda_verb alc861_auto_init_verbs[] = {
7098	/*
7099	 * Unmute ADC0 and set the default input to mic-in
7100	 */
7101//	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7102	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7103
7104	/* Unmute DAC0~3 & spdif out*/
7105	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7106	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7107	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7108	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7109	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7110
7111	/* Unmute Mixer 14 (mic) 1c (Line in)*/
7112	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7113	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7114	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7115	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7116
7117	/* Unmute Stereo Mixer 15 */
7118	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7119	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7120	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7121	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
7122
7123	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7124	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7125	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7126	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7127	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7128	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7129	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7130	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7131
7132	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7133	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7134	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7135	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7136	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7137	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7138	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7139	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7140
7141	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	// set Mic 1
7142
7143	{ }
7144};
7145
7146static struct hda_verb alc861_toshiba_init_verbs[] = {
7147	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7148
7149	{ }
7150};
7151
7152/* toggle speaker-output according to the hp-jack state */
7153static void alc861_toshiba_automute(struct hda_codec *codec)
7154{
7155	unsigned int present;
7156
7157	present = snd_hda_codec_read(codec, 0x0f, 0,
7158				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7159	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
7160				 0x80, present ? 0x80 : 0);
7161	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
7162				 0x80, present ? 0x80 : 0);
7163	snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
7164				 0x80, present ? 0 : 0x80);
7165	snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
7166				 0x80, present ? 0 : 0x80);
7167}
7168
7169static void alc861_toshiba_unsol_event(struct hda_codec *codec,
7170				       unsigned int res)
7171{
7172	/* Looks like the unsol event is incompatible with the standard
7173	 * definition.  6bit tag is placed at 26 bit!
7174	 */
7175	if ((res >> 26) == ALC880_HP_EVENT)
7176		alc861_toshiba_automute(codec);
7177}
7178
7179/* pcm configuration: identiacal with ALC880 */
7180#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
7181#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
7182#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
7183#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
7184
7185
7186#define ALC861_DIGOUT_NID	0x07
7187
7188static struct hda_channel_mode alc861_8ch_modes[1] = {
7189	{ 8, NULL }
7190};
7191
7192static hda_nid_t alc861_dac_nids[4] = {
7193	/* front, surround, clfe, side */
7194	0x03, 0x06, 0x05, 0x04
7195};
7196
7197static hda_nid_t alc660_dac_nids[3] = {
7198	/* front, clfe, surround */
7199	0x03, 0x05, 0x06
7200};
7201
7202static hda_nid_t alc861_adc_nids[1] = {
7203	/* ADC0-2 */
7204	0x08,
7205};
7206
7207static struct hda_input_mux alc861_capture_source = {
7208	.num_items = 5,
7209	.items = {
7210		{ "Mic", 0x0 },
7211		{ "Front Mic", 0x3 },
7212		{ "Line", 0x1 },
7213		{ "CD", 0x4 },
7214		{ "Mixer", 0x5 },
7215	},
7216};
7217
7218/* fill in the dac_nids table from the parsed pin configuration */
7219static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
7220{
7221	int i;
7222	hda_nid_t nid;
7223
7224	spec->multiout.dac_nids = spec->private_dac_nids;
7225	for (i = 0; i < cfg->line_outs; i++) {
7226		nid = cfg->line_out_pins[i];
7227		if (nid) {
7228			if (i >= ARRAY_SIZE(alc861_dac_nids))
7229				continue;
7230			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
7231		}
7232	}
7233	spec->multiout.num_dacs = cfg->line_outs;
7234	return 0;
7235}
7236
7237/* add playback controls from the parsed DAC table */
7238static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
7239					     const struct auto_pin_cfg *cfg)
7240{
7241	char name[32];
7242	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
7243	hda_nid_t nid;
7244	int i, idx, err;
7245
7246	for (i = 0; i < cfg->line_outs; i++) {
7247		nid = spec->multiout.dac_nids[i];
7248		if (! nid)
7249			continue;
7250		if (nid == 0x05) {
7251			/* Center/LFE */
7252			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
7253					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
7254				return err;
7255			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
7256					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
7257				return err;
7258		} else {
7259			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
7260				if (nid == alc861_dac_nids[idx])
7261					break;
7262			sprintf(name, "%s Playback Switch", chname[idx]);
7263			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
7264					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
7265				return err;
7266		}
7267	}
7268	return 0;
7269}
7270
7271static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
7272{
7273	int err;
7274	hda_nid_t nid;
7275
7276	if (! pin)
7277		return 0;
7278
7279	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
7280		nid = 0x03;
7281		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
7282				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
7283			return err;
7284		spec->multiout.hp_nid = nid;
7285	}
7286	return 0;
7287}
7288
7289/* create playback/capture controls for input pins */
7290static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
7291{
7292	struct hda_input_mux *imux = &spec->private_imux;
7293	int i, err, idx, idx1;
7294
7295	for (i = 0; i < AUTO_PIN_LAST; i++) {
7296		switch(cfg->input_pins[i]) {
7297		case 0x0c:
7298			idx1 = 1;
7299			idx = 2;	// Line In
7300			break;
7301		case 0x0f:
7302			idx1 = 2;
7303			idx = 2;	// Line In
7304			break;
7305		case 0x0d:
7306			idx1 = 0;
7307			idx = 1;	// Mic In
7308			break;
7309		case 0x10:
7310			idx1 = 3;
7311			idx = 1;	// Mic In
7312			break;
7313		case 0x11:
7314			idx1 = 4;
7315			idx = 0;	// CD
7316			break;
7317		default:
7318			continue;
7319		}
7320
7321		err = new_analog_input(spec, cfg->input_pins[i],
7322				       auto_pin_cfg_labels[i], idx, 0x15);
7323		if (err < 0)
7324			return err;
7325
7326		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
7327		imux->items[imux->num_items].index = idx1;
7328		imux->num_items++;
7329	}
7330	return 0;
7331}
7332
7333static struct snd_kcontrol_new alc861_capture_mixer[] = {
7334	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7335	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7336
7337	{
7338		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7339		/* The multiple "Capture Source" controls confuse alsamixer
7340		 * So call somewhat different..
7341		 *FIXME: the controls appear in the "playback" view!
7342		 */
7343		/* .name = "Capture Source", */
7344		.name = "Input Source",
7345		.count = 1,
7346		.info = alc_mux_enum_info,
7347		.get = alc_mux_enum_get,
7348		.put = alc_mux_enum_put,
7349	},
7350	{ } /* end */
7351};
7352
7353static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
7354					      int pin_type, int dac_idx)
7355{
7356	/* set as output */
7357
7358	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
7359	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
7360
7361}
7362
7363static void alc861_auto_init_multi_out(struct hda_codec *codec)
7364{
7365	struct alc_spec *spec = codec->spec;
7366	int i;
7367
7368	for (i = 0; i < spec->autocfg.line_outs; i++) {
7369		hda_nid_t nid = spec->autocfg.line_out_pins[i];
7370		if (nid)
7371			alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
7372	}
7373}
7374
7375static void alc861_auto_init_hp_out(struct hda_codec *codec)
7376{
7377	struct alc_spec *spec = codec->spec;
7378	hda_nid_t pin;
7379
7380	pin = spec->autocfg.hp_pins[0];
7381	if (pin) /* connect to front */
7382		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
7383}
7384
7385static void alc861_auto_init_analog_input(struct hda_codec *codec)
7386{
7387	struct alc_spec *spec = codec->spec;
7388	int i;
7389
7390	for (i = 0; i < AUTO_PIN_LAST; i++) {
7391		hda_nid_t nid = spec->autocfg.input_pins[i];
7392		if ((nid>=0x0c) && (nid <=0x11)) {
7393			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7394					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
7395		}
7396	}
7397}
7398
7399/* parse the BIOS configuration and set up the alc_spec */
7400/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
7401static int alc861_parse_auto_config(struct hda_codec *codec)
7402{
7403	struct alc_spec *spec = codec->spec;
7404	int err;
7405	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
7406
7407	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7408						alc861_ignore)) < 0)
7409		return err;
7410	if (! spec->autocfg.line_outs)
7411		return 0; /* can't find valid BIOS pin config */
7412
7413	if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
7414	    (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
7415	    (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 ||
7416	    (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
7417		return err;
7418
7419	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7420
7421	if (spec->autocfg.dig_out_pin)
7422		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
7423
7424	if (spec->kctl_alloc)
7425		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7426
7427	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
7428
7429	spec->num_mux_defs = 1;
7430	spec->input_mux = &spec->private_imux;
7431
7432	spec->adc_nids = alc861_adc_nids;
7433	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
7434	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
7435	spec->num_mixers++;
7436
7437	return 1;
7438}
7439
7440/* additional initialization for auto-configuration model */
7441static void alc861_auto_init(struct hda_codec *codec)
7442{
7443	alc861_auto_init_multi_out(codec);
7444	alc861_auto_init_hp_out(codec);
7445	alc861_auto_init_analog_input(codec);
7446}
7447
7448
7449/*
7450 * configuration and preset
7451 */
7452static const char *alc861_models[ALC861_MODEL_LAST] = {
7453	[ALC861_3ST]		= "3stack",
7454	[ALC660_3ST]		= "3stack-660",
7455	[ALC861_3ST_DIG]	= "3stack-dig",
7456	[ALC861_6ST_DIG]	= "6stack-dig",
7457	[ALC861_UNIWILL_M31]	= "uniwill-m31",
7458	[ALC861_TOSHIBA]	= "toshiba",
7459	[ALC861_ASUS]		= "asus",
7460	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
7461	[ALC861_AUTO]		= "auto",
7462};
7463
7464static struct snd_pci_quirk alc861_cfg_tbl[] = {
7465	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
7466	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
7467	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
7468	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
7469	SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
7470	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
7471	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
7472	{}
7473};
7474
7475static struct alc_config_preset alc861_presets[] = {
7476	[ALC861_3ST] = {
7477		.mixers = { alc861_3ST_mixer },
7478		.init_verbs = { alc861_threestack_init_verbs },
7479		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7480		.dac_nids = alc861_dac_nids,
7481		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7482		.channel_mode = alc861_threestack_modes,
7483		.need_dac_fix = 1,
7484		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7485		.adc_nids = alc861_adc_nids,
7486		.input_mux = &alc861_capture_source,
7487	},
7488	[ALC861_3ST_DIG] = {
7489		.mixers = { alc861_base_mixer },
7490		.init_verbs = { alc861_threestack_init_verbs },
7491		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7492		.dac_nids = alc861_dac_nids,
7493		.dig_out_nid = ALC861_DIGOUT_NID,
7494		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7495		.channel_mode = alc861_threestack_modes,
7496		.need_dac_fix = 1,
7497		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7498		.adc_nids = alc861_adc_nids,
7499		.input_mux = &alc861_capture_source,
7500	},
7501	[ALC861_6ST_DIG] = {
7502		.mixers = { alc861_base_mixer },
7503		.init_verbs = { alc861_base_init_verbs },
7504		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7505		.dac_nids = alc861_dac_nids,
7506		.dig_out_nid = ALC861_DIGOUT_NID,
7507		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
7508		.channel_mode = alc861_8ch_modes,
7509		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7510		.adc_nids = alc861_adc_nids,
7511		.input_mux = &alc861_capture_source,
7512	},
7513	[ALC660_3ST] = {
7514		.mixers = { alc861_3ST_mixer },
7515		.init_verbs = { alc861_threestack_init_verbs },
7516		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
7517		.dac_nids = alc660_dac_nids,
7518		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7519		.channel_mode = alc861_threestack_modes,
7520		.need_dac_fix = 1,
7521		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7522		.adc_nids = alc861_adc_nids,
7523		.input_mux = &alc861_capture_source,
7524	},
7525	[ALC861_UNIWILL_M31] = {
7526		.mixers = { alc861_uniwill_m31_mixer },
7527		.init_verbs = { alc861_uniwill_m31_init_verbs },
7528		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7529		.dac_nids = alc861_dac_nids,
7530		.dig_out_nid = ALC861_DIGOUT_NID,
7531		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
7532		.channel_mode = alc861_uniwill_m31_modes,
7533		.need_dac_fix = 1,
7534		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7535		.adc_nids = alc861_adc_nids,
7536		.input_mux = &alc861_capture_source,
7537	},
7538	[ALC861_TOSHIBA] = {
7539		.mixers = { alc861_toshiba_mixer },
7540		.init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs },
7541		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7542		.dac_nids = alc861_dac_nids,
7543		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7544		.channel_mode = alc883_3ST_2ch_modes,
7545		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7546		.adc_nids = alc861_adc_nids,
7547		.input_mux = &alc861_capture_source,
7548		.unsol_event = alc861_toshiba_unsol_event,
7549		.init_hook = alc861_toshiba_automute,
7550	},
7551	[ALC861_ASUS] = {
7552		.mixers = { alc861_asus_mixer },
7553		.init_verbs = { alc861_asus_init_verbs },
7554		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7555		.dac_nids = alc861_dac_nids,
7556		.dig_out_nid = ALC861_DIGOUT_NID,
7557		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
7558		.channel_mode = alc861_asus_modes,
7559		.need_dac_fix = 1,
7560		.hp_nid = 0x06,
7561		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7562		.adc_nids = alc861_adc_nids,
7563		.input_mux = &alc861_capture_source,
7564	},
7565	[ALC861_ASUS_LAPTOP] = {
7566		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
7567		.init_verbs = { alc861_asus_init_verbs,
7568				alc861_asus_laptop_init_verbs },
7569		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7570		.dac_nids = alc861_dac_nids,
7571		.dig_out_nid = ALC861_DIGOUT_NID,
7572		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7573		.channel_mode = alc883_3ST_2ch_modes,
7574		.need_dac_fix = 1,
7575		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7576		.adc_nids = alc861_adc_nids,
7577		.input_mux = &alc861_capture_source,
7578	},
7579};
7580
7581
7582static int patch_alc861(struct hda_codec *codec)
7583{
7584	struct alc_spec *spec;
7585	int board_config;
7586	int err;
7587
7588	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
7589	if (spec == NULL)
7590		return -ENOMEM;
7591
7592	codec->spec = spec;
7593
7594        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
7595						  alc861_models,
7596						  alc861_cfg_tbl);
7597
7598	if (board_config < 0) {
7599		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
7600		       "trying auto-probe from BIOS...\n");
7601		board_config = ALC861_AUTO;
7602	}
7603
7604	if (board_config == ALC861_AUTO) {
7605		/* automatic parse from the BIOS config */
7606		err = alc861_parse_auto_config(codec);
7607		if (err < 0) {
7608			alc_free(codec);
7609			return err;
7610		} else if (! err) {
7611			printk(KERN_INFO
7612			       "hda_codec: Cannot set up configuration "
7613			       "from BIOS.  Using base mode...\n");
7614		   board_config = ALC861_3ST_DIG;
7615		}
7616	}
7617
7618	if (board_config != ALC861_AUTO)
7619		setup_preset(spec, &alc861_presets[board_config]);
7620
7621	spec->stream_name_analog = "ALC861 Analog";
7622	spec->stream_analog_playback = &alc861_pcm_analog_playback;
7623	spec->stream_analog_capture = &alc861_pcm_analog_capture;
7624
7625	spec->stream_name_digital = "ALC861 Digital";
7626	spec->stream_digital_playback = &alc861_pcm_digital_playback;
7627	spec->stream_digital_capture = &alc861_pcm_digital_capture;
7628
7629	codec->patch_ops = alc_patch_ops;
7630	if (board_config == ALC861_AUTO)
7631		spec->init_hook = alc861_auto_init;
7632
7633	return 0;
7634}
7635
7636/*
7637 * patch entries
7638 */
7639struct hda_codec_preset snd_hda_preset_realtek[] = {
7640	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
7641	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
7642 	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
7643	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
7644	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
7645	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
7646	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
7647	{ .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861",
7648	  .patch = patch_alc861 },
7649	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
7650	  .patch = patch_alc861 },
7651	{ .id = 0x10ec0660, .name = "ALC660", .patch = patch_alc861 },
7652	{} /* terminator */
7653};
7654