patch_realtek.c revision 56bb0cab1c1698544e61409e3727f2b6bc205501
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 struct hda_board_config alc880_cfg_tbl[] = {
2332	/* Back 3 jack, front 2 jack */
2333	{ .modelname = "3stack", .config = ALC880_3ST },
2334	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
2335	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
2336	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
2337	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
2338	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
2339	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
2340	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
2341	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
2342	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
2343	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
2344	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
2345	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
2346	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
2347	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
2348	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
2349	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
2350	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
2351	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
2352	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe212, .config = ALC880_3ST },
2353	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe213, .config = ALC880_3ST },
2354	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
2355	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe234, .config = ALC880_3ST },
2356	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
2357	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
2358	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
2359	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
2360	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
2361	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
2362	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
2363	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
2364	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
2365	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
2366	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
2367	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
2368	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
2369	/* TCL S700 */
2370	{ .modelname = "tcl", .config = ALC880_TCL_S700 },
2371	{ .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 },
2372
2373	/* Back 3 jack, front 2 jack (Internal add Aux-In) */
2374	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
2375	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST },
2376	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST },
2377
2378	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
2379	{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
2380	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
2381	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG },
2382
2383	/* Clevo laptops */
2384	{ .modelname = "clevo", .config = ALC880_CLEVO },
2385	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x0520,
2386	  .config = ALC880_CLEVO }, /* Clevo m520G NB */
2387	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x0660,
2388	  .config = ALC880_CLEVO }, /* Clevo m665n */
2389
2390	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
2391	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
2392	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
2393	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
2394
2395	/* Back 5 jack, front 2 jack */
2396	{ .modelname = "5stack", .config = ALC880_5ST },
2397	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
2398	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
2399	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
2400	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
2401	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
2402
2403	/* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
2404	{ .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
2405	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
2406	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
2407	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
2408	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
2409	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
2410	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
2411	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
2412	{ .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
2413	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
2414	{ .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560,
2415	  .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */
2416	/* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */
2417	{ .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
2418	/* note subvendor = 0 below */
2419	/* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */
2420
2421	{ .modelname = "w810", .config = ALC880_W810 },
2422	{ .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
2423
2424	{ .modelname = "z71v", .config = ALC880_Z71V },
2425	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
2426
2427	{ .modelname = "6stack", .config = ALC880_6ST },
2428	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */
2429	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST },
2430	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
2431
2432	{ .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
2433	{ .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
2434	{ .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
2435	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
2436	{ .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
2437	{ .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG },
2438	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG },
2439	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG },
2440	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
2441	{ .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
2442	{ .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */
2443	{ .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */
2444	{ .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST_DIG }, /* Gigabyte K8N51 */
2445
2446	{ .modelname = "asus", .config = ALC880_ASUS },
2447	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
2448	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
2449	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
2450	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
2451	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG },
2452	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
2453	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10c2, .config = ALC880_ASUS_DIG }, /* Asus W6A */
2454	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
2455	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
2456	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
2457	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
2458	{ .modelname = "asus-w1v", .config = ALC880_ASUS_W1V },
2459	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
2460	{ .modelname = "asus-dig", .config = ALC880_ASUS_DIG },
2461	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */
2462	{ .modelname = "asus-dig2", .config = ALC880_ASUS_DIG2 },
2463	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
2464
2465	{ .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
2466	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
2467	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9070, .config = ALC880_UNIWILL },
2468	{ .pci_subvendor = 0x1734, .pci_subdevice = 0x10ac, .config = ALC880_UNIWILL },
2469	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9077, .config = ALC880_UNIWILL_P53 },
2470
2471	{ .modelname = "F1734", .config = ALC880_F1734 },
2472	{ .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
2473	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 },
2474
2475	{ .modelname = "lg", .config = ALC880_LG },
2476	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2477	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG },
2478
2479	{ .modelname = "lg-lw", .config = ALC880_LG_LW },
2480	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
2481	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x0077, .config = ALC880_LG_LW },
2482
2483#ifdef CONFIG_SND_DEBUG
2484	{ .modelname = "test", .config = ALC880_TEST },
2485#endif
2486	{ .modelname = "auto", .config = ALC880_AUTO },
2487
2488	{}
2489};
2490
2491/*
2492 * ALC880 codec presets
2493 */
2494static struct alc_config_preset alc880_presets[] = {
2495	[ALC880_3ST] = {
2496		.mixers = { alc880_three_stack_mixer },
2497		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2498		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2499		.dac_nids = alc880_dac_nids,
2500		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2501		.channel_mode = alc880_threestack_modes,
2502		.need_dac_fix = 1,
2503		.input_mux = &alc880_capture_source,
2504	},
2505	[ALC880_3ST_DIG] = {
2506		.mixers = { alc880_three_stack_mixer },
2507		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2508		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2509		.dac_nids = alc880_dac_nids,
2510		.dig_out_nid = ALC880_DIGOUT_NID,
2511		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2512		.channel_mode = alc880_threestack_modes,
2513		.need_dac_fix = 1,
2514		.input_mux = &alc880_capture_source,
2515	},
2516	[ALC880_TCL_S700] = {
2517		.mixers = { alc880_tcl_s700_mixer },
2518		.init_verbs = { alc880_volume_init_verbs,
2519				alc880_pin_tcl_S700_init_verbs,
2520				alc880_gpio2_init_verbs },
2521		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2522		.dac_nids = alc880_dac_nids,
2523		.hp_nid = 0x03,
2524		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2525		.channel_mode = alc880_2_jack_modes,
2526		.input_mux = &alc880_capture_source,
2527	},
2528	[ALC880_5ST] = {
2529		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
2530		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2531		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2532		.dac_nids = alc880_dac_nids,
2533		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2534		.channel_mode = alc880_fivestack_modes,
2535		.input_mux = &alc880_capture_source,
2536	},
2537	[ALC880_5ST_DIG] = {
2538		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
2539		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2540		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2541		.dac_nids = alc880_dac_nids,
2542		.dig_out_nid = ALC880_DIGOUT_NID,
2543		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2544		.channel_mode = alc880_fivestack_modes,
2545		.input_mux = &alc880_capture_source,
2546	},
2547	[ALC880_6ST] = {
2548		.mixers = { alc880_six_stack_mixer },
2549		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2550		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2551		.dac_nids = alc880_6st_dac_nids,
2552		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2553		.channel_mode = alc880_sixstack_modes,
2554		.input_mux = &alc880_6stack_capture_source,
2555	},
2556	[ALC880_6ST_DIG] = {
2557		.mixers = { alc880_six_stack_mixer },
2558		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2559		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2560		.dac_nids = alc880_6st_dac_nids,
2561		.dig_out_nid = ALC880_DIGOUT_NID,
2562		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2563		.channel_mode = alc880_sixstack_modes,
2564		.input_mux = &alc880_6stack_capture_source,
2565	},
2566	[ALC880_W810] = {
2567		.mixers = { alc880_w810_base_mixer },
2568		.init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
2569				alc880_gpio2_init_verbs },
2570		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2571		.dac_nids = alc880_w810_dac_nids,
2572		.dig_out_nid = ALC880_DIGOUT_NID,
2573		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2574		.channel_mode = alc880_w810_modes,
2575		.input_mux = &alc880_capture_source,
2576	},
2577	[ALC880_Z71V] = {
2578		.mixers = { alc880_z71v_mixer },
2579		.init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
2580		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2581		.dac_nids = alc880_z71v_dac_nids,
2582		.dig_out_nid = ALC880_DIGOUT_NID,
2583		.hp_nid = 0x03,
2584		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2585		.channel_mode = alc880_2_jack_modes,
2586		.input_mux = &alc880_capture_source,
2587	},
2588	[ALC880_F1734] = {
2589		.mixers = { alc880_f1734_mixer },
2590		.init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
2591		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2592		.dac_nids = alc880_f1734_dac_nids,
2593		.hp_nid = 0x02,
2594		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2595		.channel_mode = alc880_2_jack_modes,
2596		.input_mux = &alc880_capture_source,
2597	},
2598	[ALC880_ASUS] = {
2599		.mixers = { alc880_asus_mixer },
2600		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2601				alc880_gpio1_init_verbs },
2602		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2603		.dac_nids = alc880_asus_dac_nids,
2604		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2605		.channel_mode = alc880_asus_modes,
2606		.need_dac_fix = 1,
2607		.input_mux = &alc880_capture_source,
2608	},
2609	[ALC880_ASUS_DIG] = {
2610		.mixers = { alc880_asus_mixer },
2611		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2612				alc880_gpio1_init_verbs },
2613		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2614		.dac_nids = alc880_asus_dac_nids,
2615		.dig_out_nid = ALC880_DIGOUT_NID,
2616		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2617		.channel_mode = alc880_asus_modes,
2618		.need_dac_fix = 1,
2619		.input_mux = &alc880_capture_source,
2620	},
2621	[ALC880_ASUS_DIG2] = {
2622		.mixers = { alc880_asus_mixer },
2623		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2624				alc880_gpio2_init_verbs }, /* use GPIO2 */
2625		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2626		.dac_nids = alc880_asus_dac_nids,
2627		.dig_out_nid = ALC880_DIGOUT_NID,
2628		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2629		.channel_mode = alc880_asus_modes,
2630		.need_dac_fix = 1,
2631		.input_mux = &alc880_capture_source,
2632	},
2633	[ALC880_ASUS_W1V] = {
2634		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2635		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2636				alc880_gpio1_init_verbs },
2637		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2638		.dac_nids = alc880_asus_dac_nids,
2639		.dig_out_nid = ALC880_DIGOUT_NID,
2640		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2641		.channel_mode = alc880_asus_modes,
2642		.need_dac_fix = 1,
2643		.input_mux = &alc880_capture_source,
2644	},
2645	[ALC880_UNIWILL_DIG] = {
2646		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2647		.init_verbs = { alc880_volume_init_verbs,
2648				alc880_pin_asus_init_verbs },
2649		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2650		.dac_nids = alc880_asus_dac_nids,
2651		.dig_out_nid = ALC880_DIGOUT_NID,
2652		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2653		.channel_mode = alc880_asus_modes,
2654		.need_dac_fix = 1,
2655		.input_mux = &alc880_capture_source,
2656	},
2657	[ALC880_UNIWILL] = {
2658		.mixers = { alc880_uniwill_mixer },
2659		.init_verbs = { alc880_volume_init_verbs,
2660				alc880_uniwill_init_verbs },
2661		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2662		.dac_nids = alc880_asus_dac_nids,
2663		.dig_out_nid = ALC880_DIGOUT_NID,
2664		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2665		.channel_mode = alc880_threestack_modes,
2666		.need_dac_fix = 1,
2667		.input_mux = &alc880_capture_source,
2668		.unsol_event = alc880_uniwill_unsol_event,
2669		.init_hook = alc880_uniwill_automute,
2670	},
2671	[ALC880_UNIWILL_P53] = {
2672		.mixers = { alc880_uniwill_p53_mixer },
2673		.init_verbs = { alc880_volume_init_verbs,
2674				alc880_uniwill_p53_init_verbs },
2675		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2676		.dac_nids = alc880_asus_dac_nids,
2677		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2678		.channel_mode = alc880_w810_modes,
2679		.input_mux = &alc880_capture_source,
2680		.unsol_event = alc880_uniwill_p53_unsol_event,
2681		.init_hook = alc880_uniwill_p53_hp_automute,
2682	},
2683	[ALC880_CLEVO] = {
2684		.mixers = { alc880_three_stack_mixer },
2685		.init_verbs = { alc880_volume_init_verbs,
2686				alc880_pin_clevo_init_verbs },
2687		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2688		.dac_nids = alc880_dac_nids,
2689		.hp_nid = 0x03,
2690		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2691		.channel_mode = alc880_threestack_modes,
2692		.need_dac_fix = 1,
2693		.input_mux = &alc880_capture_source,
2694	},
2695	[ALC880_LG] = {
2696		.mixers = { alc880_lg_mixer },
2697		.init_verbs = { alc880_volume_init_verbs,
2698				alc880_lg_init_verbs },
2699		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2700		.dac_nids = alc880_lg_dac_nids,
2701		.dig_out_nid = ALC880_DIGOUT_NID,
2702		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2703		.channel_mode = alc880_lg_ch_modes,
2704		.need_dac_fix = 1,
2705		.input_mux = &alc880_lg_capture_source,
2706		.unsol_event = alc880_lg_unsol_event,
2707		.init_hook = alc880_lg_automute,
2708	},
2709	[ALC880_LG_LW] = {
2710		.mixers = { alc880_lg_lw_mixer },
2711		.init_verbs = { alc880_volume_init_verbs,
2712				alc880_lg_lw_init_verbs },
2713		.num_dacs = 1,
2714		.dac_nids = alc880_dac_nids,
2715		.dig_out_nid = ALC880_DIGOUT_NID,
2716		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2717		.channel_mode = alc880_2_jack_modes,
2718		.input_mux = &alc880_lg_lw_capture_source,
2719		.unsol_event = alc880_lg_lw_unsol_event,
2720		.init_hook = alc880_lg_lw_automute,
2721	},
2722#ifdef CONFIG_SND_DEBUG
2723	[ALC880_TEST] = {
2724		.mixers = { alc880_test_mixer },
2725		.init_verbs = { alc880_test_init_verbs },
2726		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2727		.dac_nids = alc880_test_dac_nids,
2728		.dig_out_nid = ALC880_DIGOUT_NID,
2729		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2730		.channel_mode = alc880_test_modes,
2731		.input_mux = &alc880_test_capture_source,
2732	},
2733#endif
2734};
2735
2736/*
2737 * Automatic parse of I/O pins from the BIOS configuration
2738 */
2739
2740#define NUM_CONTROL_ALLOC	32
2741#define NUM_VERB_ALLOC		32
2742
2743enum {
2744	ALC_CTL_WIDGET_VOL,
2745	ALC_CTL_WIDGET_MUTE,
2746	ALC_CTL_BIND_MUTE,
2747};
2748static struct snd_kcontrol_new alc880_control_templates[] = {
2749	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2750	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2751	HDA_BIND_MUTE(NULL, 0, 0, 0),
2752};
2753
2754/* add dynamic controls */
2755static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
2756{
2757	struct snd_kcontrol_new *knew;
2758
2759	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2760		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2761
2762		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2763		if (! knew)
2764			return -ENOMEM;
2765		if (spec->kctl_alloc) {
2766			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2767			kfree(spec->kctl_alloc);
2768		}
2769		spec->kctl_alloc = knew;
2770		spec->num_kctl_alloc = num;
2771	}
2772
2773	knew = &spec->kctl_alloc[spec->num_kctl_used];
2774	*knew = alc880_control_templates[type];
2775	knew->name = kstrdup(name, GFP_KERNEL);
2776	if (! knew->name)
2777		return -ENOMEM;
2778	knew->private_value = val;
2779	spec->num_kctl_used++;
2780	return 0;
2781}
2782
2783#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2784#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2785#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2786#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2787#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2788#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2789#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2790#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2791#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2792#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2793#define ALC880_PIN_CD_NID		0x1c
2794
2795/* fill in the dac_nids table from the parsed pin configuration */
2796static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
2797{
2798	hda_nid_t nid;
2799	int assigned[4];
2800	int i, j;
2801
2802	memset(assigned, 0, sizeof(assigned));
2803	spec->multiout.dac_nids = spec->private_dac_nids;
2804
2805	/* check the pins hardwired to audio widget */
2806	for (i = 0; i < cfg->line_outs; i++) {
2807		nid = cfg->line_out_pins[i];
2808		if (alc880_is_fixed_pin(nid)) {
2809			int idx = alc880_fixed_pin_idx(nid);
2810			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2811			assigned[idx] = 1;
2812		}
2813	}
2814	/* left pins can be connect to any audio widget */
2815	for (i = 0; i < cfg->line_outs; i++) {
2816		nid = cfg->line_out_pins[i];
2817		if (alc880_is_fixed_pin(nid))
2818			continue;
2819		/* search for an empty channel */
2820		for (j = 0; j < cfg->line_outs; j++) {
2821			if (! assigned[j]) {
2822				spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
2823				assigned[j] = 1;
2824				break;
2825			}
2826		}
2827	}
2828	spec->multiout.num_dacs = cfg->line_outs;
2829	return 0;
2830}
2831
2832/* add playback controls from the parsed DAC table */
2833static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
2834					     const struct auto_pin_cfg *cfg)
2835{
2836	char name[32];
2837	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2838	hda_nid_t nid;
2839	int i, err;
2840
2841	for (i = 0; i < cfg->line_outs; i++) {
2842		if (! spec->multiout.dac_nids[i])
2843			continue;
2844		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
2845		if (i == 2) {
2846			/* Center/LFE */
2847			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
2848					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
2849				return err;
2850			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
2851					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
2852				return err;
2853			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
2854					       HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
2855				return err;
2856			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
2857					       HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
2858				return err;
2859		} else {
2860			sprintf(name, "%s Playback Volume", chname[i]);
2861			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2862					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2863				return err;
2864			sprintf(name, "%s Playback Switch", chname[i]);
2865			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2866					       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2867				return err;
2868		}
2869	}
2870	return 0;
2871}
2872
2873/* add playback controls for speaker and HP outputs */
2874static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
2875					const char *pfx)
2876{
2877	hda_nid_t nid;
2878	int err;
2879	char name[32];
2880
2881	if (! pin)
2882		return 0;
2883
2884	if (alc880_is_fixed_pin(pin)) {
2885		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
2886		/* specify the DAC as the extra output */
2887		if (! spec->multiout.hp_nid)
2888			spec->multiout.hp_nid = nid;
2889		else
2890			spec->multiout.extra_out_nid[0] = nid;
2891		/* control HP volume/switch on the output mixer amp */
2892		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
2893		sprintf(name, "%s Playback Volume", pfx);
2894		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2895				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2896			return err;
2897		sprintf(name, "%s Playback Switch", pfx);
2898		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2899				       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2900			return err;
2901	} else if (alc880_is_multi_pin(pin)) {
2902		/* set manual connection */
2903		/* we have only a switch on HP-out PIN */
2904		sprintf(name, "%s Playback Switch", pfx);
2905		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2906				       HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
2907			return err;
2908	}
2909	return 0;
2910}
2911
2912/* create input playback/capture controls for the given pin */
2913static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
2914			    int idx, hda_nid_t mix_nid)
2915{
2916	char name[32];
2917	int err;
2918
2919	sprintf(name, "%s Playback Volume", ctlname);
2920	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2921			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2922		return err;
2923	sprintf(name, "%s Playback Switch", ctlname);
2924	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2925			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2926		return err;
2927	return 0;
2928}
2929
2930/* create playback/capture controls for input pins */
2931static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
2932						const struct auto_pin_cfg *cfg)
2933{
2934	struct hda_input_mux *imux = &spec->private_imux;
2935	int i, err, idx;
2936
2937	for (i = 0; i < AUTO_PIN_LAST; i++) {
2938		if (alc880_is_input_pin(cfg->input_pins[i])) {
2939			idx = alc880_input_pin_idx(cfg->input_pins[i]);
2940			err = new_analog_input(spec, cfg->input_pins[i],
2941					       auto_pin_cfg_labels[i],
2942					       idx, 0x0b);
2943			if (err < 0)
2944				return err;
2945			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2946			imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
2947			imux->num_items++;
2948		}
2949	}
2950	return 0;
2951}
2952
2953static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
2954					      hda_nid_t nid, int pin_type,
2955					      int dac_idx)
2956{
2957	/* set as output */
2958	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2959	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2960	/* need the manual connection? */
2961	if (alc880_is_multi_pin(nid)) {
2962		struct alc_spec *spec = codec->spec;
2963		int idx = alc880_multi_pin_idx(nid);
2964		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
2965				    AC_VERB_SET_CONNECT_SEL,
2966				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
2967	}
2968}
2969
2970static void alc880_auto_init_multi_out(struct hda_codec *codec)
2971{
2972	struct alc_spec *spec = codec->spec;
2973	int i;
2974
2975	for (i = 0; i < spec->autocfg.line_outs; i++) {
2976		hda_nid_t nid = spec->autocfg.line_out_pins[i];
2977		alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2978	}
2979}
2980
2981static void alc880_auto_init_extra_out(struct hda_codec *codec)
2982{
2983	struct alc_spec *spec = codec->spec;
2984	hda_nid_t pin;
2985
2986	pin = spec->autocfg.speaker_pins[0];
2987	if (pin) /* connect to front */
2988		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2989	pin = spec->autocfg.hp_pins[0];
2990	if (pin) /* connect to front */
2991		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2992}
2993
2994static void alc880_auto_init_analog_input(struct hda_codec *codec)
2995{
2996	struct alc_spec *spec = codec->spec;
2997	int i;
2998
2999	for (i = 0; i < AUTO_PIN_LAST; i++) {
3000		hda_nid_t nid = spec->autocfg.input_pins[i];
3001		if (alc880_is_input_pin(nid)) {
3002			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3003					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
3004			if (nid != ALC880_PIN_CD_NID)
3005				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3006						    AMP_OUT_MUTE);
3007		}
3008	}
3009}
3010
3011/* parse the BIOS configuration and set up the alc_spec */
3012/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
3013static int alc880_parse_auto_config(struct hda_codec *codec)
3014{
3015	struct alc_spec *spec = codec->spec;
3016	int err;
3017	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3018
3019	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3020						alc880_ignore)) < 0)
3021		return err;
3022	if (! spec->autocfg.line_outs)
3023		return 0; /* can't find valid BIOS pin config */
3024
3025	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
3026	    (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3027	    (err = alc880_auto_create_extra_out(spec,
3028						spec->autocfg.speaker_pins[0],
3029						"Speaker")) < 0 ||
3030	    (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3031						"Headphone")) < 0 ||
3032	    (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
3033		return err;
3034
3035	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3036
3037	if (spec->autocfg.dig_out_pin)
3038		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3039	if (spec->autocfg.dig_in_pin)
3040		spec->dig_in_nid = ALC880_DIGIN_NID;
3041
3042	if (spec->kctl_alloc)
3043		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3044
3045	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3046
3047	spec->num_mux_defs = 1;
3048	spec->input_mux = &spec->private_imux;
3049
3050	return 1;
3051}
3052
3053/* additional initialization for auto-configuration model */
3054static void alc880_auto_init(struct hda_codec *codec)
3055{
3056	alc880_auto_init_multi_out(codec);
3057	alc880_auto_init_extra_out(codec);
3058	alc880_auto_init_analog_input(codec);
3059}
3060
3061/*
3062 * OK, here we have finally the patch for ALC880
3063 */
3064
3065static int patch_alc880(struct hda_codec *codec)
3066{
3067	struct alc_spec *spec;
3068	int board_config;
3069	int err;
3070
3071	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3072	if (spec == NULL)
3073		return -ENOMEM;
3074
3075	codec->spec = spec;
3076
3077	board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
3078	if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {
3079		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3080		       "trying auto-probe from BIOS...\n");
3081		board_config = ALC880_AUTO;
3082	}
3083
3084	if (board_config == ALC880_AUTO) {
3085		/* automatic parse from the BIOS config */
3086		err = alc880_parse_auto_config(codec);
3087		if (err < 0) {
3088			alc_free(codec);
3089			return err;
3090		} else if (! err) {
3091			printk(KERN_INFO
3092			       "hda_codec: Cannot set up configuration "
3093			       "from BIOS.  Using 3-stack mode...\n");
3094			board_config = ALC880_3ST;
3095		}
3096	}
3097
3098	if (board_config != ALC880_AUTO)
3099		setup_preset(spec, &alc880_presets[board_config]);
3100
3101	spec->stream_name_analog = "ALC880 Analog";
3102	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3103	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3104
3105	spec->stream_name_digital = "ALC880 Digital";
3106	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3107	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3108
3109	if (! spec->adc_nids && spec->input_mux) {
3110		/* check whether NID 0x07 is valid */
3111		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3112		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
3113		if (wcap != AC_WID_AUD_IN) {
3114			spec->adc_nids = alc880_adc_nids_alt;
3115			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3116			spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
3117			spec->num_mixers++;
3118		} else {
3119			spec->adc_nids = alc880_adc_nids;
3120			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3121			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3122			spec->num_mixers++;
3123		}
3124	}
3125
3126	codec->patch_ops = alc_patch_ops;
3127	if (board_config == ALC880_AUTO)
3128		spec->init_hook = alc880_auto_init;
3129
3130	return 0;
3131}
3132
3133
3134/*
3135 * ALC260 support
3136 */
3137
3138static hda_nid_t alc260_dac_nids[1] = {
3139	/* front */
3140	0x02,
3141};
3142
3143static hda_nid_t alc260_adc_nids[1] = {
3144	/* ADC0 */
3145	0x04,
3146};
3147
3148static hda_nid_t alc260_adc_nids_alt[1] = {
3149	/* ADC1 */
3150	0x05,
3151};
3152
3153static hda_nid_t alc260_hp_adc_nids[2] = {
3154	/* ADC1, 0 */
3155	0x05, 0x04
3156};
3157
3158/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3159 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3160 */
3161static hda_nid_t alc260_dual_adc_nids[2] = {
3162	/* ADC0, ADC1 */
3163	0x04, 0x05
3164};
3165
3166#define ALC260_DIGOUT_NID	0x03
3167#define ALC260_DIGIN_NID	0x06
3168
3169static struct hda_input_mux alc260_capture_source = {
3170	.num_items = 4,
3171	.items = {
3172		{ "Mic", 0x0 },
3173		{ "Front Mic", 0x1 },
3174		{ "Line", 0x2 },
3175		{ "CD", 0x4 },
3176	},
3177};
3178
3179/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3180 * headphone jack and the internal CD lines since these are the only pins at
3181 * which audio can appear.  For flexibility, also allow the option of
3182 * recording the mixer output on the second ADC (ADC0 doesn't have a
3183 * connection to the mixer output).
3184 */
3185static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3186	{
3187		.num_items = 3,
3188		.items = {
3189			{ "Mic/Line", 0x0 },
3190			{ "CD", 0x4 },
3191			{ "Headphone", 0x2 },
3192		},
3193	},
3194	{
3195		.num_items = 4,
3196		.items = {
3197			{ "Mic/Line", 0x0 },
3198			{ "CD", 0x4 },
3199			{ "Headphone", 0x2 },
3200			{ "Mixer", 0x5 },
3201		},
3202	},
3203
3204};
3205
3206/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3207 * the Fujitsu S702x, but jacks are marked differently.
3208 */
3209static struct hda_input_mux alc260_acer_capture_sources[2] = {
3210	{
3211		.num_items = 4,
3212		.items = {
3213			{ "Mic", 0x0 },
3214			{ "Line", 0x2 },
3215			{ "CD", 0x4 },
3216			{ "Headphone", 0x5 },
3217		},
3218	},
3219	{
3220		.num_items = 5,
3221		.items = {
3222			{ "Mic", 0x0 },
3223			{ "Line", 0x2 },
3224			{ "CD", 0x4 },
3225			{ "Headphone", 0x6 },
3226			{ "Mixer", 0x5 },
3227		},
3228	},
3229};
3230/*
3231 * This is just place-holder, so there's something for alc_build_pcms to look
3232 * at when it calculates the maximum number of channels. ALC260 has no mixer
3233 * element which allows changing the channel mode, so the verb list is
3234 * never used.
3235 */
3236static struct hda_channel_mode alc260_modes[1] = {
3237	{ 2, NULL },
3238};
3239
3240
3241/* Mixer combinations
3242 *
3243 * basic: base_output + input + pc_beep + capture
3244 * HP: base_output + input + capture_alt
3245 * HP_3013: hp_3013 + input + capture
3246 * fujitsu: fujitsu + capture
3247 * acer: acer + capture
3248 */
3249
3250static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3251	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3252	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3253	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3254	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3255	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3256	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3257	{ } /* end */
3258};
3259
3260static struct snd_kcontrol_new alc260_input_mixer[] = {
3261	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3262	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3263	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3264	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3265	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3266	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3267	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3268	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3269	{ } /* end */
3270};
3271
3272static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3273	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3274	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3275	{ } /* end */
3276};
3277
3278static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3279	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3280	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3281	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3282	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3283	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3284	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3285	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3286	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3287	{ } /* end */
3288};
3289
3290/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3291 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3292 */
3293static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3294	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3295	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3296	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3297	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3298	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3299	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3300	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3301	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3302	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3303	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3304	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3305	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3306	{ } /* end */
3307};
3308
3309/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3310 * versions of the ALC260 don't act on requests to enable mic bias from NID
3311 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3312 * datasheet doesn't mention this restriction.  At this stage it's not clear
3313 * whether this behaviour is intentional or is a hardware bug in chip
3314 * revisions available in early 2006.  Therefore for now allow the
3315 * "Headphone Jack Mode" control to span all choices, but if it turns out
3316 * that the lack of mic bias for this NID is intentional we could change the
3317 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3318 *
3319 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3320 * don't appear to make the mic bias available from the "line" jack, even
3321 * though the NID used for this jack (0x14) can supply it.  The theory is
3322 * that perhaps Acer have included blocking capacitors between the ALC260
3323 * and the output jack.  If this turns out to be the case for all such
3324 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3325 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3326 */
3327static struct snd_kcontrol_new alc260_acer_mixer[] = {
3328	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3329	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3330	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3331	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3332	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3333	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3334	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3335	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3336	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3337	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3338	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3339	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3340	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3341	{ } /* end */
3342};
3343
3344/* capture mixer elements */
3345static struct snd_kcontrol_new alc260_capture_mixer[] = {
3346	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3347	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3348	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3349	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3350	{
3351		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3352		/* The multiple "Capture Source" controls confuse alsamixer
3353		 * So call somewhat different..
3354		 * FIXME: the controls appear in the "playback" view!
3355		 */
3356		/* .name = "Capture Source", */
3357		.name = "Input Source",
3358		.count = 2,
3359		.info = alc_mux_enum_info,
3360		.get = alc_mux_enum_get,
3361		.put = alc_mux_enum_put,
3362	},
3363	{ } /* end */
3364};
3365
3366static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3367	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3368	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3369	{
3370		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3371		/* The multiple "Capture Source" controls confuse alsamixer
3372		 * So call somewhat different..
3373		 * FIXME: the controls appear in the "playback" view!
3374		 */
3375		/* .name = "Capture Source", */
3376		.name = "Input Source",
3377		.count = 1,
3378		.info = alc_mux_enum_info,
3379		.get = alc_mux_enum_get,
3380		.put = alc_mux_enum_put,
3381	},
3382	{ } /* end */
3383};
3384
3385/*
3386 * initialization verbs
3387 */
3388static struct hda_verb alc260_init_verbs[] = {
3389	/* Line In pin widget for input */
3390	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3391	/* CD pin widget for input */
3392	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3393	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3394	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3395	/* Mic2 (front panel) pin widget for input and vref at 80% */
3396	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3397	/* LINE-2 is used for line-out in rear */
3398	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3399	/* select line-out */
3400	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3401	/* LINE-OUT pin */
3402	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3403	/* enable HP */
3404	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3405	/* enable Mono */
3406	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3407	/* mute capture amp left and right */
3408	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3409	/* set connection select to line in (default select for this ADC) */
3410	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3411	/* mute capture amp left and right */
3412	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3413	/* set connection select to line in (default select for this ADC) */
3414	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3415	/* set vol=0 Line-Out mixer amp left and right */
3416	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3417	/* unmute pin widget amp left and right (no gain on this amp) */
3418	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3419	/* set vol=0 HP mixer amp left and right */
3420	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3421	/* unmute pin widget amp left and right (no gain on this amp) */
3422	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3423	/* set vol=0 Mono mixer amp left and right */
3424	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3425	/* unmute pin widget amp left and right (no gain on this amp) */
3426	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3427	/* unmute LINE-2 out pin */
3428	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3429	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3430	/* mute CD */
3431	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3432	/* mute Line In */
3433	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3434	/* mute Mic */
3435	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3436	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3437	/* mute Front out path */
3438	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3439	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3440	/* mute Headphone out path */
3441	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3442	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3443	/* mute Mono out path */
3444	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3445	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3446	{ }
3447};
3448
3449#if 0 /* should be identical with alc260_init_verbs? */
3450static struct hda_verb alc260_hp_init_verbs[] = {
3451	/* Headphone and output */
3452	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3453	/* mono output */
3454	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3455	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3456	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3457	/* Mic2 (front panel) pin widget for input and vref at 80% */
3458	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3459	/* Line In pin widget for input */
3460	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3461	/* Line-2 pin widget for output */
3462	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3463	/* CD pin widget for input */
3464	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3465	/* unmute amp left and right */
3466	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3467	/* set connection select to line in (default select for this ADC) */
3468	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3469	/* unmute Line-Out mixer amp left and right (volume = 0) */
3470	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3471	/* mute pin widget amp left and right (no gain on this amp) */
3472	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3473	/* unmute HP mixer amp left and right (volume = 0) */
3474	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3475	/* mute pin widget amp left and right (no gain on this amp) */
3476	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3477	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3478	/* unmute CD */
3479	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3480	/* unmute Line In */
3481	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3482	/* unmute Mic */
3483	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3484	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3485	/* Unmute Front out path */
3486	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3487	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3488	/* Unmute Headphone out path */
3489	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3490	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3491	/* Unmute Mono out path */
3492	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3493	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3494	{ }
3495};
3496#endif
3497
3498static struct hda_verb alc260_hp_3013_init_verbs[] = {
3499	/* Line out and output */
3500	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3501	/* mono output */
3502	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3503	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3504	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3505	/* Mic2 (front panel) pin widget for input and vref at 80% */
3506	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3507	/* Line In pin widget for input */
3508	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3509	/* Headphone pin widget for output */
3510	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3511	/* CD pin widget for input */
3512	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3513	/* unmute amp left and right */
3514	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3515	/* set connection select to line in (default select for this ADC) */
3516	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3517	/* unmute Line-Out mixer amp left and right (volume = 0) */
3518	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3519	/* mute pin widget amp left and right (no gain on this amp) */
3520	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3521	/* unmute HP mixer amp left and right (volume = 0) */
3522	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3523	/* mute pin widget amp left and right (no gain on this amp) */
3524	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3525	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3526	/* unmute CD */
3527	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3528	/* unmute Line In */
3529	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3530	/* unmute Mic */
3531	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3532	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3533	/* Unmute Front out path */
3534	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3535	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3536	/* Unmute Headphone out path */
3537	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3538	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3539	/* Unmute Mono out path */
3540	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3541	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3542	{ }
3543};
3544
3545/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3546 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3547 * audio = 0x16, internal speaker = 0x10.
3548 */
3549static struct hda_verb alc260_fujitsu_init_verbs[] = {
3550	/* Disable all GPIOs */
3551	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3552	/* Internal speaker is connected to headphone pin */
3553	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3554	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3555	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3556	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3557	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3558	/* Ensure all other unused pins are disabled and muted. */
3559	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3560	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3561	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3562	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3563	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3564	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3565	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3566	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3567
3568	/* Disable digital (SPDIF) pins */
3569	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3570	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3571
3572	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3573	 * when acting as an output.
3574	 */
3575	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3576
3577	/* Start with output sum widgets muted and their output gains at min */
3578	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3579	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3580	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3581	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3582	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3583	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3584	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3585	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3586	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3587
3588	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3589	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3590	/* Unmute Line1 pin widget output buffer since it starts as an output.
3591	 * If the pin mode is changed by the user the pin mode control will
3592	 * take care of enabling the pin's input/output buffers as needed.
3593	 * Therefore there's no need to enable the input buffer at this
3594	 * stage.
3595	 */
3596	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3597	/* Unmute input buffer of pin widget used for Line-in (no equiv
3598	 * mixer ctrl)
3599	 */
3600	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3601
3602	/* Mute capture amp left and right */
3603	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3604	/* Set ADC connection select to match default mixer setting - line
3605	 * in (on mic1 pin)
3606	 */
3607	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3608
3609	/* Do the same for the second ADC: mute capture input amp and
3610	 * set ADC connection to line in (on mic1 pin)
3611	 */
3612	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3613	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3614
3615	/* Mute all inputs to mixer widget (even unconnected ones) */
3616	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3617	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3618	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3619	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3620	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3621	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3622	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3623	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3624
3625	{ }
3626};
3627
3628/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3629 * similar laptops (adapted from Fujitsu init verbs).
3630 */
3631static struct hda_verb alc260_acer_init_verbs[] = {
3632	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3633	 * the headphone jack.  Turn this on and rely on the standard mute
3634	 * methods whenever the user wants to turn these outputs off.
3635	 */
3636	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3637	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3638	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3639	/* Internal speaker/Headphone jack is connected to Line-out pin */
3640	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3641	/* Internal microphone/Mic jack is connected to Mic1 pin */
3642	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3643	/* Line In jack is connected to Line1 pin */
3644	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3645	/* Ensure all other unused pins are disabled and muted. */
3646	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3647	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3648	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3649	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3650	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3651	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3652	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3653	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3654	/* Disable digital (SPDIF) pins */
3655	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3656	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3657
3658	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3659	 * bus when acting as outputs.
3660	 */
3661	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3662	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3663
3664	/* Start with output sum widgets muted and their output gains at min */
3665	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3666	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3667	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3668	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3669	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3670	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3671	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3672	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3673	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3674
3675	/* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
3676	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3677	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
3678	 * inputs. If the pin mode is changed by the user the pin mode control
3679	 * will take care of enabling the pin's input/output buffers as needed.
3680	 * Therefore there's no need to enable the input buffer at this
3681	 * stage.
3682	 */
3683	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3684	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3685
3686	/* Mute capture amp left and right */
3687	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3688	/* Set ADC connection select to match default mixer setting - mic
3689	 * (on mic1 pin)
3690	 */
3691	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3692
3693	/* Do similar with the second ADC: mute capture input amp and
3694	 * set ADC connection to mic to match ALSA's default state.
3695	 */
3696	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3697	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3698
3699	/* Mute all inputs to mixer widget (even unconnected ones) */
3700	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3701	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3702	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3703	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3704	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3705	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3706	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3707	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3708
3709	{ }
3710};
3711
3712/* Test configuration for debugging, modelled after the ALC880 test
3713 * configuration.
3714 */
3715#ifdef CONFIG_SND_DEBUG
3716static hda_nid_t alc260_test_dac_nids[1] = {
3717	0x02,
3718};
3719static hda_nid_t alc260_test_adc_nids[2] = {
3720	0x04, 0x05,
3721};
3722/* For testing the ALC260, each input MUX needs its own definition since
3723 * the signal assignments are different.  This assumes that the first ADC
3724 * is NID 0x04.
3725 */
3726static struct hda_input_mux alc260_test_capture_sources[2] = {
3727	{
3728		.num_items = 7,
3729		.items = {
3730			{ "MIC1 pin", 0x0 },
3731			{ "MIC2 pin", 0x1 },
3732			{ "LINE1 pin", 0x2 },
3733			{ "LINE2 pin", 0x3 },
3734			{ "CD pin", 0x4 },
3735			{ "LINE-OUT pin", 0x5 },
3736			{ "HP-OUT pin", 0x6 },
3737		},
3738        },
3739	{
3740		.num_items = 8,
3741		.items = {
3742			{ "MIC1 pin", 0x0 },
3743			{ "MIC2 pin", 0x1 },
3744			{ "LINE1 pin", 0x2 },
3745			{ "LINE2 pin", 0x3 },
3746			{ "CD pin", 0x4 },
3747			{ "Mixer", 0x5 },
3748			{ "LINE-OUT pin", 0x6 },
3749			{ "HP-OUT pin", 0x7 },
3750		},
3751        },
3752};
3753static struct snd_kcontrol_new alc260_test_mixer[] = {
3754	/* Output driver widgets */
3755	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3756	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3757	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3758	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
3759	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3760	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
3761
3762	/* Modes for retasking pin widgets
3763	 * Note: the ALC260 doesn't seem to act on requests to enable mic
3764         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
3765         * mention this restriction.  At this stage it's not clear whether
3766         * this behaviour is intentional or is a hardware bug in chip
3767         * revisions available at least up until early 2006.  Therefore for
3768         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
3769         * choices, but if it turns out that the lack of mic bias for these
3770         * NIDs is intentional we could change their modes from
3771         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3772	 */
3773	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
3774	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
3775	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
3776	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
3777	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
3778	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
3779
3780	/* Loopback mixer controls */
3781	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
3782	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
3783	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
3784	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
3785	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
3786	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
3787	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
3788	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
3789	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3790	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3791	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3792	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3793	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
3794	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
3795	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
3796	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
3797
3798	/* Controls for GPIO pins, assuming they are configured as outputs */
3799	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
3800	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
3801	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
3802	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
3803
3804	/* Switches to allow the digital IO pins to be enabled.  The datasheet
3805	 * is ambigious as to which NID is which; testing on laptops which
3806	 * make this output available should provide clarification.
3807	 */
3808	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
3809	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
3810
3811	{ } /* end */
3812};
3813static struct hda_verb alc260_test_init_verbs[] = {
3814	/* Enable all GPIOs as outputs with an initial value of 0 */
3815	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
3816	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
3817	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
3818
3819	/* Enable retasking pins as output, initially without power amp */
3820	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3821	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3822	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3823	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3824	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3825	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3826
3827	/* Disable digital (SPDIF) pins initially, but users can enable
3828	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
3829	 * payload also sets the generation to 0, output to be in "consumer"
3830	 * PCM format, copyright asserted, no pre-emphasis and no validity
3831	 * control.
3832	 */
3833	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3834	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3835
3836	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
3837	 * OUT1 sum bus when acting as an output.
3838	 */
3839	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3840	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
3841	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3842	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
3843
3844	/* Start with output sum widgets muted and their output gains at min */
3845	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3846	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3847	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3848	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3849	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3850	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3851	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3852	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3853	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3854
3855	/* Unmute retasking pin widget output buffers since the default
3856	 * state appears to be output.  As the pin mode is changed by the
3857	 * user the pin mode control will take care of enabling the pin's
3858	 * input/output buffers as needed.
3859	 */
3860	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3861	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3862	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3863	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3864	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3865	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3866	/* Also unmute the mono-out pin widget */
3867	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3868
3869	/* Mute capture amp left and right */
3870	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3871	/* Set ADC connection select to match default mixer setting (mic1
3872	 * pin)
3873	 */
3874	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3875
3876	/* Do the same for the second ADC: mute capture input amp and
3877	 * set ADC connection to mic1 pin
3878	 */
3879	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3880	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3881
3882	/* Mute all inputs to mixer widget (even unconnected ones) */
3883	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3884	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3885	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3886	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3887	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3888	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3889	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3890	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3891
3892	{ }
3893};
3894#endif
3895
3896static struct hda_pcm_stream alc260_pcm_analog_playback = {
3897	.substreams = 1,
3898	.channels_min = 2,
3899	.channels_max = 2,
3900};
3901
3902static struct hda_pcm_stream alc260_pcm_analog_capture = {
3903	.substreams = 1,
3904	.channels_min = 2,
3905	.channels_max = 2,
3906};
3907
3908#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
3909#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
3910
3911/*
3912 * for BIOS auto-configuration
3913 */
3914
3915static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
3916					const char *pfx)
3917{
3918	hda_nid_t nid_vol;
3919	unsigned long vol_val, sw_val;
3920	char name[32];
3921	int err;
3922
3923	if (nid >= 0x0f && nid < 0x11) {
3924		nid_vol = nid - 0x7;
3925		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3926		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3927	} else if (nid == 0x11) {
3928		nid_vol = nid - 0x7;
3929		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
3930		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
3931	} else if (nid >= 0x12 && nid <= 0x15) {
3932		nid_vol = 0x08;
3933		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3934		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3935	} else
3936		return 0; /* N/A */
3937
3938	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
3939	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
3940		return err;
3941	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
3942	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
3943		return err;
3944	return 1;
3945}
3946
3947/* add playback controls from the parsed DAC table */
3948static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
3949					     const struct auto_pin_cfg *cfg)
3950{
3951	hda_nid_t nid;
3952	int err;
3953
3954	spec->multiout.num_dacs = 1;
3955	spec->multiout.dac_nids = spec->private_dac_nids;
3956	spec->multiout.dac_nids[0] = 0x02;
3957
3958	nid = cfg->line_out_pins[0];
3959	if (nid) {
3960		err = alc260_add_playback_controls(spec, nid, "Front");
3961		if (err < 0)
3962			return err;
3963	}
3964
3965	nid = cfg->speaker_pins[0];
3966	if (nid) {
3967		err = alc260_add_playback_controls(spec, nid, "Speaker");
3968		if (err < 0)
3969			return err;
3970	}
3971
3972	nid = cfg->hp_pins[0];
3973	if (nid) {
3974		err = alc260_add_playback_controls(spec, nid, "Headphone");
3975		if (err < 0)
3976			return err;
3977	}
3978	return 0;
3979}
3980
3981/* create playback/capture controls for input pins */
3982static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
3983						const struct auto_pin_cfg *cfg)
3984{
3985	struct hda_input_mux *imux = &spec->private_imux;
3986	int i, err, idx;
3987
3988	for (i = 0; i < AUTO_PIN_LAST; i++) {
3989		if (cfg->input_pins[i] >= 0x12) {
3990			idx = cfg->input_pins[i] - 0x12;
3991			err = new_analog_input(spec, cfg->input_pins[i],
3992					       auto_pin_cfg_labels[i], idx, 0x07);
3993			if (err < 0)
3994				return err;
3995			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3996			imux->items[imux->num_items].index = idx;
3997			imux->num_items++;
3998		}
3999		if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
4000			idx = cfg->input_pins[i] - 0x09;
4001			err = new_analog_input(spec, cfg->input_pins[i],
4002					       auto_pin_cfg_labels[i], idx, 0x07);
4003			if (err < 0)
4004				return err;
4005			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
4006			imux->items[imux->num_items].index = idx;
4007			imux->num_items++;
4008		}
4009	}
4010	return 0;
4011}
4012
4013static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4014					      hda_nid_t nid, int pin_type,
4015					      int sel_idx)
4016{
4017	/* set as output */
4018	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4019	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4020	/* need the manual connection? */
4021	if (nid >= 0x12) {
4022		int idx = nid - 0x12;
4023		snd_hda_codec_write(codec, idx + 0x0b, 0,
4024				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4025
4026	}
4027}
4028
4029static void alc260_auto_init_multi_out(struct hda_codec *codec)
4030{
4031	struct alc_spec *spec = codec->spec;
4032	hda_nid_t nid;
4033
4034	nid = spec->autocfg.line_out_pins[0];
4035	if (nid)
4036		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4037
4038	nid = spec->autocfg.speaker_pins[0];
4039	if (nid)
4040		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4041
4042	nid = spec->autocfg.hp_pins[0];
4043	if (nid)
4044		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4045}
4046
4047#define ALC260_PIN_CD_NID		0x16
4048static void alc260_auto_init_analog_input(struct hda_codec *codec)
4049{
4050	struct alc_spec *spec = codec->spec;
4051	int i;
4052
4053	for (i = 0; i < AUTO_PIN_LAST; i++) {
4054		hda_nid_t nid = spec->autocfg.input_pins[i];
4055		if (nid >= 0x12) {
4056			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4057					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4058			if (nid != ALC260_PIN_CD_NID)
4059				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4060						    AMP_OUT_MUTE);
4061		}
4062	}
4063}
4064
4065/*
4066 * generic initialization of ADC, input mixers and output mixers
4067 */
4068static struct hda_verb alc260_volume_init_verbs[] = {
4069	/*
4070	 * Unmute ADC0-1 and set the default input to mic-in
4071	 */
4072	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4073	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4074	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4075	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4076
4077	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4078	 * mixer widget
4079	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4080	 * mic (mic 2)
4081	 */
4082	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4083	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4084	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4085	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4086	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4087	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4088
4089	/*
4090	 * Set up output mixers (0x08 - 0x0a)
4091	 */
4092	/* set vol=0 to output mixers */
4093	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4094	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4095	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4096	/* set up input amps for analog loopback */
4097	/* Amp Indices: DAC = 0, mixer = 1 */
4098	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4099	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4100	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4101	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4102	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4103	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4104
4105	{ }
4106};
4107
4108static int alc260_parse_auto_config(struct hda_codec *codec)
4109{
4110	struct alc_spec *spec = codec->spec;
4111	unsigned int wcap;
4112	int err;
4113	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4114
4115	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4116						alc260_ignore)) < 0)
4117		return err;
4118	if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
4119		return err;
4120	if (! spec->kctl_alloc)
4121		return 0; /* can't find valid BIOS pin config */
4122	if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
4123		return err;
4124
4125	spec->multiout.max_channels = 2;
4126
4127	if (spec->autocfg.dig_out_pin)
4128		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4129	if (spec->kctl_alloc)
4130		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4131
4132	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4133
4134	spec->num_mux_defs = 1;
4135	spec->input_mux = &spec->private_imux;
4136
4137	/* check whether NID 0x04 is valid */
4138	wcap = get_wcaps(codec, 0x04);
4139	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4140	if (wcap != AC_WID_AUD_IN) {
4141		spec->adc_nids = alc260_adc_nids_alt;
4142		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4143		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4144	} else {
4145		spec->adc_nids = alc260_adc_nids;
4146		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4147		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4148	}
4149	spec->num_mixers++;
4150
4151	return 1;
4152}
4153
4154/* additional initialization for auto-configuration model */
4155static void alc260_auto_init(struct hda_codec *codec)
4156{
4157	alc260_auto_init_multi_out(codec);
4158	alc260_auto_init_analog_input(codec);
4159}
4160
4161/*
4162 * ALC260 configurations
4163 */
4164static struct hda_board_config alc260_cfg_tbl[] = {
4165	{ .modelname = "basic", .config = ALC260_BASIC },
4166	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
4167	  .config = ALC260_BASIC }, /* Sony VAIO */
4168	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc,
4169	  .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */
4170	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd,
4171	  .config = ALC260_BASIC }, /* Sony VAIO */
4172	{ .pci_subvendor = 0x152d, .pci_subdevice = 0x0729,
4173	  .config = ALC260_BASIC }, /* CTL Travel Master U553W */
4174	{ .modelname = "hp", .config = ALC260_HP },
4175	{ .modelname = "hp-3013", .config = ALC260_HP_3013 },
4176	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP_3013 },
4177	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
4178	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 },
4179	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
4180	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
4181	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
4182	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP },
4183	{ .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X },
4184	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X },
4185	{ .modelname = "acer", .config = ALC260_ACER },
4186	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER },
4187#ifdef CONFIG_SND_DEBUG
4188	{ .modelname = "test", .config = ALC260_TEST },
4189#endif
4190	{ .modelname = "auto", .config = ALC260_AUTO },
4191	{}
4192};
4193
4194static struct alc_config_preset alc260_presets[] = {
4195	[ALC260_BASIC] = {
4196		.mixers = { alc260_base_output_mixer,
4197			    alc260_input_mixer,
4198			    alc260_pc_beep_mixer,
4199			    alc260_capture_mixer },
4200		.init_verbs = { alc260_init_verbs },
4201		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4202		.dac_nids = alc260_dac_nids,
4203		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4204		.adc_nids = alc260_adc_nids,
4205		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4206		.channel_mode = alc260_modes,
4207		.input_mux = &alc260_capture_source,
4208	},
4209	[ALC260_HP] = {
4210		.mixers = { alc260_base_output_mixer,
4211			    alc260_input_mixer,
4212			    alc260_capture_alt_mixer },
4213		.init_verbs = { alc260_init_verbs },
4214		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4215		.dac_nids = alc260_dac_nids,
4216		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4217		.adc_nids = alc260_hp_adc_nids,
4218		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4219		.channel_mode = alc260_modes,
4220		.input_mux = &alc260_capture_source,
4221	},
4222	[ALC260_HP_3013] = {
4223		.mixers = { alc260_hp_3013_mixer,
4224			    alc260_input_mixer,
4225			    alc260_capture_alt_mixer },
4226		.init_verbs = { alc260_hp_3013_init_verbs },
4227		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4228		.dac_nids = alc260_dac_nids,
4229		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4230		.adc_nids = alc260_hp_adc_nids,
4231		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4232		.channel_mode = alc260_modes,
4233		.input_mux = &alc260_capture_source,
4234	},
4235	[ALC260_FUJITSU_S702X] = {
4236		.mixers = { alc260_fujitsu_mixer,
4237			    alc260_capture_mixer },
4238		.init_verbs = { alc260_fujitsu_init_verbs },
4239		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4240		.dac_nids = alc260_dac_nids,
4241		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4242		.adc_nids = alc260_dual_adc_nids,
4243		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4244		.channel_mode = alc260_modes,
4245		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4246		.input_mux = alc260_fujitsu_capture_sources,
4247	},
4248	[ALC260_ACER] = {
4249		.mixers = { alc260_acer_mixer,
4250			    alc260_capture_mixer },
4251		.init_verbs = { alc260_acer_init_verbs },
4252		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4253		.dac_nids = alc260_dac_nids,
4254		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4255		.adc_nids = alc260_dual_adc_nids,
4256		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4257		.channel_mode = alc260_modes,
4258		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4259		.input_mux = alc260_acer_capture_sources,
4260	},
4261#ifdef CONFIG_SND_DEBUG
4262	[ALC260_TEST] = {
4263		.mixers = { alc260_test_mixer,
4264			    alc260_capture_mixer },
4265		.init_verbs = { alc260_test_init_verbs },
4266		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4267		.dac_nids = alc260_test_dac_nids,
4268		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4269		.adc_nids = alc260_test_adc_nids,
4270		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4271		.channel_mode = alc260_modes,
4272		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4273		.input_mux = alc260_test_capture_sources,
4274	},
4275#endif
4276};
4277
4278static int patch_alc260(struct hda_codec *codec)
4279{
4280	struct alc_spec *spec;
4281	int err, board_config;
4282
4283	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4284	if (spec == NULL)
4285		return -ENOMEM;
4286
4287	codec->spec = spec;
4288
4289	board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
4290	if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
4291		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4292			   "trying auto-probe from BIOS...\n");
4293		board_config = ALC260_AUTO;
4294	}
4295
4296	if (board_config == ALC260_AUTO) {
4297		/* automatic parse from the BIOS config */
4298		err = alc260_parse_auto_config(codec);
4299		if (err < 0) {
4300			alc_free(codec);
4301			return err;
4302		} else if (! err) {
4303			printk(KERN_INFO
4304			       "hda_codec: Cannot set up configuration "
4305			       "from BIOS.  Using base mode...\n");
4306			board_config = ALC260_BASIC;
4307		}
4308	}
4309
4310	if (board_config != ALC260_AUTO)
4311		setup_preset(spec, &alc260_presets[board_config]);
4312
4313	spec->stream_name_analog = "ALC260 Analog";
4314	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4315	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4316
4317	spec->stream_name_digital = "ALC260 Digital";
4318	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4319	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4320
4321	codec->patch_ops = alc_patch_ops;
4322	if (board_config == ALC260_AUTO)
4323		spec->init_hook = alc260_auto_init;
4324
4325	return 0;
4326}
4327
4328
4329/*
4330 * ALC882 support
4331 *
4332 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4333 * configuration.  Each pin widget can choose any input DACs and a mixer.
4334 * Each ADC is connected from a mixer of all inputs.  This makes possible
4335 * 6-channel independent captures.
4336 *
4337 * In addition, an independent DAC for the multi-playback (not used in this
4338 * driver yet).
4339 */
4340#define ALC882_DIGOUT_NID	0x06
4341#define ALC882_DIGIN_NID	0x0a
4342
4343static struct hda_channel_mode alc882_ch_modes[1] = {
4344	{ 8, NULL }
4345};
4346
4347static hda_nid_t alc882_dac_nids[4] = {
4348	/* front, rear, clfe, rear_surr */
4349	0x02, 0x03, 0x04, 0x05
4350};
4351
4352/* identical with ALC880 */
4353#define alc882_adc_nids		alc880_adc_nids
4354#define alc882_adc_nids_alt	alc880_adc_nids_alt
4355
4356/* input MUX */
4357/* FIXME: should be a matrix-type input source selection */
4358
4359static struct hda_input_mux alc882_capture_source = {
4360	.num_items = 4,
4361	.items = {
4362		{ "Mic", 0x0 },
4363		{ "Front Mic", 0x1 },
4364		{ "Line", 0x2 },
4365		{ "CD", 0x4 },
4366	},
4367};
4368#define alc882_mux_enum_info alc_mux_enum_info
4369#define alc882_mux_enum_get alc_mux_enum_get
4370
4371static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
4372{
4373	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4374	struct alc_spec *spec = codec->spec;
4375	const struct hda_input_mux *imux = spec->input_mux;
4376	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4377	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4378	hda_nid_t nid = capture_mixers[adc_idx];
4379	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4380	unsigned int i, idx;
4381
4382	idx = ucontrol->value.enumerated.item[0];
4383	if (idx >= imux->num_items)
4384		idx = imux->num_items - 1;
4385	if (*cur_val == idx && ! codec->in_resume)
4386		return 0;
4387	for (i = 0; i < imux->num_items; i++) {
4388		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4389		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4390				    v | (imux->items[i].index << 8));
4391	}
4392	*cur_val = idx;
4393	return 1;
4394}
4395
4396/*
4397 * 6ch mode
4398 */
4399static struct hda_verb alc882_sixstack_ch6_init[] = {
4400	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4401	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4402	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4403	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4404	{ } /* end */
4405};
4406
4407/*
4408 * 8ch mode
4409 */
4410static struct hda_verb alc882_sixstack_ch8_init[] = {
4411	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4412	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4413	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4414	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4415	{ } /* end */
4416};
4417
4418static struct hda_channel_mode alc882_sixstack_modes[2] = {
4419	{ 6, alc882_sixstack_ch6_init },
4420	{ 8, alc882_sixstack_ch8_init },
4421};
4422
4423/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4424 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4425 */
4426static struct snd_kcontrol_new alc882_base_mixer[] = {
4427	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4428	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4429	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4430	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4431	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4432	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4433	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4434	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4435	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4436	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4437	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4438	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4439	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4440	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4441	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4442	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4443	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4444	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4445	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4446	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4447	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4448	{ } /* end */
4449};
4450
4451static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4452	{
4453		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4454		.name = "Channel Mode",
4455		.info = alc_ch_mode_info,
4456		.get = alc_ch_mode_get,
4457		.put = alc_ch_mode_put,
4458	},
4459	{ } /* end */
4460};
4461
4462static struct hda_verb alc882_init_verbs[] = {
4463	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4464	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4465	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4466	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4467	/* Rear mixer */
4468	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4469	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4470	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4471	/* CLFE mixer */
4472	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4473	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4474	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4475	/* Side mixer */
4476	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4477	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4478	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4479
4480	/* Front Pin: output 0 (0x0c) */
4481	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4482	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4483	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4484	/* Rear Pin: output 1 (0x0d) */
4485	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4486	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4487	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4488	/* CLFE Pin: output 2 (0x0e) */
4489	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4490	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4491	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4492	/* Side Pin: output 3 (0x0f) */
4493	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4494	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4495	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4496	/* Mic (rear) pin: input vref at 80% */
4497	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4498	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4499	/* Front Mic pin: input vref at 80% */
4500	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4501	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4502	/* Line In pin: input */
4503	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4504	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4505	/* Line-2 In: Headphone output (output 0 - 0x0c) */
4506	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4507	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4508	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4509	/* CD pin widget for input */
4510	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4511
4512	/* FIXME: use matrix-type input source selection */
4513	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4514	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4515	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4516	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4517	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4518	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4519	/* Input mixer2 */
4520	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4521	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4522	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4523	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4524	/* Input mixer3 */
4525	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4526	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4527	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4528	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4529	/* ADC1: mute amp left and right */
4530	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4531	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4532	/* ADC2: mute amp left and right */
4533	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4534	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4535	/* ADC3: mute amp left and right */
4536	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4537	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4538
4539	{ }
4540};
4541
4542static struct hda_verb alc882_eapd_verbs[] = {
4543	/* change to EAPD mode */
4544	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4545	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4546	{ }
4547};
4548
4549/*
4550 * generic initialization of ADC, input mixers and output mixers
4551 */
4552static struct hda_verb alc882_auto_init_verbs[] = {
4553	/*
4554	 * Unmute ADC0-2 and set the default input to mic-in
4555	 */
4556	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4557	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4558	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4559	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4560	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4561	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4562
4563	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4564	 * mixer widget
4565	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4566	 * mic (mic 2)
4567	 */
4568	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4569	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4570	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4571	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4572	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4573	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4574
4575	/*
4576	 * Set up output mixers (0x0c - 0x0f)
4577	 */
4578	/* set vol=0 to output mixers */
4579	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4580	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4581	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4582	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4583	/* set up input amps for analog loopback */
4584	/* Amp Indices: DAC = 0, mixer = 1 */
4585	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4586	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4587	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4588	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4589	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4590	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4591	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4592	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4593	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4594	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4595
4596	/* FIXME: use matrix-type input source selection */
4597	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4598	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4599	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4600	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4601	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4602	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4603	/* Input mixer2 */
4604	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4605	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4606	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4607	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4608	/* Input mixer3 */
4609	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4610	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4611	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4612	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4613
4614	{ }
4615};
4616
4617/* capture mixer elements */
4618static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
4619	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4620	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4621	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
4622	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
4623	{
4624		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4625		/* The multiple "Capture Source" controls confuse alsamixer
4626		 * So call somewhat different..
4627		 * FIXME: the controls appear in the "playback" view!
4628		 */
4629		/* .name = "Capture Source", */
4630		.name = "Input Source",
4631		.count = 2,
4632		.info = alc882_mux_enum_info,
4633		.get = alc882_mux_enum_get,
4634		.put = alc882_mux_enum_put,
4635	},
4636	{ } /* end */
4637};
4638
4639static struct snd_kcontrol_new alc882_capture_mixer[] = {
4640	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
4641	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
4642	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
4643	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
4644	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
4645	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
4646	{
4647		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4648		/* The multiple "Capture Source" controls confuse alsamixer
4649		 * So call somewhat different..
4650		 * FIXME: the controls appear in the "playback" view!
4651		 */
4652		/* .name = "Capture Source", */
4653		.name = "Input Source",
4654		.count = 3,
4655		.info = alc882_mux_enum_info,
4656		.get = alc882_mux_enum_get,
4657		.put = alc882_mux_enum_put,
4658	},
4659	{ } /* end */
4660};
4661
4662/* pcm configuration: identiacal with ALC880 */
4663#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
4664#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
4665#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
4666#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
4667
4668/*
4669 * configuration and preset
4670 */
4671static struct hda_board_config alc882_cfg_tbl[] = {
4672	{ .modelname = "3stack-dig", .config = ALC882_3ST_DIG },
4673	{ .modelname = "6stack-dig", .config = ALC882_6ST_DIG },
4674	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
4675	  .config = ALC882_6ST_DIG }, /* MSI  */
4676	{ .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
4677	  .config = ALC882_6ST_DIG }, /* Foxconn */
4678	{ .pci_subvendor = 0x1019, .pci_subdevice = 0x6668,
4679	  .config = ALC882_6ST_DIG }, /* ECS to Intel*/
4680	{ .modelname = "arima", .config = ALC882_ARIMA },
4681	{ .pci_subvendor = 0x161f, .pci_subdevice = 0x2054,
4682	  .config = ALC882_ARIMA }, /* Arima W820Di1 */
4683	{ .modelname = "auto", .config = ALC882_AUTO },
4684	{}
4685};
4686
4687static struct alc_config_preset alc882_presets[] = {
4688	[ALC882_3ST_DIG] = {
4689		.mixers = { alc882_base_mixer },
4690		.init_verbs = { alc882_init_verbs },
4691		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4692		.dac_nids = alc882_dac_nids,
4693		.dig_out_nid = ALC882_DIGOUT_NID,
4694		.dig_in_nid = ALC882_DIGIN_NID,
4695		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
4696		.channel_mode = alc882_ch_modes,
4697		.need_dac_fix = 1,
4698		.input_mux = &alc882_capture_source,
4699	},
4700	[ALC882_6ST_DIG] = {
4701		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
4702		.init_verbs = { alc882_init_verbs },
4703		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4704		.dac_nids = alc882_dac_nids,
4705		.dig_out_nid = ALC882_DIGOUT_NID,
4706		.dig_in_nid = ALC882_DIGIN_NID,
4707		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4708		.channel_mode = alc882_sixstack_modes,
4709		.input_mux = &alc882_capture_source,
4710	},
4711	[ALC882_ARIMA] = {
4712		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
4713		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
4714		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4715		.dac_nids = alc882_dac_nids,
4716		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4717		.channel_mode = alc882_sixstack_modes,
4718		.input_mux = &alc882_capture_source,
4719	},
4720};
4721
4722
4723/*
4724 * BIOS auto configuration
4725 */
4726static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
4727					      hda_nid_t nid, int pin_type,
4728					      int dac_idx)
4729{
4730	/* set as output */
4731	struct alc_spec *spec = codec->spec;
4732	int idx;
4733
4734	if (spec->multiout.dac_nids[dac_idx] == 0x25)
4735		idx = 4;
4736	else
4737		idx = spec->multiout.dac_nids[dac_idx] - 2;
4738
4739	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4740	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4741	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
4742
4743}
4744
4745static void alc882_auto_init_multi_out(struct hda_codec *codec)
4746{
4747	struct alc_spec *spec = codec->spec;
4748	int i;
4749
4750	for (i = 0; i <= HDA_SIDE; i++) {
4751		hda_nid_t nid = spec->autocfg.line_out_pins[i];
4752		if (nid)
4753			alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
4754	}
4755}
4756
4757static void alc882_auto_init_hp_out(struct hda_codec *codec)
4758{
4759	struct alc_spec *spec = codec->spec;
4760	hda_nid_t pin;
4761
4762	pin = spec->autocfg.hp_pins[0];
4763	if (pin) /* connect to front */
4764		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
4765}
4766
4767#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
4768#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
4769
4770static void alc882_auto_init_analog_input(struct hda_codec *codec)
4771{
4772	struct alc_spec *spec = codec->spec;
4773	int i;
4774
4775	for (i = 0; i < AUTO_PIN_LAST; i++) {
4776		hda_nid_t nid = spec->autocfg.input_pins[i];
4777		if (alc882_is_input_pin(nid)) {
4778			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4779					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4780			if (nid != ALC882_PIN_CD_NID)
4781				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4782						    AMP_OUT_MUTE);
4783		}
4784	}
4785}
4786
4787/* almost identical with ALC880 parser... */
4788static int alc882_parse_auto_config(struct hda_codec *codec)
4789{
4790	struct alc_spec *spec = codec->spec;
4791	int err = alc880_parse_auto_config(codec);
4792
4793	if (err < 0)
4794		return err;
4795	else if (err > 0)
4796		/* hack - override the init verbs */
4797		spec->init_verbs[0] = alc882_auto_init_verbs;
4798	return err;
4799}
4800
4801/* additional initialization for auto-configuration model */
4802static void alc882_auto_init(struct hda_codec *codec)
4803{
4804	alc882_auto_init_multi_out(codec);
4805	alc882_auto_init_hp_out(codec);
4806	alc882_auto_init_analog_input(codec);
4807}
4808
4809static int patch_alc882(struct hda_codec *codec)
4810{
4811	struct alc_spec *spec;
4812	int err, board_config;
4813
4814	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4815	if (spec == NULL)
4816		return -ENOMEM;
4817
4818	codec->spec = spec;
4819
4820	board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl);
4821
4822	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
4823		printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
4824		       "trying auto-probe from BIOS...\n");
4825		board_config = ALC882_AUTO;
4826	}
4827
4828	if (board_config == ALC882_AUTO) {
4829		/* automatic parse from the BIOS config */
4830		err = alc882_parse_auto_config(codec);
4831		if (err < 0) {
4832			alc_free(codec);
4833			return err;
4834		} else if (! err) {
4835			printk(KERN_INFO
4836			       "hda_codec: Cannot set up configuration "
4837			       "from BIOS.  Using base mode...\n");
4838			board_config = ALC882_3ST_DIG;
4839		}
4840	}
4841
4842	if (board_config != ALC882_AUTO)
4843		setup_preset(spec, &alc882_presets[board_config]);
4844
4845	spec->stream_name_analog = "ALC882 Analog";
4846	spec->stream_analog_playback = &alc882_pcm_analog_playback;
4847	spec->stream_analog_capture = &alc882_pcm_analog_capture;
4848
4849	spec->stream_name_digital = "ALC882 Digital";
4850	spec->stream_digital_playback = &alc882_pcm_digital_playback;
4851	spec->stream_digital_capture = &alc882_pcm_digital_capture;
4852
4853	if (! spec->adc_nids && spec->input_mux) {
4854		/* check whether NID 0x07 is valid */
4855		unsigned int wcap = get_wcaps(codec, 0x07);
4856		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4857		if (wcap != AC_WID_AUD_IN) {
4858			spec->adc_nids = alc882_adc_nids_alt;
4859			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
4860			spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
4861			spec->num_mixers++;
4862		} else {
4863			spec->adc_nids = alc882_adc_nids;
4864			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
4865			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
4866			spec->num_mixers++;
4867		}
4868	}
4869
4870	codec->patch_ops = alc_patch_ops;
4871	if (board_config == ALC882_AUTO)
4872		spec->init_hook = alc882_auto_init;
4873
4874	return 0;
4875}
4876
4877/*
4878 * ALC883 support
4879 *
4880 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
4881 * configuration.  Each pin widget can choose any input DACs and a mixer.
4882 * Each ADC is connected from a mixer of all inputs.  This makes possible
4883 * 6-channel independent captures.
4884 *
4885 * In addition, an independent DAC for the multi-playback (not used in this
4886 * driver yet).
4887 */
4888#define ALC883_DIGOUT_NID	0x06
4889#define ALC883_DIGIN_NID	0x0a
4890
4891static hda_nid_t alc883_dac_nids[4] = {
4892	/* front, rear, clfe, rear_surr */
4893	0x02, 0x04, 0x03, 0x05
4894};
4895
4896static hda_nid_t alc883_adc_nids[2] = {
4897	/* ADC1-2 */
4898	0x08, 0x09,
4899};
4900/* input MUX */
4901/* FIXME: should be a matrix-type input source selection */
4902
4903static struct hda_input_mux alc883_capture_source = {
4904	.num_items = 4,
4905	.items = {
4906		{ "Mic", 0x0 },
4907		{ "Front Mic", 0x1 },
4908		{ "Line", 0x2 },
4909		{ "CD", 0x4 },
4910	},
4911};
4912#define alc883_mux_enum_info alc_mux_enum_info
4913#define alc883_mux_enum_get alc_mux_enum_get
4914
4915static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
4916			       struct snd_ctl_elem_value *ucontrol)
4917{
4918	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4919	struct alc_spec *spec = codec->spec;
4920	const struct hda_input_mux *imux = spec->input_mux;
4921	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4922	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4923	hda_nid_t nid = capture_mixers[adc_idx];
4924	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4925	unsigned int i, idx;
4926
4927	idx = ucontrol->value.enumerated.item[0];
4928	if (idx >= imux->num_items)
4929		idx = imux->num_items - 1;
4930	if (*cur_val == idx && ! codec->in_resume)
4931		return 0;
4932	for (i = 0; i < imux->num_items; i++) {
4933		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4934		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4935				    v | (imux->items[i].index << 8));
4936	}
4937	*cur_val = idx;
4938	return 1;
4939}
4940/*
4941 * 2ch mode
4942 */
4943static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4944	{ 2, NULL }
4945};
4946
4947/*
4948 * 2ch mode
4949 */
4950static struct hda_verb alc883_3ST_ch2_init[] = {
4951	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4952	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4953	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4954	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4955	{ } /* end */
4956};
4957
4958/*
4959 * 6ch mode
4960 */
4961static struct hda_verb alc883_3ST_ch6_init[] = {
4962	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4963	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4964	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4965	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4966	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4967	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4968	{ } /* end */
4969};
4970
4971static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
4972	{ 2, alc883_3ST_ch2_init },
4973	{ 6, alc883_3ST_ch6_init },
4974};
4975
4976/*
4977 * 6ch mode
4978 */
4979static struct hda_verb alc883_sixstack_ch6_init[] = {
4980	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4981	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4982	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4983	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4984	{ } /* end */
4985};
4986
4987/*
4988 * 8ch mode
4989 */
4990static struct hda_verb alc883_sixstack_ch8_init[] = {
4991	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4992	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4993	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4994	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4995	{ } /* end */
4996};
4997
4998static struct hda_channel_mode alc883_sixstack_modes[2] = {
4999	{ 6, alc883_sixstack_ch6_init },
5000	{ 8, alc883_sixstack_ch8_init },
5001};
5002
5003static struct hda_verb alc883_medion_eapd_verbs[] = {
5004        /* eanable EAPD on medion laptop */
5005	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5006	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5007	{ }
5008};
5009
5010/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5011 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5012 */
5013
5014static struct snd_kcontrol_new alc883_base_mixer[] = {
5015	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5016	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5017	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5018	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5019	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5020	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5021	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5022	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5023	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5024	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5025	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5026	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5027	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5028	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5029	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5030	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5031	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5032	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5033	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5034	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5035	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5036	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5037	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5038	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5039	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5040	{
5041		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5042		/* .name = "Capture Source", */
5043		.name = "Input Source",
5044		.count = 2,
5045		.info = alc883_mux_enum_info,
5046		.get = alc883_mux_enum_get,
5047		.put = alc883_mux_enum_put,
5048	},
5049	{ } /* end */
5050};
5051
5052static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
5053	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5054	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5055	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5056	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5057	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5058	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5059	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5060	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5061	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5062	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5063	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5064	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5065	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5066	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5067	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5068	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5069	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5070	{
5071		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5072		/* .name = "Capture Source", */
5073		.name = "Input Source",
5074		.count = 2,
5075		.info = alc883_mux_enum_info,
5076		.get = alc883_mux_enum_get,
5077		.put = alc883_mux_enum_put,
5078	},
5079	{ } /* end */
5080};
5081
5082static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
5083	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5084	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5085	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5086	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5087	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5088	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5089	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5090	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5091	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5092	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5093	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5094	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5095	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5096	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5097	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5098	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5099	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5100	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5101	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5102	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5103	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5104	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5105	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5106	{
5107		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5108		/* .name = "Capture Source", */
5109		.name = "Input Source",
5110		.count = 2,
5111		.info = alc883_mux_enum_info,
5112		.get = alc883_mux_enum_get,
5113		.put = alc883_mux_enum_put,
5114	},
5115	{ } /* end */
5116};
5117
5118static snd_kcontrol_new_t alc883_fivestack_mixer[] = {
5119	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5120	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5121	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5122	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5123	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5124	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5125	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5126	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5127	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5128	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5129	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5130	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5131	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5132	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5133	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5134	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5135	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5136	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5137	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5138	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5139	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5140
5141	{
5142		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5143		/* .name = "Capture Source", */
5144		.name = "Input Source",
5145		.count = 1,
5146		.info = alc883_mux_enum_info,
5147		.get = alc883_mux_enum_get,
5148		.put = alc883_mux_enum_put,
5149	},
5150	{ } /* end */
5151};
5152
5153static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5154	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5155	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5156	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5157	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5158	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5159	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5160	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5161	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5162	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5163	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5164	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5165	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5166	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5167	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5168	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5169	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5170	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5171	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5172	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5173	{
5174		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5175		/* .name = "Capture Source", */
5176		.name = "Input Source",
5177		.count = 2,
5178		.info = alc883_mux_enum_info,
5179		.get = alc883_mux_enum_get,
5180		.put = alc883_mux_enum_put,
5181	},
5182	{ } /* end */
5183};
5184
5185static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5186	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5187	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5188	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5189	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5190	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5191	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5192	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5193	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5194	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5195	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5196	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5197	{
5198		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5199		/* .name = "Capture Source", */
5200		.name = "Input Source",
5201		.count = 2,
5202		.info = alc883_mux_enum_info,
5203		.get = alc883_mux_enum_get,
5204		.put = alc883_mux_enum_put,
5205	},
5206	{ } /* end */
5207};
5208
5209static struct snd_kcontrol_new alc883_chmode_mixer[] = {
5210	{
5211		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5212		.name = "Channel Mode",
5213		.info = alc_ch_mode_info,
5214		.get = alc_ch_mode_get,
5215		.put = alc_ch_mode_put,
5216	},
5217	{ } /* end */
5218};
5219
5220static struct hda_verb alc883_init_verbs[] = {
5221	/* ADC1: mute amp left and right */
5222	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5223	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5224	/* ADC2: mute amp left and right */
5225	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5226	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5227	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5228	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5229	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5230	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5231	/* Rear mixer */
5232	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5233	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5234	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5235	/* CLFE mixer */
5236	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5237	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5238	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5239	/* Side mixer */
5240	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5241	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5242	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5243
5244	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5245	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5246	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5247	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5248	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5249
5250	/* Front Pin: output 0 (0x0c) */
5251	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5252	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5253	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5254	/* Rear Pin: output 1 (0x0d) */
5255	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5256	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5257	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5258	/* CLFE Pin: output 2 (0x0e) */
5259	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5260	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5261	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5262	/* Side Pin: output 3 (0x0f) */
5263	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5264	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5265	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5266	/* Mic (rear) pin: input vref at 80% */
5267	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5268	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5269	/* Front Mic pin: input vref at 80% */
5270	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5271	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5272	/* Line In pin: input */
5273	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5274	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5275	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5276	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5277	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5278	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5279	/* CD pin widget for input */
5280	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5281
5282	/* FIXME: use matrix-type input source selection */
5283	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5284	/* Input mixer2 */
5285	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5286	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5287	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5288	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5289	/* Input mixer3 */
5290	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5291	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5292	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5293	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5294	{ }
5295};
5296
5297static struct hda_verb alc883_tagra_verbs[] = {
5298	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5299	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5300
5301	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5302	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5303
5304	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5305	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5306	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5307
5308	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5309	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5310	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5311	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5312
5313	{ } /* end */
5314};
5315
5316/* toggle speaker-output according to the hp-jack state */
5317static void alc883_tagra_automute(struct hda_codec *codec)
5318{
5319 	unsigned int present;
5320
5321 	present = snd_hda_codec_read(codec, 0x14, 0,
5322				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5323	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5324				 0x80, present ? 0x80 : 0);
5325	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5326				 0x80, present ? 0x80 : 0);
5327	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5328}
5329
5330static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
5331{
5332	if ((res >> 26) == ALC880_HP_EVENT)
5333		alc883_tagra_automute(codec);
5334}
5335
5336/*
5337 * generic initialization of ADC, input mixers and output mixers
5338 */
5339static struct hda_verb alc883_auto_init_verbs[] = {
5340	/*
5341	 * Unmute ADC0-2 and set the default input to mic-in
5342	 */
5343	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5344	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5345	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5346	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5347
5348	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5349	 * mixer widget
5350	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
5351	 * mic (mic 2)
5352	 */
5353	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5354	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5355	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5356	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5357	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5358	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5359
5360	/*
5361	 * Set up output mixers (0x0c - 0x0f)
5362	 */
5363	/* set vol=0 to output mixers */
5364	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5365	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5366	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5367	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5368	/* set up input amps for analog loopback */
5369	/* Amp Indices: DAC = 0, mixer = 1 */
5370	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5371	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5372	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5373	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5374	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5375	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5376	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5377	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5378	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5379	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5380
5381	/* FIXME: use matrix-type input source selection */
5382	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5383	/* Input mixer1 */
5384	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5385	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5386	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5387	//{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5388	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5389	/* Input mixer2 */
5390	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5391	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5392	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5393	//{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5394	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5395
5396	{ }
5397};
5398
5399/* capture mixer elements */
5400static struct snd_kcontrol_new alc883_capture_mixer[] = {
5401	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5402	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5403	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5404	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5405	{
5406		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5407		/* The multiple "Capture Source" controls confuse alsamixer
5408		 * So call somewhat different..
5409		 * FIXME: the controls appear in the "playback" view!
5410		 */
5411		/* .name = "Capture Source", */
5412		.name = "Input Source",
5413		.count = 2,
5414		.info = alc882_mux_enum_info,
5415		.get = alc882_mux_enum_get,
5416		.put = alc882_mux_enum_put,
5417	},
5418	{ } /* end */
5419};
5420
5421/* pcm configuration: identiacal with ALC880 */
5422#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
5423#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
5424#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
5425#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
5426
5427/*
5428 * configuration and preset
5429 */
5430static struct hda_board_config alc883_cfg_tbl[] = {
5431	{ .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG },
5432	{ .modelname = "3stack-6ch-dig", .config = ALC883_3ST_6ch_DIG },
5433	{ .pci_subvendor = 0x1019, .pci_subdevice = 0x6668,
5434	  .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/
5435	{ .modelname = "3stack-6ch", .config = ALC883_3ST_6ch },
5436	{ .pci_subvendor = 0x108e, .pci_subdevice = 0x534d,
5437	  .config = ALC883_3ST_6ch },
5438	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd601,
5439	  .config = ALC883_3ST_6ch }, /* D102GGC */
5440	{ .modelname = "6stack-dig", .config = ALC883_6ST_DIG },
5441	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x6668,
5442	  .config = ALC883_6ST_DIG }, /* MSI  */
5443	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x7280,
5444	  .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */
5445	{ .pci_subvendor = 0x105b, .pci_subdevice = 0x6668,
5446	  .config = ALC883_6ST_DIG }, /* Foxconn */
5447	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x7187,
5448	  .config = ALC883_6ST_DIG }, /* MSI */
5449	{ .modelname = "targa-dig", .config = ALC883_TARGA_DIG },
5450	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
5451	  .config = ALC883_TARGA_DIG }, /* MSI */
5452	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3fcc,
5453	  .config = ALC883_TARGA_DIG }, /* MSI */
5454	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc1,
5455	  .config = ALC883_TARGA_DIG }, /* MSI */
5456	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3fc3,
5457	  .config = ALC883_TARGA_DIG }, /* MSI */
5458	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4314,
5459	  .config = ALC883_TARGA_DIG }, /* MSI */
5460	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4319,
5461	  .config = ALC883_TARGA_DIG }, /* MSI */
5462	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3ef9,
5463	  .config = ALC883_TARGA_DIG }, /* MSI */
5464	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x4324,
5465	  .config = ALC883_TARGA_DIG }, /* MSI */
5466	{ .modelname = "targa-2ch-dig", .config = ALC883_TARGA_2ch_DIG },
5467	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x0579,
5468	  .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5469	{ .pci_subvendor = 0x1462, .pci_subdevice = 0xa422,
5470	  .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5471	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x3b7f,
5472	  .config = ALC883_TARGA_2ch_DIG }, /* MSI */
5473	{ .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD },
5474	{ .modelname = "acer", .config = ALC883_ACER },
5475	{ .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/,
5476	  .config = ALC883_ACER },
5477	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0102,
5478	  .config = ALC883_ACER },
5479	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x009f,
5480	  .config = ALC883_ACER },
5481	{ .pci_subvendor = 0x161f, .pci_subdevice = 0x2054,
5482	  .modelname = "medion", .config = ALC883_MEDION },
5483	{ .modelname = "laptop-eapd", .config = ALC883_LAPTOP_EAPD },
5484	{ .pci_subvendor = 0x1071, .pci_subdevice = 0x8258,
5485	  .config = ALC883_LAPTOP_EAPD }, /* Evesham Voyager C530RD */
5486	{ .pci_subvendor = 0x1558, .pci_subdevice = 0,
5487	  .config = ALC883_LAPTOP_EAPD }, /* Clevo */
5488	{ .modelname = "auto", .config = ALC883_AUTO },
5489	{}
5490};
5491
5492static struct alc_config_preset alc883_presets[] = {
5493	[ALC883_3ST_2ch_DIG] = {
5494		.mixers = { alc883_3ST_2ch_mixer },
5495		.init_verbs = { alc883_init_verbs },
5496		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5497		.dac_nids = alc883_dac_nids,
5498		.dig_out_nid = ALC883_DIGOUT_NID,
5499		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5500		.adc_nids = alc883_adc_nids,
5501		.dig_in_nid = ALC883_DIGIN_NID,
5502		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5503		.channel_mode = alc883_3ST_2ch_modes,
5504		.input_mux = &alc883_capture_source,
5505	},
5506	[ALC883_3ST_6ch_DIG] = {
5507		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
5508		.init_verbs = { alc883_init_verbs },
5509		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5510		.dac_nids = alc883_dac_nids,
5511		.dig_out_nid = ALC883_DIGOUT_NID,
5512		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5513		.adc_nids = alc883_adc_nids,
5514		.dig_in_nid = ALC883_DIGIN_NID,
5515		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5516		.channel_mode = alc883_3ST_6ch_modes,
5517		.need_dac_fix = 1,
5518		.input_mux = &alc883_capture_source,
5519	},
5520	[ALC883_3ST_6ch] = {
5521		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
5522		.init_verbs = { alc883_init_verbs },
5523		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5524		.dac_nids = alc883_dac_nids,
5525		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5526		.adc_nids = alc883_adc_nids,
5527		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5528		.channel_mode = alc883_3ST_6ch_modes,
5529		.need_dac_fix = 1,
5530		.input_mux = &alc883_capture_source,
5531	},
5532	[ALC883_6ST_DIG] = {
5533		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
5534		.init_verbs = { alc883_init_verbs },
5535		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5536		.dac_nids = alc883_dac_nids,
5537		.dig_out_nid = ALC883_DIGOUT_NID,
5538		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5539		.adc_nids = alc883_adc_nids,
5540		.dig_in_nid = ALC883_DIGIN_NID,
5541		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5542		.channel_mode = alc883_sixstack_modes,
5543		.input_mux = &alc883_capture_source,
5544	},
5545	[ALC883_TARGA_DIG] = {
5546		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
5547		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5548		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5549		.dac_nids = alc883_dac_nids,
5550		.dig_out_nid = ALC883_DIGOUT_NID,
5551		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5552		.adc_nids = alc883_adc_nids,
5553		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5554		.channel_mode = alc883_3ST_6ch_modes,
5555		.need_dac_fix = 1,
5556		.input_mux = &alc883_capture_source,
5557		.unsol_event = alc883_tagra_unsol_event,
5558		.init_hook = alc883_tagra_automute,
5559	},
5560	[ALC883_TARGA_2ch_DIG] = {
5561		.mixers = { alc883_tagra_2ch_mixer},
5562		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5563		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5564		.dac_nids = alc883_dac_nids,
5565		.dig_out_nid = ALC883_DIGOUT_NID,
5566		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5567		.adc_nids = alc883_adc_nids,
5568		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5569		.channel_mode = alc883_3ST_2ch_modes,
5570		.input_mux = &alc883_capture_source,
5571		.unsol_event = alc883_tagra_unsol_event,
5572		.init_hook = alc883_tagra_automute,
5573	},
5574	[ALC888_DEMO_BOARD] = {
5575		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
5576		.init_verbs = { alc883_init_verbs },
5577		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5578		.dac_nids = alc883_dac_nids,
5579		.dig_out_nid = ALC883_DIGOUT_NID,
5580		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5581		.adc_nids = alc883_adc_nids,
5582		.dig_in_nid = ALC883_DIGIN_NID,
5583		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5584		.channel_mode = alc883_sixstack_modes,
5585		.input_mux = &alc883_capture_source,
5586	},
5587	[ALC883_ACER] = {
5588		.mixers = { alc883_base_mixer,
5589			    alc883_chmode_mixer },
5590		/* On TravelMate laptops, GPIO 0 enables the internal speaker
5591		 * and the headphone jack.  Turn this on and rely on the
5592		 * standard mute methods whenever the user wants to turn
5593		 * these outputs off.
5594		 */
5595		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
5596		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5597		.dac_nids = alc883_dac_nids,
5598		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5599		.adc_nids = alc883_adc_nids,
5600		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5601		.channel_mode = alc883_3ST_2ch_modes,
5602		.input_mux = &alc883_capture_source,
5603	},
5604	[ALC883_MEDION] = {
5605		.mixers = { alc883_fivestack_mixer,
5606			    alc883_chmode_mixer },
5607		.init_verbs = { alc883_init_verbs,
5608				alc883_medion_eapd_verbs },
5609		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5610		.dac_nids = alc883_dac_nids,
5611		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5612		.adc_nids = alc883_adc_nids,
5613		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5614		.channel_mode = alc883_sixstack_modes,
5615		.input_mux = &alc883_capture_source,
5616	},
5617	[ALC883_LAPTOP_EAPD] = {
5618		.mixers = { alc883_base_mixer,
5619			    alc883_chmode_mixer },
5620		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
5621		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
5622		.dac_nids = alc883_dac_nids,
5623		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5624		.adc_nids = alc883_adc_nids,
5625		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5626		.channel_mode = alc883_3ST_2ch_modes,
5627		.input_mux = &alc883_capture_source,
5628	},
5629};
5630
5631
5632/*
5633 * BIOS auto configuration
5634 */
5635static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
5636					      hda_nid_t nid, int pin_type,
5637					      int dac_idx)
5638{
5639	/* set as output */
5640	struct alc_spec *spec = codec->spec;
5641	int idx;
5642
5643	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5644		idx = 4;
5645	else
5646		idx = spec->multiout.dac_nids[dac_idx] - 2;
5647
5648	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5649			    pin_type);
5650	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5651			    AMP_OUT_UNMUTE);
5652	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5653
5654}
5655
5656static void alc883_auto_init_multi_out(struct hda_codec *codec)
5657{
5658	struct alc_spec *spec = codec->spec;
5659	int i;
5660
5661	for (i = 0; i <= HDA_SIDE; i++) {
5662		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5663		if (nid)
5664			alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
5665	}
5666}
5667
5668static void alc883_auto_init_hp_out(struct hda_codec *codec)
5669{
5670	struct alc_spec *spec = codec->spec;
5671	hda_nid_t pin;
5672
5673	pin = spec->autocfg.hp_pins[0];
5674	if (pin) /* connect to front */
5675		/* use dac 0 */
5676		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5677}
5678
5679#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
5680#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
5681
5682static void alc883_auto_init_analog_input(struct hda_codec *codec)
5683{
5684	struct alc_spec *spec = codec->spec;
5685	int i;
5686
5687	for (i = 0; i < AUTO_PIN_LAST; i++) {
5688		hda_nid_t nid = spec->autocfg.input_pins[i];
5689		if (alc883_is_input_pin(nid)) {
5690			snd_hda_codec_write(codec, nid, 0,
5691					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5692					    (i <= AUTO_PIN_FRONT_MIC ?
5693					     PIN_VREF80 : PIN_IN));
5694			if (nid != ALC883_PIN_CD_NID)
5695				snd_hda_codec_write(codec, nid, 0,
5696						    AC_VERB_SET_AMP_GAIN_MUTE,
5697						    AMP_OUT_MUTE);
5698		}
5699	}
5700}
5701
5702/* almost identical with ALC880 parser... */
5703static int alc883_parse_auto_config(struct hda_codec *codec)
5704{
5705	struct alc_spec *spec = codec->spec;
5706	int err = alc880_parse_auto_config(codec);
5707
5708	if (err < 0)
5709		return err;
5710	else if (err > 0)
5711		/* hack - override the init verbs */
5712		spec->init_verbs[0] = alc883_auto_init_verbs;
5713                spec->mixers[spec->num_mixers] = alc883_capture_mixer;
5714		spec->num_mixers++;
5715	return err;
5716}
5717
5718/* additional initialization for auto-configuration model */
5719static void alc883_auto_init(struct hda_codec *codec)
5720{
5721	alc883_auto_init_multi_out(codec);
5722	alc883_auto_init_hp_out(codec);
5723	alc883_auto_init_analog_input(codec);
5724}
5725
5726static int patch_alc883(struct hda_codec *codec)
5727{
5728	struct alc_spec *spec;
5729	int err, board_config;
5730
5731	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5732	if (spec == NULL)
5733		return -ENOMEM;
5734
5735	codec->spec = spec;
5736
5737	board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl);
5738	if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
5739		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
5740		       "trying auto-probe from BIOS...\n");
5741		board_config = ALC883_AUTO;
5742	}
5743
5744	if (board_config == ALC883_AUTO) {
5745		/* automatic parse from the BIOS config */
5746		err = alc883_parse_auto_config(codec);
5747		if (err < 0) {
5748			alc_free(codec);
5749			return err;
5750		} else if (! err) {
5751			printk(KERN_INFO
5752			       "hda_codec: Cannot set up configuration "
5753			       "from BIOS.  Using base mode...\n");
5754			board_config = ALC883_3ST_2ch_DIG;
5755		}
5756	}
5757
5758	if (board_config != ALC883_AUTO)
5759		setup_preset(spec, &alc883_presets[board_config]);
5760
5761	spec->stream_name_analog = "ALC883 Analog";
5762	spec->stream_analog_playback = &alc883_pcm_analog_playback;
5763	spec->stream_analog_capture = &alc883_pcm_analog_capture;
5764
5765	spec->stream_name_digital = "ALC883 Digital";
5766	spec->stream_digital_playback = &alc883_pcm_digital_playback;
5767	spec->stream_digital_capture = &alc883_pcm_digital_capture;
5768
5769	if (! spec->adc_nids && spec->input_mux) {
5770		spec->adc_nids = alc883_adc_nids;
5771		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
5772	}
5773
5774	codec->patch_ops = alc_patch_ops;
5775	if (board_config == ALC883_AUTO)
5776		spec->init_hook = alc883_auto_init;
5777
5778	return 0;
5779}
5780
5781/*
5782 * ALC262 support
5783 */
5784
5785#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
5786#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
5787
5788#define alc262_dac_nids		alc260_dac_nids
5789#define alc262_adc_nids		alc882_adc_nids
5790#define alc262_adc_nids_alt	alc882_adc_nids_alt
5791
5792#define alc262_modes		alc260_modes
5793#define alc262_capture_source	alc882_capture_source
5794
5795static struct snd_kcontrol_new alc262_base_mixer[] = {
5796	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5797	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5798	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5799	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5800	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5801	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5802	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5803	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5804	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5805	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5806	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5807	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5808	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
5809	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5810	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5811	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5812	{ } /* end */
5813};
5814
5815static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
5816	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5817	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5818	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5819	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5820	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5821	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5822	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5823	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5824	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5825	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5826	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5827	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5828	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
5829	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5830	{ } /* end */
5831};
5832
5833static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
5834	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5835	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5836	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5837	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5838	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5839
5840	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5841	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5842	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5843	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5844	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5845	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5846	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5847	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5848	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5849	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
5850	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
5851	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
5852	{ } /* end */
5853};
5854
5855#define alc262_capture_mixer		alc882_capture_mixer
5856#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
5857
5858/*
5859 * generic initialization of ADC, input mixers and output mixers
5860 */
5861static struct hda_verb alc262_init_verbs[] = {
5862	/*
5863	 * Unmute ADC0-2 and set the default input to mic-in
5864	 */
5865	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5866	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5867	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5868	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5869	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5870	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5871
5872	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5873	 * mixer widget
5874	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
5875	 * mic (mic 2)
5876	 */
5877	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5878	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5879	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5880	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5881	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5882	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
5883
5884	/*
5885	 * Set up output mixers (0x0c - 0x0e)
5886	 */
5887	/* set vol=0 to output mixers */
5888	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5889	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5890	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5891	/* set up input amps for analog loopback */
5892	/* Amp Indices: DAC = 0, mixer = 1 */
5893	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5894	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5895	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5896	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5897	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5898	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5899
5900	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5901	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5902	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5903	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5904	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5905	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5906
5907	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5908	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5909	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5910	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5911	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5912
5913	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5914	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5915
5916	/* FIXME: use matrix-type input source selection */
5917	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5918	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5919	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5920	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5921	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5922	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5923	/* Input mixer2 */
5924	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5925	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5926	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5927	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5928	/* Input mixer3 */
5929	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5930	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5931	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5932	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5933
5934	{ }
5935};
5936
5937static struct hda_verb alc262_hippo_unsol_verbs[] = {
5938	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5939	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5940	{}
5941};
5942
5943static struct hda_verb alc262_hippo1_unsol_verbs[] = {
5944	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5945	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5946	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5947
5948	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5949	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5950	{}
5951};
5952
5953/* mute/unmute internal speaker according to the hp jack and mute state */
5954static void alc262_hippo_automute(struct hda_codec *codec, int force)
5955{
5956	struct alc_spec *spec = codec->spec;
5957	unsigned int mute;
5958
5959	if (force || ! spec->sense_updated) {
5960		unsigned int present;
5961		/* need to execute and sync at first */
5962		snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
5963		present = snd_hda_codec_read(codec, 0x15, 0,
5964				    	 AC_VERB_GET_PIN_SENSE, 0);
5965		spec->jack_present = (present & 0x80000000) != 0;
5966		spec->sense_updated = 1;
5967	}
5968	if (spec->jack_present) {
5969		/* mute internal speaker */
5970		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5971					 0x80, 0x80);
5972		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5973					 0x80, 0x80);
5974	} else {
5975		/* unmute internal speaker if necessary */
5976		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
5977		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
5978					 0x80, mute & 0x80);
5979		mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
5980		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
5981					 0x80, mute & 0x80);
5982	}
5983}
5984
5985/* unsolicited event for HP jack sensing */
5986static void alc262_hippo_unsol_event(struct hda_codec *codec,
5987				       unsigned int res)
5988{
5989	if ((res >> 26) != ALC880_HP_EVENT)
5990		return;
5991	alc262_hippo_automute(codec, 1);
5992}
5993
5994static void alc262_hippo1_automute(struct hda_codec *codec, int force)
5995{
5996	struct alc_spec *spec = codec->spec;
5997	unsigned int mute;
5998
5999	if (force || ! spec->sense_updated) {
6000		unsigned int present;
6001		/* need to execute and sync at first */
6002		snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
6003		present = snd_hda_codec_read(codec, 0x1b, 0,
6004				    	 AC_VERB_GET_PIN_SENSE, 0);
6005		spec->jack_present = (present & 0x80000000) != 0;
6006		spec->sense_updated = 1;
6007	}
6008	if (spec->jack_present) {
6009		/* mute internal speaker */
6010		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6011					 0x80, 0x80);
6012		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6013					 0x80, 0x80);
6014	} else {
6015		/* unmute internal speaker if necessary */
6016		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
6017		snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6018					 0x80, mute & 0x80);
6019		mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
6020		snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6021					 0x80, mute & 0x80);
6022	}
6023}
6024
6025/* unsolicited event for HP jack sensing */
6026static void alc262_hippo1_unsol_event(struct hda_codec *codec,
6027				       unsigned int res)
6028{
6029	if ((res >> 26) != ALC880_HP_EVENT)
6030		return;
6031	alc262_hippo1_automute(codec, 1);
6032}
6033
6034/*
6035 * fujitsu model
6036 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
6037 */
6038
6039#define ALC_HP_EVENT	0x37
6040
6041static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
6042	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
6043	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6044	{}
6045};
6046
6047static struct hda_input_mux alc262_fujitsu_capture_source = {
6048	.num_items = 2,
6049	.items = {
6050		{ "Mic", 0x0 },
6051		{ "CD", 0x4 },
6052	},
6053};
6054
6055static struct hda_input_mux alc262_HP_capture_source = {
6056	.num_items = 5,
6057	.items = {
6058		{ "Mic", 0x0 },
6059		{ "Front Mic", 0x3 },
6060		{ "Line", 0x2 },
6061		{ "CD", 0x4 },
6062		{ "AUX IN", 0x6 },
6063	},
6064};
6065
6066/* mute/unmute internal speaker according to the hp jack and mute state */
6067static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
6068{
6069	struct alc_spec *spec = codec->spec;
6070	unsigned int mute;
6071
6072	if (force || ! spec->sense_updated) {
6073		unsigned int present;
6074		/* need to execute and sync at first */
6075		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
6076		present = snd_hda_codec_read(codec, 0x14, 0,
6077				    	 AC_VERB_GET_PIN_SENSE, 0);
6078		spec->jack_present = (present & 0x80000000) != 0;
6079		spec->sense_updated = 1;
6080	}
6081	if (spec->jack_present) {
6082		/* mute internal speaker */
6083		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6084					 0x80, 0x80);
6085		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6086					 0x80, 0x80);
6087	} else {
6088		/* unmute internal speaker if necessary */
6089		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
6090		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
6091					 0x80, mute & 0x80);
6092		mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
6093		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
6094					 0x80, mute & 0x80);
6095	}
6096}
6097
6098/* unsolicited event for HP jack sensing */
6099static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
6100				       unsigned int res)
6101{
6102	if ((res >> 26) != ALC_HP_EVENT)
6103		return;
6104	alc262_fujitsu_automute(codec, 1);
6105}
6106
6107/* bind volumes of both NID 0x0c and 0x0d */
6108static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
6109					 struct snd_ctl_elem_value *ucontrol)
6110{
6111	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6112	long *valp = ucontrol->value.integer.value;
6113	int change;
6114
6115	change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
6116					  0x7f, valp[0] & 0x7f);
6117	change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
6118					   0x7f, valp[1] & 0x7f);
6119	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
6120				 0x7f, valp[0] & 0x7f);
6121	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
6122				 0x7f, valp[1] & 0x7f);
6123	return change;
6124}
6125
6126/* bind hp and internal speaker mute (with plug check) */
6127static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
6128					 struct snd_ctl_elem_value *ucontrol)
6129{
6130	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6131	long *valp = ucontrol->value.integer.value;
6132	int change;
6133
6134	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6135					  0x80, valp[0] ? 0 : 0x80);
6136	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6137					   0x80, valp[1] ? 0 : 0x80);
6138	if (change || codec->in_resume)
6139		alc262_fujitsu_automute(codec, codec->in_resume);
6140	return change;
6141}
6142
6143static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
6144	{
6145		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6146		.name = "Master Playback Volume",
6147		.info = snd_hda_mixer_amp_volume_info,
6148		.get = snd_hda_mixer_amp_volume_get,
6149		.put = alc262_fujitsu_master_vol_put,
6150		.tlv = { .c = snd_hda_mixer_amp_tlv },
6151		.private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
6152	},
6153	{
6154		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6155		.name = "Master Playback Switch",
6156		.info = snd_hda_mixer_amp_switch_info,
6157		.get = snd_hda_mixer_amp_switch_get,
6158		.put = alc262_fujitsu_master_sw_put,
6159		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
6160	},
6161	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6162	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6163	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6164	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6165	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6166	{ } /* end */
6167};
6168
6169/* additional init verbs for Benq laptops */
6170static struct hda_verb alc262_EAPD_verbs[] = {
6171	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6172	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
6173	{}
6174};
6175
6176/* add playback controls from the parsed DAC table */
6177static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
6178{
6179	hda_nid_t nid;
6180	int err;
6181
6182	spec->multiout.num_dacs = 1;	/* only use one dac */
6183	spec->multiout.dac_nids = spec->private_dac_nids;
6184	spec->multiout.dac_nids[0] = 2;
6185
6186	nid = cfg->line_out_pins[0];
6187	if (nid) {
6188		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
6189				       HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
6190			return err;
6191		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
6192				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6193			return err;
6194	}
6195
6196	nid = cfg->speaker_pins[0];
6197	if (nid) {
6198		if (nid == 0x16) {
6199			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
6200					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
6201				return err;
6202			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
6203					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
6204				return err;
6205		} else {
6206			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
6207					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6208				return err;
6209		}
6210	}
6211	nid = cfg->hp_pins[0];
6212	if (nid) {
6213		/* spec->multiout.hp_nid = 2; */
6214		if (nid == 0x16) {
6215			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
6216					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
6217				return err;
6218			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
6219					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
6220				return err;
6221		} else {
6222			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
6223					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
6224				return err;
6225		}
6226	}
6227	return 0;
6228}
6229
6230/* identical with ALC880 */
6231#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
6232
6233/*
6234 * generic initialization of ADC, input mixers and output mixers
6235 */
6236static struct hda_verb alc262_volume_init_verbs[] = {
6237	/*
6238	 * Unmute ADC0-2 and set the default input to mic-in
6239	 */
6240	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6241	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6242	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6243	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6244	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6245	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6246
6247	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6248	 * mixer widget
6249	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
6250	 * mic (mic 2)
6251	 */
6252	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6253	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6254	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6255	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6256	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6257	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6258
6259	/*
6260	 * Set up output mixers (0x0c - 0x0f)
6261	 */
6262	/* set vol=0 to output mixers */
6263	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6264	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6265	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6266
6267	/* set up input amps for analog loopback */
6268	/* Amp Indices: DAC = 0, mixer = 1 */
6269	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6270	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6271	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6272	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6273	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6274	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6275
6276	/* FIXME: use matrix-type input source selection */
6277	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6278	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6279	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6280	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6281	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6282	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6283	/* Input mixer2 */
6284	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6285	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6286	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6287	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6288	/* Input mixer3 */
6289	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6290	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6291	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6292	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6293
6294	{ }
6295};
6296
6297static struct hda_verb alc262_HP_BPC_init_verbs[] = {
6298	/*
6299	 * Unmute ADC0-2 and set the default input to mic-in
6300	 */
6301	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6302	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6303	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6304	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6305	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6306	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6307
6308	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6309	 * mixer widget
6310	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
6311	 * mic (mic 2)
6312	 */
6313	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6314	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6315	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6316	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6317	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6318	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6319	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
6320        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
6321
6322	/*
6323	 * Set up output mixers (0x0c - 0x0e)
6324	 */
6325	/* set vol=0 to output mixers */
6326	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6327	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6328	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6329
6330	/* set up input amps for analog loopback */
6331	/* Amp Indices: DAC = 0, mixer = 1 */
6332	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6333	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6334	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6335	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6336	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6337	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6338
6339	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6340	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6341	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6342
6343	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6344	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6345
6346	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6347	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6348
6349	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6350	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6351        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6352	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6353	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6354
6355	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
6356	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6357        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6358	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
6359	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6360	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6361
6362
6363	/* FIXME: use matrix-type input source selection */
6364	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6365	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6366	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6367	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6368	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6369	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6370	/* Input mixer2 */
6371	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6372	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6373	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6374	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6375	/* Input mixer3 */
6376	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6377	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6378	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6379	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6380
6381	{ }
6382};
6383
6384/* pcm configuration: identiacal with ALC880 */
6385#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
6386#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
6387#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
6388#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
6389
6390/*
6391 * BIOS auto configuration
6392 */
6393static int alc262_parse_auto_config(struct hda_codec *codec)
6394{
6395	struct alc_spec *spec = codec->spec;
6396	int err;
6397	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
6398
6399	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6400						alc262_ignore)) < 0)
6401		return err;
6402	if (! spec->autocfg.line_outs)
6403		return 0; /* can't find valid BIOS pin config */
6404	if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
6405	    (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
6406		return err;
6407
6408	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6409
6410	if (spec->autocfg.dig_out_pin)
6411		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
6412	if (spec->autocfg.dig_in_pin)
6413		spec->dig_in_nid = ALC262_DIGIN_NID;
6414
6415	if (spec->kctl_alloc)
6416		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
6417
6418	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
6419	spec->num_mux_defs = 1;
6420	spec->input_mux = &spec->private_imux;
6421
6422	return 1;
6423}
6424
6425#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
6426#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
6427#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
6428
6429
6430/* init callback for auto-configuration model -- overriding the default init */
6431static void alc262_auto_init(struct hda_codec *codec)
6432{
6433	alc262_auto_init_multi_out(codec);
6434	alc262_auto_init_hp_out(codec);
6435	alc262_auto_init_analog_input(codec);
6436}
6437
6438/*
6439 * configuration and preset
6440 */
6441static struct hda_board_config alc262_cfg_tbl[] = {
6442	{ .modelname = "basic", .config = ALC262_BASIC },
6443	{ .modelname = "hippo",
6444	  .pci_subvendor =0x1002, .pci_subdevice = 0x437b,
6445	  .config = ALC262_HIPPO},
6446	{ .modelname = "hippo",
6447	  .pci_subvendor = 0x104d, .pci_subdevice = 0x8203,
6448	  .config = ALC262_HIPPO }, /* Sony UX-90s */
6449	{ .modelname = "hippo_1",
6450	  .pci_subvendor =0x17ff, .pci_subdevice = 0x058f,
6451	  .config = ALC262_HIPPO_1},
6452	{ .modelname = "fujitsu", .config = ALC262_FUJITSU },
6453	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397,
6454	  .config = ALC262_FUJITSU },
6455	{ .modelname = "hp-bpc", .config = ALC262_HP_BPC },
6456	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x280c,
6457	  .config = ALC262_HP_BPC }, /* xw4400 */
6458	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x2801,
6459	  .config = ALC262_HP_BPC }, /* q965 */
6460	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3014,
6461	  .config = ALC262_HP_BPC }, /* xw6400 */
6462	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3015,
6463	  .config = ALC262_HP_BPC }, /* xw8400 */
6464	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe,
6465	  .config = ALC262_HP_BPC }, /* xw9400 */
6466	{ .modelname = "benq", .config = ALC262_BENQ_ED8 },
6467	{ .pci_subvendor = 0x17ff, .pci_subdevice = 0x0560,
6468	  .config = ALC262_BENQ_ED8 },
6469	{ .modelname = "auto", .config = ALC262_AUTO },
6470	{}
6471};
6472
6473static struct alc_config_preset alc262_presets[] = {
6474	[ALC262_BASIC] = {
6475		.mixers = { alc262_base_mixer },
6476		.init_verbs = { alc262_init_verbs },
6477		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6478		.dac_nids = alc262_dac_nids,
6479		.hp_nid = 0x03,
6480		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6481		.channel_mode = alc262_modes,
6482		.input_mux = &alc262_capture_source,
6483	},
6484	[ALC262_HIPPO] = {
6485		.mixers = { alc262_base_mixer },
6486		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
6487		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6488		.dac_nids = alc262_dac_nids,
6489		.hp_nid = 0x03,
6490		.dig_out_nid = ALC262_DIGOUT_NID,
6491		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6492		.channel_mode = alc262_modes,
6493		.input_mux = &alc262_capture_source,
6494		.unsol_event = alc262_hippo_unsol_event,
6495	},
6496	[ALC262_HIPPO_1] = {
6497		.mixers = { alc262_hippo1_mixer },
6498		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
6499		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6500		.dac_nids = alc262_dac_nids,
6501		.hp_nid = 0x02,
6502		.dig_out_nid = ALC262_DIGOUT_NID,
6503		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6504		.channel_mode = alc262_modes,
6505		.input_mux = &alc262_capture_source,
6506		.unsol_event = alc262_hippo1_unsol_event,
6507	},
6508	[ALC262_FUJITSU] = {
6509		.mixers = { alc262_fujitsu_mixer },
6510		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
6511		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6512		.dac_nids = alc262_dac_nids,
6513		.hp_nid = 0x03,
6514		.dig_out_nid = ALC262_DIGOUT_NID,
6515		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6516		.channel_mode = alc262_modes,
6517		.input_mux = &alc262_fujitsu_capture_source,
6518		.unsol_event = alc262_fujitsu_unsol_event,
6519	},
6520	[ALC262_HP_BPC] = {
6521		.mixers = { alc262_HP_BPC_mixer },
6522		.init_verbs = { alc262_HP_BPC_init_verbs },
6523		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6524		.dac_nids = alc262_dac_nids,
6525		.hp_nid = 0x03,
6526		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6527		.channel_mode = alc262_modes,
6528		.input_mux = &alc262_HP_capture_source,
6529	},
6530	[ALC262_BENQ_ED8] = {
6531		.mixers = { alc262_base_mixer },
6532		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
6533		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
6534		.dac_nids = alc262_dac_nids,
6535		.hp_nid = 0x03,
6536		.num_channel_mode = ARRAY_SIZE(alc262_modes),
6537		.channel_mode = alc262_modes,
6538		.input_mux = &alc262_capture_source,
6539	},
6540};
6541
6542static int patch_alc262(struct hda_codec *codec)
6543{
6544	struct alc_spec *spec;
6545	int board_config;
6546	int err;
6547
6548	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
6549	if (spec == NULL)
6550		return -ENOMEM;
6551
6552	codec->spec = spec;
6553#if 0
6554	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
6555	{
6556	int tmp;
6557	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
6558	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
6559	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
6560	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
6561	}
6562#endif
6563
6564	board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl);
6565
6566	if (board_config < 0 || board_config >= ALC262_MODEL_LAST) {
6567		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
6568		       "trying auto-probe from BIOS...\n");
6569		board_config = ALC262_AUTO;
6570	}
6571
6572	if (board_config == ALC262_AUTO) {
6573		/* automatic parse from the BIOS config */
6574		err = alc262_parse_auto_config(codec);
6575		if (err < 0) {
6576			alc_free(codec);
6577			return err;
6578		} else if (! err) {
6579			printk(KERN_INFO
6580			       "hda_codec: Cannot set up configuration "
6581			       "from BIOS.  Using base mode...\n");
6582			board_config = ALC262_BASIC;
6583		}
6584	}
6585
6586	if (board_config != ALC262_AUTO)
6587		setup_preset(spec, &alc262_presets[board_config]);
6588
6589	spec->stream_name_analog = "ALC262 Analog";
6590	spec->stream_analog_playback = &alc262_pcm_analog_playback;
6591	spec->stream_analog_capture = &alc262_pcm_analog_capture;
6592
6593	spec->stream_name_digital = "ALC262 Digital";
6594	spec->stream_digital_playback = &alc262_pcm_digital_playback;
6595	spec->stream_digital_capture = &alc262_pcm_digital_capture;
6596
6597	if (! spec->adc_nids && spec->input_mux) {
6598		/* check whether NID 0x07 is valid */
6599		unsigned int wcap = get_wcaps(codec, 0x07);
6600
6601		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
6602		if (wcap != AC_WID_AUD_IN) {
6603			spec->adc_nids = alc262_adc_nids_alt;
6604			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
6605			spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
6606			spec->num_mixers++;
6607		} else {
6608			spec->adc_nids = alc262_adc_nids;
6609			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
6610			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
6611			spec->num_mixers++;
6612		}
6613	}
6614
6615	codec->patch_ops = alc_patch_ops;
6616	if (board_config == ALC262_AUTO)
6617		spec->init_hook = alc262_auto_init;
6618
6619	return 0;
6620}
6621
6622/*
6623 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
6624 */
6625
6626/*
6627 * set the path ways for 2 channel output
6628 * need to set the codec line out and mic 1 pin widgets to inputs
6629 */
6630static struct hda_verb alc861_threestack_ch2_init[] = {
6631	/* set pin widget 1Ah (line in) for input */
6632	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6633	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
6634	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6635
6636	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
6637#if 0
6638	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6639	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
6640#endif
6641	{ } /* end */
6642};
6643/*
6644 * 6ch mode
6645 * need to set the codec line out and mic 1 pin widgets to outputs
6646 */
6647static struct hda_verb alc861_threestack_ch6_init[] = {
6648	/* set pin widget 1Ah (line in) for output (Back Surround)*/
6649	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6650	/* set pin widget 18h (mic1) for output (CLFE)*/
6651	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6652
6653	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
6654	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
6655
6656	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
6657#if 0
6658	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6659	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
6660#endif
6661	{ } /* end */
6662};
6663
6664static struct hda_channel_mode alc861_threestack_modes[2] = {
6665	{ 2, alc861_threestack_ch2_init },
6666	{ 6, alc861_threestack_ch6_init },
6667};
6668/* Set mic1 as input and unmute the mixer */
6669static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
6670	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6671	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6672	{ } /* end */
6673};
6674/* Set mic1 as output and mute mixer */
6675static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
6676	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6677	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6678	{ } /* end */
6679};
6680
6681static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
6682	{ 2, alc861_uniwill_m31_ch2_init },
6683	{ 4, alc861_uniwill_m31_ch4_init },
6684};
6685
6686/* Set mic1 and line-in as input and unmute the mixer */
6687static struct hda_verb alc861_asus_ch2_init[] = {
6688	/* set pin widget 1Ah (line in) for input */
6689	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6690	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
6691	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6692
6693	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
6694#if 0
6695	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6696	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
6697#endif
6698	{ } /* end */
6699};
6700/* Set mic1 nad line-in as output and mute mixer */
6701static struct hda_verb alc861_asus_ch6_init[] = {
6702	/* set pin widget 1Ah (line in) for output (Back Surround)*/
6703	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6704	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6705	/* set pin widget 18h (mic1) for output (CLFE)*/
6706	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6707	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6708	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
6709	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
6710
6711	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
6712#if 0
6713	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6714	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
6715#endif
6716	{ } /* end */
6717};
6718
6719static struct hda_channel_mode alc861_asus_modes[2] = {
6720	{ 2, alc861_asus_ch2_init },
6721	{ 6, alc861_asus_ch6_init },
6722};
6723
6724/* patch-ALC861 */
6725
6726static struct snd_kcontrol_new alc861_base_mixer[] = {
6727        /* output mixer control */
6728	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6729	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6730	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6731	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6732	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
6733
6734        /*Input mixer control */
6735	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6736	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6737	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6738	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6739	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6740	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6741	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6742	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6743	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6744	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6745
6746        /* Capture mixer control */
6747	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6748	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6749	{
6750		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6751		.name = "Capture Source",
6752		.count = 1,
6753		.info = alc_mux_enum_info,
6754		.get = alc_mux_enum_get,
6755		.put = alc_mux_enum_put,
6756	},
6757	{ } /* end */
6758};
6759
6760static struct snd_kcontrol_new alc861_3ST_mixer[] = {
6761        /* output mixer control */
6762	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6763	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6764	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6765	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6766	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
6767
6768	/* Input mixer control */
6769	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6770	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6771	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6772	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6773	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6774	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6775	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6776	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6777	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6778	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6779
6780	/* Capture mixer control */
6781	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6782	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6783	{
6784		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6785		.name = "Capture Source",
6786		.count = 1,
6787		.info = alc_mux_enum_info,
6788		.get = alc_mux_enum_get,
6789		.put = alc_mux_enum_put,
6790	},
6791	{
6792		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6793		.name = "Channel Mode",
6794		.info = alc_ch_mode_info,
6795		.get = alc_ch_mode_get,
6796		.put = alc_ch_mode_put,
6797                .private_value = ARRAY_SIZE(alc861_threestack_modes),
6798	},
6799	{ } /* end */
6800};
6801
6802static snd_kcontrol_new_t alc861_toshiba_mixer[] = {
6803        /* output mixer control */
6804	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6805	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6806	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6807
6808        /*Capture mixer control */
6809	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6810	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6811	{
6812		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6813		.name = "Capture Source",
6814		.count = 1,
6815		.info = alc_mux_enum_info,
6816		.get = alc_mux_enum_get,
6817		.put = alc_mux_enum_put,
6818	},
6819
6820	{ } /* end */
6821};
6822
6823static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
6824        /* output mixer control */
6825	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6826	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6827	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6828	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6829	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
6830
6831	/* Input mixer control */
6832	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6833	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
6834	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6835	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6836	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6837	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6838	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6839	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6840	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6841	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
6842
6843	/* Capture mixer control */
6844	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6845	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6846	{
6847		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6848		.name = "Capture Source",
6849		.count = 1,
6850		.info = alc_mux_enum_info,
6851		.get = alc_mux_enum_get,
6852		.put = alc_mux_enum_put,
6853	},
6854	{
6855		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6856		.name = "Channel Mode",
6857		.info = alc_ch_mode_info,
6858		.get = alc_ch_mode_get,
6859		.put = alc_ch_mode_put,
6860                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
6861	},
6862	{ } /* end */
6863};
6864
6865static struct snd_kcontrol_new alc861_asus_mixer[] = {
6866        /* output mixer control */
6867	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
6868	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
6869	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
6870	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
6871	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
6872
6873	/* Input mixer control */
6874	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
6875	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6876	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6877	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6878	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
6879	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
6880	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
6881	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
6882	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
6883	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */
6884
6885	/* Capture mixer control */
6886	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6887	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6888	{
6889		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6890		.name = "Capture Source",
6891		.count = 1,
6892		.info = alc_mux_enum_info,
6893		.get = alc_mux_enum_get,
6894		.put = alc_mux_enum_put,
6895	},
6896	{
6897		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6898		.name = "Channel Mode",
6899		.info = alc_ch_mode_info,
6900		.get = alc_ch_mode_get,
6901		.put = alc_ch_mode_put,
6902                .private_value = ARRAY_SIZE(alc861_asus_modes),
6903	},
6904	{ }
6905};
6906
6907/* additional mixer */
6908static snd_kcontrol_new_t alc861_asus_laptop_mixer[] = {
6909	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
6910	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
6911	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
6912	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
6913	{ }
6914};
6915
6916/*
6917 * generic initialization of ADC, input mixers and output mixers
6918 */
6919static struct hda_verb alc861_base_init_verbs[] = {
6920	/*
6921	 * Unmute ADC0 and set the default input to mic-in
6922	 */
6923	/* port-A for surround (rear panel) */
6924	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6925	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
6926	/* port-B for mic-in (rear panel) with vref */
6927	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6928	/* port-C for line-in (rear panel) */
6929	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6930	/* port-D for Front */
6931	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6932	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
6933	/* port-E for HP out (front panel) */
6934	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6935	/* route front PCM to HP */
6936	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6937	/* port-F for mic-in (front panel) with vref */
6938	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6939	/* port-G for CLFE (rear panel) */
6940	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6941	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6942	/* port-H for side (rear panel) */
6943	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6944	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
6945	/* CD-in */
6946	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6947	/* route front mic to ADC1*/
6948	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6949	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6950
6951	/* Unmute DAC0~3 & spdif out*/
6952	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6953	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6954	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6955	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6956	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6957
6958	/* Unmute Mixer 14 (mic) 1c (Line in)*/
6959	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6960        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6961	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6962        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6963
6964	/* Unmute Stereo Mixer 15 */
6965	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6966	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6967	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6968	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
6969
6970	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6971	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6972	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6973	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6974	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6975	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6976	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6977	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6978	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
6979        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6980
6981	{ }
6982};
6983
6984static struct hda_verb alc861_threestack_init_verbs[] = {
6985	/*
6986	 * Unmute ADC0 and set the default input to mic-in
6987	 */
6988	/* port-A for surround (rear panel) */
6989	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6990	/* port-B for mic-in (rear panel) with vref */
6991	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6992	/* port-C for line-in (rear panel) */
6993	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6994	/* port-D for Front */
6995	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6996	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
6997	/* port-E for HP out (front panel) */
6998	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6999	/* route front PCM to HP */
7000	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7001	/* port-F for mic-in (front panel) with vref */
7002	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7003	/* port-G for CLFE (rear panel) */
7004	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7005	/* port-H for side (rear panel) */
7006	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7007	/* CD-in */
7008	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7009	/* route front mic to ADC1*/
7010	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7011	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7012	/* Unmute DAC0~3 & spdif out*/
7013	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7014	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7015	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7016	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7017	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7018
7019	/* Unmute Mixer 14 (mic) 1c (Line in)*/
7020	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7021        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7022	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7023        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7024
7025	/* Unmute Stereo Mixer 15 */
7026	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7027	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7028	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7029	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
7030
7031	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7032	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7033	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7034	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7035	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7036	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7037	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7038	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7039	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
7040        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7041	{ }
7042};
7043
7044static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
7045	/*
7046	 * Unmute ADC0 and set the default input to mic-in
7047	 */
7048	/* port-A for surround (rear panel) */
7049	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7050	/* port-B for mic-in (rear panel) with vref */
7051	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7052	/* port-C for line-in (rear panel) */
7053	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7054	/* port-D for Front */
7055	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7056	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
7057	/* port-E for HP out (front panel) */
7058	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80
7059	/* route front PCM to HP */
7060	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7061	/* port-F for mic-in (front panel) with vref */
7062	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7063	/* port-G for CLFE (rear panel) */
7064	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7065	/* port-H for side (rear panel) */
7066	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7067	/* CD-in */
7068	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7069	/* route front mic to ADC1*/
7070	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7071	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7072	/* Unmute DAC0~3 & spdif out*/
7073	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7074	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7075	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7076	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7077	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7078
7079	/* Unmute Mixer 14 (mic) 1c (Line in)*/
7080	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7081        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7082	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7083        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7084
7085	/* Unmute Stereo Mixer 15 */
7086	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7087	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7088	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7089	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
7090
7091	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7092	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7093	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7094	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7095	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7096	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7097	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7098	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7099	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
7100        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7101	{ }
7102};
7103
7104static struct hda_verb alc861_asus_init_verbs[] = {
7105	/*
7106	 * Unmute ADC0 and set the default input to mic-in
7107	 */
7108	/* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/
7109	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
7110	/* route front PCM to HP */
7111	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
7112	/* port-B for mic-in (rear panel) with vref */
7113	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7114	/* port-C for line-in (rear panel) */
7115	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7116	/* port-D for Front */
7117	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7118	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
7119	/* port-E for HP out (front panel) */
7120	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */
7121	/* route front PCM to HP */
7122	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7123	/* port-F for mic-in (front panel) with vref */
7124	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7125	/* port-G for CLFE (rear panel) */
7126	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7127	/* port-H for side (rear panel) */
7128	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7129	/* CD-in */
7130	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7131	/* route front mic to ADC1*/
7132	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7133	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7134	/* Unmute DAC0~3 & spdif out*/
7135	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7136	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7137	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7138	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7139	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7140	/* Unmute Mixer 14 (mic) 1c (Line in)*/
7141	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7142        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7143	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7144        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7145
7146	/* Unmute Stereo Mixer 15 */
7147	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7148	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7149	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7150	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, /* Output 0~12 step */
7151
7152	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7153	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7154	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7155	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7156	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7157	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7158	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7159	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7160	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */
7161	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7162	{ }
7163};
7164
7165/* additional init verbs for ASUS laptops */
7166static struct hda_verb alc861_asus_laptop_init_verbs[] = {
7167	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
7168	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
7169	{ }
7170};
7171
7172/*
7173 * generic initialization of ADC, input mixers and output mixers
7174 */
7175static struct hda_verb alc861_auto_init_verbs[] = {
7176	/*
7177	 * Unmute ADC0 and set the default input to mic-in
7178	 */
7179//	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7180	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7181
7182	/* Unmute DAC0~3 & spdif out*/
7183	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7184	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7185	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7186	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7187	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7188
7189	/* Unmute Mixer 14 (mic) 1c (Line in)*/
7190	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7191	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7192	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7193	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7194
7195	/* Unmute Stereo Mixer 15 */
7196	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7197	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7198	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7199	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
7200
7201	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7202	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7203	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7204	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7205	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7206	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7207	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7208	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7209
7210	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7211	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7212	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7213	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7214	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7215	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7216	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7217	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7218
7219	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	// set Mic 1
7220
7221	{ }
7222};
7223
7224static struct hda_verb alc861_toshiba_init_verbs[] = {
7225	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7226
7227	{ }
7228};
7229
7230/* toggle speaker-output according to the hp-jack state */
7231static void alc861_toshiba_automute(struct hda_codec *codec)
7232{
7233	unsigned int present;
7234
7235	present = snd_hda_codec_read(codec, 0x0f, 0,
7236				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7237	snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
7238				 0x80, present ? 0x80 : 0);
7239	snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
7240				 0x80, present ? 0x80 : 0);
7241	snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
7242				 0x80, present ? 0 : 0x80);
7243	snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
7244				 0x80, present ? 0 : 0x80);
7245}
7246
7247static void alc861_toshiba_unsol_event(struct hda_codec *codec,
7248				       unsigned int res)
7249{
7250	/* Looks like the unsol event is incompatible with the standard
7251	 * definition.  6bit tag is placed at 26 bit!
7252	 */
7253	if ((res >> 26) == ALC880_HP_EVENT)
7254		alc861_toshiba_automute(codec);
7255}
7256
7257/* pcm configuration: identiacal with ALC880 */
7258#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
7259#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
7260#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
7261#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
7262
7263
7264#define ALC861_DIGOUT_NID	0x07
7265
7266static struct hda_channel_mode alc861_8ch_modes[1] = {
7267	{ 8, NULL }
7268};
7269
7270static hda_nid_t alc861_dac_nids[4] = {
7271	/* front, surround, clfe, side */
7272	0x03, 0x06, 0x05, 0x04
7273};
7274
7275static hda_nid_t alc660_dac_nids[3] = {
7276	/* front, clfe, surround */
7277	0x03, 0x05, 0x06
7278};
7279
7280static hda_nid_t alc861_adc_nids[1] = {
7281	/* ADC0-2 */
7282	0x08,
7283};
7284
7285static struct hda_input_mux alc861_capture_source = {
7286	.num_items = 5,
7287	.items = {
7288		{ "Mic", 0x0 },
7289		{ "Front Mic", 0x3 },
7290		{ "Line", 0x1 },
7291		{ "CD", 0x4 },
7292		{ "Mixer", 0x5 },
7293	},
7294};
7295
7296/* fill in the dac_nids table from the parsed pin configuration */
7297static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
7298{
7299	int i;
7300	hda_nid_t nid;
7301
7302	spec->multiout.dac_nids = spec->private_dac_nids;
7303	for (i = 0; i < cfg->line_outs; i++) {
7304		nid = cfg->line_out_pins[i];
7305		if (nid) {
7306			if (i >= ARRAY_SIZE(alc861_dac_nids))
7307				continue;
7308			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
7309		}
7310	}
7311	spec->multiout.num_dacs = cfg->line_outs;
7312	return 0;
7313}
7314
7315/* add playback controls from the parsed DAC table */
7316static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
7317					     const struct auto_pin_cfg *cfg)
7318{
7319	char name[32];
7320	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
7321	hda_nid_t nid;
7322	int i, idx, err;
7323
7324	for (i = 0; i < cfg->line_outs; i++) {
7325		nid = spec->multiout.dac_nids[i];
7326		if (! nid)
7327			continue;
7328		if (nid == 0x05) {
7329			/* Center/LFE */
7330			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
7331					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
7332				return err;
7333			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
7334					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
7335				return err;
7336		} else {
7337			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
7338				if (nid == alc861_dac_nids[idx])
7339					break;
7340			sprintf(name, "%s Playback Switch", chname[idx]);
7341			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
7342					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
7343				return err;
7344		}
7345	}
7346	return 0;
7347}
7348
7349static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
7350{
7351	int err;
7352	hda_nid_t nid;
7353
7354	if (! pin)
7355		return 0;
7356
7357	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
7358		nid = 0x03;
7359		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
7360				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
7361			return err;
7362		spec->multiout.hp_nid = nid;
7363	}
7364	return 0;
7365}
7366
7367/* create playback/capture controls for input pins */
7368static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
7369{
7370	struct hda_input_mux *imux = &spec->private_imux;
7371	int i, err, idx, idx1;
7372
7373	for (i = 0; i < AUTO_PIN_LAST; i++) {
7374		switch(cfg->input_pins[i]) {
7375		case 0x0c:
7376			idx1 = 1;
7377			idx = 2;	// Line In
7378			break;
7379		case 0x0f:
7380			idx1 = 2;
7381			idx = 2;	// Line In
7382			break;
7383		case 0x0d:
7384			idx1 = 0;
7385			idx = 1;	// Mic In
7386			break;
7387		case 0x10:
7388			idx1 = 3;
7389			idx = 1;	// Mic In
7390			break;
7391		case 0x11:
7392			idx1 = 4;
7393			idx = 0;	// CD
7394			break;
7395		default:
7396			continue;
7397		}
7398
7399		err = new_analog_input(spec, cfg->input_pins[i],
7400				       auto_pin_cfg_labels[i], idx, 0x15);
7401		if (err < 0)
7402			return err;
7403
7404		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
7405		imux->items[imux->num_items].index = idx1;
7406		imux->num_items++;
7407	}
7408	return 0;
7409}
7410
7411static struct snd_kcontrol_new alc861_capture_mixer[] = {
7412	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7413	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7414
7415	{
7416		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7417		/* The multiple "Capture Source" controls confuse alsamixer
7418		 * So call somewhat different..
7419		 *FIXME: the controls appear in the "playback" view!
7420		 */
7421		/* .name = "Capture Source", */
7422		.name = "Input Source",
7423		.count = 1,
7424		.info = alc_mux_enum_info,
7425		.get = alc_mux_enum_get,
7426		.put = alc_mux_enum_put,
7427	},
7428	{ } /* end */
7429};
7430
7431static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
7432					      int pin_type, int dac_idx)
7433{
7434	/* set as output */
7435
7436	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
7437	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
7438
7439}
7440
7441static void alc861_auto_init_multi_out(struct hda_codec *codec)
7442{
7443	struct alc_spec *spec = codec->spec;
7444	int i;
7445
7446	for (i = 0; i < spec->autocfg.line_outs; i++) {
7447		hda_nid_t nid = spec->autocfg.line_out_pins[i];
7448		if (nid)
7449			alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
7450	}
7451}
7452
7453static void alc861_auto_init_hp_out(struct hda_codec *codec)
7454{
7455	struct alc_spec *spec = codec->spec;
7456	hda_nid_t pin;
7457
7458	pin = spec->autocfg.hp_pins[0];
7459	if (pin) /* connect to front */
7460		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
7461}
7462
7463static void alc861_auto_init_analog_input(struct hda_codec *codec)
7464{
7465	struct alc_spec *spec = codec->spec;
7466	int i;
7467
7468	for (i = 0; i < AUTO_PIN_LAST; i++) {
7469		hda_nid_t nid = spec->autocfg.input_pins[i];
7470		if ((nid>=0x0c) && (nid <=0x11)) {
7471			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7472					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
7473		}
7474	}
7475}
7476
7477/* parse the BIOS configuration and set up the alc_spec */
7478/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
7479static int alc861_parse_auto_config(struct hda_codec *codec)
7480{
7481	struct alc_spec *spec = codec->spec;
7482	int err;
7483	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
7484
7485	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7486						alc861_ignore)) < 0)
7487		return err;
7488	if (! spec->autocfg.line_outs)
7489		return 0; /* can't find valid BIOS pin config */
7490
7491	if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
7492	    (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
7493	    (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 ||
7494	    (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
7495		return err;
7496
7497	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
7498
7499	if (spec->autocfg.dig_out_pin)
7500		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
7501
7502	if (spec->kctl_alloc)
7503		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
7504
7505	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
7506
7507	spec->num_mux_defs = 1;
7508	spec->input_mux = &spec->private_imux;
7509
7510	spec->adc_nids = alc861_adc_nids;
7511	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
7512	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
7513	spec->num_mixers++;
7514
7515	return 1;
7516}
7517
7518/* additional initialization for auto-configuration model */
7519static void alc861_auto_init(struct hda_codec *codec)
7520{
7521	alc861_auto_init_multi_out(codec);
7522	alc861_auto_init_hp_out(codec);
7523	alc861_auto_init_analog_input(codec);
7524}
7525
7526
7527/*
7528 * configuration and preset
7529 */
7530static struct hda_board_config alc861_cfg_tbl[] = {
7531	{ .modelname = "3stack", .config = ALC861_3ST },
7532	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd600,
7533	  .config = ALC861_3ST },
7534	{ .modelname = "3stack-660", .config = ALC660_3ST },
7535	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7,
7536	  .config = ALC660_3ST },
7537	{ .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
7538	{ .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
7539	{ .modelname = "uniwill-m31", .config = ALC861_UNIWILL_M31},
7540	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9072,
7541	  .config = ALC861_UNIWILL_M31 },
7542	{ .modelname = "toshiba", .config = ALC861_TOSHIBA },
7543	{ .pci_subvendor = 0x1179, .pci_subdevice = 0xff10,
7544	  .config = ALC861_TOSHIBA },
7545	{ .modelname = "asus", .config = ALC861_ASUS},
7546	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1393,
7547	  .config = ALC861_ASUS },
7548	{ .modelname = "asus-laptop", .config = ALC861_ASUS_LAPTOP },
7549	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1335,
7550	  .config = ALC861_ASUS_LAPTOP }, /* ASUS F2/F3 */
7551	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1338,
7552	  .config = ALC861_ASUS_LAPTOP }, /* ASUS F2/F3 */
7553	{ .modelname = "auto", .config = ALC861_AUTO },
7554	{}
7555};
7556
7557static struct alc_config_preset alc861_presets[] = {
7558	[ALC861_3ST] = {
7559		.mixers = { alc861_3ST_mixer },
7560		.init_verbs = { alc861_threestack_init_verbs },
7561		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7562		.dac_nids = alc861_dac_nids,
7563		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7564		.channel_mode = alc861_threestack_modes,
7565		.need_dac_fix = 1,
7566		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7567		.adc_nids = alc861_adc_nids,
7568		.input_mux = &alc861_capture_source,
7569	},
7570	[ALC861_3ST_DIG] = {
7571		.mixers = { alc861_base_mixer },
7572		.init_verbs = { alc861_threestack_init_verbs },
7573		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7574		.dac_nids = alc861_dac_nids,
7575		.dig_out_nid = ALC861_DIGOUT_NID,
7576		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7577		.channel_mode = alc861_threestack_modes,
7578		.need_dac_fix = 1,
7579		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7580		.adc_nids = alc861_adc_nids,
7581		.input_mux = &alc861_capture_source,
7582	},
7583	[ALC861_6ST_DIG] = {
7584		.mixers = { alc861_base_mixer },
7585		.init_verbs = { alc861_base_init_verbs },
7586		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7587		.dac_nids = alc861_dac_nids,
7588		.dig_out_nid = ALC861_DIGOUT_NID,
7589		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
7590		.channel_mode = alc861_8ch_modes,
7591		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7592		.adc_nids = alc861_adc_nids,
7593		.input_mux = &alc861_capture_source,
7594	},
7595	[ALC660_3ST] = {
7596		.mixers = { alc861_3ST_mixer },
7597		.init_verbs = { alc861_threestack_init_verbs },
7598		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
7599		.dac_nids = alc660_dac_nids,
7600		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
7601		.channel_mode = alc861_threestack_modes,
7602		.need_dac_fix = 1,
7603		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7604		.adc_nids = alc861_adc_nids,
7605		.input_mux = &alc861_capture_source,
7606	},
7607	[ALC861_UNIWILL_M31] = {
7608		.mixers = { alc861_uniwill_m31_mixer },
7609		.init_verbs = { alc861_uniwill_m31_init_verbs },
7610		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7611		.dac_nids = alc861_dac_nids,
7612		.dig_out_nid = ALC861_DIGOUT_NID,
7613		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
7614		.channel_mode = alc861_uniwill_m31_modes,
7615		.need_dac_fix = 1,
7616		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7617		.adc_nids = alc861_adc_nids,
7618		.input_mux = &alc861_capture_source,
7619	},
7620	[ALC861_TOSHIBA] = {
7621		.mixers = { alc861_toshiba_mixer },
7622		.init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs },
7623		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7624		.dac_nids = alc861_dac_nids,
7625		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7626		.channel_mode = alc883_3ST_2ch_modes,
7627		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7628		.adc_nids = alc861_adc_nids,
7629		.input_mux = &alc861_capture_source,
7630		.unsol_event = alc861_toshiba_unsol_event,
7631		.init_hook = alc861_toshiba_automute,
7632	},
7633	[ALC861_ASUS] = {
7634		.mixers = { alc861_asus_mixer },
7635		.init_verbs = { alc861_asus_init_verbs },
7636		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7637		.dac_nids = alc861_dac_nids,
7638		.dig_out_nid = ALC861_DIGOUT_NID,
7639		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
7640		.channel_mode = alc861_asus_modes,
7641		.need_dac_fix = 1,
7642		.hp_nid = 0x06,
7643		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7644		.adc_nids = alc861_adc_nids,
7645		.input_mux = &alc861_capture_source,
7646	},
7647	[ALC861_ASUS_LAPTOP] = {
7648		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
7649		.init_verbs = { alc861_asus_init_verbs,
7650				alc861_asus_laptop_init_verbs },
7651		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
7652		.dac_nids = alc861_dac_nids,
7653		.dig_out_nid = ALC861_DIGOUT_NID,
7654		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7655		.channel_mode = alc883_3ST_2ch_modes,
7656		.need_dac_fix = 1,
7657		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7658		.adc_nids = alc861_adc_nids,
7659		.input_mux = &alc861_capture_source,
7660	},
7661};
7662
7663
7664static int patch_alc861(struct hda_codec *codec)
7665{
7666	struct alc_spec *spec;
7667	int board_config;
7668	int err;
7669
7670	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
7671	if (spec == NULL)
7672		return -ENOMEM;
7673
7674	codec->spec = spec;
7675
7676        board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl);
7677
7678	if (board_config < 0 || board_config >= ALC861_MODEL_LAST) {
7679		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
7680		       "trying auto-probe from BIOS...\n");
7681		board_config = ALC861_AUTO;
7682	}
7683
7684	if (board_config == ALC861_AUTO) {
7685		/* automatic parse from the BIOS config */
7686		err = alc861_parse_auto_config(codec);
7687		if (err < 0) {
7688			alc_free(codec);
7689			return err;
7690		} else if (! err) {
7691			printk(KERN_INFO
7692			       "hda_codec: Cannot set up configuration "
7693			       "from BIOS.  Using base mode...\n");
7694		   board_config = ALC861_3ST_DIG;
7695		}
7696	}
7697
7698	if (board_config != ALC861_AUTO)
7699		setup_preset(spec, &alc861_presets[board_config]);
7700
7701	spec->stream_name_analog = "ALC861 Analog";
7702	spec->stream_analog_playback = &alc861_pcm_analog_playback;
7703	spec->stream_analog_capture = &alc861_pcm_analog_capture;
7704
7705	spec->stream_name_digital = "ALC861 Digital";
7706	spec->stream_digital_playback = &alc861_pcm_digital_playback;
7707	spec->stream_digital_capture = &alc861_pcm_digital_capture;
7708
7709	codec->patch_ops = alc_patch_ops;
7710	if (board_config == ALC861_AUTO)
7711		spec->init_hook = alc861_auto_init;
7712
7713	return 0;
7714}
7715
7716/*
7717 * patch entries
7718 */
7719struct hda_codec_preset snd_hda_preset_realtek[] = {
7720	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
7721	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
7722 	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
7723	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
7724	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
7725	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
7726	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
7727	{ .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861",
7728	  .patch = patch_alc861 },
7729	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
7730	  .patch = patch_alc861 },
7731	{ .id = 0x10ec0660, .name = "ALC660", .patch = patch_alc861 },
7732	{} /* terminator */
7733};
7734