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