patch_realtek.c revision 6bc9685796529754acd819d9c979227d823c408d
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 *                    PeiSen Hou <pshou@realtek.com.tw>
8 *                    Takashi Iwai <tiwai@suse.de>
9 *                    Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10 *
11 *  This driver is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This driver is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License
22 *  along with this program; if not, write to the Free Software
23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24 */
25
26#include <sound/driver.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pci.h>
31#include <sound/core.h>
32#include "hda_codec.h"
33#include "hda_local.h"
34
35#define ALC880_FRONT_EVENT		0x01
36#define ALC880_DCVOL_EVENT		0x02
37#define ALC880_HP_EVENT			0x04
38#define ALC880_MIC_EVENT		0x08
39
40/* ALC880 board config type */
41enum {
42	ALC880_3ST,
43	ALC880_3ST_DIG,
44	ALC880_5ST,
45	ALC880_5ST_DIG,
46	ALC880_W810,
47	ALC880_Z71V,
48	ALC880_6ST,
49	ALC880_6ST_DIG,
50	ALC880_F1734,
51	ALC880_ASUS,
52	ALC880_ASUS_DIG,
53	ALC880_ASUS_W1V,
54	ALC880_ASUS_DIG2,
55	ALC880_FUJITSU,
56	ALC880_UNIWILL_DIG,
57	ALC880_UNIWILL,
58	ALC880_UNIWILL_P53,
59	ALC880_CLEVO,
60	ALC880_TCL_S700,
61	ALC880_LG,
62	ALC880_LG_LW,
63#ifdef CONFIG_SND_DEBUG
64	ALC880_TEST,
65#endif
66	ALC880_AUTO,
67	ALC880_MODEL_LAST /* last tag */
68};
69
70/* ALC260 models */
71enum {
72	ALC260_BASIC,
73	ALC260_HP,
74	ALC260_HP_3013,
75	ALC260_FUJITSU_S702X,
76	ALC260_ACER,
77	ALC260_WILL,
78	ALC260_REPLACER_672V,
79#ifdef CONFIG_SND_DEBUG
80	ALC260_TEST,
81#endif
82	ALC260_AUTO,
83	ALC260_MODEL_LAST /* last tag */
84};
85
86/* ALC262 models */
87enum {
88	ALC262_BASIC,
89	ALC262_HIPPO,
90	ALC262_HIPPO_1,
91	ALC262_FUJITSU,
92	ALC262_HP_BPC,
93	ALC262_HP_BPC_D7000_WL,
94	ALC262_HP_BPC_D7000_WF,
95	ALC262_BENQ_ED8,
96	ALC262_SONY_ASSAMD,
97	ALC262_BENQ_T31,
98	ALC262_AUTO,
99	ALC262_MODEL_LAST /* last tag */
100};
101
102/* ALC268 models */
103enum {
104	ALC268_3ST,
105	ALC268_TOSHIBA,
106	ALC268_ACER,
107	ALC268_AUTO,
108	ALC268_MODEL_LAST /* last tag */
109};
110
111/* ALC861 models */
112enum {
113	ALC861_3ST,
114	ALC660_3ST,
115	ALC861_3ST_DIG,
116	ALC861_6ST_DIG,
117	ALC861_UNIWILL_M31,
118	ALC861_TOSHIBA,
119	ALC861_ASUS,
120	ALC861_ASUS_LAPTOP,
121	ALC861_AUTO,
122	ALC861_MODEL_LAST,
123};
124
125/* ALC861-VD models */
126enum {
127	ALC660VD_3ST,
128	ALC660VD_3ST_DIG,
129	ALC861VD_3ST,
130	ALC861VD_3ST_DIG,
131	ALC861VD_6ST_DIG,
132	ALC861VD_LENOVO,
133	ALC861VD_DALLAS,
134	ALC861VD_HP,
135	ALC861VD_AUTO,
136	ALC861VD_MODEL_LAST,
137};
138
139/* ALC662 models */
140enum {
141	ALC662_3ST_2ch_DIG,
142	ALC662_3ST_6ch_DIG,
143	ALC662_3ST_6ch,
144	ALC662_5ST_DIG,
145	ALC662_LENOVO_101E,
146	ALC662_AUTO,
147	ALC662_MODEL_LAST,
148};
149
150/* ALC882 models */
151enum {
152	ALC882_3ST_DIG,
153	ALC882_6ST_DIG,
154	ALC882_ARIMA,
155	ALC882_W2JC,
156	ALC882_TARGA,
157	ALC882_ASUS_A7J,
158	ALC885_MACPRO,
159	ALC885_MBP3,
160	ALC885_IMAC24,
161	ALC882_AUTO,
162	ALC882_MODEL_LAST,
163};
164
165/* ALC883 models */
166enum {
167	ALC883_3ST_2ch_DIG,
168	ALC883_3ST_6ch_DIG,
169	ALC883_3ST_6ch,
170	ALC883_6ST_DIG,
171	ALC883_TARGA_DIG,
172	ALC883_TARGA_2ch_DIG,
173	ALC883_ACER,
174	ALC883_ACER_ASPIRE,
175	ALC883_MEDION,
176	ALC883_MEDION_MD2,
177	ALC883_LAPTOP_EAPD,
178	ALC883_LENOVO_101E_2ch,
179	ALC883_LENOVO_NB0763,
180	ALC888_LENOVO_MS7195_DIG,
181	ALC888_6ST_HP,
182	ALC888_3ST_HP,
183	ALC883_AUTO,
184	ALC883_MODEL_LAST,
185};
186
187/* for GPIO Poll */
188#define GPIO_MASK	0x03
189
190struct alc_spec {
191	/* codec parameterization */
192	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
193	unsigned int num_mixers;
194
195	const struct hda_verb *init_verbs[5];	/* initialization verbs
196						 * don't forget NULL
197						 * termination!
198						 */
199	unsigned int num_init_verbs;
200
201	char *stream_name_analog;	/* analog PCM stream */
202	struct hda_pcm_stream *stream_analog_playback;
203	struct hda_pcm_stream *stream_analog_capture;
204
205	char *stream_name_digital;	/* digital PCM stream */
206	struct hda_pcm_stream *stream_digital_playback;
207	struct hda_pcm_stream *stream_digital_capture;
208
209	/* playback */
210	struct hda_multi_out multiout;	/* playback set-up
211					 * max_channels, dacs must be set
212					 * dig_out_nid and hp_nid are optional
213					 */
214
215	/* capture */
216	unsigned int num_adc_nids;
217	hda_nid_t *adc_nids;
218	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
219
220	/* capture source */
221	unsigned int num_mux_defs;
222	const struct hda_input_mux *input_mux;
223	unsigned int cur_mux[3];
224
225	/* channel model */
226	const struct hda_channel_mode *channel_mode;
227	int num_channel_mode;
228	int need_dac_fix;
229
230	/* PCM information */
231	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
232
233	/* dynamic controls, init_verbs and input_mux */
234	struct auto_pin_cfg autocfg;
235	unsigned int num_kctl_alloc, num_kctl_used;
236	struct snd_kcontrol_new *kctl_alloc;
237	struct hda_input_mux private_imux;
238	hda_nid_t private_dac_nids[5];
239
240	/* hooks */
241	void (*init_hook)(struct hda_codec *codec);
242	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
243
244	/* for pin sensing */
245	unsigned int sense_updated: 1;
246	unsigned int jack_present: 1;
247
248#ifdef CONFIG_SND_HDA_POWER_SAVE
249	struct hda_loopback_check loopback;
250#endif
251};
252
253/*
254 * configuration template - to be copied to the spec instance
255 */
256struct alc_config_preset {
257	struct snd_kcontrol_new *mixers[5]; /* should be identical size
258					     * with spec
259					     */
260	const struct hda_verb *init_verbs[5];
261	unsigned int num_dacs;
262	hda_nid_t *dac_nids;
263	hda_nid_t dig_out_nid;		/* optional */
264	hda_nid_t hp_nid;		/* optional */
265	unsigned int num_adc_nids;
266	hda_nid_t *adc_nids;
267	hda_nid_t dig_in_nid;
268	unsigned int num_channel_mode;
269	const struct hda_channel_mode *channel_mode;
270	int need_dac_fix;
271	unsigned int num_mux_defs;
272	const struct hda_input_mux *input_mux;
273	void (*unsol_event)(struct hda_codec *, unsigned int);
274	void (*init_hook)(struct hda_codec *);
275#ifdef CONFIG_SND_HDA_POWER_SAVE
276	struct hda_amp_list *loopbacks;
277#endif
278};
279
280
281/*
282 * input MUX handling
283 */
284static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
285			     struct snd_ctl_elem_info *uinfo)
286{
287	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
288	struct alc_spec *spec = codec->spec;
289	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
290	if (mux_idx >= spec->num_mux_defs)
291		mux_idx = 0;
292	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
293}
294
295static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
296			    struct snd_ctl_elem_value *ucontrol)
297{
298	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
299	struct alc_spec *spec = codec->spec;
300	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
301
302	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
303	return 0;
304}
305
306static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
307			    struct snd_ctl_elem_value *ucontrol)
308{
309	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
310	struct alc_spec *spec = codec->spec;
311	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
312	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
313	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
314				     spec->adc_nids[adc_idx],
315				     &spec->cur_mux[adc_idx]);
316}
317
318
319/*
320 * channel mode setting
321 */
322static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
323			    struct snd_ctl_elem_info *uinfo)
324{
325	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
326	struct alc_spec *spec = codec->spec;
327	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
328				    spec->num_channel_mode);
329}
330
331static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
332			   struct snd_ctl_elem_value *ucontrol)
333{
334	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335	struct alc_spec *spec = codec->spec;
336	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
337				   spec->num_channel_mode,
338				   spec->multiout.max_channels);
339}
340
341static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
342			   struct snd_ctl_elem_value *ucontrol)
343{
344	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
345	struct alc_spec *spec = codec->spec;
346	int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
347				      spec->num_channel_mode,
348				      &spec->multiout.max_channels);
349	if (err >= 0 && spec->need_dac_fix)
350		spec->multiout.num_dacs = spec->multiout.max_channels / 2;
351	return err;
352}
353
354/*
355 * Control the mode of pin widget settings via the mixer.  "pc" is used
356 * instead of "%" to avoid consequences of accidently treating the % as
357 * being part of a format specifier.  Maximum allowed length of a value is
358 * 63 characters plus NULL terminator.
359 *
360 * Note: some retasking pin complexes seem to ignore requests for input
361 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
362 * are requested.  Therefore order this list so that this behaviour will not
363 * cause problems when mixer clients move through the enum sequentially.
364 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
365 * March 2006.
366 */
367static char *alc_pin_mode_names[] = {
368	"Mic 50pc bias", "Mic 80pc bias",
369	"Line in", "Line out", "Headphone out",
370};
371static unsigned char alc_pin_mode_values[] = {
372	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
373};
374/* The control can present all 5 options, or it can limit the options based
375 * in the pin being assumed to be exclusively an input or an output pin.  In
376 * addition, "input" pins may or may not process the mic bias option
377 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
378 * accept requests for bias as of chip versions up to March 2006) and/or
379 * wiring in the computer.
380 */
381#define ALC_PIN_DIR_IN              0x00
382#define ALC_PIN_DIR_OUT             0x01
383#define ALC_PIN_DIR_INOUT           0x02
384#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
385#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
386
387/* Info about the pin modes supported by the different pin direction modes.
388 * For each direction the minimum and maximum values are given.
389 */
390static signed char alc_pin_mode_dir_info[5][2] = {
391	{ 0, 2 },    /* ALC_PIN_DIR_IN */
392	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
393	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
394	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
395	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
396};
397#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
398#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
399#define alc_pin_mode_n_items(_dir) \
400	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
401
402static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
403			     struct snd_ctl_elem_info *uinfo)
404{
405	unsigned int item_num = uinfo->value.enumerated.item;
406	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
407
408	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
409	uinfo->count = 1;
410	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
411
412	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
413		item_num = alc_pin_mode_min(dir);
414	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
415	return 0;
416}
417
418static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
419			    struct snd_ctl_elem_value *ucontrol)
420{
421	unsigned int i;
422	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
423	hda_nid_t nid = kcontrol->private_value & 0xffff;
424	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
425	long *valp = ucontrol->value.integer.value;
426	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
427						 AC_VERB_GET_PIN_WIDGET_CONTROL,
428						 0x00);
429
430	/* Find enumerated value for current pinctl setting */
431	i = alc_pin_mode_min(dir);
432	while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
433		i++;
434	*valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
435	return 0;
436}
437
438static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
439			    struct snd_ctl_elem_value *ucontrol)
440{
441	signed int change;
442	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
443	hda_nid_t nid = kcontrol->private_value & 0xffff;
444	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
445	long val = *ucontrol->value.integer.value;
446	unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
447						 AC_VERB_GET_PIN_WIDGET_CONTROL,
448						 0x00);
449
450	if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
451		val = alc_pin_mode_min(dir);
452
453	change = pinctl != alc_pin_mode_values[val];
454	if (change) {
455		/* Set pin mode to that requested */
456		snd_hda_codec_write_cache(codec, nid, 0,
457					  AC_VERB_SET_PIN_WIDGET_CONTROL,
458					  alc_pin_mode_values[val]);
459
460		/* Also enable the retasking pin's input/output as required
461		 * for the requested pin mode.  Enum values of 2 or less are
462		 * input modes.
463		 *
464		 * Dynamically switching the input/output buffers probably
465		 * reduces noise slightly (particularly on input) so we'll
466		 * do it.  However, having both input and output buffers
467		 * enabled simultaneously doesn't seem to be problematic if
468		 * this turns out to be necessary in the future.
469		 */
470		if (val <= 2) {
471			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
472						 HDA_AMP_MUTE, HDA_AMP_MUTE);
473			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
474						 HDA_AMP_MUTE, 0);
475		} else {
476			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
477						 HDA_AMP_MUTE, HDA_AMP_MUTE);
478			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
479						 HDA_AMP_MUTE, 0);
480		}
481	}
482	return change;
483}
484
485#define ALC_PIN_MODE(xname, nid, dir) \
486	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
487	  .info = alc_pin_mode_info, \
488	  .get = alc_pin_mode_get, \
489	  .put = alc_pin_mode_put, \
490	  .private_value = nid | (dir<<16) }
491
492/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
493 * together using a mask with more than one bit set.  This control is
494 * currently used only by the ALC260 test model.  At this stage they are not
495 * needed for any "production" models.
496 */
497#ifdef CONFIG_SND_DEBUG
498#define alc_gpio_data_info	snd_ctl_boolean_mono_info
499
500static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
501			     struct snd_ctl_elem_value *ucontrol)
502{
503	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
504	hda_nid_t nid = kcontrol->private_value & 0xffff;
505	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
506	long *valp = ucontrol->value.integer.value;
507	unsigned int val = snd_hda_codec_read(codec, nid, 0,
508					      AC_VERB_GET_GPIO_DATA, 0x00);
509
510	*valp = (val & mask) != 0;
511	return 0;
512}
513static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
514			     struct snd_ctl_elem_value *ucontrol)
515{
516	signed int change;
517	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
518	hda_nid_t nid = kcontrol->private_value & 0xffff;
519	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
520	long val = *ucontrol->value.integer.value;
521	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
522						    AC_VERB_GET_GPIO_DATA,
523						    0x00);
524
525	/* Set/unset the masked GPIO bit(s) as needed */
526	change = (val == 0 ? 0 : mask) != (gpio_data & mask);
527	if (val == 0)
528		gpio_data &= ~mask;
529	else
530		gpio_data |= mask;
531	snd_hda_codec_write_cache(codec, nid, 0,
532				  AC_VERB_SET_GPIO_DATA, gpio_data);
533
534	return change;
535}
536#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
537	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
538	  .info = alc_gpio_data_info, \
539	  .get = alc_gpio_data_get, \
540	  .put = alc_gpio_data_put, \
541	  .private_value = nid | (mask<<16) }
542#endif   /* CONFIG_SND_DEBUG */
543
544/* A switch control to allow the enabling of the digital IO pins on the
545 * ALC260.  This is incredibly simplistic; the intention of this control is
546 * to provide something in the test model allowing digital outputs to be
547 * identified if present.  If models are found which can utilise these
548 * outputs a more complete mixer control can be devised for those models if
549 * necessary.
550 */
551#ifdef CONFIG_SND_DEBUG
552#define alc_spdif_ctrl_info	snd_ctl_boolean_mono_info
553
554static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
555			      struct snd_ctl_elem_value *ucontrol)
556{
557	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
558	hda_nid_t nid = kcontrol->private_value & 0xffff;
559	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
560	long *valp = ucontrol->value.integer.value;
561	unsigned int val = snd_hda_codec_read(codec, nid, 0,
562					      AC_VERB_GET_DIGI_CONVERT, 0x00);
563
564	*valp = (val & mask) != 0;
565	return 0;
566}
567static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
568			      struct snd_ctl_elem_value *ucontrol)
569{
570	signed int change;
571	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
572	hda_nid_t nid = kcontrol->private_value & 0xffff;
573	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
574	long val = *ucontrol->value.integer.value;
575	unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
576						    AC_VERB_GET_DIGI_CONVERT,
577						    0x00);
578
579	/* Set/unset the masked control bit(s) as needed */
580	change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
581	if (val==0)
582		ctrl_data &= ~mask;
583	else
584		ctrl_data |= mask;
585	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
586				  ctrl_data);
587
588	return change;
589}
590#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
591	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
592	  .info = alc_spdif_ctrl_info, \
593	  .get = alc_spdif_ctrl_get, \
594	  .put = alc_spdif_ctrl_put, \
595	  .private_value = nid | (mask<<16) }
596#endif   /* CONFIG_SND_DEBUG */
597
598/*
599 * set up from the preset table
600 */
601static void setup_preset(struct alc_spec *spec,
602			 const struct alc_config_preset *preset)
603{
604	int i;
605
606	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
607		spec->mixers[spec->num_mixers++] = preset->mixers[i];
608	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
609	     i++)
610		spec->init_verbs[spec->num_init_verbs++] =
611			preset->init_verbs[i];
612
613	spec->channel_mode = preset->channel_mode;
614	spec->num_channel_mode = preset->num_channel_mode;
615	spec->need_dac_fix = preset->need_dac_fix;
616
617	spec->multiout.max_channels = spec->channel_mode[0].channels;
618
619	spec->multiout.num_dacs = preset->num_dacs;
620	spec->multiout.dac_nids = preset->dac_nids;
621	spec->multiout.dig_out_nid = preset->dig_out_nid;
622	spec->multiout.hp_nid = preset->hp_nid;
623
624	spec->num_mux_defs = preset->num_mux_defs;
625	if (!spec->num_mux_defs)
626		spec->num_mux_defs = 1;
627	spec->input_mux = preset->input_mux;
628
629	spec->num_adc_nids = preset->num_adc_nids;
630	spec->adc_nids = preset->adc_nids;
631	spec->dig_in_nid = preset->dig_in_nid;
632
633	spec->unsol_event = preset->unsol_event;
634	spec->init_hook = preset->init_hook;
635#ifdef CONFIG_SND_HDA_POWER_SAVE
636	spec->loopback.amplist = preset->loopbacks;
637#endif
638}
639
640/* Enable GPIO mask and set output */
641static struct hda_verb alc_gpio1_init_verbs[] = {
642	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
643	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
644	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
645	{ }
646};
647
648static struct hda_verb alc_gpio2_init_verbs[] = {
649	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
650	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
651	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
652	{ }
653};
654
655static struct hda_verb alc_gpio3_init_verbs[] = {
656	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
657	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
658	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
659	{ }
660};
661
662/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
663 *	31 ~ 16 :	Manufacture ID
664 *	15 ~ 8	:	SKU ID
665 *	7  ~ 0	:	Assembly ID
666 *	port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
667 */
668static void alc_subsystem_id(struct hda_codec *codec,
669			     unsigned int porta, unsigned int porte,
670			     unsigned int portd)
671{
672	unsigned int ass, tmp;
673
674	ass = codec->subsystem_id;
675	if (!(ass & 1))
676		return;
677
678	/* Override */
679	tmp = (ass & 0x38) >> 3;	/* external Amp control */
680	switch (tmp) {
681	case 1:
682		snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
683		break;
684	case 3:
685		snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
686		break;
687	case 7:
688		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
689		break;
690	case 5:
691		switch (codec->vendor_id) {
692		case 0x10ec0862:
693		case 0x10ec0660:
694		case 0x10ec0662:
695		case 0x10ec0267:
696		case 0x10ec0268:
697			snd_hda_codec_write(codec, 0x14, 0,
698					    AC_VERB_SET_EAPD_BTLENABLE, 2);
699			snd_hda_codec_write(codec, 0x15, 0,
700					    AC_VERB_SET_EAPD_BTLENABLE, 2);
701			return;
702		}
703	case 6:
704		if (ass & 4) {	/* bit 2 : 0 = Desktop, 1 = Laptop */
705			hda_nid_t port = 0;
706			tmp = (ass & 0x1800) >> 11;
707			switch (tmp) {
708			case 0: port = porta; break;
709			case 1: port = porte; break;
710			case 2: port = portd; break;
711			}
712			if (port)
713				snd_hda_codec_write(codec, port, 0,
714						    AC_VERB_SET_EAPD_BTLENABLE,
715						    2);
716		}
717		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
718		snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF,
719				    (tmp == 5 ? 0x3040 : 0x3050));
720		break;
721	}
722}
723
724/*
725 * Fix-up pin default configurations
726 */
727
728struct alc_pincfg {
729	hda_nid_t nid;
730	u32 val;
731};
732
733static void alc_fix_pincfg(struct hda_codec *codec,
734			   const struct snd_pci_quirk *quirk,
735			   const struct alc_pincfg **pinfix)
736{
737	const struct alc_pincfg *cfg;
738
739	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
740	if (!quirk)
741		return;
742
743	cfg = pinfix[quirk->value];
744	for (; cfg->nid; cfg++) {
745		int i;
746		u32 val = cfg->val;
747		for (i = 0; i < 4; i++) {
748			snd_hda_codec_write(codec, cfg->nid, 0,
749				    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
750				    val & 0xff);
751			val >>= 8;
752		}
753	}
754}
755
756/*
757 * ALC880 3-stack model
758 *
759 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
760 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
761 *                 F-Mic = 0x1b, HP = 0x19
762 */
763
764static hda_nid_t alc880_dac_nids[4] = {
765	/* front, rear, clfe, rear_surr */
766	0x02, 0x05, 0x04, 0x03
767};
768
769static hda_nid_t alc880_adc_nids[3] = {
770	/* ADC0-2 */
771	0x07, 0x08, 0x09,
772};
773
774/* The datasheet says the node 0x07 is connected from inputs,
775 * but it shows zero connection in the real implementation on some devices.
776 * Note: this is a 915GAV bug, fixed on 915GLV
777 */
778static hda_nid_t alc880_adc_nids_alt[2] = {
779	/* ADC1-2 */
780	0x08, 0x09,
781};
782
783#define ALC880_DIGOUT_NID	0x06
784#define ALC880_DIGIN_NID	0x0a
785
786static struct hda_input_mux alc880_capture_source = {
787	.num_items = 4,
788	.items = {
789		{ "Mic", 0x0 },
790		{ "Front Mic", 0x3 },
791		{ "Line", 0x2 },
792		{ "CD", 0x4 },
793	},
794};
795
796/* channel source setting (2/6 channel selection for 3-stack) */
797/* 2ch mode */
798static struct hda_verb alc880_threestack_ch2_init[] = {
799	/* set line-in to input, mute it */
800	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
801	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
802	/* set mic-in to input vref 80%, mute it */
803	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
804	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
805	{ } /* end */
806};
807
808/* 6ch mode */
809static struct hda_verb alc880_threestack_ch6_init[] = {
810	/* set line-in to output, unmute it */
811	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
812	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
813	/* set mic-in to output, unmute it */
814	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
815	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
816	{ } /* end */
817};
818
819static struct hda_channel_mode alc880_threestack_modes[2] = {
820	{ 2, alc880_threestack_ch2_init },
821	{ 6, alc880_threestack_ch6_init },
822};
823
824static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
825	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
826	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
827	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
828	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
829	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
830	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
831	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
832	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
833	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
834	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
835	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
836	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
837	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
838	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
839	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
840	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
841	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
842	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
843	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
844	{
845		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
846		.name = "Channel Mode",
847		.info = alc_ch_mode_info,
848		.get = alc_ch_mode_get,
849		.put = alc_ch_mode_put,
850	},
851	{ } /* end */
852};
853
854/* capture mixer elements */
855static struct snd_kcontrol_new alc880_capture_mixer[] = {
856	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
857	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
858	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
859	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
860	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
861	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
862	{
863		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
864		/* The multiple "Capture Source" controls confuse alsamixer
865		 * So call somewhat different..
866		 * FIXME: the controls appear in the "playback" view!
867		 */
868		/* .name = "Capture Source", */
869		.name = "Input Source",
870		.count = 3,
871		.info = alc_mux_enum_info,
872		.get = alc_mux_enum_get,
873		.put = alc_mux_enum_put,
874	},
875	{ } /* end */
876};
877
878/* capture mixer elements (in case NID 0x07 not available) */
879static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
880	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
881	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
882	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
883	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
884	{
885		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
886		/* The multiple "Capture Source" controls confuse alsamixer
887		 * So call somewhat different..
888		 * FIXME: the controls appear in the "playback" view!
889		 */
890		/* .name = "Capture Source", */
891		.name = "Input Source",
892		.count = 2,
893		.info = alc_mux_enum_info,
894		.get = alc_mux_enum_get,
895		.put = alc_mux_enum_put,
896	},
897	{ } /* end */
898};
899
900
901
902/*
903 * ALC880 5-stack model
904 *
905 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
906 *      Side = 0x02 (0xd)
907 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
908 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
909 */
910
911/* additional mixers to alc880_three_stack_mixer */
912static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
913	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
914	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
915	{ } /* end */
916};
917
918/* channel source setting (6/8 channel selection for 5-stack) */
919/* 6ch mode */
920static struct hda_verb alc880_fivestack_ch6_init[] = {
921	/* set line-in to input, mute it */
922	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
923	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
924	{ } /* end */
925};
926
927/* 8ch mode */
928static struct hda_verb alc880_fivestack_ch8_init[] = {
929	/* set line-in to output, unmute it */
930	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
931	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
932	{ } /* end */
933};
934
935static struct hda_channel_mode alc880_fivestack_modes[2] = {
936	{ 6, alc880_fivestack_ch6_init },
937	{ 8, alc880_fivestack_ch8_init },
938};
939
940
941/*
942 * ALC880 6-stack model
943 *
944 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
945 *      Side = 0x05 (0x0f)
946 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
947 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
948 */
949
950static hda_nid_t alc880_6st_dac_nids[4] = {
951	/* front, rear, clfe, rear_surr */
952	0x02, 0x03, 0x04, 0x05
953};
954
955static struct hda_input_mux alc880_6stack_capture_source = {
956	.num_items = 4,
957	.items = {
958		{ "Mic", 0x0 },
959		{ "Front Mic", 0x1 },
960		{ "Line", 0x2 },
961		{ "CD", 0x4 },
962	},
963};
964
965/* fixed 8-channels */
966static struct hda_channel_mode alc880_sixstack_modes[1] = {
967	{ 8, NULL },
968};
969
970static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
971	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
972	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
973	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
974	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
975	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
976	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
977	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
978	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
979	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
980	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
981	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
982	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
983	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
984	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
985	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
986	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
987	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
988	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
989	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
990	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
991	{
992		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
993		.name = "Channel Mode",
994		.info = alc_ch_mode_info,
995		.get = alc_ch_mode_get,
996		.put = alc_ch_mode_put,
997	},
998	{ } /* end */
999};
1000
1001
1002/*
1003 * ALC880 W810 model
1004 *
1005 * W810 has rear IO for:
1006 * Front (DAC 02)
1007 * Surround (DAC 03)
1008 * Center/LFE (DAC 04)
1009 * Digital out (06)
1010 *
1011 * The system also has a pair of internal speakers, and a headphone jack.
1012 * These are both connected to Line2 on the codec, hence to DAC 02.
1013 *
1014 * There is a variable resistor to control the speaker or headphone
1015 * volume. This is a hardware-only device without a software API.
1016 *
1017 * Plugging headphones in will disable the internal speakers. This is
1018 * implemented in hardware, not via the driver using jack sense. In
1019 * a similar fashion, plugging into the rear socket marked "front" will
1020 * disable both the speakers and headphones.
1021 *
1022 * For input, there's a microphone jack, and an "audio in" jack.
1023 * These may not do anything useful with this driver yet, because I
1024 * haven't setup any initialization verbs for these yet...
1025 */
1026
1027static hda_nid_t alc880_w810_dac_nids[3] = {
1028	/* front, rear/surround, clfe */
1029	0x02, 0x03, 0x04
1030};
1031
1032/* fixed 6 channels */
1033static struct hda_channel_mode alc880_w810_modes[1] = {
1034	{ 6, NULL }
1035};
1036
1037/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1038static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1039	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1040	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1041	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1042	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1043	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1044	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1045	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1046	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1047	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1048	{ } /* end */
1049};
1050
1051
1052/*
1053 * Z710V model
1054 *
1055 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1056 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1057 *                 Line = 0x1a
1058 */
1059
1060static hda_nid_t alc880_z71v_dac_nids[1] = {
1061	0x02
1062};
1063#define ALC880_Z71V_HP_DAC	0x03
1064
1065/* fixed 2 channels */
1066static struct hda_channel_mode alc880_2_jack_modes[1] = {
1067	{ 2, NULL }
1068};
1069
1070static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1071	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1072	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1073	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1074	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1075	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1076	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1077	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1078	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1079	{ } /* end */
1080};
1081
1082
1083/* FIXME! */
1084/*
1085 * ALC880 F1734 model
1086 *
1087 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1088 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1089 */
1090
1091static hda_nid_t alc880_f1734_dac_nids[1] = {
1092	0x03
1093};
1094#define ALC880_F1734_HP_DAC	0x02
1095
1096static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1097	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1098	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1099	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1100	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1101	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1102	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1103	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1104	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1105	{ } /* end */
1106};
1107
1108
1109/* FIXME! */
1110/*
1111 * ALC880 ASUS model
1112 *
1113 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1114 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1115 *  Mic = 0x18, Line = 0x1a
1116 */
1117
1118#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
1119#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
1120
1121static struct snd_kcontrol_new alc880_asus_mixer[] = {
1122	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1123	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1124	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1125	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1126	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1127	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1128	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1129	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1130	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1131	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1132	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1133	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1134	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1135	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1136	{
1137		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1138		.name = "Channel Mode",
1139		.info = alc_ch_mode_info,
1140		.get = alc_ch_mode_get,
1141		.put = alc_ch_mode_put,
1142	},
1143	{ } /* end */
1144};
1145
1146/* FIXME! */
1147/*
1148 * ALC880 ASUS W1V model
1149 *
1150 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1151 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1152 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1153 */
1154
1155/* additional mixers to alc880_asus_mixer */
1156static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1157	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1158	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1159	{ } /* end */
1160};
1161
1162/* additional mixers to alc880_asus_mixer */
1163static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1164	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1165	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1166	{ } /* end */
1167};
1168
1169/* TCL S700 */
1170static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1171	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1172	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1173	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1174	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1175	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1176	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1177	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1178	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1179	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1180	{
1181		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1182		/* The multiple "Capture Source" controls confuse alsamixer
1183		 * So call somewhat different..
1184		 * FIXME: the controls appear in the "playback" view!
1185		 */
1186		/* .name = "Capture Source", */
1187		.name = "Input Source",
1188		.count = 1,
1189		.info = alc_mux_enum_info,
1190		.get = alc_mux_enum_get,
1191		.put = alc_mux_enum_put,
1192	},
1193	{ } /* end */
1194};
1195
1196/* Uniwill */
1197static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1198	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1199	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1200	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1201	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1202	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1203	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1204	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1205	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1206	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1207	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1208	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1209	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1210	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1211	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1212	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1213	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1214	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1215	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1216	{
1217		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1218		.name = "Channel Mode",
1219		.info = alc_ch_mode_info,
1220		.get = alc_ch_mode_get,
1221		.put = alc_ch_mode_put,
1222	},
1223	{ } /* end */
1224};
1225
1226static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1227	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1228	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1229	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1230	HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1231	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1232	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1233	HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1234	HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1235	HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1236	HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1237	{ } /* end */
1238};
1239
1240static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1241	HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1242	HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1243	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1244	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1245	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1246	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1247	{ } /* end */
1248};
1249
1250/*
1251 * build control elements
1252 */
1253static int alc_build_controls(struct hda_codec *codec)
1254{
1255	struct alc_spec *spec = codec->spec;
1256	int err;
1257	int i;
1258
1259	for (i = 0; i < spec->num_mixers; i++) {
1260		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1261		if (err < 0)
1262			return err;
1263	}
1264
1265	if (spec->multiout.dig_out_nid) {
1266		err = snd_hda_create_spdif_out_ctls(codec,
1267						    spec->multiout.dig_out_nid);
1268		if (err < 0)
1269			return err;
1270	}
1271	if (spec->dig_in_nid) {
1272		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1273		if (err < 0)
1274			return err;
1275	}
1276	return 0;
1277}
1278
1279
1280/*
1281 * initialize the codec volumes, etc
1282 */
1283
1284/*
1285 * generic initialization of ADC, input mixers and output mixers
1286 */
1287static struct hda_verb alc880_volume_init_verbs[] = {
1288	/*
1289	 * Unmute ADC0-2 and set the default input to mic-in
1290	 */
1291	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1292	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1293	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1294	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1295	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1296	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1297
1298	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1299	 * mixer widget
1300	 * Note: PASD motherboards uses the Line In 2 as the input for front
1301	 * panel mic (mic 2)
1302	 */
1303	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1304	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1305	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1306	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1307	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1308	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1309	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1310	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1311
1312	/*
1313	 * Set up output mixers (0x0c - 0x0f)
1314	 */
1315	/* set vol=0 to output mixers */
1316	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1317	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1318	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1319	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1320	/* set up input amps for analog loopback */
1321	/* Amp Indices: DAC = 0, mixer = 1 */
1322	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1323	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1324	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1327	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1328	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1329	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1330
1331	{ }
1332};
1333
1334/*
1335 * 3-stack pin configuration:
1336 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1337 */
1338static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1339	/*
1340	 * preset connection lists of input pins
1341	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1342	 */
1343	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1344	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1345	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1346
1347	/*
1348	 * Set pin mode and muting
1349	 */
1350	/* set front pin widgets 0x14 for output */
1351	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1352	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1353	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1354	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1355	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1356	/* Mic2 (as headphone out) for HP output */
1357	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1358	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1359	/* Line In pin widget for input */
1360	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1361	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1362	/* Line2 (as front mic) pin widget for input and vref at 80% */
1363	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1364	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1365	/* CD pin widget for input */
1366	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1367
1368	{ }
1369};
1370
1371/*
1372 * 5-stack pin configuration:
1373 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1374 * line-in/side = 0x1a, f-mic = 0x1b
1375 */
1376static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1377	/*
1378	 * preset connection lists of input pins
1379	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1380	 */
1381	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1382	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1383
1384	/*
1385	 * Set pin mode and muting
1386	 */
1387	/* set pin widgets 0x14-0x17 for output */
1388	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1389	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1390	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1391	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1392	/* unmute pins for output (no gain on this amp) */
1393	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1394	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1395	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1396	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1397
1398	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1399	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1400	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1401	/* Mic2 (as headphone out) for HP output */
1402	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1403	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1404	/* Line In pin widget for input */
1405	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1406	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1407	/* Line2 (as front mic) pin widget for input and vref at 80% */
1408	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1409	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1410	/* CD pin widget for input */
1411	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1412
1413	{ }
1414};
1415
1416/*
1417 * W810 pin configuration:
1418 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1419 */
1420static struct hda_verb alc880_pin_w810_init_verbs[] = {
1421	/* hphone/speaker input selector: front DAC */
1422	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1423
1424	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1425	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1426	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1427	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1428	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1429	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1430
1431	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1432	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1433
1434	{ }
1435};
1436
1437/*
1438 * Z71V pin configuration:
1439 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1440 */
1441static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1442	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1443	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1445	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1446
1447	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1448	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1449	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1450	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1451
1452	{ }
1453};
1454
1455/*
1456 * 6-stack pin configuration:
1457 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1458 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1459 */
1460static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1461	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1462
1463	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1464	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1466	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1468	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1470	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1471
1472	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1473	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1474	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1475	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1476	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1477	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1478	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1479	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1480	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1481
1482	{ }
1483};
1484
1485/*
1486 * Uniwill pin configuration:
1487 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1488 * line = 0x1a
1489 */
1490static struct hda_verb alc880_uniwill_init_verbs[] = {
1491	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1492
1493	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1494	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1496	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1497	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1498	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1500	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1501	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1502	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1503	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1504	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1505	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1506	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1507
1508	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1509	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1510	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1511	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1512	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1513	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1514	/* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1515	/* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1516	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1517
1518	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1519	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1520
1521	{ }
1522};
1523
1524/*
1525* Uniwill P53
1526* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1527 */
1528static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1529	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1530
1531	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1532	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1533	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1534	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1535	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1536	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1537	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1538	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1539	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1540	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1541	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1542	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1543
1544	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1545	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1546	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1547	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1548	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1549	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1550
1551	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1552	{0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1553
1554	{ }
1555};
1556
1557static struct hda_verb alc880_beep_init_verbs[] = {
1558	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1559	{ }
1560};
1561
1562/* toggle speaker-output according to the hp-jack state */
1563static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1564{
1565 	unsigned int present;
1566	unsigned char bits;
1567
1568 	present = snd_hda_codec_read(codec, 0x14, 0,
1569				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1570	bits = present ? HDA_AMP_MUTE : 0;
1571	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1572				 HDA_AMP_MUTE, bits);
1573	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1574				 HDA_AMP_MUTE, bits);
1575}
1576
1577/* auto-toggle front mic */
1578static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1579{
1580 	unsigned int present;
1581	unsigned char bits;
1582
1583	present = snd_hda_codec_read(codec, 0x18, 0,
1584				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1585	bits = present ? HDA_AMP_MUTE : 0;
1586	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1587}
1588
1589static void alc880_uniwill_automute(struct hda_codec *codec)
1590{
1591	alc880_uniwill_hp_automute(codec);
1592	alc880_uniwill_mic_automute(codec);
1593}
1594
1595static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1596				       unsigned int res)
1597{
1598	/* Looks like the unsol event is incompatible with the standard
1599	 * definition.  4bit tag is placed at 28 bit!
1600	 */
1601	switch (res >> 28) {
1602	case ALC880_HP_EVENT:
1603		alc880_uniwill_hp_automute(codec);
1604		break;
1605	case ALC880_MIC_EVENT:
1606		alc880_uniwill_mic_automute(codec);
1607		break;
1608	}
1609}
1610
1611static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1612{
1613 	unsigned int present;
1614	unsigned char bits;
1615
1616 	present = snd_hda_codec_read(codec, 0x14, 0,
1617				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1618	bits = present ? HDA_AMP_MUTE : 0;
1619	snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1620}
1621
1622static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1623{
1624	unsigned int present;
1625
1626	present = snd_hda_codec_read(codec, 0x21, 0,
1627				     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1628	present &= HDA_AMP_VOLMASK;
1629	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1630				 HDA_AMP_VOLMASK, present);
1631	snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1632				 HDA_AMP_VOLMASK, present);
1633}
1634
1635static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1636					   unsigned int res)
1637{
1638	/* Looks like the unsol event is incompatible with the standard
1639	 * definition.  4bit tag is placed at 28 bit!
1640	 */
1641	if ((res >> 28) == ALC880_HP_EVENT)
1642		alc880_uniwill_p53_hp_automute(codec);
1643	if ((res >> 28) == ALC880_DCVOL_EVENT)
1644		alc880_uniwill_p53_dcvol_automute(codec);
1645}
1646
1647/* FIXME! */
1648/*
1649 * F1734 pin configuration:
1650 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1651 */
1652static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1653	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1654	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1655	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1656	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1657
1658	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1659	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1660	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1661	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662
1663	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1664	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1665	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1666	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1667	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1668	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1669	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1670	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1672
1673	{ }
1674};
1675
1676/* FIXME! */
1677/*
1678 * ASUS pin configuration:
1679 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1680 */
1681static struct hda_verb alc880_pin_asus_init_verbs[] = {
1682	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1683	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1684	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1685	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1686
1687	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1688	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1689	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1690	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1691	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1694	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695
1696	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1697	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1698	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1699	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1700	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1701	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1702	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1703	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1705
1706	{ }
1707};
1708
1709/* Enable GPIO mask and set output */
1710#define alc880_gpio1_init_verbs	alc_gpio1_init_verbs
1711#define alc880_gpio2_init_verbs	alc_gpio2_init_verbs
1712
1713/* Clevo m520g init */
1714static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1715	/* headphone output */
1716	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1717	/* line-out */
1718	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1719	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1720	/* Line-in */
1721	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1722	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1723	/* CD */
1724	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1725	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726	/* Mic1 (rear panel) */
1727	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1728	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1729	/* Mic2 (front panel) */
1730	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1731	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732	/* headphone */
1733	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1734	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1735        /* change to EAPD mode */
1736	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1737	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1738
1739	{ }
1740};
1741
1742static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1743	/* change to EAPD mode */
1744	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1745	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1746
1747	/* Headphone output */
1748	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1749	/* Front output*/
1750	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1751	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1752
1753	/* Line In pin widget for input */
1754	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1755	/* CD pin widget for input */
1756	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1757	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1758	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1759
1760	/* change to EAPD mode */
1761	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1762	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1763
1764	{ }
1765};
1766
1767/*
1768 * LG m1 express dual
1769 *
1770 * Pin assignment:
1771 *   Rear Line-In/Out (blue): 0x14
1772 *   Build-in Mic-In: 0x15
1773 *   Speaker-out: 0x17
1774 *   HP-Out (green): 0x1b
1775 *   Mic-In/Out (red): 0x19
1776 *   SPDIF-Out: 0x1e
1777 */
1778
1779/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1780static hda_nid_t alc880_lg_dac_nids[3] = {
1781	0x05, 0x02, 0x03
1782};
1783
1784/* seems analog CD is not working */
1785static struct hda_input_mux alc880_lg_capture_source = {
1786	.num_items = 3,
1787	.items = {
1788		{ "Mic", 0x1 },
1789		{ "Line", 0x5 },
1790		{ "Internal Mic", 0x6 },
1791	},
1792};
1793
1794/* 2,4,6 channel modes */
1795static struct hda_verb alc880_lg_ch2_init[] = {
1796	/* set line-in and mic-in to input */
1797	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1798	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1799	{ }
1800};
1801
1802static struct hda_verb alc880_lg_ch4_init[] = {
1803	/* set line-in to out and mic-in to input */
1804	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1805	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1806	{ }
1807};
1808
1809static struct hda_verb alc880_lg_ch6_init[] = {
1810	/* set line-in and mic-in to output */
1811	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1812	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1813	{ }
1814};
1815
1816static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1817	{ 2, alc880_lg_ch2_init },
1818	{ 4, alc880_lg_ch4_init },
1819	{ 6, alc880_lg_ch6_init },
1820};
1821
1822static struct snd_kcontrol_new alc880_lg_mixer[] = {
1823	/* FIXME: it's not really "master" but front channels */
1824	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1825	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1826	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1827	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1828	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1829	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1830	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1831	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1832	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1833	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1834	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1835	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1836	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1837	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1838	{
1839		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1840		.name = "Channel Mode",
1841		.info = alc_ch_mode_info,
1842		.get = alc_ch_mode_get,
1843		.put = alc_ch_mode_put,
1844	},
1845	{ } /* end */
1846};
1847
1848static struct hda_verb alc880_lg_init_verbs[] = {
1849	/* set capture source to mic-in */
1850	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1851	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1852	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1853	/* mute all amp mixer inputs */
1854	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1855	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1856	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1857	/* line-in to input */
1858	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1859	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1860	/* built-in mic */
1861	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1862	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863	/* speaker-out */
1864	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1865	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866	/* mic-in to input */
1867	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1868	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1869	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1870	/* HP-out */
1871	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1872	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1873	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874	/* jack sense */
1875	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1876	{ }
1877};
1878
1879/* toggle speaker-output according to the hp-jack state */
1880static void alc880_lg_automute(struct hda_codec *codec)
1881{
1882	unsigned int present;
1883	unsigned char bits;
1884
1885	present = snd_hda_codec_read(codec, 0x1b, 0,
1886				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1887	bits = present ? HDA_AMP_MUTE : 0;
1888	snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
1889				 HDA_AMP_MUTE, bits);
1890}
1891
1892static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1893{
1894	/* Looks like the unsol event is incompatible with the standard
1895	 * definition.  4bit tag is placed at 28 bit!
1896	 */
1897	if ((res >> 28) == 0x01)
1898		alc880_lg_automute(codec);
1899}
1900
1901/*
1902 * LG LW20
1903 *
1904 * Pin assignment:
1905 *   Speaker-out: 0x14
1906 *   Mic-In: 0x18
1907 *   Built-in Mic-In: 0x19
1908 *   Line-In: 0x1b
1909 *   HP-Out: 0x1a
1910 *   SPDIF-Out: 0x1e
1911 */
1912
1913static struct hda_input_mux alc880_lg_lw_capture_source = {
1914	.num_items = 3,
1915	.items = {
1916		{ "Mic", 0x0 },
1917		{ "Internal Mic", 0x1 },
1918		{ "Line In", 0x2 },
1919	},
1920};
1921
1922#define alc880_lg_lw_modes alc880_threestack_modes
1923
1924static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1925	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1926	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1927	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1928	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1929	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1930	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1931	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1932	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1933	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1934	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1935	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1936	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1937	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1938	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1939	{
1940		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1941		.name = "Channel Mode",
1942		.info = alc_ch_mode_info,
1943		.get = alc_ch_mode_get,
1944		.put = alc_ch_mode_put,
1945	},
1946	{ } /* end */
1947};
1948
1949static struct hda_verb alc880_lg_lw_init_verbs[] = {
1950	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1951	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1952	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1953
1954	/* set capture source to mic-in */
1955	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1956	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1957	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1958	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1959	/* speaker-out */
1960	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1961	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1962	/* HP-out */
1963	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1964	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1965	/* mic-in to input */
1966	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1967	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1968	/* built-in mic */
1969	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1970	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1971	/* jack sense */
1972	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1973	{ }
1974};
1975
1976/* toggle speaker-output according to the hp-jack state */
1977static void alc880_lg_lw_automute(struct hda_codec *codec)
1978{
1979	unsigned int present;
1980	unsigned char bits;
1981
1982	present = snd_hda_codec_read(codec, 0x1b, 0,
1983				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1984	bits = present ? HDA_AMP_MUTE : 0;
1985	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1986				 HDA_AMP_MUTE, bits);
1987}
1988
1989static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1990{
1991	/* Looks like the unsol event is incompatible with the standard
1992	 * definition.  4bit tag is placed at 28 bit!
1993	 */
1994	if ((res >> 28) == 0x01)
1995		alc880_lg_lw_automute(codec);
1996}
1997
1998#ifdef CONFIG_SND_HDA_POWER_SAVE
1999static struct hda_amp_list alc880_loopbacks[] = {
2000	{ 0x0b, HDA_INPUT, 0 },
2001	{ 0x0b, HDA_INPUT, 1 },
2002	{ 0x0b, HDA_INPUT, 2 },
2003	{ 0x0b, HDA_INPUT, 3 },
2004	{ 0x0b, HDA_INPUT, 4 },
2005	{ } /* end */
2006};
2007
2008static struct hda_amp_list alc880_lg_loopbacks[] = {
2009	{ 0x0b, HDA_INPUT, 1 },
2010	{ 0x0b, HDA_INPUT, 6 },
2011	{ 0x0b, HDA_INPUT, 7 },
2012	{ } /* end */
2013};
2014#endif
2015
2016/*
2017 * Common callbacks
2018 */
2019
2020static int alc_init(struct hda_codec *codec)
2021{
2022	struct alc_spec *spec = codec->spec;
2023	unsigned int i;
2024
2025	for (i = 0; i < spec->num_init_verbs; i++)
2026		snd_hda_sequence_write(codec, spec->init_verbs[i]);
2027
2028	if (spec->init_hook)
2029		spec->init_hook(codec);
2030
2031	return 0;
2032}
2033
2034static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2035{
2036	struct alc_spec *spec = codec->spec;
2037
2038	if (spec->unsol_event)
2039		spec->unsol_event(codec, res);
2040}
2041
2042#ifdef CONFIG_SND_HDA_POWER_SAVE
2043static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2044{
2045	struct alc_spec *spec = codec->spec;
2046	return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2047}
2048#endif
2049
2050/*
2051 * Analog playback callbacks
2052 */
2053static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2054				    struct hda_codec *codec,
2055				    struct snd_pcm_substream *substream)
2056{
2057	struct alc_spec *spec = codec->spec;
2058	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2059}
2060
2061static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2062				       struct hda_codec *codec,
2063				       unsigned int stream_tag,
2064				       unsigned int format,
2065				       struct snd_pcm_substream *substream)
2066{
2067	struct alc_spec *spec = codec->spec;
2068	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2069						stream_tag, format, substream);
2070}
2071
2072static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2073				       struct hda_codec *codec,
2074				       struct snd_pcm_substream *substream)
2075{
2076	struct alc_spec *spec = codec->spec;
2077	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2078}
2079
2080/*
2081 * Digital out
2082 */
2083static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2084					struct hda_codec *codec,
2085					struct snd_pcm_substream *substream)
2086{
2087	struct alc_spec *spec = codec->spec;
2088	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2089}
2090
2091static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2092					   struct hda_codec *codec,
2093					   unsigned int stream_tag,
2094					   unsigned int format,
2095					   struct snd_pcm_substream *substream)
2096{
2097	struct alc_spec *spec = codec->spec;
2098	return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2099					     stream_tag, format, substream);
2100}
2101
2102static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2103					 struct hda_codec *codec,
2104					 struct snd_pcm_substream *substream)
2105{
2106	struct alc_spec *spec = codec->spec;
2107	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2108}
2109
2110/*
2111 * Analog capture
2112 */
2113static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2114				      struct hda_codec *codec,
2115				      unsigned int stream_tag,
2116				      unsigned int format,
2117				      struct snd_pcm_substream *substream)
2118{
2119	struct alc_spec *spec = codec->spec;
2120
2121	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2122				   stream_tag, 0, format);
2123	return 0;
2124}
2125
2126static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2127				      struct hda_codec *codec,
2128				      struct snd_pcm_substream *substream)
2129{
2130	struct alc_spec *spec = codec->spec;
2131
2132	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2133				   0, 0, 0);
2134	return 0;
2135}
2136
2137
2138/*
2139 */
2140static struct hda_pcm_stream alc880_pcm_analog_playback = {
2141	.substreams = 1,
2142	.channels_min = 2,
2143	.channels_max = 8,
2144	/* NID is set in alc_build_pcms */
2145	.ops = {
2146		.open = alc880_playback_pcm_open,
2147		.prepare = alc880_playback_pcm_prepare,
2148		.cleanup = alc880_playback_pcm_cleanup
2149	},
2150};
2151
2152static struct hda_pcm_stream alc880_pcm_analog_capture = {
2153	.substreams = 2,
2154	.channels_min = 2,
2155	.channels_max = 2,
2156	/* NID is set in alc_build_pcms */
2157	.ops = {
2158		.prepare = alc880_capture_pcm_prepare,
2159		.cleanup = alc880_capture_pcm_cleanup
2160	},
2161};
2162
2163static struct hda_pcm_stream alc880_pcm_digital_playback = {
2164	.substreams = 1,
2165	.channels_min = 2,
2166	.channels_max = 2,
2167	/* NID is set in alc_build_pcms */
2168	.ops = {
2169		.open = alc880_dig_playback_pcm_open,
2170		.close = alc880_dig_playback_pcm_close,
2171		.prepare = alc880_dig_playback_pcm_prepare
2172	},
2173};
2174
2175static struct hda_pcm_stream alc880_pcm_digital_capture = {
2176	.substreams = 1,
2177	.channels_min = 2,
2178	.channels_max = 2,
2179	/* NID is set in alc_build_pcms */
2180};
2181
2182/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2183static struct hda_pcm_stream alc_pcm_null_playback = {
2184	.substreams = 0,
2185	.channels_min = 0,
2186	.channels_max = 0,
2187};
2188
2189static int alc_build_pcms(struct hda_codec *codec)
2190{
2191	struct alc_spec *spec = codec->spec;
2192	struct hda_pcm *info = spec->pcm_rec;
2193	int i;
2194
2195	codec->num_pcms = 1;
2196	codec->pcm_info = info;
2197
2198	info->name = spec->stream_name_analog;
2199	if (spec->stream_analog_playback) {
2200		snd_assert(spec->multiout.dac_nids, return -EINVAL);
2201		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2202		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2203	}
2204	if (spec->stream_analog_capture) {
2205		snd_assert(spec->adc_nids, return -EINVAL);
2206		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2207		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2208	}
2209
2210	if (spec->channel_mode) {
2211		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2212		for (i = 0; i < spec->num_channel_mode; i++) {
2213			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2214				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2215			}
2216		}
2217	}
2218
2219	/* SPDIF for stream index #1 */
2220	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2221		codec->num_pcms = 2;
2222		info = spec->pcm_rec + 1;
2223		info->name = spec->stream_name_digital;
2224		if (spec->multiout.dig_out_nid &&
2225		    spec->stream_digital_playback) {
2226			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2227			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2228		}
2229		if (spec->dig_in_nid &&
2230		    spec->stream_digital_capture) {
2231			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2232			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2233		}
2234	}
2235
2236	/* If the use of more than one ADC is requested for the current
2237	 * model, configure a second analog capture-only PCM.
2238	 */
2239	/* Additional Analaog capture for index #2 */
2240	if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2241	    spec->adc_nids) {
2242		codec->num_pcms = 3;
2243		info = spec->pcm_rec + 2;
2244		info->name = spec->stream_name_analog;
2245		/* No playback stream for second PCM */
2246		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2247		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2248		if (spec->stream_analog_capture) {
2249			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2250			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2251		}
2252	}
2253
2254	return 0;
2255}
2256
2257static void alc_free(struct hda_codec *codec)
2258{
2259	struct alc_spec *spec = codec->spec;
2260	unsigned int i;
2261
2262	if (!spec)
2263		return;
2264
2265	if (spec->kctl_alloc) {
2266		for (i = 0; i < spec->num_kctl_used; i++)
2267			kfree(spec->kctl_alloc[i].name);
2268		kfree(spec->kctl_alloc);
2269	}
2270	kfree(spec);
2271}
2272
2273/*
2274 */
2275static struct hda_codec_ops alc_patch_ops = {
2276	.build_controls = alc_build_controls,
2277	.build_pcms = alc_build_pcms,
2278	.init = alc_init,
2279	.free = alc_free,
2280	.unsol_event = alc_unsol_event,
2281#ifdef CONFIG_SND_HDA_POWER_SAVE
2282	.check_power_status = alc_check_power_status,
2283#endif
2284};
2285
2286
2287/*
2288 * Test configuration for debugging
2289 *
2290 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2291 * enum controls.
2292 */
2293#ifdef CONFIG_SND_DEBUG
2294static hda_nid_t alc880_test_dac_nids[4] = {
2295	0x02, 0x03, 0x04, 0x05
2296};
2297
2298static struct hda_input_mux alc880_test_capture_source = {
2299	.num_items = 7,
2300	.items = {
2301		{ "In-1", 0x0 },
2302		{ "In-2", 0x1 },
2303		{ "In-3", 0x2 },
2304		{ "In-4", 0x3 },
2305		{ "CD", 0x4 },
2306		{ "Front", 0x5 },
2307		{ "Surround", 0x6 },
2308	},
2309};
2310
2311static struct hda_channel_mode alc880_test_modes[4] = {
2312	{ 2, NULL },
2313	{ 4, NULL },
2314	{ 6, NULL },
2315	{ 8, NULL },
2316};
2317
2318static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2319				 struct snd_ctl_elem_info *uinfo)
2320{
2321	static char *texts[] = {
2322		"N/A", "Line Out", "HP Out",
2323		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2324	};
2325	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2326	uinfo->count = 1;
2327	uinfo->value.enumerated.items = 8;
2328	if (uinfo->value.enumerated.item >= 8)
2329		uinfo->value.enumerated.item = 7;
2330	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2331	return 0;
2332}
2333
2334static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2335				struct snd_ctl_elem_value *ucontrol)
2336{
2337	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2338	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2339	unsigned int pin_ctl, item = 0;
2340
2341	pin_ctl = snd_hda_codec_read(codec, nid, 0,
2342				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2343	if (pin_ctl & AC_PINCTL_OUT_EN) {
2344		if (pin_ctl & AC_PINCTL_HP_EN)
2345			item = 2;
2346		else
2347			item = 1;
2348	} else if (pin_ctl & AC_PINCTL_IN_EN) {
2349		switch (pin_ctl & AC_PINCTL_VREFEN) {
2350		case AC_PINCTL_VREF_HIZ: item = 3; break;
2351		case AC_PINCTL_VREF_50:  item = 4; break;
2352		case AC_PINCTL_VREF_GRD: item = 5; break;
2353		case AC_PINCTL_VREF_80:  item = 6; break;
2354		case AC_PINCTL_VREF_100: item = 7; break;
2355		}
2356	}
2357	ucontrol->value.enumerated.item[0] = item;
2358	return 0;
2359}
2360
2361static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2362				struct snd_ctl_elem_value *ucontrol)
2363{
2364	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2365	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2366	static unsigned int ctls[] = {
2367		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2368		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2369		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2370		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2371		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2372		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2373	};
2374	unsigned int old_ctl, new_ctl;
2375
2376	old_ctl = snd_hda_codec_read(codec, nid, 0,
2377				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2378	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2379	if (old_ctl != new_ctl) {
2380		int val;
2381		snd_hda_codec_write_cache(codec, nid, 0,
2382					  AC_VERB_SET_PIN_WIDGET_CONTROL,
2383					  new_ctl);
2384		val = ucontrol->value.enumerated.item[0] >= 3 ?
2385			HDA_AMP_MUTE : 0;
2386		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2387					 HDA_AMP_MUTE, val);
2388		return 1;
2389	}
2390	return 0;
2391}
2392
2393static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2394				 struct snd_ctl_elem_info *uinfo)
2395{
2396	static char *texts[] = {
2397		"Front", "Surround", "CLFE", "Side"
2398	};
2399	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2400	uinfo->count = 1;
2401	uinfo->value.enumerated.items = 4;
2402	if (uinfo->value.enumerated.item >= 4)
2403		uinfo->value.enumerated.item = 3;
2404	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2405	return 0;
2406}
2407
2408static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2409				struct snd_ctl_elem_value *ucontrol)
2410{
2411	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2412	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2413	unsigned int sel;
2414
2415	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2416	ucontrol->value.enumerated.item[0] = sel & 3;
2417	return 0;
2418}
2419
2420static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2421				struct snd_ctl_elem_value *ucontrol)
2422{
2423	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2424	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2425	unsigned int sel;
2426
2427	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2428	if (ucontrol->value.enumerated.item[0] != sel) {
2429		sel = ucontrol->value.enumerated.item[0] & 3;
2430		snd_hda_codec_write_cache(codec, nid, 0,
2431					  AC_VERB_SET_CONNECT_SEL, sel);
2432		return 1;
2433	}
2434	return 0;
2435}
2436
2437#define PIN_CTL_TEST(xname,nid) {			\
2438		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2439			.name = xname,		       \
2440			.info = alc_test_pin_ctl_info, \
2441			.get = alc_test_pin_ctl_get,   \
2442			.put = alc_test_pin_ctl_put,   \
2443			.private_value = nid	       \
2444			}
2445
2446#define PIN_SRC_TEST(xname,nid) {			\
2447		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
2448			.name = xname,		       \
2449			.info = alc_test_pin_src_info, \
2450			.get = alc_test_pin_src_get,   \
2451			.put = alc_test_pin_src_put,   \
2452			.private_value = nid	       \
2453			}
2454
2455static struct snd_kcontrol_new alc880_test_mixer[] = {
2456	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2457	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2458	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2459	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2460	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2461	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2462	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2463	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2464	PIN_CTL_TEST("Front Pin Mode", 0x14),
2465	PIN_CTL_TEST("Surround Pin Mode", 0x15),
2466	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2467	PIN_CTL_TEST("Side Pin Mode", 0x17),
2468	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2469	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2470	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2471	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2472	PIN_SRC_TEST("In-1 Pin Source", 0x18),
2473	PIN_SRC_TEST("In-2 Pin Source", 0x19),
2474	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2475	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2476	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2477	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2478	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2479	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2480	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2481	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2482	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2483	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2484	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2485	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2486	{
2487		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2488		.name = "Channel Mode",
2489		.info = alc_ch_mode_info,
2490		.get = alc_ch_mode_get,
2491		.put = alc_ch_mode_put,
2492	},
2493	{ } /* end */
2494};
2495
2496static struct hda_verb alc880_test_init_verbs[] = {
2497	/* Unmute inputs of 0x0c - 0x0f */
2498	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2499	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2500	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2501	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2502	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2503	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2504	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2505	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2506	/* Vol output for 0x0c-0x0f */
2507	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2508	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2509	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2510	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2511	/* Set output pins 0x14-0x17 */
2512	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2513	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2514	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2515	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2516	/* Unmute output pins 0x14-0x17 */
2517	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2518	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2519	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2520	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521	/* Set input pins 0x18-0x1c */
2522	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2523	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2524	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2525	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2526	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2527	/* Mute input pins 0x18-0x1b */
2528	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2529	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2531	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2532	/* ADC set up */
2533	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2534	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2535	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2536	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2537	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2538	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2539	/* Analog input/passthru */
2540	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2541	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2542	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2543	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2544	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2545	{ }
2546};
2547#endif
2548
2549/*
2550 */
2551
2552static const char *alc880_models[ALC880_MODEL_LAST] = {
2553	[ALC880_3ST]		= "3stack",
2554	[ALC880_TCL_S700]	= "tcl",
2555	[ALC880_3ST_DIG]	= "3stack-digout",
2556	[ALC880_CLEVO]		= "clevo",
2557	[ALC880_5ST]		= "5stack",
2558	[ALC880_5ST_DIG]	= "5stack-digout",
2559	[ALC880_W810]		= "w810",
2560	[ALC880_Z71V]		= "z71v",
2561	[ALC880_6ST]		= "6stack",
2562	[ALC880_6ST_DIG]	= "6stack-digout",
2563	[ALC880_ASUS]		= "asus",
2564	[ALC880_ASUS_W1V]	= "asus-w1v",
2565	[ALC880_ASUS_DIG]	= "asus-dig",
2566	[ALC880_ASUS_DIG2]	= "asus-dig2",
2567	[ALC880_UNIWILL_DIG]	= "uniwill",
2568	[ALC880_UNIWILL_P53]	= "uniwill-p53",
2569	[ALC880_FUJITSU]	= "fujitsu",
2570	[ALC880_F1734]		= "F1734",
2571	[ALC880_LG]		= "lg",
2572	[ALC880_LG_LW]		= "lg-lw",
2573#ifdef CONFIG_SND_DEBUG
2574	[ALC880_TEST]		= "test",
2575#endif
2576	[ALC880_AUTO]		= "auto",
2577};
2578
2579static struct snd_pci_quirk alc880_cfg_tbl[] = {
2580	/* Broken BIOS configuration */
2581	SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2582	SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2583
2584	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2585	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2586	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2587	SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2588	SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2589	SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2590	SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2591	SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2592	SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2593
2594	SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2595	SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2596
2597	SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2598	SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2599	SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2600	SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2601	SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2602	SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2603	SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2604	/* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2605	SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2606	SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2607	SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2608	SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2609	SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2610	SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2611	SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2612
2613	SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2614	SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2615	SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2616	SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2617	SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2618	SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2619	SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2620	SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2621	SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2622	SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2623	SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2624	SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2625	SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2626	SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2627	SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2628	SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2629	SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2630	SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2631
2632	SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2633	SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2634	SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2635	SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2636
2637	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2638	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2639	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2640	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2641
2642	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2643	SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2644	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2645	SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2646
2647	SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2648	SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2649	SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2650	SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2651	SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2652	SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2653	SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2654	SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2655	SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2656	SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2657	SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2658
2659	{}
2660};
2661
2662/*
2663 * ALC880 codec presets
2664 */
2665static struct alc_config_preset alc880_presets[] = {
2666	[ALC880_3ST] = {
2667		.mixers = { alc880_three_stack_mixer },
2668		.init_verbs = { alc880_volume_init_verbs,
2669				alc880_pin_3stack_init_verbs },
2670		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2671		.dac_nids = alc880_dac_nids,
2672		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2673		.channel_mode = alc880_threestack_modes,
2674		.need_dac_fix = 1,
2675		.input_mux = &alc880_capture_source,
2676	},
2677	[ALC880_3ST_DIG] = {
2678		.mixers = { alc880_three_stack_mixer },
2679		.init_verbs = { alc880_volume_init_verbs,
2680				alc880_pin_3stack_init_verbs },
2681		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2682		.dac_nids = alc880_dac_nids,
2683		.dig_out_nid = ALC880_DIGOUT_NID,
2684		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2685		.channel_mode = alc880_threestack_modes,
2686		.need_dac_fix = 1,
2687		.input_mux = &alc880_capture_source,
2688	},
2689	[ALC880_TCL_S700] = {
2690		.mixers = { alc880_tcl_s700_mixer },
2691		.init_verbs = { alc880_volume_init_verbs,
2692				alc880_pin_tcl_S700_init_verbs,
2693				alc880_gpio2_init_verbs },
2694		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2695		.dac_nids = alc880_dac_nids,
2696		.hp_nid = 0x03,
2697		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2698		.channel_mode = alc880_2_jack_modes,
2699		.input_mux = &alc880_capture_source,
2700	},
2701	[ALC880_5ST] = {
2702		.mixers = { alc880_three_stack_mixer,
2703			    alc880_five_stack_mixer},
2704		.init_verbs = { alc880_volume_init_verbs,
2705				alc880_pin_5stack_init_verbs },
2706		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2707		.dac_nids = alc880_dac_nids,
2708		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2709		.channel_mode = alc880_fivestack_modes,
2710		.input_mux = &alc880_capture_source,
2711	},
2712	[ALC880_5ST_DIG] = {
2713		.mixers = { alc880_three_stack_mixer,
2714			    alc880_five_stack_mixer },
2715		.init_verbs = { alc880_volume_init_verbs,
2716				alc880_pin_5stack_init_verbs },
2717		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2718		.dac_nids = alc880_dac_nids,
2719		.dig_out_nid = ALC880_DIGOUT_NID,
2720		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2721		.channel_mode = alc880_fivestack_modes,
2722		.input_mux = &alc880_capture_source,
2723	},
2724	[ALC880_6ST] = {
2725		.mixers = { alc880_six_stack_mixer },
2726		.init_verbs = { alc880_volume_init_verbs,
2727				alc880_pin_6stack_init_verbs },
2728		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2729		.dac_nids = alc880_6st_dac_nids,
2730		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2731		.channel_mode = alc880_sixstack_modes,
2732		.input_mux = &alc880_6stack_capture_source,
2733	},
2734	[ALC880_6ST_DIG] = {
2735		.mixers = { alc880_six_stack_mixer },
2736		.init_verbs = { alc880_volume_init_verbs,
2737				alc880_pin_6stack_init_verbs },
2738		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2739		.dac_nids = alc880_6st_dac_nids,
2740		.dig_out_nid = ALC880_DIGOUT_NID,
2741		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2742		.channel_mode = alc880_sixstack_modes,
2743		.input_mux = &alc880_6stack_capture_source,
2744	},
2745	[ALC880_W810] = {
2746		.mixers = { alc880_w810_base_mixer },
2747		.init_verbs = { alc880_volume_init_verbs,
2748				alc880_pin_w810_init_verbs,
2749				alc880_gpio2_init_verbs },
2750		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2751		.dac_nids = alc880_w810_dac_nids,
2752		.dig_out_nid = ALC880_DIGOUT_NID,
2753		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2754		.channel_mode = alc880_w810_modes,
2755		.input_mux = &alc880_capture_source,
2756	},
2757	[ALC880_Z71V] = {
2758		.mixers = { alc880_z71v_mixer },
2759		.init_verbs = { alc880_volume_init_verbs,
2760				alc880_pin_z71v_init_verbs },
2761		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2762		.dac_nids = alc880_z71v_dac_nids,
2763		.dig_out_nid = ALC880_DIGOUT_NID,
2764		.hp_nid = 0x03,
2765		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2766		.channel_mode = alc880_2_jack_modes,
2767		.input_mux = &alc880_capture_source,
2768	},
2769	[ALC880_F1734] = {
2770		.mixers = { alc880_f1734_mixer },
2771		.init_verbs = { alc880_volume_init_verbs,
2772				alc880_pin_f1734_init_verbs },
2773		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2774		.dac_nids = alc880_f1734_dac_nids,
2775		.hp_nid = 0x02,
2776		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2777		.channel_mode = alc880_2_jack_modes,
2778		.input_mux = &alc880_capture_source,
2779	},
2780	[ALC880_ASUS] = {
2781		.mixers = { alc880_asus_mixer },
2782		.init_verbs = { alc880_volume_init_verbs,
2783				alc880_pin_asus_init_verbs,
2784				alc880_gpio1_init_verbs },
2785		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2786		.dac_nids = alc880_asus_dac_nids,
2787		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2788		.channel_mode = alc880_asus_modes,
2789		.need_dac_fix = 1,
2790		.input_mux = &alc880_capture_source,
2791	},
2792	[ALC880_ASUS_DIG] = {
2793		.mixers = { alc880_asus_mixer },
2794		.init_verbs = { alc880_volume_init_verbs,
2795				alc880_pin_asus_init_verbs,
2796				alc880_gpio1_init_verbs },
2797		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2798		.dac_nids = alc880_asus_dac_nids,
2799		.dig_out_nid = ALC880_DIGOUT_NID,
2800		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2801		.channel_mode = alc880_asus_modes,
2802		.need_dac_fix = 1,
2803		.input_mux = &alc880_capture_source,
2804	},
2805	[ALC880_ASUS_DIG2] = {
2806		.mixers = { alc880_asus_mixer },
2807		.init_verbs = { alc880_volume_init_verbs,
2808				alc880_pin_asus_init_verbs,
2809				alc880_gpio2_init_verbs }, /* use GPIO2 */
2810		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2811		.dac_nids = alc880_asus_dac_nids,
2812		.dig_out_nid = ALC880_DIGOUT_NID,
2813		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2814		.channel_mode = alc880_asus_modes,
2815		.need_dac_fix = 1,
2816		.input_mux = &alc880_capture_source,
2817	},
2818	[ALC880_ASUS_W1V] = {
2819		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2820		.init_verbs = { alc880_volume_init_verbs,
2821				alc880_pin_asus_init_verbs,
2822				alc880_gpio1_init_verbs },
2823		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2824		.dac_nids = alc880_asus_dac_nids,
2825		.dig_out_nid = ALC880_DIGOUT_NID,
2826		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2827		.channel_mode = alc880_asus_modes,
2828		.need_dac_fix = 1,
2829		.input_mux = &alc880_capture_source,
2830	},
2831	[ALC880_UNIWILL_DIG] = {
2832		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2833		.init_verbs = { alc880_volume_init_verbs,
2834				alc880_pin_asus_init_verbs },
2835		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2836		.dac_nids = alc880_asus_dac_nids,
2837		.dig_out_nid = ALC880_DIGOUT_NID,
2838		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2839		.channel_mode = alc880_asus_modes,
2840		.need_dac_fix = 1,
2841		.input_mux = &alc880_capture_source,
2842	},
2843	[ALC880_UNIWILL] = {
2844		.mixers = { alc880_uniwill_mixer },
2845		.init_verbs = { alc880_volume_init_verbs,
2846				alc880_uniwill_init_verbs },
2847		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2848		.dac_nids = alc880_asus_dac_nids,
2849		.dig_out_nid = ALC880_DIGOUT_NID,
2850		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2851		.channel_mode = alc880_threestack_modes,
2852		.need_dac_fix = 1,
2853		.input_mux = &alc880_capture_source,
2854		.unsol_event = alc880_uniwill_unsol_event,
2855		.init_hook = alc880_uniwill_automute,
2856	},
2857	[ALC880_UNIWILL_P53] = {
2858		.mixers = { alc880_uniwill_p53_mixer },
2859		.init_verbs = { alc880_volume_init_verbs,
2860				alc880_uniwill_p53_init_verbs },
2861		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2862		.dac_nids = alc880_asus_dac_nids,
2863		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2864		.channel_mode = alc880_threestack_modes,
2865		.input_mux = &alc880_capture_source,
2866		.unsol_event = alc880_uniwill_p53_unsol_event,
2867		.init_hook = alc880_uniwill_p53_hp_automute,
2868	},
2869	[ALC880_FUJITSU] = {
2870		.mixers = { alc880_fujitsu_mixer,
2871			    alc880_pcbeep_mixer, },
2872		.init_verbs = { alc880_volume_init_verbs,
2873				alc880_uniwill_p53_init_verbs,
2874	       			alc880_beep_init_verbs },
2875		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2876		.dac_nids = alc880_dac_nids,
2877		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2878		.channel_mode = alc880_2_jack_modes,
2879		.input_mux = &alc880_capture_source,
2880		.unsol_event = alc880_uniwill_p53_unsol_event,
2881		.init_hook = alc880_uniwill_p53_hp_automute,
2882	},
2883	[ALC880_CLEVO] = {
2884		.mixers = { alc880_three_stack_mixer },
2885		.init_verbs = { alc880_volume_init_verbs,
2886				alc880_pin_clevo_init_verbs },
2887		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2888		.dac_nids = alc880_dac_nids,
2889		.hp_nid = 0x03,
2890		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2891		.channel_mode = alc880_threestack_modes,
2892		.need_dac_fix = 1,
2893		.input_mux = &alc880_capture_source,
2894	},
2895	[ALC880_LG] = {
2896		.mixers = { alc880_lg_mixer },
2897		.init_verbs = { alc880_volume_init_verbs,
2898				alc880_lg_init_verbs },
2899		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2900		.dac_nids = alc880_lg_dac_nids,
2901		.dig_out_nid = ALC880_DIGOUT_NID,
2902		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2903		.channel_mode = alc880_lg_ch_modes,
2904		.need_dac_fix = 1,
2905		.input_mux = &alc880_lg_capture_source,
2906		.unsol_event = alc880_lg_unsol_event,
2907		.init_hook = alc880_lg_automute,
2908#ifdef CONFIG_SND_HDA_POWER_SAVE
2909		.loopbacks = alc880_lg_loopbacks,
2910#endif
2911	},
2912	[ALC880_LG_LW] = {
2913		.mixers = { alc880_lg_lw_mixer },
2914		.init_verbs = { alc880_volume_init_verbs,
2915				alc880_lg_lw_init_verbs },
2916		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2917		.dac_nids = alc880_dac_nids,
2918		.dig_out_nid = ALC880_DIGOUT_NID,
2919		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
2920		.channel_mode = alc880_lg_lw_modes,
2921		.input_mux = &alc880_lg_lw_capture_source,
2922		.unsol_event = alc880_lg_lw_unsol_event,
2923		.init_hook = alc880_lg_lw_automute,
2924	},
2925#ifdef CONFIG_SND_DEBUG
2926	[ALC880_TEST] = {
2927		.mixers = { alc880_test_mixer },
2928		.init_verbs = { alc880_test_init_verbs },
2929		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2930		.dac_nids = alc880_test_dac_nids,
2931		.dig_out_nid = ALC880_DIGOUT_NID,
2932		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2933		.channel_mode = alc880_test_modes,
2934		.input_mux = &alc880_test_capture_source,
2935	},
2936#endif
2937};
2938
2939/*
2940 * Automatic parse of I/O pins from the BIOS configuration
2941 */
2942
2943#define NUM_CONTROL_ALLOC	32
2944#define NUM_VERB_ALLOC		32
2945
2946enum {
2947	ALC_CTL_WIDGET_VOL,
2948	ALC_CTL_WIDGET_MUTE,
2949	ALC_CTL_BIND_MUTE,
2950};
2951static struct snd_kcontrol_new alc880_control_templates[] = {
2952	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2953	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2954	HDA_BIND_MUTE(NULL, 0, 0, 0),
2955};
2956
2957/* add dynamic controls */
2958static int add_control(struct alc_spec *spec, int type, const char *name,
2959		       unsigned long val)
2960{
2961	struct snd_kcontrol_new *knew;
2962
2963	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2964		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2965
2966		/* array + terminator */
2967		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
2968		if (!knew)
2969			return -ENOMEM;
2970		if (spec->kctl_alloc) {
2971			memcpy(knew, spec->kctl_alloc,
2972			       sizeof(*knew) * spec->num_kctl_alloc);
2973			kfree(spec->kctl_alloc);
2974		}
2975		spec->kctl_alloc = knew;
2976		spec->num_kctl_alloc = num;
2977	}
2978
2979	knew = &spec->kctl_alloc[spec->num_kctl_used];
2980	*knew = alc880_control_templates[type];
2981	knew->name = kstrdup(name, GFP_KERNEL);
2982	if (!knew->name)
2983		return -ENOMEM;
2984	knew->private_value = val;
2985	spec->num_kctl_used++;
2986	return 0;
2987}
2988
2989#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2990#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2991#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2992#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2993#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2994#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2995#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2996#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2997#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2998#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2999#define ALC880_PIN_CD_NID		0x1c
3000
3001/* fill in the dac_nids table from the parsed pin configuration */
3002static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3003				     const struct auto_pin_cfg *cfg)
3004{
3005	hda_nid_t nid;
3006	int assigned[4];
3007	int i, j;
3008
3009	memset(assigned, 0, sizeof(assigned));
3010	spec->multiout.dac_nids = spec->private_dac_nids;
3011
3012	/* check the pins hardwired to audio widget */
3013	for (i = 0; i < cfg->line_outs; i++) {
3014		nid = cfg->line_out_pins[i];
3015		if (alc880_is_fixed_pin(nid)) {
3016			int idx = alc880_fixed_pin_idx(nid);
3017			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3018			assigned[idx] = 1;
3019		}
3020	}
3021	/* left pins can be connect to any audio widget */
3022	for (i = 0; i < cfg->line_outs; i++) {
3023		nid = cfg->line_out_pins[i];
3024		if (alc880_is_fixed_pin(nid))
3025			continue;
3026		/* search for an empty channel */
3027		for (j = 0; j < cfg->line_outs; j++) {
3028			if (!assigned[j]) {
3029				spec->multiout.dac_nids[i] =
3030					alc880_idx_to_dac(j);
3031				assigned[j] = 1;
3032				break;
3033			}
3034		}
3035	}
3036	spec->multiout.num_dacs = cfg->line_outs;
3037	return 0;
3038}
3039
3040/* add playback controls from the parsed DAC table */
3041static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3042					     const struct auto_pin_cfg *cfg)
3043{
3044	char name[32];
3045	static const char *chname[4] = {
3046		"Front", "Surround", NULL /*CLFE*/, "Side"
3047	};
3048	hda_nid_t nid;
3049	int i, err;
3050
3051	for (i = 0; i < cfg->line_outs; i++) {
3052		if (!spec->multiout.dac_nids[i])
3053			continue;
3054		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3055		if (i == 2) {
3056			/* Center/LFE */
3057			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3058					  "Center Playback Volume",
3059					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3060							      HDA_OUTPUT));
3061			if (err < 0)
3062				return err;
3063			err = add_control(spec, ALC_CTL_WIDGET_VOL,
3064					  "LFE Playback Volume",
3065					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3066							      HDA_OUTPUT));
3067			if (err < 0)
3068				return err;
3069			err = add_control(spec, ALC_CTL_BIND_MUTE,
3070					  "Center Playback Switch",
3071					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3072							      HDA_INPUT));
3073			if (err < 0)
3074				return err;
3075			err = add_control(spec, ALC_CTL_BIND_MUTE,
3076					  "LFE Playback Switch",
3077					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3078							      HDA_INPUT));
3079			if (err < 0)
3080				return err;
3081		} else {
3082			sprintf(name, "%s Playback Volume", chname[i]);
3083			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3084					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3085							      HDA_OUTPUT));
3086			if (err < 0)
3087				return err;
3088			sprintf(name, "%s Playback Switch", chname[i]);
3089			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3090					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3091							      HDA_INPUT));
3092			if (err < 0)
3093				return err;
3094		}
3095	}
3096	return 0;
3097}
3098
3099/* add playback controls for speaker and HP outputs */
3100static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3101					const char *pfx)
3102{
3103	hda_nid_t nid;
3104	int err;
3105	char name[32];
3106
3107	if (!pin)
3108		return 0;
3109
3110	if (alc880_is_fixed_pin(pin)) {
3111		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3112		/* specify the DAC as the extra output */
3113		if (!spec->multiout.hp_nid)
3114			spec->multiout.hp_nid = nid;
3115		else
3116			spec->multiout.extra_out_nid[0] = nid;
3117		/* control HP volume/switch on the output mixer amp */
3118		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3119		sprintf(name, "%s Playback Volume", pfx);
3120		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3121				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3122		if (err < 0)
3123			return err;
3124		sprintf(name, "%s Playback Switch", pfx);
3125		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3126				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3127		if (err < 0)
3128			return err;
3129	} else if (alc880_is_multi_pin(pin)) {
3130		/* set manual connection */
3131		/* we have only a switch on HP-out PIN */
3132		sprintf(name, "%s Playback Switch", pfx);
3133		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3134				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3135		if (err < 0)
3136			return err;
3137	}
3138	return 0;
3139}
3140
3141/* create input playback/capture controls for the given pin */
3142static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3143			    const char *ctlname,
3144			    int idx, hda_nid_t mix_nid)
3145{
3146	char name[32];
3147	int err;
3148
3149	sprintf(name, "%s Playback Volume", ctlname);
3150	err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3151			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3152	if (err < 0)
3153		return err;
3154	sprintf(name, "%s Playback Switch", ctlname);
3155	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3156			  HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3157	if (err < 0)
3158		return err;
3159	return 0;
3160}
3161
3162/* create playback/capture controls for input pins */
3163static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3164						const struct auto_pin_cfg *cfg)
3165{
3166	struct hda_input_mux *imux = &spec->private_imux;
3167	int i, err, idx;
3168
3169	for (i = 0; i < AUTO_PIN_LAST; i++) {
3170		if (alc880_is_input_pin(cfg->input_pins[i])) {
3171			idx = alc880_input_pin_idx(cfg->input_pins[i]);
3172			err = new_analog_input(spec, cfg->input_pins[i],
3173					       auto_pin_cfg_labels[i],
3174					       idx, 0x0b);
3175			if (err < 0)
3176				return err;
3177			imux->items[imux->num_items].label =
3178				auto_pin_cfg_labels[i];
3179			imux->items[imux->num_items].index =
3180				alc880_input_pin_idx(cfg->input_pins[i]);
3181			imux->num_items++;
3182		}
3183	}
3184	return 0;
3185}
3186
3187static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3188					      hda_nid_t nid, int pin_type,
3189					      int dac_idx)
3190{
3191	/* set as output */
3192	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3193			    pin_type);
3194	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3195			    AMP_OUT_UNMUTE);
3196	/* need the manual connection? */
3197	if (alc880_is_multi_pin(nid)) {
3198		struct alc_spec *spec = codec->spec;
3199		int idx = alc880_multi_pin_idx(nid);
3200		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3201				    AC_VERB_SET_CONNECT_SEL,
3202				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3203	}
3204}
3205
3206static int get_pin_type(int line_out_type)
3207{
3208	if (line_out_type == AUTO_PIN_HP_OUT)
3209		return PIN_HP;
3210	else
3211		return PIN_OUT;
3212}
3213
3214static void alc880_auto_init_multi_out(struct hda_codec *codec)
3215{
3216	struct alc_spec *spec = codec->spec;
3217	int i;
3218
3219	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3220	for (i = 0; i < spec->autocfg.line_outs; i++) {
3221		hda_nid_t nid = spec->autocfg.line_out_pins[i];
3222		int pin_type = get_pin_type(spec->autocfg.line_out_type);
3223		alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3224	}
3225}
3226
3227static void alc880_auto_init_extra_out(struct hda_codec *codec)
3228{
3229	struct alc_spec *spec = codec->spec;
3230	hda_nid_t pin;
3231
3232	pin = spec->autocfg.speaker_pins[0];
3233	if (pin) /* connect to front */
3234		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3235	pin = spec->autocfg.hp_pins[0];
3236	if (pin) /* connect to front */
3237		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3238}
3239
3240static void alc880_auto_init_analog_input(struct hda_codec *codec)
3241{
3242	struct alc_spec *spec = codec->spec;
3243	int i;
3244
3245	for (i = 0; i < AUTO_PIN_LAST; i++) {
3246		hda_nid_t nid = spec->autocfg.input_pins[i];
3247		if (alc880_is_input_pin(nid)) {
3248			snd_hda_codec_write(codec, nid, 0,
3249					    AC_VERB_SET_PIN_WIDGET_CONTROL,
3250					    i <= AUTO_PIN_FRONT_MIC ?
3251					    PIN_VREF80 : PIN_IN);
3252			if (nid != ALC880_PIN_CD_NID)
3253				snd_hda_codec_write(codec, nid, 0,
3254						    AC_VERB_SET_AMP_GAIN_MUTE,
3255						    AMP_OUT_MUTE);
3256		}
3257	}
3258}
3259
3260/* parse the BIOS configuration and set up the alc_spec */
3261/* return 1 if successful, 0 if the proper config is not found,
3262 * or a negative error code
3263 */
3264static int alc880_parse_auto_config(struct hda_codec *codec)
3265{
3266	struct alc_spec *spec = codec->spec;
3267	int err;
3268	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3269
3270	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3271					   alc880_ignore);
3272	if (err < 0)
3273		return err;
3274	if (!spec->autocfg.line_outs)
3275		return 0; /* can't find valid BIOS pin config */
3276
3277	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3278	if (err < 0)
3279		return err;
3280	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3281	if (err < 0)
3282		return err;
3283	err = alc880_auto_create_extra_out(spec,
3284					   spec->autocfg.speaker_pins[0],
3285					   "Speaker");
3286	if (err < 0)
3287		return err;
3288	err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3289					   "Headphone");
3290	if (err < 0)
3291		return err;
3292	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3293	if (err < 0)
3294		return err;
3295
3296	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3297
3298	if (spec->autocfg.dig_out_pin)
3299		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3300	if (spec->autocfg.dig_in_pin)
3301		spec->dig_in_nid = ALC880_DIGIN_NID;
3302
3303	if (spec->kctl_alloc)
3304		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3305
3306	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3307
3308	spec->num_mux_defs = 1;
3309	spec->input_mux = &spec->private_imux;
3310
3311	return 1;
3312}
3313
3314/* additional initialization for auto-configuration model */
3315static void alc880_auto_init(struct hda_codec *codec)
3316{
3317	alc880_auto_init_multi_out(codec);
3318	alc880_auto_init_extra_out(codec);
3319	alc880_auto_init_analog_input(codec);
3320}
3321
3322/*
3323 * OK, here we have finally the patch for ALC880
3324 */
3325
3326static int patch_alc880(struct hda_codec *codec)
3327{
3328	struct alc_spec *spec;
3329	int board_config;
3330	int err;
3331
3332	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3333	if (spec == NULL)
3334		return -ENOMEM;
3335
3336	codec->spec = spec;
3337
3338	board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3339						  alc880_models,
3340						  alc880_cfg_tbl);
3341	if (board_config < 0) {
3342		printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3343		       "trying auto-probe from BIOS...\n");
3344		board_config = ALC880_AUTO;
3345	}
3346
3347	if (board_config == ALC880_AUTO) {
3348		/* automatic parse from the BIOS config */
3349		err = alc880_parse_auto_config(codec);
3350		if (err < 0) {
3351			alc_free(codec);
3352			return err;
3353		} else if (!err) {
3354			printk(KERN_INFO
3355			       "hda_codec: Cannot set up configuration "
3356			       "from BIOS.  Using 3-stack mode...\n");
3357			board_config = ALC880_3ST;
3358		}
3359	}
3360
3361	if (board_config != ALC880_AUTO)
3362		setup_preset(spec, &alc880_presets[board_config]);
3363
3364	spec->stream_name_analog = "ALC880 Analog";
3365	spec->stream_analog_playback = &alc880_pcm_analog_playback;
3366	spec->stream_analog_capture = &alc880_pcm_analog_capture;
3367
3368	spec->stream_name_digital = "ALC880 Digital";
3369	spec->stream_digital_playback = &alc880_pcm_digital_playback;
3370	spec->stream_digital_capture = &alc880_pcm_digital_capture;
3371
3372	if (!spec->adc_nids && spec->input_mux) {
3373		/* check whether NID 0x07 is valid */
3374		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3375		/* get type */
3376		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3377		if (wcap != AC_WID_AUD_IN) {
3378			spec->adc_nids = alc880_adc_nids_alt;
3379			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3380			spec->mixers[spec->num_mixers] =
3381				alc880_capture_alt_mixer;
3382			spec->num_mixers++;
3383		} else {
3384			spec->adc_nids = alc880_adc_nids;
3385			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3386			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3387			spec->num_mixers++;
3388		}
3389	}
3390
3391	codec->patch_ops = alc_patch_ops;
3392	if (board_config == ALC880_AUTO)
3393		spec->init_hook = alc880_auto_init;
3394#ifdef CONFIG_SND_HDA_POWER_SAVE
3395	if (!spec->loopback.amplist)
3396		spec->loopback.amplist = alc880_loopbacks;
3397#endif
3398
3399	return 0;
3400}
3401
3402
3403/*
3404 * ALC260 support
3405 */
3406
3407static hda_nid_t alc260_dac_nids[1] = {
3408	/* front */
3409	0x02,
3410};
3411
3412static hda_nid_t alc260_adc_nids[1] = {
3413	/* ADC0 */
3414	0x04,
3415};
3416
3417static hda_nid_t alc260_adc_nids_alt[1] = {
3418	/* ADC1 */
3419	0x05,
3420};
3421
3422static hda_nid_t alc260_hp_adc_nids[2] = {
3423	/* ADC1, 0 */
3424	0x05, 0x04
3425};
3426
3427/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3428 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3429 */
3430static hda_nid_t alc260_dual_adc_nids[2] = {
3431	/* ADC0, ADC1 */
3432	0x04, 0x05
3433};
3434
3435#define ALC260_DIGOUT_NID	0x03
3436#define ALC260_DIGIN_NID	0x06
3437
3438static struct hda_input_mux alc260_capture_source = {
3439	.num_items = 4,
3440	.items = {
3441		{ "Mic", 0x0 },
3442		{ "Front Mic", 0x1 },
3443		{ "Line", 0x2 },
3444		{ "CD", 0x4 },
3445	},
3446};
3447
3448/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3449 * headphone jack and the internal CD lines since these are the only pins at
3450 * which audio can appear.  For flexibility, also allow the option of
3451 * recording the mixer output on the second ADC (ADC0 doesn't have a
3452 * connection to the mixer output).
3453 */
3454static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3455	{
3456		.num_items = 3,
3457		.items = {
3458			{ "Mic/Line", 0x0 },
3459			{ "CD", 0x4 },
3460			{ "Headphone", 0x2 },
3461		},
3462	},
3463	{
3464		.num_items = 4,
3465		.items = {
3466			{ "Mic/Line", 0x0 },
3467			{ "CD", 0x4 },
3468			{ "Headphone", 0x2 },
3469			{ "Mixer", 0x5 },
3470		},
3471	},
3472
3473};
3474
3475/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3476 * the Fujitsu S702x, but jacks are marked differently.
3477 */
3478static struct hda_input_mux alc260_acer_capture_sources[2] = {
3479	{
3480		.num_items = 4,
3481		.items = {
3482			{ "Mic", 0x0 },
3483			{ "Line", 0x2 },
3484			{ "CD", 0x4 },
3485			{ "Headphone", 0x5 },
3486		},
3487	},
3488	{
3489		.num_items = 5,
3490		.items = {
3491			{ "Mic", 0x0 },
3492			{ "Line", 0x2 },
3493			{ "CD", 0x4 },
3494			{ "Headphone", 0x6 },
3495			{ "Mixer", 0x5 },
3496		},
3497	},
3498};
3499/*
3500 * This is just place-holder, so there's something for alc_build_pcms to look
3501 * at when it calculates the maximum number of channels. ALC260 has no mixer
3502 * element which allows changing the channel mode, so the verb list is
3503 * never used.
3504 */
3505static struct hda_channel_mode alc260_modes[1] = {
3506	{ 2, NULL },
3507};
3508
3509
3510/* Mixer combinations
3511 *
3512 * basic: base_output + input + pc_beep + capture
3513 * HP: base_output + input + capture_alt
3514 * HP_3013: hp_3013 + input + capture
3515 * fujitsu: fujitsu + capture
3516 * acer: acer + capture
3517 */
3518
3519static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3520	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3521	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3522	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3523	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3524	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3525	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3526	{ } /* end */
3527};
3528
3529static struct snd_kcontrol_new alc260_input_mixer[] = {
3530	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3531	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3532	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3533	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3534	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3535	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3536	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3537	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3538	{ } /* end */
3539};
3540
3541static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3542	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3543	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3544	{ } /* end */
3545};
3546
3547static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3548	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3549	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3550	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3551	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3552	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3553	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3554	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3555	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3556	{ } /* end */
3557};
3558
3559/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
3560 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3561 */
3562static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3563	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3564	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3565	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3566	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3567	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3568	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3569	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3570	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3571	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3572	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3573	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3574	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3575	{ } /* end */
3576};
3577
3578/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3579 * versions of the ALC260 don't act on requests to enable mic bias from NID
3580 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3581 * datasheet doesn't mention this restriction.  At this stage it's not clear
3582 * whether this behaviour is intentional or is a hardware bug in chip
3583 * revisions available in early 2006.  Therefore for now allow the
3584 * "Headphone Jack Mode" control to span all choices, but if it turns out
3585 * that the lack of mic bias for this NID is intentional we could change the
3586 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3587 *
3588 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3589 * don't appear to make the mic bias available from the "line" jack, even
3590 * though the NID used for this jack (0x14) can supply it.  The theory is
3591 * that perhaps Acer have included blocking capacitors between the ALC260
3592 * and the output jack.  If this turns out to be the case for all such
3593 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3594 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3595 *
3596 * The C20x Tablet series have a mono internal speaker which is controlled
3597 * via the chip's Mono sum widget and pin complex, so include the necessary
3598 * controls for such models.  On models without a "mono speaker" the control
3599 * won't do anything.
3600 */
3601static struct snd_kcontrol_new alc260_acer_mixer[] = {
3602	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3603	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3604	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3605	HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3606			      HDA_OUTPUT),
3607	HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3608			   HDA_INPUT),
3609	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3610	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3611	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3612	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3613	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3614	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3615	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3616	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3617	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3618	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3619	{ } /* end */
3620};
3621
3622/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3623 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3624 */
3625static struct snd_kcontrol_new alc260_will_mixer[] = {
3626	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3627	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3628	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3629	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3630	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3631	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3632	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3633	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3634	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3635	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3636	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3637	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3638	{ } /* end */
3639};
3640
3641/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3642 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3643 */
3644static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3645	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3646	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3647	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3648	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3649	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3650	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3651	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3652	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3653	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3654	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3655	{ } /* end */
3656};
3657
3658/* capture mixer elements */
3659static struct snd_kcontrol_new alc260_capture_mixer[] = {
3660	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3661	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3662	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3663	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3664	{
3665		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3666		/* The multiple "Capture Source" controls confuse alsamixer
3667		 * So call somewhat different..
3668		 * FIXME: the controls appear in the "playback" view!
3669		 */
3670		/* .name = "Capture Source", */
3671		.name = "Input Source",
3672		.count = 2,
3673		.info = alc_mux_enum_info,
3674		.get = alc_mux_enum_get,
3675		.put = alc_mux_enum_put,
3676	},
3677	{ } /* end */
3678};
3679
3680static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3681	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3682	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3683	{
3684		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3685		/* The multiple "Capture Source" controls confuse alsamixer
3686		 * So call somewhat different..
3687		 * FIXME: the controls appear in the "playback" view!
3688		 */
3689		/* .name = "Capture Source", */
3690		.name = "Input Source",
3691		.count = 1,
3692		.info = alc_mux_enum_info,
3693		.get = alc_mux_enum_get,
3694		.put = alc_mux_enum_put,
3695	},
3696	{ } /* end */
3697};
3698
3699/*
3700 * initialization verbs
3701 */
3702static struct hda_verb alc260_init_verbs[] = {
3703	/* Line In pin widget for input */
3704	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3705	/* CD pin widget for input */
3706	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3707	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3708	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3709	/* Mic2 (front panel) pin widget for input and vref at 80% */
3710	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3711	/* LINE-2 is used for line-out in rear */
3712	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3713	/* select line-out */
3714	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3715	/* LINE-OUT pin */
3716	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3717	/* enable HP */
3718	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3719	/* enable Mono */
3720	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3721	/* mute capture amp left and right */
3722	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3723	/* set connection select to line in (default select for this ADC) */
3724	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3725	/* mute capture amp left and right */
3726	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3727	/* set connection select to line in (default select for this ADC) */
3728	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3729	/* set vol=0 Line-Out mixer amp left and right */
3730	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3731	/* unmute pin widget amp left and right (no gain on this amp) */
3732	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3733	/* set vol=0 HP mixer amp left and right */
3734	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3735	/* unmute pin widget amp left and right (no gain on this amp) */
3736	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737	/* set vol=0 Mono mixer amp left and right */
3738	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3739	/* unmute pin widget amp left and right (no gain on this amp) */
3740	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3741	/* unmute LINE-2 out pin */
3742	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3743	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3744	 * Line In 2 = 0x03
3745	 */
3746	/* mute analog inputs */
3747	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3748	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3749	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3750	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3751	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3752	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3753	/* mute Front out path */
3754	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3755	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3756	/* mute Headphone out path */
3757	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3758	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3759	/* mute Mono out path */
3760	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3761	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3762	{ }
3763};
3764
3765#if 0 /* should be identical with alc260_init_verbs? */
3766static struct hda_verb alc260_hp_init_verbs[] = {
3767	/* Headphone and output */
3768	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3769	/* mono output */
3770	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3771	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3772	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3773	/* Mic2 (front panel) pin widget for input and vref at 80% */
3774	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3775	/* Line In pin widget for input */
3776	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3777	/* Line-2 pin widget for output */
3778	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3779	/* CD pin widget for input */
3780	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3781	/* unmute amp left and right */
3782	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3783	/* set connection select to line in (default select for this ADC) */
3784	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3785	/* unmute Line-Out mixer amp left and right (volume = 0) */
3786	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3787	/* mute pin widget amp left and right (no gain on this amp) */
3788	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3789	/* unmute HP mixer amp left and right (volume = 0) */
3790	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3791	/* mute pin widget amp left and right (no gain on this amp) */
3792	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3793	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3794	 * Line In 2 = 0x03
3795	 */
3796	/* mute analog inputs */
3797	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3798	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3799	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3800	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3801	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3802	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3803	/* Unmute Front out path */
3804	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3805	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3806	/* Unmute Headphone out path */
3807	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3808	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3809	/* Unmute Mono out path */
3810	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3811	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3812	{ }
3813};
3814#endif
3815
3816static struct hda_verb alc260_hp_3013_init_verbs[] = {
3817	/* Line out and output */
3818	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3819	/* mono output */
3820	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3821	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3822	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3823	/* Mic2 (front panel) pin widget for input and vref at 80% */
3824	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3825	/* Line In pin widget for input */
3826	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3827	/* Headphone pin widget for output */
3828	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3829	/* CD pin widget for input */
3830	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3831	/* unmute amp left and right */
3832	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3833	/* set connection select to line in (default select for this ADC) */
3834	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3835	/* unmute Line-Out mixer amp left and right (volume = 0) */
3836	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3837	/* mute pin widget amp left and right (no gain on this amp) */
3838	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3839	/* unmute HP mixer amp left and right (volume = 0) */
3840	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3841	/* mute pin widget amp left and right (no gain on this amp) */
3842	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3843	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3844	 * Line In 2 = 0x03
3845	 */
3846	/* mute analog inputs */
3847	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3848	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3849	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3850	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3851	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3852	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3853	/* Unmute Front out path */
3854	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3855	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3856	/* Unmute Headphone out path */
3857	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3858	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3859	/* Unmute Mono out path */
3860	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3861	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3862	{ }
3863};
3864
3865/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3866 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3867 * audio = 0x16, internal speaker = 0x10.
3868 */
3869static struct hda_verb alc260_fujitsu_init_verbs[] = {
3870	/* Disable all GPIOs */
3871	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3872	/* Internal speaker is connected to headphone pin */
3873	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3874	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3875	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3876	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3877	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3878	/* Ensure all other unused pins are disabled and muted. */
3879	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3880	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3881	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3882	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3883	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3884	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3885	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3886	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3887
3888	/* Disable digital (SPDIF) pins */
3889	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3890	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3891
3892	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3893	 * when acting as an output.
3894	 */
3895	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3896
3897	/* Start with output sum widgets muted and their output gains at min */
3898	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3899	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3900	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3901	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3902	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3903	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3904	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3905	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3906	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3907
3908	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3909	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3910	/* Unmute Line1 pin widget output buffer since it starts as an output.
3911	 * If the pin mode is changed by the user the pin mode control will
3912	 * take care of enabling the pin's input/output buffers as needed.
3913	 * Therefore there's no need to enable the input buffer at this
3914	 * stage.
3915	 */
3916	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3917	/* Unmute input buffer of pin widget used for Line-in (no equiv
3918	 * mixer ctrl)
3919	 */
3920	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3921
3922	/* Mute capture amp left and right */
3923	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3924	/* Set ADC connection select to match default mixer setting - line
3925	 * in (on mic1 pin)
3926	 */
3927	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3928
3929	/* Do the same for the second ADC: mute capture input amp and
3930	 * set ADC connection to line in (on mic1 pin)
3931	 */
3932	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3933	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3934
3935	/* Mute all inputs to mixer widget (even unconnected ones) */
3936	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3937	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3938	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3939	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3940	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3941	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3942	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3943	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3944
3945	{ }
3946};
3947
3948/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3949 * similar laptops (adapted from Fujitsu init verbs).
3950 */
3951static struct hda_verb alc260_acer_init_verbs[] = {
3952	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3953	 * the headphone jack.  Turn this on and rely on the standard mute
3954	 * methods whenever the user wants to turn these outputs off.
3955	 */
3956	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3957	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3958	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3959	/* Internal speaker/Headphone jack is connected to Line-out pin */
3960	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3961	/* Internal microphone/Mic jack is connected to Mic1 pin */
3962	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3963	/* Line In jack is connected to Line1 pin */
3964	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3965	/* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3966	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3967	/* Ensure all other unused pins are disabled and muted. */
3968	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3969	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3970	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3971	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3972	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3973	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3974	/* Disable digital (SPDIF) pins */
3975	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3976	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3977
3978	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3979	 * bus when acting as outputs.
3980	 */
3981	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3982	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3983
3984	/* Start with output sum widgets muted and their output gains at min */
3985	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3986	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3987	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3988	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3989	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3990	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3991	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3992	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3993	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3994
3995	/* Unmute Line-out pin widget amp left and right
3996	 * (no equiv mixer ctrl)
3997	 */
3998	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3999	/* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4000	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4001	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
4002	 * inputs. If the pin mode is changed by the user the pin mode control
4003	 * will take care of enabling the pin's input/output buffers as needed.
4004	 * Therefore there's no need to enable the input buffer at this
4005	 * stage.
4006	 */
4007	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4008	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4009
4010	/* Mute capture amp left and right */
4011	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4012	/* Set ADC connection select to match default mixer setting - mic
4013	 * (on mic1 pin)
4014	 */
4015	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4016
4017	/* Do similar with the second ADC: mute capture input amp and
4018	 * set ADC connection to mic to match ALSA's default state.
4019	 */
4020	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4021	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4022
4023	/* Mute all inputs to mixer widget (even unconnected ones) */
4024	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4025	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4026	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4027	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4028	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4029	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4030	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4031	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4032
4033	{ }
4034};
4035
4036static struct hda_verb alc260_will_verbs[] = {
4037	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4038	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4039	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4040	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4041	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4042	{0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4043	{}
4044};
4045
4046static struct hda_verb alc260_replacer_672v_verbs[] = {
4047	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4048	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4049	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4050
4051	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4052	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4053	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4054
4055	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4056	{}
4057};
4058
4059/* toggle speaker-output according to the hp-jack state */
4060static void alc260_replacer_672v_automute(struct hda_codec *codec)
4061{
4062        unsigned int present;
4063
4064	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4065        present = snd_hda_codec_read(codec, 0x0f, 0,
4066                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4067	if (present) {
4068		snd_hda_codec_write_cache(codec, 0x01, 0,
4069					  AC_VERB_SET_GPIO_DATA, 1);
4070		snd_hda_codec_write_cache(codec, 0x0f, 0,
4071					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4072					  PIN_HP);
4073	} else {
4074		snd_hda_codec_write_cache(codec, 0x01, 0,
4075					  AC_VERB_SET_GPIO_DATA, 0);
4076		snd_hda_codec_write_cache(codec, 0x0f, 0,
4077					  AC_VERB_SET_PIN_WIDGET_CONTROL,
4078					  PIN_OUT);
4079	}
4080}
4081
4082static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4083                                       unsigned int res)
4084{
4085        if ((res >> 26) == ALC880_HP_EVENT)
4086                alc260_replacer_672v_automute(codec);
4087}
4088
4089/* Test configuration for debugging, modelled after the ALC880 test
4090 * configuration.
4091 */
4092#ifdef CONFIG_SND_DEBUG
4093static hda_nid_t alc260_test_dac_nids[1] = {
4094	0x02,
4095};
4096static hda_nid_t alc260_test_adc_nids[2] = {
4097	0x04, 0x05,
4098};
4099/* For testing the ALC260, each input MUX needs its own definition since
4100 * the signal assignments are different.  This assumes that the first ADC
4101 * is NID 0x04.
4102 */
4103static struct hda_input_mux alc260_test_capture_sources[2] = {
4104	{
4105		.num_items = 7,
4106		.items = {
4107			{ "MIC1 pin", 0x0 },
4108			{ "MIC2 pin", 0x1 },
4109			{ "LINE1 pin", 0x2 },
4110			{ "LINE2 pin", 0x3 },
4111			{ "CD pin", 0x4 },
4112			{ "LINE-OUT pin", 0x5 },
4113			{ "HP-OUT pin", 0x6 },
4114		},
4115        },
4116	{
4117		.num_items = 8,
4118		.items = {
4119			{ "MIC1 pin", 0x0 },
4120			{ "MIC2 pin", 0x1 },
4121			{ "LINE1 pin", 0x2 },
4122			{ "LINE2 pin", 0x3 },
4123			{ "CD pin", 0x4 },
4124			{ "Mixer", 0x5 },
4125			{ "LINE-OUT pin", 0x6 },
4126			{ "HP-OUT pin", 0x7 },
4127		},
4128        },
4129};
4130static struct snd_kcontrol_new alc260_test_mixer[] = {
4131	/* Output driver widgets */
4132	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4133	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4134	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4135	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4136	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4137	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4138
4139	/* Modes for retasking pin widgets
4140	 * Note: the ALC260 doesn't seem to act on requests to enable mic
4141         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4142         * mention this restriction.  At this stage it's not clear whether
4143         * this behaviour is intentional or is a hardware bug in chip
4144         * revisions available at least up until early 2006.  Therefore for
4145         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4146         * choices, but if it turns out that the lack of mic bias for these
4147         * NIDs is intentional we could change their modes from
4148         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4149	 */
4150	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4151	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4152	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4153	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4154	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4155	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4156
4157	/* Loopback mixer controls */
4158	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4159	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4160	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4161	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4162	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4163	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4164	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4165	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4166	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4167	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4168	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4169	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4170	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4171	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4172	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4173	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4174
4175	/* Controls for GPIO pins, assuming they are configured as outputs */
4176	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4177	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4178	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4179	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4180
4181	/* Switches to allow the digital IO pins to be enabled.  The datasheet
4182	 * is ambigious as to which NID is which; testing on laptops which
4183	 * make this output available should provide clarification.
4184	 */
4185	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4186	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4187
4188	{ } /* end */
4189};
4190static struct hda_verb alc260_test_init_verbs[] = {
4191	/* Enable all GPIOs as outputs with an initial value of 0 */
4192	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4193	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4194	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4195
4196	/* Enable retasking pins as output, initially without power amp */
4197	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4198	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4199	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4200	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4201	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4202	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4203
4204	/* Disable digital (SPDIF) pins initially, but users can enable
4205	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
4206	 * payload also sets the generation to 0, output to be in "consumer"
4207	 * PCM format, copyright asserted, no pre-emphasis and no validity
4208	 * control.
4209	 */
4210	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4211	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4212
4213	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4214	 * OUT1 sum bus when acting as an output.
4215	 */
4216	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4217	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4218	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4219	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4220
4221	/* Start with output sum widgets muted and their output gains at min */
4222	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4223	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4224	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4225	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4226	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4227	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4228	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4229	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4230	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4231
4232	/* Unmute retasking pin widget output buffers since the default
4233	 * state appears to be output.  As the pin mode is changed by the
4234	 * user the pin mode control will take care of enabling the pin's
4235	 * input/output buffers as needed.
4236	 */
4237	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4238	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4239	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4240	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4241	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4242	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4243	/* Also unmute the mono-out pin widget */
4244	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4245
4246	/* Mute capture amp left and right */
4247	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4248	/* Set ADC connection select to match default mixer setting (mic1
4249	 * pin)
4250	 */
4251	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4252
4253	/* Do the same for the second ADC: mute capture input amp and
4254	 * set ADC connection to mic1 pin
4255	 */
4256	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4257	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4258
4259	/* Mute all inputs to mixer widget (even unconnected ones) */
4260	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4261	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4262	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4263	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4264	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4265	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4266	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4267	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4268
4269	{ }
4270};
4271#endif
4272
4273static struct hda_pcm_stream alc260_pcm_analog_playback = {
4274	.substreams = 1,
4275	.channels_min = 2,
4276	.channels_max = 2,
4277};
4278
4279static struct hda_pcm_stream alc260_pcm_analog_capture = {
4280	.substreams = 1,
4281	.channels_min = 2,
4282	.channels_max = 2,
4283};
4284
4285#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
4286#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
4287
4288/*
4289 * for BIOS auto-configuration
4290 */
4291
4292static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4293					const char *pfx)
4294{
4295	hda_nid_t nid_vol;
4296	unsigned long vol_val, sw_val;
4297	char name[32];
4298	int err;
4299
4300	if (nid >= 0x0f && nid < 0x11) {
4301		nid_vol = nid - 0x7;
4302		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4303		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4304	} else if (nid == 0x11) {
4305		nid_vol = nid - 0x7;
4306		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4307		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4308	} else if (nid >= 0x12 && nid <= 0x15) {
4309		nid_vol = 0x08;
4310		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4311		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4312	} else
4313		return 0; /* N/A */
4314
4315	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4316	err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4317	if (err < 0)
4318		return err;
4319	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4320	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4321	if (err < 0)
4322		return err;
4323	return 1;
4324}
4325
4326/* add playback controls from the parsed DAC table */
4327static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4328					     const struct auto_pin_cfg *cfg)
4329{
4330	hda_nid_t nid;
4331	int err;
4332
4333	spec->multiout.num_dacs = 1;
4334	spec->multiout.dac_nids = spec->private_dac_nids;
4335	spec->multiout.dac_nids[0] = 0x02;
4336
4337	nid = cfg->line_out_pins[0];
4338	if (nid) {
4339		err = alc260_add_playback_controls(spec, nid, "Front");
4340		if (err < 0)
4341			return err;
4342	}
4343
4344	nid = cfg->speaker_pins[0];
4345	if (nid) {
4346		err = alc260_add_playback_controls(spec, nid, "Speaker");
4347		if (err < 0)
4348			return err;
4349	}
4350
4351	nid = cfg->hp_pins[0];
4352	if (nid) {
4353		err = alc260_add_playback_controls(spec, nid, "Headphone");
4354		if (err < 0)
4355			return err;
4356	}
4357	return 0;
4358}
4359
4360/* create playback/capture controls for input pins */
4361static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4362						const struct auto_pin_cfg *cfg)
4363{
4364	struct hda_input_mux *imux = &spec->private_imux;
4365	int i, err, idx;
4366
4367	for (i = 0; i < AUTO_PIN_LAST; i++) {
4368		if (cfg->input_pins[i] >= 0x12) {
4369			idx = cfg->input_pins[i] - 0x12;
4370			err = new_analog_input(spec, cfg->input_pins[i],
4371					       auto_pin_cfg_labels[i], idx,
4372					       0x07);
4373			if (err < 0)
4374				return err;
4375			imux->items[imux->num_items].label =
4376				auto_pin_cfg_labels[i];
4377			imux->items[imux->num_items].index = idx;
4378			imux->num_items++;
4379		}
4380		if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4381			idx = cfg->input_pins[i] - 0x09;
4382			err = new_analog_input(spec, cfg->input_pins[i],
4383					       auto_pin_cfg_labels[i], idx,
4384					       0x07);
4385			if (err < 0)
4386				return err;
4387			imux->items[imux->num_items].label =
4388				auto_pin_cfg_labels[i];
4389			imux->items[imux->num_items].index = idx;
4390			imux->num_items++;
4391		}
4392	}
4393	return 0;
4394}
4395
4396static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4397					      hda_nid_t nid, int pin_type,
4398					      int sel_idx)
4399{
4400	/* set as output */
4401	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4402			    pin_type);
4403	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4404			    AMP_OUT_UNMUTE);
4405	/* need the manual connection? */
4406	if (nid >= 0x12) {
4407		int idx = nid - 0x12;
4408		snd_hda_codec_write(codec, idx + 0x0b, 0,
4409				    AC_VERB_SET_CONNECT_SEL, sel_idx);
4410	}
4411}
4412
4413static void alc260_auto_init_multi_out(struct hda_codec *codec)
4414{
4415	struct alc_spec *spec = codec->spec;
4416	hda_nid_t nid;
4417
4418	alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4419	nid = spec->autocfg.line_out_pins[0];
4420	if (nid) {
4421		int pin_type = get_pin_type(spec->autocfg.line_out_type);
4422		alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4423	}
4424
4425	nid = spec->autocfg.speaker_pins[0];
4426	if (nid)
4427		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4428
4429	nid = spec->autocfg.hp_pins[0];
4430	if (nid)
4431		alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4432}
4433
4434#define ALC260_PIN_CD_NID		0x16
4435static void alc260_auto_init_analog_input(struct hda_codec *codec)
4436{
4437	struct alc_spec *spec = codec->spec;
4438	int i;
4439
4440	for (i = 0; i < AUTO_PIN_LAST; i++) {
4441		hda_nid_t nid = spec->autocfg.input_pins[i];
4442		if (nid >= 0x12) {
4443			snd_hda_codec_write(codec, nid, 0,
4444					    AC_VERB_SET_PIN_WIDGET_CONTROL,
4445					    i <= AUTO_PIN_FRONT_MIC ?
4446					    PIN_VREF80 : PIN_IN);
4447			if (nid != ALC260_PIN_CD_NID)
4448				snd_hda_codec_write(codec, nid, 0,
4449						    AC_VERB_SET_AMP_GAIN_MUTE,
4450						    AMP_OUT_MUTE);
4451		}
4452	}
4453}
4454
4455/*
4456 * generic initialization of ADC, input mixers and output mixers
4457 */
4458static struct hda_verb alc260_volume_init_verbs[] = {
4459	/*
4460	 * Unmute ADC0-1 and set the default input to mic-in
4461	 */
4462	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4463	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4464	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4465	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4466
4467	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4468	 * mixer widget
4469	 * Note: PASD motherboards uses the Line In 2 as the input for
4470	 * front panel mic (mic 2)
4471	 */
4472	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4473	/* mute analog inputs */
4474	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4475	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4476	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4477	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4478	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4479
4480	/*
4481	 * Set up output mixers (0x08 - 0x0a)
4482	 */
4483	/* set vol=0 to output mixers */
4484	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4485	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4486	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4487	/* set up input amps for analog loopback */
4488	/* Amp Indices: DAC = 0, mixer = 1 */
4489	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4490	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4491	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4492	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4493	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4494	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4495
4496	{ }
4497};
4498
4499static int alc260_parse_auto_config(struct hda_codec *codec)
4500{
4501	struct alc_spec *spec = codec->spec;
4502	unsigned int wcap;
4503	int err;
4504	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4505
4506	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4507					   alc260_ignore);
4508	if (err < 0)
4509		return err;
4510	err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4511	if (err < 0)
4512		return err;
4513	if (!spec->kctl_alloc)
4514		return 0; /* can't find valid BIOS pin config */
4515	err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4516	if (err < 0)
4517		return err;
4518
4519	spec->multiout.max_channels = 2;
4520
4521	if (spec->autocfg.dig_out_pin)
4522		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4523	if (spec->kctl_alloc)
4524		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4525
4526	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4527
4528	spec->num_mux_defs = 1;
4529	spec->input_mux = &spec->private_imux;
4530
4531	/* check whether NID 0x04 is valid */
4532	wcap = get_wcaps(codec, 0x04);
4533	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4534	if (wcap != AC_WID_AUD_IN) {
4535		spec->adc_nids = alc260_adc_nids_alt;
4536		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4537		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4538	} else {
4539		spec->adc_nids = alc260_adc_nids;
4540		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4541		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4542	}
4543	spec->num_mixers++;
4544
4545	return 1;
4546}
4547
4548/* additional initialization for auto-configuration model */
4549static void alc260_auto_init(struct hda_codec *codec)
4550{
4551	alc260_auto_init_multi_out(codec);
4552	alc260_auto_init_analog_input(codec);
4553}
4554
4555#ifdef CONFIG_SND_HDA_POWER_SAVE
4556static struct hda_amp_list alc260_loopbacks[] = {
4557	{ 0x07, HDA_INPUT, 0 },
4558	{ 0x07, HDA_INPUT, 1 },
4559	{ 0x07, HDA_INPUT, 2 },
4560	{ 0x07, HDA_INPUT, 3 },
4561	{ 0x07, HDA_INPUT, 4 },
4562	{ } /* end */
4563};
4564#endif
4565
4566/*
4567 * ALC260 configurations
4568 */
4569static const char *alc260_models[ALC260_MODEL_LAST] = {
4570	[ALC260_BASIC]		= "basic",
4571	[ALC260_HP]		= "hp",
4572	[ALC260_HP_3013]	= "hp-3013",
4573	[ALC260_FUJITSU_S702X]	= "fujitsu",
4574	[ALC260_ACER]		= "acer",
4575	[ALC260_WILL]		= "will",
4576	[ALC260_REPLACER_672V]	= "replacer",
4577#ifdef CONFIG_SND_DEBUG
4578	[ALC260_TEST]		= "test",
4579#endif
4580	[ALC260_AUTO]		= "auto",
4581};
4582
4583static struct snd_pci_quirk alc260_cfg_tbl[] = {
4584	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4585	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4586	SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4587	SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4588	SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4589	SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4590	SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4591	SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4592	SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4593	SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4594	SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4595	SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4596	SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4597	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4598	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4599	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4600	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4601	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4602	{}
4603};
4604
4605static struct alc_config_preset alc260_presets[] = {
4606	[ALC260_BASIC] = {
4607		.mixers = { alc260_base_output_mixer,
4608			    alc260_input_mixer,
4609			    alc260_pc_beep_mixer,
4610			    alc260_capture_mixer },
4611		.init_verbs = { alc260_init_verbs },
4612		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4613		.dac_nids = alc260_dac_nids,
4614		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4615		.adc_nids = alc260_adc_nids,
4616		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4617		.channel_mode = alc260_modes,
4618		.input_mux = &alc260_capture_source,
4619	},
4620	[ALC260_HP] = {
4621		.mixers = { alc260_base_output_mixer,
4622			    alc260_input_mixer,
4623			    alc260_capture_alt_mixer },
4624		.init_verbs = { alc260_init_verbs },
4625		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4626		.dac_nids = alc260_dac_nids,
4627		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4628		.adc_nids = alc260_hp_adc_nids,
4629		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4630		.channel_mode = alc260_modes,
4631		.input_mux = &alc260_capture_source,
4632	},
4633	[ALC260_HP_3013] = {
4634		.mixers = { alc260_hp_3013_mixer,
4635			    alc260_input_mixer,
4636			    alc260_capture_alt_mixer },
4637		.init_verbs = { alc260_hp_3013_init_verbs },
4638		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4639		.dac_nids = alc260_dac_nids,
4640		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4641		.adc_nids = alc260_hp_adc_nids,
4642		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4643		.channel_mode = alc260_modes,
4644		.input_mux = &alc260_capture_source,
4645	},
4646	[ALC260_FUJITSU_S702X] = {
4647		.mixers = { alc260_fujitsu_mixer,
4648			    alc260_capture_mixer },
4649		.init_verbs = { alc260_fujitsu_init_verbs },
4650		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4651		.dac_nids = alc260_dac_nids,
4652		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4653		.adc_nids = alc260_dual_adc_nids,
4654		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4655		.channel_mode = alc260_modes,
4656		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4657		.input_mux = alc260_fujitsu_capture_sources,
4658	},
4659	[ALC260_ACER] = {
4660		.mixers = { alc260_acer_mixer,
4661			    alc260_capture_mixer },
4662		.init_verbs = { alc260_acer_init_verbs },
4663		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4664		.dac_nids = alc260_dac_nids,
4665		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4666		.adc_nids = alc260_dual_adc_nids,
4667		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4668		.channel_mode = alc260_modes,
4669		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4670		.input_mux = alc260_acer_capture_sources,
4671	},
4672	[ALC260_WILL] = {
4673		.mixers = { alc260_will_mixer,
4674			    alc260_capture_mixer },
4675		.init_verbs = { alc260_init_verbs, alc260_will_verbs },
4676		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4677		.dac_nids = alc260_dac_nids,
4678		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4679		.adc_nids = alc260_adc_nids,
4680		.dig_out_nid = ALC260_DIGOUT_NID,
4681		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4682		.channel_mode = alc260_modes,
4683		.input_mux = &alc260_capture_source,
4684	},
4685	[ALC260_REPLACER_672V] = {
4686		.mixers = { alc260_replacer_672v_mixer,
4687			    alc260_capture_mixer },
4688		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4689		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
4690		.dac_nids = alc260_dac_nids,
4691		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4692		.adc_nids = alc260_adc_nids,
4693		.dig_out_nid = ALC260_DIGOUT_NID,
4694		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4695		.channel_mode = alc260_modes,
4696		.input_mux = &alc260_capture_source,
4697		.unsol_event = alc260_replacer_672v_unsol_event,
4698		.init_hook = alc260_replacer_672v_automute,
4699	},
4700#ifdef CONFIG_SND_DEBUG
4701	[ALC260_TEST] = {
4702		.mixers = { alc260_test_mixer,
4703			    alc260_capture_mixer },
4704		.init_verbs = { alc260_test_init_verbs },
4705		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4706		.dac_nids = alc260_test_dac_nids,
4707		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4708		.adc_nids = alc260_test_adc_nids,
4709		.num_channel_mode = ARRAY_SIZE(alc260_modes),
4710		.channel_mode = alc260_modes,
4711		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4712		.input_mux = alc260_test_capture_sources,
4713	},
4714#endif
4715};
4716
4717static int patch_alc260(struct hda_codec *codec)
4718{
4719	struct alc_spec *spec;
4720	int err, board_config;
4721
4722	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4723	if (spec == NULL)
4724		return -ENOMEM;
4725
4726	codec->spec = spec;
4727
4728	board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4729						  alc260_models,
4730						  alc260_cfg_tbl);
4731	if (board_config < 0) {
4732		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4733			   "trying auto-probe from BIOS...\n");
4734		board_config = ALC260_AUTO;
4735	}
4736
4737	if (board_config == ALC260_AUTO) {
4738		/* automatic parse from the BIOS config */
4739		err = alc260_parse_auto_config(codec);
4740		if (err < 0) {
4741			alc_free(codec);
4742			return err;
4743		} else if (!err) {
4744			printk(KERN_INFO
4745			       "hda_codec: Cannot set up configuration "
4746			       "from BIOS.  Using base mode...\n");
4747			board_config = ALC260_BASIC;
4748		}
4749	}
4750
4751	if (board_config != ALC260_AUTO)
4752		setup_preset(spec, &alc260_presets[board_config]);
4753
4754	spec->stream_name_analog = "ALC260 Analog";
4755	spec->stream_analog_playback = &alc260_pcm_analog_playback;
4756	spec->stream_analog_capture = &alc260_pcm_analog_capture;
4757
4758	spec->stream_name_digital = "ALC260 Digital";
4759	spec->stream_digital_playback = &alc260_pcm_digital_playback;
4760	spec->stream_digital_capture = &alc260_pcm_digital_capture;
4761
4762	codec->patch_ops = alc_patch_ops;
4763	if (board_config == ALC260_AUTO)
4764		spec->init_hook = alc260_auto_init;
4765#ifdef CONFIG_SND_HDA_POWER_SAVE
4766	if (!spec->loopback.amplist)
4767		spec->loopback.amplist = alc260_loopbacks;
4768#endif
4769
4770	return 0;
4771}
4772
4773
4774/*
4775 * ALC882 support
4776 *
4777 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4778 * configuration.  Each pin widget can choose any input DACs and a mixer.
4779 * Each ADC is connected from a mixer of all inputs.  This makes possible
4780 * 6-channel independent captures.
4781 *
4782 * In addition, an independent DAC for the multi-playback (not used in this
4783 * driver yet).
4784 */
4785#define ALC882_DIGOUT_NID	0x06
4786#define ALC882_DIGIN_NID	0x0a
4787
4788static struct hda_channel_mode alc882_ch_modes[1] = {
4789	{ 8, NULL }
4790};
4791
4792static hda_nid_t alc882_dac_nids[4] = {
4793	/* front, rear, clfe, rear_surr */
4794	0x02, 0x03, 0x04, 0x05
4795};
4796
4797/* identical with ALC880 */
4798#define alc882_adc_nids		alc880_adc_nids
4799#define alc882_adc_nids_alt	alc880_adc_nids_alt
4800
4801/* input MUX */
4802/* FIXME: should be a matrix-type input source selection */
4803
4804static struct hda_input_mux alc882_capture_source = {
4805	.num_items = 4,
4806	.items = {
4807		{ "Mic", 0x0 },
4808		{ "Front Mic", 0x1 },
4809		{ "Line", 0x2 },
4810		{ "CD", 0x4 },
4811	},
4812};
4813#define alc882_mux_enum_info alc_mux_enum_info
4814#define alc882_mux_enum_get alc_mux_enum_get
4815
4816static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4817			       struct snd_ctl_elem_value *ucontrol)
4818{
4819	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4820	struct alc_spec *spec = codec->spec;
4821	const struct hda_input_mux *imux = spec->input_mux;
4822	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4823	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4824	hda_nid_t nid = capture_mixers[adc_idx];
4825	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4826	unsigned int i, idx;
4827
4828	idx = ucontrol->value.enumerated.item[0];
4829	if (idx >= imux->num_items)
4830		idx = imux->num_items - 1;
4831	if (*cur_val == idx)
4832		return 0;
4833	for (i = 0; i < imux->num_items; i++) {
4834		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4835		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4836					 imux->items[i].index,
4837					 HDA_AMP_MUTE, v);
4838	}
4839	*cur_val = idx;
4840	return 1;
4841}
4842
4843/*
4844 * 2ch mode
4845 */
4846static struct hda_verb alc882_3ST_ch2_init[] = {
4847	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4848	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4849	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4850	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4851	{ } /* end */
4852};
4853
4854/*
4855 * 6ch mode
4856 */
4857static struct hda_verb alc882_3ST_ch6_init[] = {
4858	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4859	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4860	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
4861	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4862	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
4863	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4864	{ } /* end */
4865};
4866
4867static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
4868	{ 2, alc882_3ST_ch2_init },
4869	{ 6, alc882_3ST_ch6_init },
4870};
4871
4872/*
4873 * 6ch mode
4874 */
4875static struct hda_verb alc882_sixstack_ch6_init[] = {
4876	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4877	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4878	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4879	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4880	{ } /* end */
4881};
4882
4883/*
4884 * 8ch mode
4885 */
4886static struct hda_verb alc882_sixstack_ch8_init[] = {
4887	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4888	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4889	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4890	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4891	{ } /* end */
4892};
4893
4894static struct hda_channel_mode alc882_sixstack_modes[2] = {
4895	{ 6, alc882_sixstack_ch6_init },
4896	{ 8, alc882_sixstack_ch8_init },
4897};
4898
4899/*
4900 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
4901 */
4902
4903/*
4904 * 2ch mode
4905 */
4906static struct hda_verb alc885_mbp_ch2_init[] = {
4907	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4908	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4909	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4910	{ } /* end */
4911};
4912
4913/*
4914 * 6ch mode
4915 */
4916static struct hda_verb alc885_mbp_ch6_init[] = {
4917	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4918	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4919	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
4920	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4921	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4922	{ } /* end */
4923};
4924
4925static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
4926	{ 2, alc885_mbp_ch2_init },
4927	{ 6, alc885_mbp_ch6_init },
4928};
4929
4930
4931/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4932 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4933 */
4934static struct snd_kcontrol_new alc882_base_mixer[] = {
4935	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4936	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4937	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4938	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4939	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4940	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4941	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4942	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4943	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4944	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4945	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4946	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4947	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4948	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4949	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4950	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4951	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4952	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4953	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4954	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4955	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4956	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4957	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4958	{ } /* end */
4959};
4960
4961static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
4962	HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
4963	HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
4964	HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
4965	HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
4966	HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
4967	HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
4968	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
4969	HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
4970	HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
4971	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
4972	{ } /* end */
4973};
4974static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
4975	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4976	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4977	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4978	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4979	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4980	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4981	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4982	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4983	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4984	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4985	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4986	{ } /* end */
4987};
4988
4989static struct snd_kcontrol_new alc882_targa_mixer[] = {
4990	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4991	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4992	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4993	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4994	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4995	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4996	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4997	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4998	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4999	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5000	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5001	{ } /* end */
5002};
5003
5004/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5005 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5006 */
5007static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5008	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5009	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5010	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5011	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5012	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5013	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5014	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5015	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5016	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5017	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5018	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5019	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5020	{ } /* end */
5021};
5022
5023static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5024	{
5025		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5026		.name = "Channel Mode",
5027		.info = alc_ch_mode_info,
5028		.get = alc_ch_mode_get,
5029		.put = alc_ch_mode_put,
5030	},
5031	{ } /* end */
5032};
5033
5034static struct hda_verb alc882_init_verbs[] = {
5035	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5036	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5037	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5038	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5039	/* Rear mixer */
5040	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5041	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5042	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5043	/* CLFE mixer */
5044	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5045	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5046	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5047	/* Side mixer */
5048	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5049	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5050	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5051
5052	/* Front Pin: output 0 (0x0c) */
5053	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5054	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5055	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5056	/* Rear Pin: output 1 (0x0d) */
5057	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5058	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5059	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5060	/* CLFE Pin: output 2 (0x0e) */
5061	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5062	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5063	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5064	/* Side Pin: output 3 (0x0f) */
5065	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5066	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5067	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5068	/* Mic (rear) pin: input vref at 80% */
5069	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5070	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5071	/* Front Mic pin: input vref at 80% */
5072	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5073	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5074	/* Line In pin: input */
5075	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5076	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5077	/* Line-2 In: Headphone output (output 0 - 0x0c) */
5078	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5079	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5080	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5081	/* CD pin widget for input */
5082	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5083
5084	/* FIXME: use matrix-type input source selection */
5085	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5086	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5087	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5088	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5089	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5090	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5091	/* Input mixer2 */
5092	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5093	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5094	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5095	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5096	/* Input mixer3 */
5097	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5098	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5099	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5100	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5101	/* ADC1: mute amp left and right */
5102	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5103	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5104	/* ADC2: mute amp left and right */
5105	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5106	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5107	/* ADC3: mute amp left and right */
5108	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5109	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5110
5111	{ }
5112};
5113
5114static struct hda_verb alc882_eapd_verbs[] = {
5115	/* change to EAPD mode */
5116	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5117	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5118	{ }
5119};
5120
5121/* Mac Pro test */
5122static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5123	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5124	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5125	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5126	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5127	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5128	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5129	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5130	{ } /* end */
5131};
5132
5133static struct hda_verb alc882_macpro_init_verbs[] = {
5134	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5135	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5136	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5137	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5138	/* Front Pin: output 0 (0x0c) */
5139	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5140	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5141	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5142	/* Front Mic pin: input vref at 80% */
5143	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5144	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5145	/* Speaker:  output */
5146	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5147	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5148	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5149	/* Headphone output (output 0 - 0x0c) */
5150	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5151	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5152	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5153
5154	/* FIXME: use matrix-type input source selection */
5155	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5156	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5157	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5158	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5159	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5160	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5161	/* Input mixer2 */
5162	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5163	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5164	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5165	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5166	/* Input mixer3 */
5167	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5168	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5169	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5170	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5171	/* ADC1: mute amp left and right */
5172	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5173	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5174	/* ADC2: mute amp left and right */
5175	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5176	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5177	/* ADC3: mute amp left and right */
5178	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5179	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5180
5181	{ }
5182};
5183
5184/* Macbook Pro rev3 */
5185static struct hda_verb alc885_mbp3_init_verbs[] = {
5186	/* Front mixer: unmute input/output amp left and right (volume = 0) */
5187	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5188	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5189	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5190	/* Rear mixer */
5191	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5192	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5193	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5194	/* Front Pin: output 0 (0x0c) */
5195	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5196	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5197	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5198	/* HP Pin: output 0 (0x0d) */
5199	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5200	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5201	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5202	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5203	/* Mic (rear) pin: input vref at 80% */
5204	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5205	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5206	/* Front Mic pin: input vref at 80% */
5207	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5208	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5209	/* Line In pin: use output 1 when in LineOut mode */
5210	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5211	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5212	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5213
5214	/* FIXME: use matrix-type input source selection */
5215	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5216	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5217	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5218	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5219	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5220	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5221	/* Input mixer2 */
5222	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5223	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5224	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5225	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5226	/* Input mixer3 */
5227	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5228	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5229	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5230	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5231	/* ADC1: mute amp left and right */
5232	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5233	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5234	/* ADC2: mute amp left and right */
5235	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5236	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5237	/* ADC3: mute amp left and right */
5238	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5239	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5240
5241	{ }
5242};
5243
5244/* iMac 24 mixer. */
5245static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5246	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5247	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5248	{ } /* end */
5249};
5250
5251/* iMac 24 init verbs. */
5252static struct hda_verb alc885_imac24_init_verbs[] = {
5253	/* Internal speakers: output 0 (0x0c) */
5254	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5255	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5256	{0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5257	/* Internal speakers: output 0 (0x0c) */
5258	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5259	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5260	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5261	/* Headphone: output 0 (0x0c) */
5262	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5263	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5264	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5265	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5266	/* Front Mic: input vref at 80% */
5267	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5268	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5269	{ }
5270};
5271
5272/* Toggle speaker-output according to the hp-jack state */
5273static void alc885_imac24_automute(struct hda_codec *codec)
5274{
5275 	unsigned int present;
5276
5277 	present = snd_hda_codec_read(codec, 0x14, 0,
5278				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5279	snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5280				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5281	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5282				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5283}
5284
5285/* Processes unsolicited events. */
5286static void alc885_imac24_unsol_event(struct hda_codec *codec,
5287				      unsigned int res)
5288{
5289	/* Headphone insertion or removal. */
5290	if ((res >> 26) == ALC880_HP_EVENT)
5291		alc885_imac24_automute(codec);
5292}
5293
5294static void alc885_mbp3_automute(struct hda_codec *codec)
5295{
5296 	unsigned int present;
5297
5298 	present = snd_hda_codec_read(codec, 0x15, 0,
5299				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5300	snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5301				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5302	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5303				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5304
5305}
5306static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5307				    unsigned int res)
5308{
5309	/* Headphone insertion or removal. */
5310	if ((res >> 26) == ALC880_HP_EVENT)
5311		alc885_mbp3_automute(codec);
5312}
5313
5314
5315static struct hda_verb alc882_targa_verbs[] = {
5316	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5317	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5318
5319	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5320	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5321
5322	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5323	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5324	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5325
5326	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5327	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5328	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5329	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5330	{ } /* end */
5331};
5332
5333/* toggle speaker-output according to the hp-jack state */
5334static void alc882_targa_automute(struct hda_codec *codec)
5335{
5336 	unsigned int present;
5337
5338 	present = snd_hda_codec_read(codec, 0x14, 0,
5339				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5340	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5341				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5342	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5343				  present ? 1 : 3);
5344}
5345
5346static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5347{
5348	/* Looks like the unsol event is incompatible with the standard
5349	 * definition.  4bit tag is placed at 26 bit!
5350	 */
5351	if (((res >> 26) == ALC880_HP_EVENT)) {
5352		alc882_targa_automute(codec);
5353	}
5354}
5355
5356static struct hda_verb alc882_asus_a7j_verbs[] = {
5357	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5358	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5359
5360	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5361	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5362	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5363
5364	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5365	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5366	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5367
5368	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5369	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5370	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5371	{ } /* end */
5372};
5373
5374static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5375{
5376	unsigned int gpiostate, gpiomask, gpiodir;
5377
5378	gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5379				       AC_VERB_GET_GPIO_DATA, 0);
5380
5381	if (!muted)
5382		gpiostate |= (1 << pin);
5383	else
5384		gpiostate &= ~(1 << pin);
5385
5386	gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5387				      AC_VERB_GET_GPIO_MASK, 0);
5388	gpiomask |= (1 << pin);
5389
5390	gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5391				     AC_VERB_GET_GPIO_DIRECTION, 0);
5392	gpiodir |= (1 << pin);
5393
5394
5395	snd_hda_codec_write(codec, codec->afg, 0,
5396			    AC_VERB_SET_GPIO_MASK, gpiomask);
5397	snd_hda_codec_write(codec, codec->afg, 0,
5398			    AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5399
5400	msleep(1);
5401
5402	snd_hda_codec_write(codec, codec->afg, 0,
5403			    AC_VERB_SET_GPIO_DATA, gpiostate);
5404}
5405
5406/* set up GPIO at initialization */
5407static void alc885_macpro_init_hook(struct hda_codec *codec)
5408{
5409	alc882_gpio_mute(codec, 0, 0);
5410	alc882_gpio_mute(codec, 1, 0);
5411}
5412
5413/* set up GPIO and update auto-muting at initialization */
5414static void alc885_imac24_init_hook(struct hda_codec *codec)
5415{
5416	alc885_macpro_init_hook(codec);
5417	alc885_imac24_automute(codec);
5418}
5419
5420/*
5421 * generic initialization of ADC, input mixers and output mixers
5422 */
5423static struct hda_verb alc882_auto_init_verbs[] = {
5424	/*
5425	 * Unmute ADC0-2 and set the default input to mic-in
5426	 */
5427	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5428	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5429	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5430	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5431	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5432	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5433
5434	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5435	 * mixer widget
5436	 * Note: PASD motherboards uses the Line In 2 as the input for
5437	 * front panel mic (mic 2)
5438	 */
5439	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5440	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5441	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5442	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5443	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5444	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5445
5446	/*
5447	 * Set up output mixers (0x0c - 0x0f)
5448	 */
5449	/* set vol=0 to output mixers */
5450	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5451	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5452	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5453	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5454	/* set up input amps for analog loopback */
5455	/* Amp Indices: DAC = 0, mixer = 1 */
5456	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5457	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5458	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5459	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5460	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5461	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5462	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5463	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5464	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5465	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5466
5467	/* FIXME: use matrix-type input source selection */
5468	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5469	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5470	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5471	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5472	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5473	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5474	/* Input mixer2 */
5475	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5476	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5477	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5478	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5479	/* Input mixer3 */
5480	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5481	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5482	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5483	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5484
5485	{ }
5486};
5487
5488/* capture mixer elements */
5489static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5490	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5491	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5492	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5493	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5494	{
5495		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5496		/* The multiple "Capture Source" controls confuse alsamixer
5497		 * So call somewhat different..
5498		 * FIXME: the controls appear in the "playback" view!
5499		 */
5500		/* .name = "Capture Source", */
5501		.name = "Input Source",
5502		.count = 2,
5503		.info = alc882_mux_enum_info,
5504		.get = alc882_mux_enum_get,
5505		.put = alc882_mux_enum_put,
5506	},
5507	{ } /* end */
5508};
5509
5510static struct snd_kcontrol_new alc882_capture_mixer[] = {
5511	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5512	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5513	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5514	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5515	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5516	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5517	{
5518		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5519		/* The multiple "Capture Source" controls confuse alsamixer
5520		 * So call somewhat different..
5521		 * FIXME: the controls appear in the "playback" view!
5522		 */
5523		/* .name = "Capture Source", */
5524		.name = "Input Source",
5525		.count = 3,
5526		.info = alc882_mux_enum_info,
5527		.get = alc882_mux_enum_get,
5528		.put = alc882_mux_enum_put,
5529	},
5530	{ } /* end */
5531};
5532
5533#ifdef CONFIG_SND_HDA_POWER_SAVE
5534#define alc882_loopbacks	alc880_loopbacks
5535#endif
5536
5537/* pcm configuration: identiacal with ALC880 */
5538#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
5539#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
5540#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
5541#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
5542
5543/*
5544 * configuration and preset
5545 */
5546static const char *alc882_models[ALC882_MODEL_LAST] = {
5547	[ALC882_3ST_DIG]	= "3stack-dig",
5548	[ALC882_6ST_DIG]	= "6stack-dig",
5549	[ALC882_ARIMA]		= "arima",
5550	[ALC882_W2JC]		= "w2jc",
5551	[ALC885_MACPRO]		= "macpro",
5552	[ALC885_MBP3]		= "mbp3",
5553	[ALC885_IMAC24]		= "imac24",
5554	[ALC882_AUTO]		= "auto",
5555};
5556
5557static struct snd_pci_quirk alc882_cfg_tbl[] = {
5558	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5559	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5560	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5561	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5562	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5563	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5564	SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5565	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5566	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5567	{}
5568};
5569
5570static struct alc_config_preset alc882_presets[] = {
5571	[ALC882_3ST_DIG] = {
5572		.mixers = { alc882_base_mixer },
5573		.init_verbs = { alc882_init_verbs },
5574		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5575		.dac_nids = alc882_dac_nids,
5576		.dig_out_nid = ALC882_DIGOUT_NID,
5577		.dig_in_nid = ALC882_DIGIN_NID,
5578		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5579		.channel_mode = alc882_ch_modes,
5580		.need_dac_fix = 1,
5581		.input_mux = &alc882_capture_source,
5582	},
5583	[ALC882_6ST_DIG] = {
5584		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5585		.init_verbs = { alc882_init_verbs },
5586		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5587		.dac_nids = alc882_dac_nids,
5588		.dig_out_nid = ALC882_DIGOUT_NID,
5589		.dig_in_nid = ALC882_DIGIN_NID,
5590		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5591		.channel_mode = alc882_sixstack_modes,
5592		.input_mux = &alc882_capture_source,
5593	},
5594	[ALC882_ARIMA] = {
5595		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
5596		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5597		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5598		.dac_nids = alc882_dac_nids,
5599		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5600		.channel_mode = alc882_sixstack_modes,
5601		.input_mux = &alc882_capture_source,
5602	},
5603	[ALC882_W2JC] = {
5604		.mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5605		.init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5606				alc880_gpio1_init_verbs },
5607		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5608		.dac_nids = alc882_dac_nids,
5609		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5610		.channel_mode = alc880_threestack_modes,
5611		.need_dac_fix = 1,
5612		.input_mux = &alc882_capture_source,
5613		.dig_out_nid = ALC882_DIGOUT_NID,
5614	},
5615	[ALC885_MBP3] = {
5616		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5617		.init_verbs = { alc885_mbp3_init_verbs,
5618				alc880_gpio1_init_verbs },
5619		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5620		.dac_nids = alc882_dac_nids,
5621		.channel_mode = alc885_mbp_6ch_modes,
5622		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5623		.input_mux = &alc882_capture_source,
5624		.dig_out_nid = ALC882_DIGOUT_NID,
5625		.dig_in_nid = ALC882_DIGIN_NID,
5626		.unsol_event = alc885_mbp3_unsol_event,
5627		.init_hook = alc885_mbp3_automute,
5628	},
5629	[ALC885_MACPRO] = {
5630		.mixers = { alc882_macpro_mixer },
5631		.init_verbs = { alc882_macpro_init_verbs },
5632		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5633		.dac_nids = alc882_dac_nids,
5634		.dig_out_nid = ALC882_DIGOUT_NID,
5635		.dig_in_nid = ALC882_DIGIN_NID,
5636		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5637		.channel_mode = alc882_ch_modes,
5638		.input_mux = &alc882_capture_source,
5639		.init_hook = alc885_macpro_init_hook,
5640	},
5641	[ALC885_IMAC24] = {
5642		.mixers = { alc885_imac24_mixer },
5643		.init_verbs = { alc885_imac24_init_verbs },
5644		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5645		.dac_nids = alc882_dac_nids,
5646		.dig_out_nid = ALC882_DIGOUT_NID,
5647		.dig_in_nid = ALC882_DIGIN_NID,
5648		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5649		.channel_mode = alc882_ch_modes,
5650		.input_mux = &alc882_capture_source,
5651		.unsol_event = alc885_imac24_unsol_event,
5652		.init_hook = alc885_imac24_init_hook,
5653	},
5654	[ALC882_TARGA] = {
5655		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5656			    alc882_capture_mixer },
5657		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5658		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5659		.dac_nids = alc882_dac_nids,
5660		.dig_out_nid = ALC882_DIGOUT_NID,
5661		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5662		.adc_nids = alc882_adc_nids,
5663		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5664		.channel_mode = alc882_3ST_6ch_modes,
5665		.need_dac_fix = 1,
5666		.input_mux = &alc882_capture_source,
5667		.unsol_event = alc882_targa_unsol_event,
5668		.init_hook = alc882_targa_automute,
5669	},
5670	[ALC882_ASUS_A7J] = {
5671		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5672			    alc882_capture_mixer },
5673		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5674		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
5675		.dac_nids = alc882_dac_nids,
5676		.dig_out_nid = ALC882_DIGOUT_NID,
5677		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5678		.adc_nids = alc882_adc_nids,
5679		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5680		.channel_mode = alc882_3ST_6ch_modes,
5681		.need_dac_fix = 1,
5682		.input_mux = &alc882_capture_source,
5683	},
5684};
5685
5686
5687/*
5688 * Pin config fixes
5689 */
5690enum {
5691	PINFIX_ABIT_AW9D_MAX
5692};
5693
5694static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5695	{ 0x15, 0x01080104 }, /* side */
5696	{ 0x16, 0x01011012 }, /* rear */
5697	{ 0x17, 0x01016011 }, /* clfe */
5698	{ }
5699};
5700
5701static const struct alc_pincfg *alc882_pin_fixes[] = {
5702	[PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5703};
5704
5705static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5706	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5707	{}
5708};
5709
5710/*
5711 * BIOS auto configuration
5712 */
5713static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5714					      hda_nid_t nid, int pin_type,
5715					      int dac_idx)
5716{
5717	/* set as output */
5718	struct alc_spec *spec = codec->spec;
5719	int idx;
5720
5721	if (spec->multiout.dac_nids[dac_idx] == 0x25)
5722		idx = 4;
5723	else
5724		idx = spec->multiout.dac_nids[dac_idx] - 2;
5725
5726	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5727			    pin_type);
5728	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5729			    AMP_OUT_UNMUTE);
5730	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5731
5732}
5733
5734static void alc882_auto_init_multi_out(struct hda_codec *codec)
5735{
5736	struct alc_spec *spec = codec->spec;
5737	int i;
5738
5739	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5740	for (i = 0; i <= HDA_SIDE; i++) {
5741		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5742		int pin_type = get_pin_type(spec->autocfg.line_out_type);
5743		if (nid)
5744			alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5745							  i);
5746	}
5747}
5748
5749static void alc882_auto_init_hp_out(struct hda_codec *codec)
5750{
5751	struct alc_spec *spec = codec->spec;
5752	hda_nid_t pin;
5753
5754	pin = spec->autocfg.hp_pins[0];
5755	if (pin) /* connect to front */
5756		/* use dac 0 */
5757		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5758}
5759
5760#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
5761#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
5762
5763static void alc882_auto_init_analog_input(struct hda_codec *codec)
5764{
5765	struct alc_spec *spec = codec->spec;
5766	int i;
5767
5768	for (i = 0; i < AUTO_PIN_LAST; i++) {
5769		hda_nid_t nid = spec->autocfg.input_pins[i];
5770		if (alc882_is_input_pin(nid)) {
5771			snd_hda_codec_write(codec, nid, 0,
5772					    AC_VERB_SET_PIN_WIDGET_CONTROL,
5773					    i <= AUTO_PIN_FRONT_MIC ?
5774					    PIN_VREF80 : PIN_IN);
5775			if (nid != ALC882_PIN_CD_NID)
5776				snd_hda_codec_write(codec, nid, 0,
5777						    AC_VERB_SET_AMP_GAIN_MUTE,
5778						    AMP_OUT_MUTE);
5779		}
5780	}
5781}
5782
5783/* almost identical with ALC880 parser... */
5784static int alc882_parse_auto_config(struct hda_codec *codec)
5785{
5786	struct alc_spec *spec = codec->spec;
5787	int err = alc880_parse_auto_config(codec);
5788
5789	if (err < 0)
5790		return err;
5791	else if (err > 0)
5792		/* hack - override the init verbs */
5793		spec->init_verbs[0] = alc882_auto_init_verbs;
5794	return err;
5795}
5796
5797/* additional initialization for auto-configuration model */
5798static void alc882_auto_init(struct hda_codec *codec)
5799{
5800	alc882_auto_init_multi_out(codec);
5801	alc882_auto_init_hp_out(codec);
5802	alc882_auto_init_analog_input(codec);
5803}
5804
5805static int patch_alc882(struct hda_codec *codec)
5806{
5807	struct alc_spec *spec;
5808	int err, board_config;
5809
5810	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5811	if (spec == NULL)
5812		return -ENOMEM;
5813
5814	codec->spec = spec;
5815
5816	board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
5817						  alc882_models,
5818						  alc882_cfg_tbl);
5819
5820	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
5821		/* Pick up systems that don't supply PCI SSID */
5822		switch (codec->subsystem_id) {
5823		case 0x106b0c00: /* Mac Pro */
5824			board_config = ALC885_MACPRO;
5825			break;
5826		case 0x106b1000: /* iMac 24 */
5827			board_config = ALC885_IMAC24;
5828			break;
5829		case 0x106b2c00: /* Macbook Pro rev3 */
5830			board_config = ALC885_MBP3;
5831			break;
5832		default:
5833			printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
5834		       			 "trying auto-probe from BIOS...\n");
5835			board_config = ALC882_AUTO;
5836		}
5837	}
5838
5839	alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
5840
5841	if (board_config == ALC882_AUTO) {
5842		/* automatic parse from the BIOS config */
5843		err = alc882_parse_auto_config(codec);
5844		if (err < 0) {
5845			alc_free(codec);
5846			return err;
5847		} else if (!err) {
5848			printk(KERN_INFO
5849			       "hda_codec: Cannot set up configuration "
5850			       "from BIOS.  Using base mode...\n");
5851			board_config = ALC882_3ST_DIG;
5852		}
5853	}
5854
5855	if (board_config != ALC882_AUTO)
5856		setup_preset(spec, &alc882_presets[board_config]);
5857
5858	spec->stream_name_analog = "ALC882 Analog";
5859	spec->stream_analog_playback = &alc882_pcm_analog_playback;
5860	spec->stream_analog_capture = &alc882_pcm_analog_capture;
5861
5862	spec->stream_name_digital = "ALC882 Digital";
5863	spec->stream_digital_playback = &alc882_pcm_digital_playback;
5864	spec->stream_digital_capture = &alc882_pcm_digital_capture;
5865
5866	if (!spec->adc_nids && spec->input_mux) {
5867		/* check whether NID 0x07 is valid */
5868		unsigned int wcap = get_wcaps(codec, 0x07);
5869		/* get type */
5870		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5871		if (wcap != AC_WID_AUD_IN) {
5872			spec->adc_nids = alc882_adc_nids_alt;
5873			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
5874			spec->mixers[spec->num_mixers] =
5875				alc882_capture_alt_mixer;
5876			spec->num_mixers++;
5877		} else {
5878			spec->adc_nids = alc882_adc_nids;
5879			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
5880			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
5881			spec->num_mixers++;
5882		}
5883	}
5884
5885	codec->patch_ops = alc_patch_ops;
5886	if (board_config == ALC882_AUTO)
5887		spec->init_hook = alc882_auto_init;
5888#ifdef CONFIG_SND_HDA_POWER_SAVE
5889	if (!spec->loopback.amplist)
5890		spec->loopback.amplist = alc882_loopbacks;
5891#endif
5892
5893	return 0;
5894}
5895
5896/*
5897 * ALC883 support
5898 *
5899 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5900 * configuration.  Each pin widget can choose any input DACs and a mixer.
5901 * Each ADC is connected from a mixer of all inputs.  This makes possible
5902 * 6-channel independent captures.
5903 *
5904 * In addition, an independent DAC for the multi-playback (not used in this
5905 * driver yet).
5906 */
5907#define ALC883_DIGOUT_NID	0x06
5908#define ALC883_DIGIN_NID	0x0a
5909
5910static hda_nid_t alc883_dac_nids[4] = {
5911	/* front, rear, clfe, rear_surr */
5912	0x02, 0x04, 0x03, 0x05
5913};
5914
5915static hda_nid_t alc883_adc_nids[2] = {
5916	/* ADC1-2 */
5917	0x08, 0x09,
5918};
5919
5920/* input MUX */
5921/* FIXME: should be a matrix-type input source selection */
5922
5923static struct hda_input_mux alc883_capture_source = {
5924	.num_items = 4,
5925	.items = {
5926		{ "Mic", 0x0 },
5927		{ "Front Mic", 0x1 },
5928		{ "Line", 0x2 },
5929		{ "CD", 0x4 },
5930	},
5931};
5932
5933static struct hda_input_mux alc883_lenovo_101e_capture_source = {
5934	.num_items = 2,
5935	.items = {
5936		{ "Mic", 0x1 },
5937		{ "Line", 0x2 },
5938	},
5939};
5940
5941static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
5942	.num_items = 4,
5943	.items = {
5944		{ "Mic", 0x0 },
5945		{ "iMic", 0x1 },
5946		{ "Line", 0x2 },
5947		{ "CD", 0x4 },
5948	},
5949};
5950
5951#define alc883_mux_enum_info alc_mux_enum_info
5952#define alc883_mux_enum_get alc_mux_enum_get
5953
5954static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
5955			       struct snd_ctl_elem_value *ucontrol)
5956{
5957	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5958	struct alc_spec *spec = codec->spec;
5959	const struct hda_input_mux *imux = spec->input_mux;
5960	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5961	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5962	hda_nid_t nid = capture_mixers[adc_idx];
5963	unsigned int *cur_val = &spec->cur_mux[adc_idx];
5964	unsigned int i, idx;
5965
5966	idx = ucontrol->value.enumerated.item[0];
5967	if (idx >= imux->num_items)
5968		idx = imux->num_items - 1;
5969	if (*cur_val == idx)
5970		return 0;
5971	for (i = 0; i < imux->num_items; i++) {
5972		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5973		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5974					 imux->items[i].index,
5975					 HDA_AMP_MUTE, v);
5976	}
5977	*cur_val = idx;
5978	return 1;
5979}
5980
5981/*
5982 * 2ch mode
5983 */
5984static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
5985	{ 2, NULL }
5986};
5987
5988/*
5989 * 2ch mode
5990 */
5991static struct hda_verb alc883_3ST_ch2_init[] = {
5992	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5993	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5994	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5995	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5996	{ } /* end */
5997};
5998
5999/*
6000 * 6ch mode
6001 */
6002static struct hda_verb alc883_3ST_ch6_init[] = {
6003	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6004	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6005	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6006	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6007	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6008	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6009	{ } /* end */
6010};
6011
6012static struct hda_channel_mode alc883_3ST_6ch_modes[2] = {
6013	{ 2, alc883_3ST_ch2_init },
6014	{ 6, alc883_3ST_ch6_init },
6015};
6016
6017/*
6018 * 6ch mode
6019 */
6020static struct hda_verb alc883_sixstack_ch6_init[] = {
6021	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6022	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6023	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6024	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6025	{ } /* end */
6026};
6027
6028/*
6029 * 8ch mode
6030 */
6031static struct hda_verb alc883_sixstack_ch8_init[] = {
6032	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6033	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6034	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6035	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6036	{ } /* end */
6037};
6038
6039static struct hda_channel_mode alc883_sixstack_modes[2] = {
6040	{ 6, alc883_sixstack_ch6_init },
6041	{ 8, alc883_sixstack_ch8_init },
6042};
6043
6044static struct hda_verb alc883_medion_eapd_verbs[] = {
6045        /* eanable EAPD on medion laptop */
6046	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6047	{0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6048	{ }
6049};
6050
6051/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6052 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6053 */
6054
6055static struct snd_kcontrol_new alc883_base_mixer[] = {
6056	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6057	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6058	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6059	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6060	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6061	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6062	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6063	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6064	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6065	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6066	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6067	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6068	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6069	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6070	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6071	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6072	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6073	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6074	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6075	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6076	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6077	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6078	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6079	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6080	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6081	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6082	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6083	{
6084		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6085		/* .name = "Capture Source", */
6086		.name = "Input Source",
6087		.count = 2,
6088		.info = alc883_mux_enum_info,
6089		.get = alc883_mux_enum_get,
6090		.put = alc883_mux_enum_put,
6091	},
6092	{ } /* end */
6093};
6094
6095static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6096	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6097	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6098	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6099	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6100	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6101	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6102	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6103	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6104	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6105	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6106	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6107	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6108	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6109	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6110	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6111	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6112	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6113	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6114	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6115	{
6116		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6117		/* .name = "Capture Source", */
6118		.name = "Input Source",
6119		.count = 2,
6120		.info = alc883_mux_enum_info,
6121		.get = alc883_mux_enum_get,
6122		.put = alc883_mux_enum_put,
6123	},
6124	{ } /* end */
6125};
6126
6127static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6128	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6129	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6130	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6131	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6132	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6133	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6134	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6135	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6136	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6137	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6138	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6139	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6140	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6141	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6142	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6143	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6144	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6145	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6146	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6147	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6148	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6149	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6150	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6151	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6152	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6153	{
6154		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6155		/* .name = "Capture Source", */
6156		.name = "Input Source",
6157		.count = 2,
6158		.info = alc883_mux_enum_info,
6159		.get = alc883_mux_enum_get,
6160		.put = alc883_mux_enum_put,
6161	},
6162	{ } /* end */
6163};
6164
6165static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6166	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6167	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6168	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6169	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6170	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6171	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6172	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6173	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6174	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6175	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6176	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6177	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6178	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6179	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6180	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6181	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6182	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6183	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6184	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6185	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6186	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6187	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6188	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6189
6190	{
6191		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6192		/* .name = "Capture Source", */
6193		.name = "Input Source",
6194		.count = 1,
6195		.info = alc883_mux_enum_info,
6196		.get = alc883_mux_enum_get,
6197		.put = alc883_mux_enum_put,
6198	},
6199	{ } /* end */
6200};
6201
6202static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6203	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6204	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6205	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6206	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6207	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6208	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6209	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6210	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6211	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6212	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6213	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6214	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6215	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6216	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6217	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6218	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6219	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6220	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6221	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6222	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6223	{
6224		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6225		/* .name = "Capture Source", */
6226		.name = "Input Source",
6227		.count = 2,
6228		.info = alc883_mux_enum_info,
6229		.get = alc883_mux_enum_get,
6230		.put = alc883_mux_enum_put,
6231	},
6232	{ } /* end */
6233};
6234
6235static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6236	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6237	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6238	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6239	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6240	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6241	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6242	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6243	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6244	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6245	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6246	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6247	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6248	{
6249		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6250		/* .name = "Capture Source", */
6251		.name = "Input Source",
6252		.count = 2,
6253		.info = alc883_mux_enum_info,
6254		.get = alc883_mux_enum_get,
6255		.put = alc883_mux_enum_put,
6256	},
6257	{ } /* end */
6258};
6259
6260static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6261	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6262	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6263	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6264	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6265	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6266	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6267	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6268	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6269	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6270	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6271	{
6272		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6273		/* .name = "Capture Source", */
6274		.name = "Input Source",
6275		.count = 1,
6276		.info = alc883_mux_enum_info,
6277		.get = alc883_mux_enum_get,
6278		.put = alc883_mux_enum_put,
6279	},
6280	{ } /* end */
6281};
6282
6283static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6284	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6285	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6286	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6287	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6288	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6289	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6290	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6291	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6292	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6293	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6294	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6295	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6296	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6297	{
6298		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6299		/* .name = "Capture Source", */
6300		.name = "Input Source",
6301		.count = 2,
6302		.info = alc883_mux_enum_info,
6303		.get = alc883_mux_enum_get,
6304		.put = alc883_mux_enum_put,
6305	},
6306	{ } /* end */
6307};
6308
6309static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6310	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6311	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6312	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6313	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6314	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6315	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6316	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6317	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6318	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6319	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6320	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6321	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6322	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6323	{
6324		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6325		/* .name = "Capture Source", */
6326		.name = "Input Source",
6327		.count = 2,
6328		.info = alc883_mux_enum_info,
6329		.get = alc883_mux_enum_get,
6330		.put = alc883_mux_enum_put,
6331	},
6332	{ } /* end */
6333};
6334
6335static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6336	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6337	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6338	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6339	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6340	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6341	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6342	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6343	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6344	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6345	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6346	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6347	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6348	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6349	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6350	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6351	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6352	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6353	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6354	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6355	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6356	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6357	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6358	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6359	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6360	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6361	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6362	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6363	{
6364		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6365		/* .name = "Capture Source", */
6366		.name = "Input Source",
6367		.count = 2,
6368		.info = alc883_mux_enum_info,
6369		.get = alc883_mux_enum_get,
6370		.put = alc883_mux_enum_put,
6371	},
6372	{ } /* end */
6373};
6374
6375static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6376	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6377	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6378	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6379	HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6380	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6381	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6382	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6383	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6384	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6385	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6386	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6387	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6388	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6389	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6390	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6391	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6392	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6393	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6394	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6395	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6396	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6397	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6398	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6399	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6400	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6401	{
6402		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6403		/* .name = "Capture Source", */
6404		.name = "Input Source",
6405		.count = 2,
6406		.info = alc883_mux_enum_info,
6407		.get = alc883_mux_enum_get,
6408		.put = alc883_mux_enum_put,
6409	},
6410	{ } /* end */
6411};
6412
6413static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6414	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6415	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6416	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6417	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6418	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6419	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6420	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6421	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6422	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6423	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6424	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6425	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6426	{
6427		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6428		/* .name = "Capture Source", */
6429		.name = "Input Source",
6430		.count = 2,
6431		.info = alc883_mux_enum_info,
6432		.get = alc883_mux_enum_get,
6433		.put = alc883_mux_enum_put,
6434	},
6435	{ } /* end */
6436};
6437
6438static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6439	{
6440		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6441		.name = "Channel Mode",
6442		.info = alc_ch_mode_info,
6443		.get = alc_ch_mode_get,
6444		.put = alc_ch_mode_put,
6445	},
6446	{ } /* end */
6447};
6448
6449static struct hda_verb alc883_init_verbs[] = {
6450	/* ADC1: mute amp left and right */
6451	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6452	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6453	/* ADC2: mute amp left and right */
6454	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6455	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6456	/* Front mixer: unmute input/output amp left and right (volume = 0) */
6457	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6458	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6459	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6460	/* Rear mixer */
6461	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6462	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6463	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6464	/* CLFE mixer */
6465	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6466	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6467	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6468	/* Side mixer */
6469	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6470	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6471	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6472
6473	/* mute analog input loopbacks */
6474	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6475	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6476	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6477	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6478	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6479
6480	/* Front Pin: output 0 (0x0c) */
6481	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6482	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6483	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6484	/* Rear Pin: output 1 (0x0d) */
6485	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6486	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6487	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6488	/* CLFE Pin: output 2 (0x0e) */
6489	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6490	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6491	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6492	/* Side Pin: output 3 (0x0f) */
6493	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6494	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6495	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6496	/* Mic (rear) pin: input vref at 80% */
6497	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6498	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6499	/* Front Mic pin: input vref at 80% */
6500	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6501	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6502	/* Line In pin: input */
6503	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6504	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6505	/* Line-2 In: Headphone output (output 0 - 0x0c) */
6506	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6507	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6509	/* CD pin widget for input */
6510	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6511
6512	/* FIXME: use matrix-type input source selection */
6513	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6514	/* Input mixer2 */
6515	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6516	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6517	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6518	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6519	/* Input mixer3 */
6520	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6521	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6522	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6523	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6524	{ }
6525};
6526
6527static struct hda_verb alc883_tagra_verbs[] = {
6528	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6529	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6530
6531	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6532	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6533
6534	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6535	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6536	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6537
6538	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6539	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6540	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6541	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6542
6543	{ } /* end */
6544};
6545
6546static struct hda_verb alc883_lenovo_101e_verbs[] = {
6547	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6548	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6549        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6550	{ } /* end */
6551};
6552
6553static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6554        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6555	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6556        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6557        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6558	{ } /* end */
6559};
6560
6561static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6562	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6563	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6564	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6565	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6566	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6567	{ } /* end */
6568};
6569
6570static struct hda_verb alc888_6st_hp_verbs[] = {
6571	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6572	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},	/* Rear : output 2 (0x0e) */
6573	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* CLFE : output 1 (0x0d) */
6574	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},	/* Side : output 3 (0x0f) */
6575	{ }
6576};
6577
6578static struct hda_verb alc888_3st_hp_verbs[] = {
6579	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */
6580	{0x18, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */
6581	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */
6582	{ }
6583};
6584
6585static struct hda_verb alc888_3st_hp_2ch_init[] = {
6586	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6587	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6588	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6589	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6590	{ }
6591};
6592
6593static struct hda_verb alc888_3st_hp_6ch_init[] = {
6594	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6595	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6596	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6597	{ 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6598	{ }
6599};
6600
6601static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6602	{ 2, alc888_3st_hp_2ch_init },
6603	{ 6, alc888_3st_hp_6ch_init },
6604};
6605
6606/* toggle front-jack and RCA according to the hp-jack state */
6607static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6608{
6609 	unsigned int present;
6610
6611 	present = snd_hda_codec_read(codec, 0x1b, 0,
6612				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6613	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6614				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6615	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6616				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6617}
6618
6619/* toggle RCA according to the front-jack state */
6620static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6621{
6622 	unsigned int present;
6623
6624 	present = snd_hda_codec_read(codec, 0x14, 0,
6625				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6626	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6627				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6628}
6629
6630static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6631					     unsigned int res)
6632{
6633	if ((res >> 26) == ALC880_HP_EVENT)
6634		alc888_lenovo_ms7195_front_automute(codec);
6635	if ((res >> 26) == ALC880_FRONT_EVENT)
6636		alc888_lenovo_ms7195_rca_automute(codec);
6637}
6638
6639static struct hda_verb alc883_medion_md2_verbs[] = {
6640	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6641	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6642
6643	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6644
6645	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6646	{ } /* end */
6647};
6648
6649/* toggle speaker-output according to the hp-jack state */
6650static void alc883_medion_md2_automute(struct hda_codec *codec)
6651{
6652 	unsigned int present;
6653
6654 	present = snd_hda_codec_read(codec, 0x14, 0,
6655				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6656	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6657				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6658}
6659
6660static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6661					  unsigned int res)
6662{
6663	if ((res >> 26) == ALC880_HP_EVENT)
6664		alc883_medion_md2_automute(codec);
6665}
6666
6667/* toggle speaker-output according to the hp-jack state */
6668static void alc883_tagra_automute(struct hda_codec *codec)
6669{
6670 	unsigned int present;
6671	unsigned char bits;
6672
6673 	present = snd_hda_codec_read(codec, 0x14, 0,
6674				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6675	bits = present ? HDA_AMP_MUTE : 0;
6676	snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6677				 HDA_AMP_MUTE, bits);
6678	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6679				  present ? 1 : 3);
6680}
6681
6682static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6683{
6684	if ((res >> 26) == ALC880_HP_EVENT)
6685		alc883_tagra_automute(codec);
6686}
6687
6688static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6689{
6690 	unsigned int present;
6691	unsigned char bits;
6692
6693 	present = snd_hda_codec_read(codec, 0x14, 0,
6694				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6695	bits = present ? HDA_AMP_MUTE : 0;
6696	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6697				 HDA_AMP_MUTE, bits);
6698}
6699
6700static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6701{
6702 	unsigned int present;
6703	unsigned char bits;
6704
6705 	present = snd_hda_codec_read(codec, 0x1b, 0,
6706				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6707	bits = present ? HDA_AMP_MUTE : 0;
6708	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6709				 HDA_AMP_MUTE, bits);
6710	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6711				 HDA_AMP_MUTE, bits);
6712}
6713
6714static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6715					   unsigned int res)
6716{
6717	if ((res >> 26) == ALC880_HP_EVENT)
6718		alc883_lenovo_101e_all_automute(codec);
6719	if ((res >> 26) == ALC880_FRONT_EVENT)
6720		alc883_lenovo_101e_ispeaker_automute(codec);
6721}
6722
6723/* toggle speaker-output according to the hp-jack state */
6724static void alc883_acer_aspire_automute(struct hda_codec *codec)
6725{
6726 	unsigned int present;
6727
6728 	present = snd_hda_codec_read(codec, 0x14, 0,
6729				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6730	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6731				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6732	snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
6733				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6734}
6735
6736static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
6737					   unsigned int res)
6738{
6739	if ((res >> 26) == ALC880_HP_EVENT)
6740		alc883_acer_aspire_automute(codec);
6741}
6742
6743static struct hda_verb alc883_acer_eapd_verbs[] = {
6744	/* HP Pin: output 0 (0x0c) */
6745	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6746	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6747	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6748	/* Front Pin: output 0 (0x0c) */
6749	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6750	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6751	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6752	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
6753        /* eanable EAPD on medion laptop */
6754	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6755	{0x20, AC_VERB_SET_PROC_COEF, 0x3050},
6756	/* enable unsolicited event */
6757	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6758	{ }
6759};
6760
6761/*
6762 * generic initialization of ADC, input mixers and output mixers
6763 */
6764static struct hda_verb alc883_auto_init_verbs[] = {
6765	/*
6766	 * Unmute ADC0-2 and set the default input to mic-in
6767	 */
6768	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6769	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6770	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6771	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772
6773	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6774	 * mixer widget
6775	 * Note: PASD motherboards uses the Line In 2 as the input for
6776	 * front panel mic (mic 2)
6777	 */
6778	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6779	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6780	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6781	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6782	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6783	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6784
6785	/*
6786	 * Set up output mixers (0x0c - 0x0f)
6787	 */
6788	/* set vol=0 to output mixers */
6789	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6790	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6791	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6792	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6793	/* set up input amps for analog loopback */
6794	/* Amp Indices: DAC = 0, mixer = 1 */
6795	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6796	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6797	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6798	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6799	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6800	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6801	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6802	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6803	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6804	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6805
6806	/* FIXME: use matrix-type input source selection */
6807	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6808	/* Input mixer1 */
6809	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6810	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6811	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6812	/* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6813	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6814	/* Input mixer2 */
6815	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6816	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6817	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6818	/* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6819	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6820
6821	{ }
6822};
6823
6824/* capture mixer elements */
6825static struct snd_kcontrol_new alc883_capture_mixer[] = {
6826	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6827	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6828	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6829	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6830	{
6831		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6832		/* The multiple "Capture Source" controls confuse alsamixer
6833		 * So call somewhat different..
6834		 * FIXME: the controls appear in the "playback" view!
6835		 */
6836		/* .name = "Capture Source", */
6837		.name = "Input Source",
6838		.count = 2,
6839		.info = alc882_mux_enum_info,
6840		.get = alc882_mux_enum_get,
6841		.put = alc882_mux_enum_put,
6842	},
6843	{ } /* end */
6844};
6845
6846#ifdef CONFIG_SND_HDA_POWER_SAVE
6847#define alc883_loopbacks	alc880_loopbacks
6848#endif
6849
6850/* pcm configuration: identiacal with ALC880 */
6851#define alc883_pcm_analog_playback	alc880_pcm_analog_playback
6852#define alc883_pcm_analog_capture	alc880_pcm_analog_capture
6853#define alc883_pcm_digital_playback	alc880_pcm_digital_playback
6854#define alc883_pcm_digital_capture	alc880_pcm_digital_capture
6855
6856/*
6857 * configuration and preset
6858 */
6859static const char *alc883_models[ALC883_MODEL_LAST] = {
6860	[ALC883_3ST_2ch_DIG]	= "3stack-dig",
6861	[ALC883_3ST_6ch_DIG]	= "3stack-6ch-dig",
6862	[ALC883_3ST_6ch]	= "3stack-6ch",
6863	[ALC883_6ST_DIG]	= "6stack-dig",
6864	[ALC883_TARGA_DIG]	= "targa-dig",
6865	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
6866	[ALC883_ACER]		= "acer",
6867	[ALC883_ACER_ASPIRE]	= "acer-aspire",
6868	[ALC883_MEDION]		= "medion",
6869	[ALC883_MEDION_MD2]	= "medion-md2",
6870	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
6871	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
6872	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
6873	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
6874	[ALC888_6ST_HP]		= "6stack-hp",
6875	[ALC888_3ST_HP]		= "3stack-hp",
6876	[ALC883_AUTO]		= "auto",
6877};
6878
6879static struct snd_pci_quirk alc883_cfg_tbl[] = {
6880	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
6881	SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
6882	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
6883	SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
6884	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
6885	SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6886	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
6887	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
6888	SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
6889	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
6890	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
6891	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
6892	SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
6893	SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
6894	SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
6895	SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
6896	SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
6897	SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
6898	SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
6899	SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
6900	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
6901	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
6902	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
6903	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
6904	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
6905	SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
6906	SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
6907	SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
6908	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
6909	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
6910	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
6911	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
6912	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6913	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
6914	SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
6915	SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
6916	SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
6917	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
6918	{}
6919};
6920
6921static struct alc_config_preset alc883_presets[] = {
6922	[ALC883_3ST_2ch_DIG] = {
6923		.mixers = { alc883_3ST_2ch_mixer },
6924		.init_verbs = { alc883_init_verbs },
6925		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6926		.dac_nids = alc883_dac_nids,
6927		.dig_out_nid = ALC883_DIGOUT_NID,
6928		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6929		.adc_nids = alc883_adc_nids,
6930		.dig_in_nid = ALC883_DIGIN_NID,
6931		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6932		.channel_mode = alc883_3ST_2ch_modes,
6933		.input_mux = &alc883_capture_source,
6934	},
6935	[ALC883_3ST_6ch_DIG] = {
6936		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6937		.init_verbs = { alc883_init_verbs },
6938		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6939		.dac_nids = alc883_dac_nids,
6940		.dig_out_nid = ALC883_DIGOUT_NID,
6941		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6942		.adc_nids = alc883_adc_nids,
6943		.dig_in_nid = ALC883_DIGIN_NID,
6944		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6945		.channel_mode = alc883_3ST_6ch_modes,
6946		.need_dac_fix = 1,
6947		.input_mux = &alc883_capture_source,
6948	},
6949	[ALC883_3ST_6ch] = {
6950		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
6951		.init_verbs = { alc883_init_verbs },
6952		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6953		.dac_nids = alc883_dac_nids,
6954		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6955		.adc_nids = alc883_adc_nids,
6956		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6957		.channel_mode = alc883_3ST_6ch_modes,
6958		.need_dac_fix = 1,
6959		.input_mux = &alc883_capture_source,
6960	},
6961	[ALC883_6ST_DIG] = {
6962		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
6963		.init_verbs = { alc883_init_verbs },
6964		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6965		.dac_nids = alc883_dac_nids,
6966		.dig_out_nid = ALC883_DIGOUT_NID,
6967		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6968		.adc_nids = alc883_adc_nids,
6969		.dig_in_nid = ALC883_DIGIN_NID,
6970		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
6971		.channel_mode = alc883_sixstack_modes,
6972		.input_mux = &alc883_capture_source,
6973	},
6974	[ALC883_TARGA_DIG] = {
6975		.mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
6976		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6977		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6978		.dac_nids = alc883_dac_nids,
6979		.dig_out_nid = ALC883_DIGOUT_NID,
6980		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6981		.adc_nids = alc883_adc_nids,
6982		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
6983		.channel_mode = alc883_3ST_6ch_modes,
6984		.need_dac_fix = 1,
6985		.input_mux = &alc883_capture_source,
6986		.unsol_event = alc883_tagra_unsol_event,
6987		.init_hook = alc883_tagra_automute,
6988	},
6989	[ALC883_TARGA_2ch_DIG] = {
6990		.mixers = { alc883_tagra_2ch_mixer},
6991		.init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
6992		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
6993		.dac_nids = alc883_dac_nids,
6994		.dig_out_nid = ALC883_DIGOUT_NID,
6995		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
6996		.adc_nids = alc883_adc_nids,
6997		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
6998		.channel_mode = alc883_3ST_2ch_modes,
6999		.input_mux = &alc883_capture_source,
7000		.unsol_event = alc883_tagra_unsol_event,
7001		.init_hook = alc883_tagra_automute,
7002	},
7003	[ALC883_ACER] = {
7004		.mixers = { alc883_base_mixer },
7005		/* On TravelMate laptops, GPIO 0 enables the internal speaker
7006		 * and the headphone jack.  Turn this on and rely on the
7007		 * standard mute methods whenever the user wants to turn
7008		 * these outputs off.
7009		 */
7010		.init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7011		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7012		.dac_nids = alc883_dac_nids,
7013		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7014		.adc_nids = alc883_adc_nids,
7015		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7016		.channel_mode = alc883_3ST_2ch_modes,
7017		.input_mux = &alc883_capture_source,
7018	},
7019	[ALC883_ACER_ASPIRE] = {
7020		.mixers = { alc883_acer_aspire_mixer },
7021		.init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7022		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7023		.dac_nids = alc883_dac_nids,
7024		.dig_out_nid = ALC883_DIGOUT_NID,
7025		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7026		.adc_nids = alc883_adc_nids,
7027		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7028		.channel_mode = alc883_3ST_2ch_modes,
7029		.input_mux = &alc883_capture_source,
7030		.unsol_event = alc883_acer_aspire_unsol_event,
7031		.init_hook = alc883_acer_aspire_automute,
7032	},
7033	[ALC883_MEDION] = {
7034		.mixers = { alc883_fivestack_mixer,
7035			    alc883_chmode_mixer },
7036		.init_verbs = { alc883_init_verbs,
7037				alc883_medion_eapd_verbs },
7038		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7039		.dac_nids = alc883_dac_nids,
7040		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7041		.adc_nids = alc883_adc_nids,
7042		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7043		.channel_mode = alc883_sixstack_modes,
7044		.input_mux = &alc883_capture_source,
7045	},
7046	[ALC883_MEDION_MD2] = {
7047		.mixers = { alc883_medion_md2_mixer},
7048		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7049		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7050		.dac_nids = alc883_dac_nids,
7051		.dig_out_nid = ALC883_DIGOUT_NID,
7052		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7053		.adc_nids = alc883_adc_nids,
7054		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7055		.channel_mode = alc883_3ST_2ch_modes,
7056		.input_mux = &alc883_capture_source,
7057		.unsol_event = alc883_medion_md2_unsol_event,
7058		.init_hook = alc883_medion_md2_automute,
7059	},
7060	[ALC883_LAPTOP_EAPD] = {
7061		.mixers = { alc883_base_mixer },
7062		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7063		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7064		.dac_nids = alc883_dac_nids,
7065		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7066		.adc_nids = alc883_adc_nids,
7067		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7068		.channel_mode = alc883_3ST_2ch_modes,
7069		.input_mux = &alc883_capture_source,
7070	},
7071	[ALC883_LENOVO_101E_2ch] = {
7072		.mixers = { alc883_lenovo_101e_2ch_mixer},
7073		.init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7074		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7075		.dac_nids = alc883_dac_nids,
7076		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7077		.adc_nids = alc883_adc_nids,
7078		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7079		.channel_mode = alc883_3ST_2ch_modes,
7080		.input_mux = &alc883_lenovo_101e_capture_source,
7081		.unsol_event = alc883_lenovo_101e_unsol_event,
7082		.init_hook = alc883_lenovo_101e_all_automute,
7083	},
7084	[ALC883_LENOVO_NB0763] = {
7085		.mixers = { alc883_lenovo_nb0763_mixer },
7086		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7087		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7088		.dac_nids = alc883_dac_nids,
7089		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7090		.adc_nids = alc883_adc_nids,
7091		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7092		.channel_mode = alc883_3ST_2ch_modes,
7093		.need_dac_fix = 1,
7094		.input_mux = &alc883_lenovo_nb0763_capture_source,
7095		.unsol_event = alc883_medion_md2_unsol_event,
7096		.init_hook = alc883_medion_md2_automute,
7097	},
7098	[ALC888_LENOVO_MS7195_DIG] = {
7099		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7100		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7101		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7102		.dac_nids = alc883_dac_nids,
7103		.dig_out_nid = ALC883_DIGOUT_NID,
7104		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7105		.adc_nids = alc883_adc_nids,
7106		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7107		.channel_mode = alc883_3ST_6ch_modes,
7108		.need_dac_fix = 1,
7109		.input_mux = &alc883_capture_source,
7110		.unsol_event = alc883_lenovo_ms7195_unsol_event,
7111		.init_hook = alc888_lenovo_ms7195_front_automute,
7112	},
7113	[ALC888_6ST_HP] = {
7114		.mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7115		.init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7116		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7117		.dac_nids = alc883_dac_nids,
7118		.dig_out_nid = ALC883_DIGOUT_NID,
7119		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7120		.adc_nids = alc883_adc_nids,
7121		.dig_in_nid = ALC883_DIGIN_NID,
7122		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7123		.channel_mode = alc883_sixstack_modes,
7124		.input_mux = &alc883_capture_source,
7125	},
7126	[ALC888_3ST_HP] = {
7127		.mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7128		.init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7129		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
7130		.dac_nids = alc883_dac_nids,
7131		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7132		.adc_nids = alc883_adc_nids,
7133		.num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7134		.channel_mode = alc888_3st_hp_modes,
7135		.need_dac_fix = 1,
7136		.input_mux = &alc883_capture_source,
7137	},
7138};
7139
7140
7141/*
7142 * BIOS auto configuration
7143 */
7144static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7145					      hda_nid_t nid, int pin_type,
7146					      int dac_idx)
7147{
7148	/* set as output */
7149	struct alc_spec *spec = codec->spec;
7150	int idx;
7151
7152	if (spec->multiout.dac_nids[dac_idx] == 0x25)
7153		idx = 4;
7154	else
7155		idx = spec->multiout.dac_nids[dac_idx] - 2;
7156
7157	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7158			    pin_type);
7159	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7160			    AMP_OUT_UNMUTE);
7161	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7162
7163}
7164
7165static void alc883_auto_init_multi_out(struct hda_codec *codec)
7166{
7167	struct alc_spec *spec = codec->spec;
7168	int i;
7169
7170	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7171	for (i = 0; i <= HDA_SIDE; i++) {
7172		hda_nid_t nid = spec->autocfg.line_out_pins[i];
7173		int pin_type = get_pin_type(spec->autocfg.line_out_type);
7174		if (nid)
7175			alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7176							  i);
7177	}
7178}
7179
7180static void alc883_auto_init_hp_out(struct hda_codec *codec)
7181{
7182	struct alc_spec *spec = codec->spec;
7183	hda_nid_t pin;
7184
7185	pin = spec->autocfg.hp_pins[0];
7186	if (pin) /* connect to front */
7187		/* use dac 0 */
7188		alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7189}
7190
7191#define alc883_is_input_pin(nid)	alc880_is_input_pin(nid)
7192#define ALC883_PIN_CD_NID		ALC880_PIN_CD_NID
7193
7194static void alc883_auto_init_analog_input(struct hda_codec *codec)
7195{
7196	struct alc_spec *spec = codec->spec;
7197	int i;
7198
7199	for (i = 0; i < AUTO_PIN_LAST; i++) {
7200		hda_nid_t nid = spec->autocfg.input_pins[i];
7201		if (alc883_is_input_pin(nid)) {
7202			snd_hda_codec_write(codec, nid, 0,
7203					    AC_VERB_SET_PIN_WIDGET_CONTROL,
7204					    (i <= AUTO_PIN_FRONT_MIC ?
7205					     PIN_VREF80 : PIN_IN));
7206			if (nid != ALC883_PIN_CD_NID)
7207				snd_hda_codec_write(codec, nid, 0,
7208						    AC_VERB_SET_AMP_GAIN_MUTE,
7209						    AMP_OUT_MUTE);
7210		}
7211	}
7212}
7213
7214/* almost identical with ALC880 parser... */
7215static int alc883_parse_auto_config(struct hda_codec *codec)
7216{
7217	struct alc_spec *spec = codec->spec;
7218	int err = alc880_parse_auto_config(codec);
7219
7220	if (err < 0)
7221		return err;
7222	else if (err > 0)
7223		/* hack - override the init verbs */
7224		spec->init_verbs[0] = alc883_auto_init_verbs;
7225	spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7226	spec->num_mixers++;
7227	return err;
7228}
7229
7230/* additional initialization for auto-configuration model */
7231static void alc883_auto_init(struct hda_codec *codec)
7232{
7233	alc883_auto_init_multi_out(codec);
7234	alc883_auto_init_hp_out(codec);
7235	alc883_auto_init_analog_input(codec);
7236}
7237
7238static int patch_alc883(struct hda_codec *codec)
7239{
7240	struct alc_spec *spec;
7241	int err, board_config;
7242
7243	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7244	if (spec == NULL)
7245		return -ENOMEM;
7246
7247	codec->spec = spec;
7248
7249	board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7250						  alc883_models,
7251						  alc883_cfg_tbl);
7252	if (board_config < 0) {
7253		printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7254		       "trying auto-probe from BIOS...\n");
7255		board_config = ALC883_AUTO;
7256	}
7257
7258	if (board_config == ALC883_AUTO) {
7259		/* automatic parse from the BIOS config */
7260		err = alc883_parse_auto_config(codec);
7261		if (err < 0) {
7262			alc_free(codec);
7263			return err;
7264		} else if (!err) {
7265			printk(KERN_INFO
7266			       "hda_codec: Cannot set up configuration "
7267			       "from BIOS.  Using base mode...\n");
7268			board_config = ALC883_3ST_2ch_DIG;
7269		}
7270	}
7271
7272	if (board_config != ALC883_AUTO)
7273		setup_preset(spec, &alc883_presets[board_config]);
7274
7275	spec->stream_name_analog = "ALC883 Analog";
7276	spec->stream_analog_playback = &alc883_pcm_analog_playback;
7277	spec->stream_analog_capture = &alc883_pcm_analog_capture;
7278
7279	spec->stream_name_digital = "ALC883 Digital";
7280	spec->stream_digital_playback = &alc883_pcm_digital_playback;
7281	spec->stream_digital_capture = &alc883_pcm_digital_capture;
7282
7283	if (!spec->adc_nids && spec->input_mux) {
7284		spec->adc_nids = alc883_adc_nids;
7285		spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7286	}
7287
7288	codec->patch_ops = alc_patch_ops;
7289	if (board_config == ALC883_AUTO)
7290		spec->init_hook = alc883_auto_init;
7291#ifdef CONFIG_SND_HDA_POWER_SAVE
7292	if (!spec->loopback.amplist)
7293		spec->loopback.amplist = alc883_loopbacks;
7294#endif
7295
7296	return 0;
7297}
7298
7299/*
7300 * ALC262 support
7301 */
7302
7303#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
7304#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
7305
7306#define alc262_dac_nids		alc260_dac_nids
7307#define alc262_adc_nids		alc882_adc_nids
7308#define alc262_adc_nids_alt	alc882_adc_nids_alt
7309
7310#define alc262_modes		alc260_modes
7311#define alc262_capture_source	alc882_capture_source
7312
7313static struct snd_kcontrol_new alc262_base_mixer[] = {
7314	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7315	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7316	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7317	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7318	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7319	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7320	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7321	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7322	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7323	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7324	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7325	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7326	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7327	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7328	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7329	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7330	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7331	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7332	{ } /* end */
7333};
7334
7335static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7336	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7337	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7338	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7339	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7340	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7341	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7342	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7343	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7344	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7345	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7346	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7347	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7348	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7349	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7350	/*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7351	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7352	{ } /* end */
7353};
7354
7355static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7356	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7357	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7358	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7359	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7360	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7361
7362	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7363	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7364	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7365	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7366	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7367	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7368	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7369	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7370	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7371	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7372	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7373	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7374	HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7375	HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7376	{ } /* end */
7377};
7378
7379static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7380	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7381	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7382	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7383	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7384	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7385	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7386	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7387	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7388	HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7389	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7390	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7391	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7392	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7393	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7394	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7395	{ } /* end */
7396};
7397
7398static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7399	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7400	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7401	HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7402	{ } /* end */
7403};
7404
7405static struct hda_bind_ctls alc262_sony_bind_sw = {
7406	.ops = &snd_hda_bind_sw,
7407	.values = {
7408		HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7409		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7410		0,
7411	},
7412};
7413
7414static struct snd_kcontrol_new alc262_sony_mixer[] = {
7415	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7416	HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw),
7417	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7418	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7419	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7420	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7421	{ } /* end */
7422};
7423
7424static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7425	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7426	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7427	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7428	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7429	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7430	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7431	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7432	{ } /* end */
7433};
7434
7435#define alc262_capture_mixer		alc882_capture_mixer
7436#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
7437
7438/*
7439 * generic initialization of ADC, input mixers and output mixers
7440 */
7441static struct hda_verb alc262_init_verbs[] = {
7442	/*
7443	 * Unmute ADC0-2 and set the default input to mic-in
7444	 */
7445	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7446	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7447	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7448	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7449	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7450	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7451
7452	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7453	 * mixer widget
7454	 * Note: PASD motherboards uses the Line In 2 as the input for
7455	 * front panel mic (mic 2)
7456	 */
7457	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7458	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7459	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7460	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7461	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7462	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7463
7464	/*
7465	 * Set up output mixers (0x0c - 0x0e)
7466	 */
7467	/* set vol=0 to output mixers */
7468	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7469	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7470	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7471	/* set up input amps for analog loopback */
7472	/* Amp Indices: DAC = 0, mixer = 1 */
7473	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7474	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7475	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7476	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7477	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7478	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7479
7480	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7481	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7482	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7483	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7484	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7485	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7486
7487	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7488	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7489	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7490	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7491	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7492
7493	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7494	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7495
7496	/* FIXME: use matrix-type input source selection */
7497	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7498	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7499	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7500	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7501	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7502	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7503	/* Input mixer2 */
7504	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7505	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7506	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7507	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7508	/* Input mixer3 */
7509	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7510	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7511	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7512	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7513
7514	{ }
7515};
7516
7517static struct hda_verb alc262_hippo_unsol_verbs[] = {
7518	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7519	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7520	{}
7521};
7522
7523static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7524	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7525	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7526	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7527
7528	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7529	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7530	{}
7531};
7532
7533static struct hda_verb alc262_sony_unsol_verbs[] = {
7534	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7535	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7536	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
7537
7538	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7539	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7540};
7541
7542/* mute/unmute internal speaker according to the hp jack and mute state */
7543static void alc262_hippo_automute(struct hda_codec *codec)
7544{
7545	struct alc_spec *spec = codec->spec;
7546	unsigned int mute;
7547	unsigned int present;
7548
7549	/* need to execute and sync at first */
7550	snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7551	present = snd_hda_codec_read(codec, 0x15, 0,
7552				     AC_VERB_GET_PIN_SENSE, 0);
7553	spec->jack_present = (present & 0x80000000) != 0;
7554	if (spec->jack_present) {
7555		/* mute internal speaker */
7556		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7557					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7558	} else {
7559		/* unmute internal speaker if necessary */
7560		mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7561		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7562					 HDA_AMP_MUTE, mute);
7563	}
7564}
7565
7566/* unsolicited event for HP jack sensing */
7567static void alc262_hippo_unsol_event(struct hda_codec *codec,
7568				       unsigned int res)
7569{
7570	if ((res >> 26) != ALC880_HP_EVENT)
7571		return;
7572	alc262_hippo_automute(codec);
7573}
7574
7575static void alc262_hippo1_automute(struct hda_codec *codec)
7576{
7577	unsigned int mute;
7578	unsigned int present;
7579
7580	snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7581	present = snd_hda_codec_read(codec, 0x1b, 0,
7582				     AC_VERB_GET_PIN_SENSE, 0);
7583	present = (present & 0x80000000) != 0;
7584	if (present) {
7585		/* mute internal speaker */
7586		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7587					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7588	} else {
7589		/* unmute internal speaker if necessary */
7590		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7591		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7592					 HDA_AMP_MUTE, mute);
7593	}
7594}
7595
7596/* unsolicited event for HP jack sensing */
7597static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7598				       unsigned int res)
7599{
7600	if ((res >> 26) != ALC880_HP_EVENT)
7601		return;
7602	alc262_hippo1_automute(codec);
7603}
7604
7605/*
7606 * fujitsu model
7607 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7608 */
7609
7610#define ALC_HP_EVENT	0x37
7611
7612static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7613	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7614	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7615	{}
7616};
7617
7618static struct hda_input_mux alc262_fujitsu_capture_source = {
7619	.num_items = 2,
7620	.items = {
7621		{ "Mic", 0x0 },
7622		{ "CD", 0x4 },
7623	},
7624};
7625
7626static struct hda_input_mux alc262_HP_capture_source = {
7627	.num_items = 5,
7628	.items = {
7629		{ "Mic", 0x0 },
7630		{ "Front Mic", 0x3 },
7631		{ "Line", 0x2 },
7632		{ "CD", 0x4 },
7633		{ "AUX IN", 0x6 },
7634	},
7635};
7636
7637/* mute/unmute internal speaker according to the hp jack and mute state */
7638static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7639{
7640	struct alc_spec *spec = codec->spec;
7641	unsigned int mute;
7642
7643	if (force || !spec->sense_updated) {
7644		unsigned int present;
7645		/* need to execute and sync at first */
7646		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7647		present = snd_hda_codec_read(codec, 0x14, 0,
7648				    	 AC_VERB_GET_PIN_SENSE, 0);
7649		spec->jack_present = (present & 0x80000000) != 0;
7650		spec->sense_updated = 1;
7651	}
7652	if (spec->jack_present) {
7653		/* mute internal speaker */
7654		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7655					 HDA_AMP_MUTE, HDA_AMP_MUTE);
7656	} else {
7657		/* unmute internal speaker if necessary */
7658		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
7659		snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7660					 HDA_AMP_MUTE, mute);
7661	}
7662}
7663
7664/* unsolicited event for HP jack sensing */
7665static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
7666				       unsigned int res)
7667{
7668	if ((res >> 26) != ALC_HP_EVENT)
7669		return;
7670	alc262_fujitsu_automute(codec, 1);
7671}
7672
7673/* bind volumes of both NID 0x0c and 0x0d */
7674static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
7675	.ops = &snd_hda_bind_vol,
7676	.values = {
7677		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7678		HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7679		0
7680	},
7681};
7682
7683/* bind hp and internal speaker mute (with plug check) */
7684static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
7685					 struct snd_ctl_elem_value *ucontrol)
7686{
7687	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7688	long *valp = ucontrol->value.integer.value;
7689	int change;
7690
7691	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
7692					  HDA_AMP_MUTE,
7693					  valp[0] ? 0 : HDA_AMP_MUTE);
7694	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
7695					   HDA_AMP_MUTE,
7696					   valp[1] ? 0 : HDA_AMP_MUTE);
7697	if (change)
7698		alc262_fujitsu_automute(codec, 0);
7699	return change;
7700}
7701
7702static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
7703	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
7704	{
7705		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7706		.name = "Master Playback Switch",
7707		.info = snd_hda_mixer_amp_switch_info,
7708		.get = snd_hda_mixer_amp_switch_get,
7709		.put = alc262_fujitsu_master_sw_put,
7710		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7711	},
7712	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7713	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7714	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7715	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7716	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7717	{ } /* end */
7718};
7719
7720/* additional init verbs for Benq laptops */
7721static struct hda_verb alc262_EAPD_verbs[] = {
7722	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7723	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
7724	{}
7725};
7726
7727static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
7728	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7729	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7730
7731	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7732	{0x20, AC_VERB_SET_PROC_COEF,  0x3050},
7733	{}
7734};
7735
7736/* add playback controls from the parsed DAC table */
7737static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
7738					     const struct auto_pin_cfg *cfg)
7739{
7740	hda_nid_t nid;
7741	int err;
7742
7743	spec->multiout.num_dacs = 1;	/* only use one dac */
7744	spec->multiout.dac_nids = spec->private_dac_nids;
7745	spec->multiout.dac_nids[0] = 2;
7746
7747	nid = cfg->line_out_pins[0];
7748	if (nid) {
7749		err = add_control(spec, ALC_CTL_WIDGET_VOL,
7750				  "Front Playback Volume",
7751				  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
7752		if (err < 0)
7753			return err;
7754		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7755				  "Front Playback Switch",
7756				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
7757		if (err < 0)
7758			return err;
7759	}
7760
7761	nid = cfg->speaker_pins[0];
7762	if (nid) {
7763		if (nid == 0x16) {
7764			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7765					  "Speaker Playback Volume",
7766					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7767							      HDA_OUTPUT));
7768			if (err < 0)
7769				return err;
7770			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7771					  "Speaker Playback Switch",
7772					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7773							      HDA_OUTPUT));
7774			if (err < 0)
7775				return err;
7776		} else {
7777			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7778					  "Speaker Playback Switch",
7779					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7780							      HDA_OUTPUT));
7781			if (err < 0)
7782				return err;
7783		}
7784	}
7785	nid = cfg->hp_pins[0];
7786	if (nid) {
7787		/* spec->multiout.hp_nid = 2; */
7788		if (nid == 0x16) {
7789			err = add_control(spec, ALC_CTL_WIDGET_VOL,
7790					  "Headphone Playback Volume",
7791					  HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7792							      HDA_OUTPUT));
7793			if (err < 0)
7794				return err;
7795			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7796					  "Headphone Playback Switch",
7797					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
7798							      HDA_OUTPUT));
7799			if (err < 0)
7800				return err;
7801		} else {
7802			err = add_control(spec, ALC_CTL_WIDGET_MUTE,
7803					  "Headphone Playback Switch",
7804					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
7805							      HDA_OUTPUT));
7806			if (err < 0)
7807				return err;
7808		}
7809	}
7810	return 0;
7811}
7812
7813/* identical with ALC880 */
7814#define alc262_auto_create_analog_input_ctls \
7815	alc880_auto_create_analog_input_ctls
7816
7817/*
7818 * generic initialization of ADC, input mixers and output mixers
7819 */
7820static struct hda_verb alc262_volume_init_verbs[] = {
7821	/*
7822	 * Unmute ADC0-2 and set the default input to mic-in
7823	 */
7824	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7825	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7826	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7827	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7828	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7829	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7830
7831	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7832	 * mixer widget
7833	 * Note: PASD motherboards uses the Line In 2 as the input for
7834	 * front panel mic (mic 2)
7835	 */
7836	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7837	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7838	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7839	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7840	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7841	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7842
7843	/*
7844	 * Set up output mixers (0x0c - 0x0f)
7845	 */
7846	/* set vol=0 to output mixers */
7847	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7848	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7849	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7850
7851	/* set up input amps for analog loopback */
7852	/* Amp Indices: DAC = 0, mixer = 1 */
7853	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7854	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7855	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7856	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7857	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7858	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7859
7860	/* FIXME: use matrix-type input source selection */
7861	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7862	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7863	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7864	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7865	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7866	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7867	/* Input mixer2 */
7868	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7869	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7870	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7871	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7872	/* Input mixer3 */
7873	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7874	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7875	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7876	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7877
7878	{ }
7879};
7880
7881static struct hda_verb alc262_HP_BPC_init_verbs[] = {
7882	/*
7883	 * Unmute ADC0-2 and set the default input to mic-in
7884	 */
7885	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7886	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7887	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7888	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7889	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7890	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7891
7892	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7893	 * mixer widget
7894	 * Note: PASD motherboards uses the Line In 2 as the input for
7895	 * front panel mic (mic 2)
7896	 */
7897	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7898	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7899	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7900	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7901	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7902	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7903	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7904        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7905
7906	/*
7907	 * Set up output mixers (0x0c - 0x0e)
7908	 */
7909	/* set vol=0 to output mixers */
7910	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7911	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7912	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7913
7914	/* set up input amps for analog loopback */
7915	/* Amp Indices: DAC = 0, mixer = 1 */
7916	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7917	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7918	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7919	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7920	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7921	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7922
7923	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7924	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7925	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7926
7927	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7928	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7929
7930	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7931	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7932
7933	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7934	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7935        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7936	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7937	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7938
7939	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7940	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7941        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7942	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
7943	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7944	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
7945
7946
7947	/* FIXME: use matrix-type input source selection */
7948	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7949	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7950	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7951	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7952	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7953	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7954	/* Input mixer2 */
7955	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7956	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7957	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7958	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7959	/* Input mixer3 */
7960	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7961	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
7962	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
7963	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
7964
7965	{ }
7966};
7967
7968static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
7969	/*
7970	 * Unmute ADC0-2 and set the default input to mic-in
7971	 */
7972	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7973	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7974	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7975	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7976	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7977	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7978
7979	/* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7980	 * mixer widget
7981	 * Note: PASD motherboards uses the Line In 2 as the input for front
7982	 * panel mic (mic 2)
7983	 */
7984	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7985	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7986	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7987	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7988	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7989	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7990	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
7991	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
7992	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
7993	/*
7994	 * Set up output mixers (0x0c - 0x0e)
7995	 */
7996	/* set vol=0 to output mixers */
7997	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7998	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7999	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8000
8001	/* set up input amps for analog loopback */
8002	/* Amp Indices: DAC = 0, mixer = 1 */
8003	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8004	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8005	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8006	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8007	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8008	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8009
8010
8011	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },	/* HP */
8012	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Mono */
8013	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* rear MIC */
8014	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* Line in */
8015	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },	/* Front MIC */
8016	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Line out */
8017	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },	/* CD in */
8018
8019	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8020	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8021
8022	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8023	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8024
8025	/* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8026	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8027	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8028	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8029	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8030	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8031
8032	/* FIXME: use matrix-type input source selection */
8033	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8034	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8035	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8036	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8037	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8038	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8039	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8040        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8041	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8042	/* Input mixer2 */
8043	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8044	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8045	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8046	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8047	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8048        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8049	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8050	/* Input mixer3 */
8051	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8052	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8053	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8054	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8055	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8056        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8057	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8058
8059	{ }
8060};
8061
8062#ifdef CONFIG_SND_HDA_POWER_SAVE
8063#define alc262_loopbacks	alc880_loopbacks
8064#endif
8065
8066/* pcm configuration: identiacal with ALC880 */
8067#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
8068#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
8069#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
8070#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
8071
8072/*
8073 * BIOS auto configuration
8074 */
8075static int alc262_parse_auto_config(struct hda_codec *codec)
8076{
8077	struct alc_spec *spec = codec->spec;
8078	int err;
8079	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8080
8081	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8082					   alc262_ignore);
8083	if (err < 0)
8084		return err;
8085	if (!spec->autocfg.line_outs)
8086		return 0; /* can't find valid BIOS pin config */
8087	err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8088	if (err < 0)
8089		return err;
8090	err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8091	if (err < 0)
8092		return err;
8093
8094	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8095
8096	if (spec->autocfg.dig_out_pin)
8097		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8098	if (spec->autocfg.dig_in_pin)
8099		spec->dig_in_nid = ALC262_DIGIN_NID;
8100
8101	if (spec->kctl_alloc)
8102		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8103
8104	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8105	spec->num_mux_defs = 1;
8106	spec->input_mux = &spec->private_imux;
8107
8108	return 1;
8109}
8110
8111#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
8112#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
8113#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
8114
8115
8116/* init callback for auto-configuration model -- overriding the default init */
8117static void alc262_auto_init(struct hda_codec *codec)
8118{
8119	alc262_auto_init_multi_out(codec);
8120	alc262_auto_init_hp_out(codec);
8121	alc262_auto_init_analog_input(codec);
8122}
8123
8124/*
8125 * configuration and preset
8126 */
8127static const char *alc262_models[ALC262_MODEL_LAST] = {
8128	[ALC262_BASIC]		= "basic",
8129	[ALC262_HIPPO]		= "hippo",
8130	[ALC262_HIPPO_1]	= "hippo_1",
8131	[ALC262_FUJITSU]	= "fujitsu",
8132	[ALC262_HP_BPC]		= "hp-bpc",
8133	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8134	[ALC262_BENQ_ED8]	= "benq",
8135	[ALC262_BENQ_T31]	= "benq-t31",
8136	[ALC262_SONY_ASSAMD]	= "sony-assamd",
8137	[ALC262_AUTO]		= "auto",
8138};
8139
8140static struct snd_pci_quirk alc262_cfg_tbl[] = {
8141	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8142	SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8143	SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8144	SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8145	SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8146	SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8147	SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8148	SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8149	SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8150	SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8151	SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8152	SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8153	SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8154	SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8155	SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8156	SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8157	SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8158	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8159	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8160	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8161	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8162	SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8163	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8164	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8165	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8166	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8167	{}
8168};
8169
8170static struct alc_config_preset alc262_presets[] = {
8171	[ALC262_BASIC] = {
8172		.mixers = { alc262_base_mixer },
8173		.init_verbs = { alc262_init_verbs },
8174		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8175		.dac_nids = alc262_dac_nids,
8176		.hp_nid = 0x03,
8177		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8178		.channel_mode = alc262_modes,
8179		.input_mux = &alc262_capture_source,
8180	},
8181	[ALC262_HIPPO] = {
8182		.mixers = { alc262_base_mixer },
8183		.init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8184		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8185		.dac_nids = alc262_dac_nids,
8186		.hp_nid = 0x03,
8187		.dig_out_nid = ALC262_DIGOUT_NID,
8188		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8189		.channel_mode = alc262_modes,
8190		.input_mux = &alc262_capture_source,
8191		.unsol_event = alc262_hippo_unsol_event,
8192		.init_hook = alc262_hippo_automute,
8193	},
8194	[ALC262_HIPPO_1] = {
8195		.mixers = { alc262_hippo1_mixer },
8196		.init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8197		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8198		.dac_nids = alc262_dac_nids,
8199		.hp_nid = 0x02,
8200		.dig_out_nid = ALC262_DIGOUT_NID,
8201		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8202		.channel_mode = alc262_modes,
8203		.input_mux = &alc262_capture_source,
8204		.unsol_event = alc262_hippo1_unsol_event,
8205		.init_hook = alc262_hippo1_automute,
8206	},
8207	[ALC262_FUJITSU] = {
8208		.mixers = { alc262_fujitsu_mixer },
8209		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
8210		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8211		.dac_nids = alc262_dac_nids,
8212		.hp_nid = 0x03,
8213		.dig_out_nid = ALC262_DIGOUT_NID,
8214		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8215		.channel_mode = alc262_modes,
8216		.input_mux = &alc262_fujitsu_capture_source,
8217		.unsol_event = alc262_fujitsu_unsol_event,
8218	},
8219	[ALC262_HP_BPC] = {
8220		.mixers = { alc262_HP_BPC_mixer },
8221		.init_verbs = { alc262_HP_BPC_init_verbs },
8222		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8223		.dac_nids = alc262_dac_nids,
8224		.hp_nid = 0x03,
8225		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8226		.channel_mode = alc262_modes,
8227		.input_mux = &alc262_HP_capture_source,
8228	},
8229	[ALC262_HP_BPC_D7000_WF] = {
8230		.mixers = { alc262_HP_BPC_WildWest_mixer },
8231		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8232		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8233		.dac_nids = alc262_dac_nids,
8234		.hp_nid = 0x03,
8235		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8236		.channel_mode = alc262_modes,
8237		.input_mux = &alc262_HP_capture_source,
8238	},
8239	[ALC262_HP_BPC_D7000_WL] = {
8240		.mixers = { alc262_HP_BPC_WildWest_mixer,
8241			    alc262_HP_BPC_WildWest_option_mixer },
8242		.init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8243		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8244		.dac_nids = alc262_dac_nids,
8245		.hp_nid = 0x03,
8246		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8247		.channel_mode = alc262_modes,
8248		.input_mux = &alc262_HP_capture_source,
8249	},
8250	[ALC262_BENQ_ED8] = {
8251		.mixers = { alc262_base_mixer },
8252		.init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8253		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8254		.dac_nids = alc262_dac_nids,
8255		.hp_nid = 0x03,
8256		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8257		.channel_mode = alc262_modes,
8258		.input_mux = &alc262_capture_source,
8259	},
8260	[ALC262_SONY_ASSAMD] = {
8261		.mixers = { alc262_sony_mixer },
8262		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8263		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8264		.dac_nids = alc262_dac_nids,
8265		.hp_nid = 0x02,
8266		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8267		.channel_mode = alc262_modes,
8268		.input_mux = &alc262_capture_source,
8269		.unsol_event = alc262_hippo_unsol_event,
8270		.init_hook = alc262_hippo_automute,
8271	},
8272	[ALC262_BENQ_T31] = {
8273		.mixers = { alc262_benq_t31_mixer },
8274		.init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8275		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
8276		.dac_nids = alc262_dac_nids,
8277		.hp_nid = 0x03,
8278		.num_channel_mode = ARRAY_SIZE(alc262_modes),
8279		.channel_mode = alc262_modes,
8280		.input_mux = &alc262_capture_source,
8281		.unsol_event = alc262_hippo_unsol_event,
8282		.init_hook = alc262_hippo_automute,
8283	},
8284};
8285
8286static int patch_alc262(struct hda_codec *codec)
8287{
8288	struct alc_spec *spec;
8289	int board_config;
8290	int err;
8291
8292	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8293	if (spec == NULL)
8294		return -ENOMEM;
8295
8296	codec->spec = spec;
8297#if 0
8298	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8299	 * under-run
8300	 */
8301	{
8302	int tmp;
8303	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8304	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8305	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8306	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8307	}
8308#endif
8309
8310	board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8311						  alc262_models,
8312						  alc262_cfg_tbl);
8313
8314	if (board_config < 0) {
8315		printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8316		       "trying auto-probe from BIOS...\n");
8317		board_config = ALC262_AUTO;
8318	}
8319
8320	if (board_config == ALC262_AUTO) {
8321		/* automatic parse from the BIOS config */
8322		err = alc262_parse_auto_config(codec);
8323		if (err < 0) {
8324			alc_free(codec);
8325			return err;
8326		} else if (!err) {
8327			printk(KERN_INFO
8328			       "hda_codec: Cannot set up configuration "
8329			       "from BIOS.  Using base mode...\n");
8330			board_config = ALC262_BASIC;
8331		}
8332	}
8333
8334	if (board_config != ALC262_AUTO)
8335		setup_preset(spec, &alc262_presets[board_config]);
8336
8337	spec->stream_name_analog = "ALC262 Analog";
8338	spec->stream_analog_playback = &alc262_pcm_analog_playback;
8339	spec->stream_analog_capture = &alc262_pcm_analog_capture;
8340
8341	spec->stream_name_digital = "ALC262 Digital";
8342	spec->stream_digital_playback = &alc262_pcm_digital_playback;
8343	spec->stream_digital_capture = &alc262_pcm_digital_capture;
8344
8345	if (!spec->adc_nids && spec->input_mux) {
8346		/* check whether NID 0x07 is valid */
8347		unsigned int wcap = get_wcaps(codec, 0x07);
8348
8349		/* get type */
8350		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8351		if (wcap != AC_WID_AUD_IN) {
8352			spec->adc_nids = alc262_adc_nids_alt;
8353			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8354			spec->mixers[spec->num_mixers] =
8355				alc262_capture_alt_mixer;
8356			spec->num_mixers++;
8357		} else {
8358			spec->adc_nids = alc262_adc_nids;
8359			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8360			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8361			spec->num_mixers++;
8362		}
8363	}
8364
8365	codec->patch_ops = alc_patch_ops;
8366	if (board_config == ALC262_AUTO)
8367		spec->init_hook = alc262_auto_init;
8368#ifdef CONFIG_SND_HDA_POWER_SAVE
8369	if (!spec->loopback.amplist)
8370		spec->loopback.amplist = alc262_loopbacks;
8371#endif
8372
8373	return 0;
8374}
8375
8376/*
8377 *  ALC268 channel source setting (2 channel)
8378 */
8379#define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID
8380#define alc268_modes		alc260_modes
8381
8382static hda_nid_t alc268_dac_nids[2] = {
8383	/* front, hp */
8384	0x02, 0x03
8385};
8386
8387static hda_nid_t alc268_adc_nids[2] = {
8388	/* ADC0-1 */
8389	0x08, 0x07
8390};
8391
8392static hda_nid_t alc268_adc_nids_alt[1] = {
8393	/* ADC0 */
8394	0x08
8395};
8396
8397static struct snd_kcontrol_new alc268_base_mixer[] = {
8398	/* output mixer control */
8399	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8400	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8401	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8402	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8403	{ }
8404};
8405
8406static struct hda_verb alc268_eapd_verbs[] = {
8407	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8408	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8409	{ }
8410};
8411
8412/* Toshiba specific */
8413#define alc268_toshiba_automute	alc262_hippo_automute
8414
8415static struct hda_verb alc268_toshiba_verbs[] = {
8416	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8417	{ } /* end */
8418};
8419
8420/* Acer specific */
8421/* bind volumes of both NID 0x0c and 0x0d */
8422static struct hda_bind_ctls alc268_acer_bind_master_vol = {
8423	.ops = &snd_hda_bind_vol,
8424	.values = {
8425		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
8426		HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
8427		0
8428	},
8429};
8430
8431#define alc268_acer_master_sw_put	alc262_fujitsu_master_sw_put
8432#define alc268_acer_automute	alc262_fujitsu_automute
8433
8434static struct snd_kcontrol_new alc268_acer_mixer[] = {
8435	/* output mixer control */
8436	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
8437	{
8438		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8439		.name = "Master Playback Switch",
8440		.info = snd_hda_mixer_amp_switch_info,
8441		.get = snd_hda_mixer_amp_switch_get,
8442		.put = alc268_acer_master_sw_put,
8443		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8444	},
8445	{ }
8446};
8447
8448static struct hda_verb alc268_acer_verbs[] = {
8449	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8450	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8451
8452	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8453	{ }
8454};
8455
8456/* unsolicited event for HP jack sensing */
8457static void alc268_toshiba_unsol_event(struct hda_codec *codec,
8458				       unsigned int res)
8459{
8460	if ((res >> 28) != ALC880_HP_EVENT)
8461		return;
8462	alc268_toshiba_automute(codec);
8463}
8464
8465static void alc268_acer_unsol_event(struct hda_codec *codec,
8466				       unsigned int res)
8467{
8468	if ((res >> 28) != ALC880_HP_EVENT)
8469		return;
8470	alc268_acer_automute(codec, 1);
8471}
8472
8473/*
8474 * generic initialization of ADC, input mixers and output mixers
8475 */
8476static struct hda_verb alc268_base_init_verbs[] = {
8477	/* Unmute DAC0-1 and set vol = 0 */
8478	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8479	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8481	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8482	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8483	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8484
8485	/*
8486	 * Set up output mixers (0x0c - 0x0e)
8487	 */
8488	/* set vol=0 to output mixers */
8489	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8490	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8491	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8492        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8493
8494	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8495	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8496
8497	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8498	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8499	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8500	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8501	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8502	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8503	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8504	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8505
8506	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8507	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8508	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8509	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8510	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8511	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8512	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8513	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8514
8515	/* FIXME: use matrix-type input source selection */
8516	/* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8517	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8518	/* Input mixer2 */
8519	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8520	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8521	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8522	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8523
8524	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8525	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8526	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8527	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8528	{ }
8529};
8530
8531/*
8532 * generic initialization of ADC, input mixers and output mixers
8533 */
8534static struct hda_verb alc268_volume_init_verbs[] = {
8535	/* set output DAC */
8536	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8537	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8538	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8539	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8540
8541	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8542	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8543	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8544	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8545	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8546
8547	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8548	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8550	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8551	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8552
8553	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8554	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8555	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8556	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8557
8558	/* set PCBEEP vol = 0 */
8559	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8560
8561	{ }
8562};
8563
8564#define alc268_mux_enum_info alc_mux_enum_info
8565#define alc268_mux_enum_get alc_mux_enum_get
8566
8567static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8568			       struct snd_ctl_elem_value *ucontrol)
8569{
8570	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8571	struct alc_spec *spec = codec->spec;
8572	const struct hda_input_mux *imux = spec->input_mux;
8573	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8574	static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8575	hda_nid_t nid = capture_mixers[adc_idx];
8576	unsigned int *cur_val = &spec->cur_mux[adc_idx];
8577	unsigned int i, idx;
8578
8579	idx = ucontrol->value.enumerated.item[0];
8580	if (idx >= imux->num_items)
8581		idx = imux->num_items - 1;
8582	if (*cur_val == idx)
8583		return 0;
8584	for (i = 0; i < imux->num_items; i++) {
8585		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
8586		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
8587					 imux->items[i].index,
8588					 HDA_AMP_MUTE, v);
8589                snd_hda_codec_write_cache(codec, nid, 0,
8590					  AC_VERB_SET_CONNECT_SEL,
8591					  idx );
8592	}
8593	*cur_val = idx;
8594	return 1;
8595}
8596
8597static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
8598	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8599	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8600	{
8601		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8602		/* The multiple "Capture Source" controls confuse alsamixer
8603		 * So call somewhat different..
8604		 * FIXME: the controls appear in the "playback" view!
8605		 */
8606		/* .name = "Capture Source", */
8607		.name = "Input Source",
8608		.count = 1,
8609		.info = alc268_mux_enum_info,
8610		.get = alc268_mux_enum_get,
8611		.put = alc268_mux_enum_put,
8612	},
8613	{ } /* end */
8614};
8615
8616static struct snd_kcontrol_new alc268_capture_mixer[] = {
8617	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
8618	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
8619	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
8620	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
8621	{
8622		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8623		/* The multiple "Capture Source" controls confuse alsamixer
8624		 * So call somewhat different..
8625		 * FIXME: the controls appear in the "playback" view!
8626		 */
8627		/* .name = "Capture Source", */
8628		.name = "Input Source",
8629		.count = 2,
8630		.info = alc268_mux_enum_info,
8631		.get = alc268_mux_enum_get,
8632		.put = alc268_mux_enum_put,
8633	},
8634	{ } /* end */
8635};
8636
8637static struct hda_input_mux alc268_capture_source = {
8638	.num_items = 4,
8639	.items = {
8640		{ "Mic", 0x0 },
8641		{ "Front Mic", 0x1 },
8642		{ "Line", 0x2 },
8643		{ "CD", 0x3 },
8644	},
8645};
8646
8647/* create input playback/capture controls for the given pin */
8648static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
8649				    const char *ctlname, int idx)
8650{
8651	char name[32];
8652	int err;
8653
8654	sprintf(name, "%s Playback Volume", ctlname);
8655	if (nid == 0x14) {
8656		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8657				  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
8658						      HDA_OUTPUT));
8659		if (err < 0)
8660			return err;
8661	} else if (nid == 0x15) {
8662		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8663				  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
8664						      HDA_OUTPUT));
8665		if (err < 0)
8666			return err;
8667	} else
8668		return -1;
8669	sprintf(name, "%s Playback Switch", ctlname);
8670	err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8671			  HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
8672	if (err < 0)
8673		return err;
8674	return 0;
8675}
8676
8677/* add playback controls from the parsed DAC table */
8678static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
8679					     const struct auto_pin_cfg *cfg)
8680{
8681	hda_nid_t nid;
8682	int err;
8683
8684	spec->multiout.num_dacs = 2;	/* only use one dac */
8685	spec->multiout.dac_nids = spec->private_dac_nids;
8686	spec->multiout.dac_nids[0] = 2;
8687	spec->multiout.dac_nids[1] = 3;
8688
8689	nid = cfg->line_out_pins[0];
8690	if (nid)
8691		alc268_new_analog_output(spec, nid, "Front", 0);
8692
8693	nid = cfg->speaker_pins[0];
8694	if (nid == 0x1d) {
8695		err = add_control(spec, ALC_CTL_WIDGET_VOL,
8696				  "Speaker Playback Volume",
8697				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
8698		if (err < 0)
8699			return err;
8700	}
8701	nid = cfg->hp_pins[0];
8702	if (nid)
8703		alc268_new_analog_output(spec, nid, "Headphone", 0);
8704
8705	nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
8706	if (nid == 0x16) {
8707		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8708				  "Mono Playback Switch",
8709				  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
8710		if (err < 0)
8711			return err;
8712	}
8713	return 0;
8714}
8715
8716/* create playback/capture controls for input pins */
8717static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
8718						const struct auto_pin_cfg *cfg)
8719{
8720	struct hda_input_mux *imux = &spec->private_imux;
8721	int i, idx1;
8722
8723	for (i = 0; i < AUTO_PIN_LAST; i++) {
8724		switch(cfg->input_pins[i]) {
8725		case 0x18:
8726			idx1 = 0;	/* Mic 1 */
8727			break;
8728		case 0x19:
8729			idx1 = 1;	/* Mic 2 */
8730			break;
8731		case 0x1a:
8732			idx1 = 2;	/* Line In */
8733			break;
8734		case 0x1c:
8735			idx1 = 3;	/* CD */
8736			break;
8737		default:
8738			continue;
8739		}
8740		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
8741		imux->items[imux->num_items].index = idx1;
8742		imux->num_items++;
8743	}
8744	return 0;
8745}
8746
8747static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
8748{
8749	struct alc_spec *spec = codec->spec;
8750	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
8751	hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
8752	hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
8753	unsigned int	dac_vol1, dac_vol2;
8754
8755	if (speaker_nid) {
8756		snd_hda_codec_write(codec, speaker_nid, 0,
8757				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
8758		snd_hda_codec_write(codec, 0x0f, 0,
8759				    AC_VERB_SET_AMP_GAIN_MUTE,
8760				    AMP_IN_UNMUTE(1));
8761		snd_hda_codec_write(codec, 0x10, 0,
8762				    AC_VERB_SET_AMP_GAIN_MUTE,
8763				    AMP_IN_UNMUTE(1));
8764	} else {
8765		snd_hda_codec_write(codec, 0x0f, 0,
8766				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8767		snd_hda_codec_write(codec, 0x10, 0,
8768				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
8769	}
8770
8771	dac_vol1 = dac_vol2 = 0xb000 | 0x40;	/* set max volume  */
8772	if (line_nid == 0x14)
8773		dac_vol2 = AMP_OUT_ZERO;
8774	else if (line_nid == 0x15)
8775		dac_vol1 = AMP_OUT_ZERO;
8776	if (hp_nid == 0x14)
8777		dac_vol2 = AMP_OUT_ZERO;
8778	else if (hp_nid == 0x15)
8779		dac_vol1 = AMP_OUT_ZERO;
8780	if (line_nid != 0x16 || hp_nid != 0x16 ||
8781	    spec->autocfg.line_out_pins[1] != 0x16 ||
8782	    spec->autocfg.line_out_pins[2] != 0x16)
8783		dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
8784
8785	snd_hda_codec_write(codec, 0x02, 0,
8786			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
8787	snd_hda_codec_write(codec, 0x03, 0,
8788			    AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
8789}
8790
8791/* pcm configuration: identiacal with ALC880 */
8792#define alc268_pcm_analog_playback	alc880_pcm_analog_playback
8793#define alc268_pcm_analog_capture	alc880_pcm_analog_capture
8794#define alc268_pcm_digital_playback	alc880_pcm_digital_playback
8795
8796/*
8797 * BIOS auto configuration
8798 */
8799static int alc268_parse_auto_config(struct hda_codec *codec)
8800{
8801	struct alc_spec *spec = codec->spec;
8802	int err;
8803	static hda_nid_t alc268_ignore[] = { 0 };
8804
8805	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8806					   alc268_ignore);
8807	if (err < 0)
8808		return err;
8809	if (!spec->autocfg.line_outs)
8810		return 0; /* can't find valid BIOS pin config */
8811
8812	err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
8813	if (err < 0)
8814		return err;
8815	err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
8816	if (err < 0)
8817		return err;
8818
8819	spec->multiout.max_channels = 2;
8820
8821	/* digital only support output */
8822	if (spec->autocfg.dig_out_pin)
8823		spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
8824
8825	if (spec->kctl_alloc)
8826		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8827
8828	spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
8829	spec->num_mux_defs = 1;
8830	spec->input_mux = &spec->private_imux;
8831
8832	return 1;
8833}
8834
8835#define alc268_auto_init_multi_out	alc882_auto_init_multi_out
8836#define alc268_auto_init_hp_out		alc882_auto_init_hp_out
8837#define alc268_auto_init_analog_input	alc882_auto_init_analog_input
8838
8839/* init callback for auto-configuration model -- overriding the default init */
8840static void alc268_auto_init(struct hda_codec *codec)
8841{
8842	alc268_auto_init_multi_out(codec);
8843	alc268_auto_init_hp_out(codec);
8844	alc268_auto_init_mono_speaker_out(codec);
8845	alc268_auto_init_analog_input(codec);
8846}
8847
8848/*
8849 * configuration and preset
8850 */
8851static const char *alc268_models[ALC268_MODEL_LAST] = {
8852	[ALC268_3ST]		= "3stack",
8853	[ALC268_TOSHIBA]	= "toshiba",
8854	[ALC268_ACER]		= "acer",
8855	[ALC268_AUTO]		= "auto",
8856};
8857
8858static struct snd_pci_quirk alc268_cfg_tbl[] = {
8859	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8860	SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8861	SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
8862	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
8863	{}
8864};
8865
8866static struct alc_config_preset alc268_presets[] = {
8867	[ALC268_3ST] = {
8868		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8869		.init_verbs = { alc268_base_init_verbs },
8870		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8871		.dac_nids = alc268_dac_nids,
8872                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8873                .adc_nids = alc268_adc_nids_alt,
8874		.hp_nid = 0x03,
8875		.dig_out_nid = ALC268_DIGOUT_NID,
8876		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8877		.channel_mode = alc268_modes,
8878		.input_mux = &alc268_capture_source,
8879	},
8880	[ALC268_TOSHIBA] = {
8881		.mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
8882		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
8883				alc268_toshiba_verbs },
8884		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8885		.dac_nids = alc268_dac_nids,
8886		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8887		.adc_nids = alc268_adc_nids_alt,
8888		.hp_nid = 0x03,
8889		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8890		.channel_mode = alc268_modes,
8891		.input_mux = &alc268_capture_source,
8892		.input_mux = &alc268_capture_source,
8893		.unsol_event = alc268_toshiba_unsol_event,
8894		.init_hook = alc268_toshiba_automute,
8895	},
8896	[ALC268_ACER] = {
8897		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
8898		.init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
8899				alc268_acer_verbs },
8900		.num_dacs = ARRAY_SIZE(alc268_dac_nids),
8901		.dac_nids = alc268_dac_nids,
8902		.num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
8903		.adc_nids = alc268_adc_nids_alt,
8904		.hp_nid = 0x02,
8905		.num_channel_mode = ARRAY_SIZE(alc268_modes),
8906		.channel_mode = alc268_modes,
8907		.input_mux = &alc268_capture_source,
8908		.unsol_event = alc268_acer_unsol_event,
8909	},
8910};
8911
8912static int patch_alc268(struct hda_codec *codec)
8913{
8914	struct alc_spec *spec;
8915	int board_config;
8916	int err;
8917
8918	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
8919	if (spec == NULL)
8920		return -ENOMEM;
8921
8922	codec->spec = spec;
8923
8924	board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
8925						  alc268_models,
8926						  alc268_cfg_tbl);
8927
8928	if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
8929		printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
8930		       "trying auto-probe from BIOS...\n");
8931		board_config = ALC268_AUTO;
8932	}
8933
8934	if (board_config == ALC268_AUTO) {
8935		/* automatic parse from the BIOS config */
8936		err = alc268_parse_auto_config(codec);
8937		if (err < 0) {
8938			alc_free(codec);
8939			return err;
8940		} else if (!err) {
8941			printk(KERN_INFO
8942			       "hda_codec: Cannot set up configuration "
8943			       "from BIOS.  Using base mode...\n");
8944			board_config = ALC268_3ST;
8945		}
8946	}
8947
8948	if (board_config != ALC268_AUTO)
8949		setup_preset(spec, &alc268_presets[board_config]);
8950
8951	spec->stream_name_analog = "ALC268 Analog";
8952	spec->stream_analog_playback = &alc268_pcm_analog_playback;
8953	spec->stream_analog_capture = &alc268_pcm_analog_capture;
8954
8955	spec->stream_name_digital = "ALC268 Digital";
8956	spec->stream_digital_playback = &alc268_pcm_digital_playback;
8957
8958	if (board_config == ALC268_AUTO) {
8959		if (!spec->adc_nids && spec->input_mux) {
8960			/* check whether NID 0x07 is valid */
8961			unsigned int wcap = get_wcaps(codec, 0x07);
8962
8963			/* get type */
8964			wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8965			if (wcap != AC_WID_AUD_IN) {
8966				spec->adc_nids = alc268_adc_nids_alt;
8967				spec->num_adc_nids =
8968					ARRAY_SIZE(alc268_adc_nids_alt);
8969				spec->mixers[spec->num_mixers] =
8970					alc268_capture_alt_mixer;
8971				spec->num_mixers++;
8972			} else {
8973				spec->adc_nids = alc268_adc_nids;
8974				spec->num_adc_nids =
8975					ARRAY_SIZE(alc268_adc_nids);
8976				spec->mixers[spec->num_mixers] =
8977					alc268_capture_mixer;
8978				spec->num_mixers++;
8979			}
8980		}
8981	}
8982	codec->patch_ops = alc_patch_ops;
8983	if (board_config == ALC268_AUTO)
8984		spec->init_hook = alc268_auto_init;
8985
8986	return 0;
8987}
8988
8989/*
8990 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
8991 */
8992
8993/*
8994 * set the path ways for 2 channel output
8995 * need to set the codec line out and mic 1 pin widgets to inputs
8996 */
8997static struct hda_verb alc861_threestack_ch2_init[] = {
8998	/* set pin widget 1Ah (line in) for input */
8999	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9000	/* set pin widget 18h (mic1/2) for input, for mic also enable
9001	 * the vref
9002	 */
9003	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9004
9005	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9006#if 0
9007	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9008	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9009#endif
9010	{ } /* end */
9011};
9012/*
9013 * 6ch mode
9014 * need to set the codec line out and mic 1 pin widgets to outputs
9015 */
9016static struct hda_verb alc861_threestack_ch6_init[] = {
9017	/* set pin widget 1Ah (line in) for output (Back Surround)*/
9018	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9019	/* set pin widget 18h (mic1) for output (CLFE)*/
9020	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9021
9022	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9023	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9024
9025	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9026#if 0
9027	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9028	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9029#endif
9030	{ } /* end */
9031};
9032
9033static struct hda_channel_mode alc861_threestack_modes[2] = {
9034	{ 2, alc861_threestack_ch2_init },
9035	{ 6, alc861_threestack_ch6_init },
9036};
9037/* Set mic1 as input and unmute the mixer */
9038static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
9039	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9040	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9041	{ } /* end */
9042};
9043/* Set mic1 as output and mute mixer */
9044static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
9045	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9046	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9047	{ } /* end */
9048};
9049
9050static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
9051	{ 2, alc861_uniwill_m31_ch2_init },
9052	{ 4, alc861_uniwill_m31_ch4_init },
9053};
9054
9055/* Set mic1 and line-in as input and unmute the mixer */
9056static struct hda_verb alc861_asus_ch2_init[] = {
9057	/* set pin widget 1Ah (line in) for input */
9058	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9059	/* set pin widget 18h (mic1/2) for input, for mic also enable
9060	 * the vref
9061	 */
9062	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9063
9064	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9065#if 0
9066	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9067	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9068#endif
9069	{ } /* end */
9070};
9071/* Set mic1 nad line-in as output and mute mixer */
9072static struct hda_verb alc861_asus_ch6_init[] = {
9073	/* set pin widget 1Ah (line in) for output (Back Surround)*/
9074	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9075	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9076	/* set pin widget 18h (mic1) for output (CLFE)*/
9077	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9078	/* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9079	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9080	{ 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9081
9082	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9083#if 0
9084	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9085	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9086#endif
9087	{ } /* end */
9088};
9089
9090static struct hda_channel_mode alc861_asus_modes[2] = {
9091	{ 2, alc861_asus_ch2_init },
9092	{ 6, alc861_asus_ch6_init },
9093};
9094
9095/* patch-ALC861 */
9096
9097static struct snd_kcontrol_new alc861_base_mixer[] = {
9098        /* output mixer control */
9099	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9100	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9101	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9102	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9103	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9104
9105        /*Input mixer control */
9106	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9107	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9108	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9109	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9110	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9111	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9112	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9113	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9114	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9115	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9116
9117        /* Capture mixer control */
9118	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9119	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9120	{
9121		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9122		.name = "Capture Source",
9123		.count = 1,
9124		.info = alc_mux_enum_info,
9125		.get = alc_mux_enum_get,
9126		.put = alc_mux_enum_put,
9127	},
9128	{ } /* end */
9129};
9130
9131static struct snd_kcontrol_new alc861_3ST_mixer[] = {
9132        /* output mixer control */
9133	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9134	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9135	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9136	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9137	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9138
9139	/* Input mixer control */
9140	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9141	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9142	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9143	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9144	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9145	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9146	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9147	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9148	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9149	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9150
9151	/* Capture mixer control */
9152	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9153	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9154	{
9155		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9156		.name = "Capture Source",
9157		.count = 1,
9158		.info = alc_mux_enum_info,
9159		.get = alc_mux_enum_get,
9160		.put = alc_mux_enum_put,
9161	},
9162	{
9163		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9164		.name = "Channel Mode",
9165		.info = alc_ch_mode_info,
9166		.get = alc_ch_mode_get,
9167		.put = alc_ch_mode_put,
9168                .private_value = ARRAY_SIZE(alc861_threestack_modes),
9169	},
9170	{ } /* end */
9171};
9172
9173static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
9174        /* output mixer control */
9175	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9176	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9177	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9178
9179        /*Capture mixer control */
9180	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9181	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9182	{
9183		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9184		.name = "Capture Source",
9185		.count = 1,
9186		.info = alc_mux_enum_info,
9187		.get = alc_mux_enum_get,
9188		.put = alc_mux_enum_put,
9189	},
9190
9191	{ } /* end */
9192};
9193
9194static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
9195        /* output mixer control */
9196	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9197	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9198	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9199	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9200	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9201
9202	/* Input mixer control */
9203	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9204	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9205	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9206	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9207	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9208	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9209	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9210	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9211	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9212	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9213
9214	/* Capture mixer control */
9215	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9216	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9217	{
9218		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9219		.name = "Capture Source",
9220		.count = 1,
9221		.info = alc_mux_enum_info,
9222		.get = alc_mux_enum_get,
9223		.put = alc_mux_enum_put,
9224	},
9225	{
9226		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9227		.name = "Channel Mode",
9228		.info = alc_ch_mode_info,
9229		.get = alc_ch_mode_get,
9230		.put = alc_ch_mode_put,
9231                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
9232	},
9233	{ } /* end */
9234};
9235
9236static struct snd_kcontrol_new alc861_asus_mixer[] = {
9237        /* output mixer control */
9238	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9239	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9240	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9241	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9242	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9243
9244	/* Input mixer control */
9245	HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9246	HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9247	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9248	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9249	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9250	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9251	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9252	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9253	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9254	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
9255
9256	/* Capture mixer control */
9257	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9258	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9259	{
9260		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9261		.name = "Capture Source",
9262		.count = 1,
9263		.info = alc_mux_enum_info,
9264		.get = alc_mux_enum_get,
9265		.put = alc_mux_enum_put,
9266	},
9267	{
9268		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9269		.name = "Channel Mode",
9270		.info = alc_ch_mode_info,
9271		.get = alc_ch_mode_get,
9272		.put = alc_ch_mode_put,
9273                .private_value = ARRAY_SIZE(alc861_asus_modes),
9274	},
9275	{ }
9276};
9277
9278/* additional mixer */
9279static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9280	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9281	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9282	HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9283	HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9284	{ }
9285};
9286
9287/*
9288 * generic initialization of ADC, input mixers and output mixers
9289 */
9290static struct hda_verb alc861_base_init_verbs[] = {
9291	/*
9292	 * Unmute ADC0 and set the default input to mic-in
9293	 */
9294	/* port-A for surround (rear panel) */
9295	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9296	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9297	/* port-B for mic-in (rear panel) with vref */
9298	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9299	/* port-C for line-in (rear panel) */
9300	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9301	/* port-D for Front */
9302	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9303	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9304	/* port-E for HP out (front panel) */
9305	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9306	/* route front PCM to HP */
9307	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9308	/* port-F for mic-in (front panel) with vref */
9309	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9310	/* port-G for CLFE (rear panel) */
9311	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9312	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9313	/* port-H for side (rear panel) */
9314	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9315	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9316	/* CD-in */
9317	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9318	/* route front mic to ADC1*/
9319	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9320	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9321
9322	/* Unmute DAC0~3 & spdif out*/
9323	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9324	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9325	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9326	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9327	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9328
9329	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9330	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9331        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9332	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9333        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9334
9335	/* Unmute Stereo Mixer 15 */
9336	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9337	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9338	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9339	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9340
9341	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9342	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9343	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9344	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9345	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9346	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9347	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9348	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9349	/* hp used DAC 3 (Front) */
9350	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9351        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9352
9353	{ }
9354};
9355
9356static struct hda_verb alc861_threestack_init_verbs[] = {
9357	/*
9358	 * Unmute ADC0 and set the default input to mic-in
9359	 */
9360	/* port-A for surround (rear panel) */
9361	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9362	/* port-B for mic-in (rear panel) with vref */
9363	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9364	/* port-C for line-in (rear panel) */
9365	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9366	/* port-D for Front */
9367	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9368	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9369	/* port-E for HP out (front panel) */
9370	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9371	/* route front PCM to HP */
9372	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9373	/* port-F for mic-in (front panel) with vref */
9374	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9375	/* port-G for CLFE (rear panel) */
9376	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9377	/* port-H for side (rear panel) */
9378	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9379	/* CD-in */
9380	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9381	/* route front mic to ADC1*/
9382	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9383	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9384	/* Unmute DAC0~3 & spdif out*/
9385	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9386	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9387	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9388	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9389	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9390
9391	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9392	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9393        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9394	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9395        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9396
9397	/* Unmute Stereo Mixer 15 */
9398	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9399	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9400	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9401	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9402
9403	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9404	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9405	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9406	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9407	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9408	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9409	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9410	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9411	/* hp used DAC 3 (Front) */
9412	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9413        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9414	{ }
9415};
9416
9417static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9418	/*
9419	 * Unmute ADC0 and set the default input to mic-in
9420	 */
9421	/* port-A for surround (rear panel) */
9422	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9423	/* port-B for mic-in (rear panel) with vref */
9424	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9425	/* port-C for line-in (rear panel) */
9426	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9427	/* port-D for Front */
9428	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9429	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9430	/* port-E for HP out (front panel) */
9431	/* this has to be set to VREF80 */
9432	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9433	/* route front PCM to HP */
9434	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9435	/* port-F for mic-in (front panel) with vref */
9436	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9437	/* port-G for CLFE (rear panel) */
9438	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9439	/* port-H for side (rear panel) */
9440	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9441	/* CD-in */
9442	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9443	/* route front mic to ADC1*/
9444	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9445	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9446	/* Unmute DAC0~3 & spdif out*/
9447	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9448	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9449	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9450	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9451	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9452
9453	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9454	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9455        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9456	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9457        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9458
9459	/* Unmute Stereo Mixer 15 */
9460	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9461	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9462	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9463	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9464
9465	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9466	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9467	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9468	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9469	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9470	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9471	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9472	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9473	/* hp used DAC 3 (Front) */
9474	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9475        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9476	{ }
9477};
9478
9479static struct hda_verb alc861_asus_init_verbs[] = {
9480	/*
9481	 * Unmute ADC0 and set the default input to mic-in
9482	 */
9483	/* port-A for surround (rear panel)
9484	 * according to codec#0 this is the HP jack
9485	 */
9486	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9487	/* route front PCM to HP */
9488	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9489	/* port-B for mic-in (rear panel) with vref */
9490	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9491	/* port-C for line-in (rear panel) */
9492	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9493	/* port-D for Front */
9494	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9495	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9496	/* port-E for HP out (front panel) */
9497	/* this has to be set to VREF80 */
9498	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9499	/* route front PCM to HP */
9500	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9501	/* port-F for mic-in (front panel) with vref */
9502	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9503	/* port-G for CLFE (rear panel) */
9504	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9505	/* port-H for side (rear panel) */
9506	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9507	/* CD-in */
9508	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9509	/* route front mic to ADC1*/
9510	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9511	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9512	/* Unmute DAC0~3 & spdif out*/
9513	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9514	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9515	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9516	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9517	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9518	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9519	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9520        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9521	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9522        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9523
9524	/* Unmute Stereo Mixer 15 */
9525	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9526	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9527	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9528	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9529
9530	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9531	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9532	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9533	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9534	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9535	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9536	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9537	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9538	/* hp used DAC 3 (Front) */
9539	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9540	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9541	{ }
9542};
9543
9544/* additional init verbs for ASUS laptops */
9545static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9546	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9547	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9548	{ }
9549};
9550
9551/*
9552 * generic initialization of ADC, input mixers and output mixers
9553 */
9554static struct hda_verb alc861_auto_init_verbs[] = {
9555	/*
9556	 * Unmute ADC0 and set the default input to mic-in
9557	 */
9558	/* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9559	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9560
9561	/* Unmute DAC0~3 & spdif out*/
9562	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9563	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9564	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9565	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9566	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9567
9568	/* Unmute Mixer 14 (mic) 1c (Line in)*/
9569	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9570	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9571	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9572	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9573
9574	/* Unmute Stereo Mixer 15 */
9575	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9576	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9577	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9578	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9579
9580	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9581	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9582	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9583	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9584	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9585	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9586	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9587	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9588
9589	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9590	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9591	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9592	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9593	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9594	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9595	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9596	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9597
9598	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	/* set Mic 1 */
9599
9600	{ }
9601};
9602
9603static struct hda_verb alc861_toshiba_init_verbs[] = {
9604	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9605
9606	{ }
9607};
9608
9609/* toggle speaker-output according to the hp-jack state */
9610static void alc861_toshiba_automute(struct hda_codec *codec)
9611{
9612	unsigned int present;
9613
9614	present = snd_hda_codec_read(codec, 0x0f, 0,
9615				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9616	snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
9617				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9618	snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
9619				 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
9620}
9621
9622static void alc861_toshiba_unsol_event(struct hda_codec *codec,
9623				       unsigned int res)
9624{
9625	if ((res >> 26) == ALC880_HP_EVENT)
9626		alc861_toshiba_automute(codec);
9627}
9628
9629/* pcm configuration: identiacal with ALC880 */
9630#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
9631#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
9632#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
9633#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
9634
9635
9636#define ALC861_DIGOUT_NID	0x07
9637
9638static struct hda_channel_mode alc861_8ch_modes[1] = {
9639	{ 8, NULL }
9640};
9641
9642static hda_nid_t alc861_dac_nids[4] = {
9643	/* front, surround, clfe, side */
9644	0x03, 0x06, 0x05, 0x04
9645};
9646
9647static hda_nid_t alc660_dac_nids[3] = {
9648	/* front, clfe, surround */
9649	0x03, 0x05, 0x06
9650};
9651
9652static hda_nid_t alc861_adc_nids[1] = {
9653	/* ADC0-2 */
9654	0x08,
9655};
9656
9657static struct hda_input_mux alc861_capture_source = {
9658	.num_items = 5,
9659	.items = {
9660		{ "Mic", 0x0 },
9661		{ "Front Mic", 0x3 },
9662		{ "Line", 0x1 },
9663		{ "CD", 0x4 },
9664		{ "Mixer", 0x5 },
9665	},
9666};
9667
9668/* fill in the dac_nids table from the parsed pin configuration */
9669static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
9670				     const struct auto_pin_cfg *cfg)
9671{
9672	int i;
9673	hda_nid_t nid;
9674
9675	spec->multiout.dac_nids = spec->private_dac_nids;
9676	for (i = 0; i < cfg->line_outs; i++) {
9677		nid = cfg->line_out_pins[i];
9678		if (nid) {
9679			if (i >= ARRAY_SIZE(alc861_dac_nids))
9680				continue;
9681			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
9682		}
9683	}
9684	spec->multiout.num_dacs = cfg->line_outs;
9685	return 0;
9686}
9687
9688/* add playback controls from the parsed DAC table */
9689static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
9690					     const struct auto_pin_cfg *cfg)
9691{
9692	char name[32];
9693	static const char *chname[4] = {
9694		"Front", "Surround", NULL /*CLFE*/, "Side"
9695	};
9696	hda_nid_t nid;
9697	int i, idx, err;
9698
9699	for (i = 0; i < cfg->line_outs; i++) {
9700		nid = spec->multiout.dac_nids[i];
9701		if (!nid)
9702			continue;
9703		if (nid == 0x05) {
9704			/* Center/LFE */
9705			err = add_control(spec, ALC_CTL_BIND_MUTE,
9706					  "Center Playback Switch",
9707					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
9708							      HDA_OUTPUT));
9709			if (err < 0)
9710				return err;
9711			err = add_control(spec, ALC_CTL_BIND_MUTE,
9712					  "LFE Playback Switch",
9713					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9714							      HDA_OUTPUT));
9715			if (err < 0)
9716				return err;
9717		} else {
9718			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
9719			     idx++)
9720				if (nid == alc861_dac_nids[idx])
9721					break;
9722			sprintf(name, "%s Playback Switch", chname[idx]);
9723			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
9724					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9725							      HDA_OUTPUT));
9726			if (err < 0)
9727				return err;
9728		}
9729	}
9730	return 0;
9731}
9732
9733static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
9734{
9735	int err;
9736	hda_nid_t nid;
9737
9738	if (!pin)
9739		return 0;
9740
9741	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
9742		nid = 0x03;
9743		err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9744				  "Headphone Playback Switch",
9745				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9746		if (err < 0)
9747			return err;
9748		spec->multiout.hp_nid = nid;
9749	}
9750	return 0;
9751}
9752
9753/* create playback/capture controls for input pins */
9754static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
9755						const struct auto_pin_cfg *cfg)
9756{
9757	struct hda_input_mux *imux = &spec->private_imux;
9758	int i, err, idx, idx1;
9759
9760	for (i = 0; i < AUTO_PIN_LAST; i++) {
9761		switch (cfg->input_pins[i]) {
9762		case 0x0c:
9763			idx1 = 1;
9764			idx = 2;	/* Line In */
9765			break;
9766		case 0x0f:
9767			idx1 = 2;
9768			idx = 2;	/* Line In */
9769			break;
9770		case 0x0d:
9771			idx1 = 0;
9772			idx = 1;	/* Mic In */
9773			break;
9774		case 0x10:
9775			idx1 = 3;
9776			idx = 1;	/* Mic In */
9777			break;
9778		case 0x11:
9779			idx1 = 4;
9780			idx = 0;	/* CD */
9781			break;
9782		default:
9783			continue;
9784		}
9785
9786		err = new_analog_input(spec, cfg->input_pins[i],
9787				       auto_pin_cfg_labels[i], idx, 0x15);
9788		if (err < 0)
9789			return err;
9790
9791		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9792		imux->items[imux->num_items].index = idx1;
9793		imux->num_items++;
9794	}
9795	return 0;
9796}
9797
9798static struct snd_kcontrol_new alc861_capture_mixer[] = {
9799	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9800	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9801
9802	{
9803		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9804		/* The multiple "Capture Source" controls confuse alsamixer
9805		 * So call somewhat different..
9806		 *FIXME: the controls appear in the "playback" view!
9807		 */
9808		/* .name = "Capture Source", */
9809		.name = "Input Source",
9810		.count = 1,
9811		.info = alc_mux_enum_info,
9812		.get = alc_mux_enum_get,
9813		.put = alc_mux_enum_put,
9814	},
9815	{ } /* end */
9816};
9817
9818static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
9819					      hda_nid_t nid,
9820					      int pin_type, int dac_idx)
9821{
9822	/* set as output */
9823
9824	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
9825			    pin_type);
9826	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
9827			    AMP_OUT_UNMUTE);
9828
9829}
9830
9831static void alc861_auto_init_multi_out(struct hda_codec *codec)
9832{
9833	struct alc_spec *spec = codec->spec;
9834	int i;
9835
9836	alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
9837	for (i = 0; i < spec->autocfg.line_outs; i++) {
9838		hda_nid_t nid = spec->autocfg.line_out_pins[i];
9839		int pin_type = get_pin_type(spec->autocfg.line_out_type);
9840		if (nid)
9841			alc861_auto_set_output_and_unmute(codec, nid, pin_type,
9842							  spec->multiout.dac_nids[i]);
9843	}
9844}
9845
9846static void alc861_auto_init_hp_out(struct hda_codec *codec)
9847{
9848	struct alc_spec *spec = codec->spec;
9849	hda_nid_t pin;
9850
9851	pin = spec->autocfg.hp_pins[0];
9852	if (pin) /* connect to front */
9853		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
9854						  spec->multiout.dac_nids[0]);
9855}
9856
9857static void alc861_auto_init_analog_input(struct hda_codec *codec)
9858{
9859	struct alc_spec *spec = codec->spec;
9860	int i;
9861
9862	for (i = 0; i < AUTO_PIN_LAST; i++) {
9863		hda_nid_t nid = spec->autocfg.input_pins[i];
9864		if (nid >= 0x0c && nid <= 0x11) {
9865			snd_hda_codec_write(codec, nid, 0,
9866					    AC_VERB_SET_PIN_WIDGET_CONTROL,
9867					    i <= AUTO_PIN_FRONT_MIC ?
9868					    PIN_VREF80 : PIN_IN);
9869		}
9870	}
9871}
9872
9873/* parse the BIOS configuration and set up the alc_spec */
9874/* return 1 if successful, 0 if the proper config is not found,
9875 * or a negative error code
9876 */
9877static int alc861_parse_auto_config(struct hda_codec *codec)
9878{
9879	struct alc_spec *spec = codec->spec;
9880	int err;
9881	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
9882
9883	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9884					   alc861_ignore);
9885	if (err < 0)
9886		return err;
9887	if (!spec->autocfg.line_outs)
9888		return 0; /* can't find valid BIOS pin config */
9889
9890	err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
9891	if (err < 0)
9892		return err;
9893	err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
9894	if (err < 0)
9895		return err;
9896	err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
9897	if (err < 0)
9898		return err;
9899	err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
9900	if (err < 0)
9901		return err;
9902
9903	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9904
9905	if (spec->autocfg.dig_out_pin)
9906		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
9907
9908	if (spec->kctl_alloc)
9909		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9910
9911	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
9912
9913	spec->num_mux_defs = 1;
9914	spec->input_mux = &spec->private_imux;
9915
9916	spec->adc_nids = alc861_adc_nids;
9917	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
9918	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
9919	spec->num_mixers++;
9920
9921	return 1;
9922}
9923
9924/* additional initialization for auto-configuration model */
9925static void alc861_auto_init(struct hda_codec *codec)
9926{
9927	alc861_auto_init_multi_out(codec);
9928	alc861_auto_init_hp_out(codec);
9929	alc861_auto_init_analog_input(codec);
9930}
9931
9932#ifdef CONFIG_SND_HDA_POWER_SAVE
9933static struct hda_amp_list alc861_loopbacks[] = {
9934	{ 0x15, HDA_INPUT, 0 },
9935	{ 0x15, HDA_INPUT, 1 },
9936	{ 0x15, HDA_INPUT, 2 },
9937	{ 0x15, HDA_INPUT, 3 },
9938	{ } /* end */
9939};
9940#endif
9941
9942
9943/*
9944 * configuration and preset
9945 */
9946static const char *alc861_models[ALC861_MODEL_LAST] = {
9947	[ALC861_3ST]		= "3stack",
9948	[ALC660_3ST]		= "3stack-660",
9949	[ALC861_3ST_DIG]	= "3stack-dig",
9950	[ALC861_6ST_DIG]	= "6stack-dig",
9951	[ALC861_UNIWILL_M31]	= "uniwill-m31",
9952	[ALC861_TOSHIBA]	= "toshiba",
9953	[ALC861_ASUS]		= "asus",
9954	[ALC861_ASUS_LAPTOP]	= "asus-laptop",
9955	[ALC861_AUTO]		= "auto",
9956};
9957
9958static struct snd_pci_quirk alc861_cfg_tbl[] = {
9959	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
9960	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9961	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
9962	SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
9963	SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
9964	SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
9965	SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
9966	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
9967	/* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9968	 *        Any other models that need this preset?
9969	 */
9970	/* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9971	SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
9972	SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
9973	SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
9974	SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
9975	SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
9976	SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
9977	SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
9978	{}
9979};
9980
9981static struct alc_config_preset alc861_presets[] = {
9982	[ALC861_3ST] = {
9983		.mixers = { alc861_3ST_mixer },
9984		.init_verbs = { alc861_threestack_init_verbs },
9985		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9986		.dac_nids = alc861_dac_nids,
9987		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
9988		.channel_mode = alc861_threestack_modes,
9989		.need_dac_fix = 1,
9990		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
9991		.adc_nids = alc861_adc_nids,
9992		.input_mux = &alc861_capture_source,
9993	},
9994	[ALC861_3ST_DIG] = {
9995		.mixers = { alc861_base_mixer },
9996		.init_verbs = { alc861_threestack_init_verbs },
9997		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
9998		.dac_nids = alc861_dac_nids,
9999		.dig_out_nid = ALC861_DIGOUT_NID,
10000		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10001		.channel_mode = alc861_threestack_modes,
10002		.need_dac_fix = 1,
10003		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10004		.adc_nids = alc861_adc_nids,
10005		.input_mux = &alc861_capture_source,
10006	},
10007	[ALC861_6ST_DIG] = {
10008		.mixers = { alc861_base_mixer },
10009		.init_verbs = { alc861_base_init_verbs },
10010		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10011		.dac_nids = alc861_dac_nids,
10012		.dig_out_nid = ALC861_DIGOUT_NID,
10013		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
10014		.channel_mode = alc861_8ch_modes,
10015		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10016		.adc_nids = alc861_adc_nids,
10017		.input_mux = &alc861_capture_source,
10018	},
10019	[ALC660_3ST] = {
10020		.mixers = { alc861_3ST_mixer },
10021		.init_verbs = { alc861_threestack_init_verbs },
10022		.num_dacs = ARRAY_SIZE(alc660_dac_nids),
10023		.dac_nids = alc660_dac_nids,
10024		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10025		.channel_mode = alc861_threestack_modes,
10026		.need_dac_fix = 1,
10027		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10028		.adc_nids = alc861_adc_nids,
10029		.input_mux = &alc861_capture_source,
10030	},
10031	[ALC861_UNIWILL_M31] = {
10032		.mixers = { alc861_uniwill_m31_mixer },
10033		.init_verbs = { alc861_uniwill_m31_init_verbs },
10034		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10035		.dac_nids = alc861_dac_nids,
10036		.dig_out_nid = ALC861_DIGOUT_NID,
10037		.num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
10038		.channel_mode = alc861_uniwill_m31_modes,
10039		.need_dac_fix = 1,
10040		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10041		.adc_nids = alc861_adc_nids,
10042		.input_mux = &alc861_capture_source,
10043	},
10044	[ALC861_TOSHIBA] = {
10045		.mixers = { alc861_toshiba_mixer },
10046		.init_verbs = { alc861_base_init_verbs,
10047				alc861_toshiba_init_verbs },
10048		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10049		.dac_nids = alc861_dac_nids,
10050		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10051		.channel_mode = alc883_3ST_2ch_modes,
10052		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10053		.adc_nids = alc861_adc_nids,
10054		.input_mux = &alc861_capture_source,
10055		.unsol_event = alc861_toshiba_unsol_event,
10056		.init_hook = alc861_toshiba_automute,
10057	},
10058	[ALC861_ASUS] = {
10059		.mixers = { alc861_asus_mixer },
10060		.init_verbs = { alc861_asus_init_verbs },
10061		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10062		.dac_nids = alc861_dac_nids,
10063		.dig_out_nid = ALC861_DIGOUT_NID,
10064		.num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
10065		.channel_mode = alc861_asus_modes,
10066		.need_dac_fix = 1,
10067		.hp_nid = 0x06,
10068		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10069		.adc_nids = alc861_adc_nids,
10070		.input_mux = &alc861_capture_source,
10071	},
10072	[ALC861_ASUS_LAPTOP] = {
10073		.mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
10074		.init_verbs = { alc861_asus_init_verbs,
10075				alc861_asus_laptop_init_verbs },
10076		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
10077		.dac_nids = alc861_dac_nids,
10078		.dig_out_nid = ALC861_DIGOUT_NID,
10079		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10080		.channel_mode = alc883_3ST_2ch_modes,
10081		.need_dac_fix = 1,
10082		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10083		.adc_nids = alc861_adc_nids,
10084		.input_mux = &alc861_capture_source,
10085	},
10086};
10087
10088
10089static int patch_alc861(struct hda_codec *codec)
10090{
10091	struct alc_spec *spec;
10092	int board_config;
10093	int err;
10094
10095	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10096	if (spec == NULL)
10097		return -ENOMEM;
10098
10099	codec->spec = spec;
10100
10101        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
10102						  alc861_models,
10103						  alc861_cfg_tbl);
10104
10105	if (board_config < 0) {
10106		printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
10107		       "trying auto-probe from BIOS...\n");
10108		board_config = ALC861_AUTO;
10109	}
10110
10111	if (board_config == ALC861_AUTO) {
10112		/* automatic parse from the BIOS config */
10113		err = alc861_parse_auto_config(codec);
10114		if (err < 0) {
10115			alc_free(codec);
10116			return err;
10117		} else if (!err) {
10118			printk(KERN_INFO
10119			       "hda_codec: Cannot set up configuration "
10120			       "from BIOS.  Using base mode...\n");
10121		   board_config = ALC861_3ST_DIG;
10122		}
10123	}
10124
10125	if (board_config != ALC861_AUTO)
10126		setup_preset(spec, &alc861_presets[board_config]);
10127
10128	spec->stream_name_analog = "ALC861 Analog";
10129	spec->stream_analog_playback = &alc861_pcm_analog_playback;
10130	spec->stream_analog_capture = &alc861_pcm_analog_capture;
10131
10132	spec->stream_name_digital = "ALC861 Digital";
10133	spec->stream_digital_playback = &alc861_pcm_digital_playback;
10134	spec->stream_digital_capture = &alc861_pcm_digital_capture;
10135
10136	codec->patch_ops = alc_patch_ops;
10137	if (board_config == ALC861_AUTO)
10138		spec->init_hook = alc861_auto_init;
10139#ifdef CONFIG_SND_HDA_POWER_SAVE
10140	if (!spec->loopback.amplist)
10141		spec->loopback.amplist = alc861_loopbacks;
10142#endif
10143
10144	return 0;
10145}
10146
10147/*
10148 * ALC861-VD support
10149 *
10150 * Based on ALC882
10151 *
10152 * In addition, an independent DAC
10153 */
10154#define ALC861VD_DIGOUT_NID	0x06
10155
10156static hda_nid_t alc861vd_dac_nids[4] = {
10157	/* front, surr, clfe, side surr */
10158	0x02, 0x03, 0x04, 0x05
10159};
10160
10161/* dac_nids for ALC660vd are in a different order - according to
10162 * Realtek's driver.
10163 * This should probably tesult in a different mixer for 6stack models
10164 * of ALC660vd codecs, but for now there is only 3stack mixer
10165 * - and it is the same as in 861vd.
10166 * adc_nids in ALC660vd are (is) the same as in 861vd
10167 */
10168static hda_nid_t alc660vd_dac_nids[3] = {
10169	/* front, rear, clfe, rear_surr */
10170	0x02, 0x04, 0x03
10171};
10172
10173static hda_nid_t alc861vd_adc_nids[1] = {
10174	/* ADC0 */
10175	0x09,
10176};
10177
10178/* input MUX */
10179/* FIXME: should be a matrix-type input source selection */
10180static struct hda_input_mux alc861vd_capture_source = {
10181	.num_items = 4,
10182	.items = {
10183		{ "Mic", 0x0 },
10184		{ "Front Mic", 0x1 },
10185		{ "Line", 0x2 },
10186		{ "CD", 0x4 },
10187	},
10188};
10189
10190static struct hda_input_mux alc861vd_dallas_capture_source = {
10191	.num_items = 3,
10192	.items = {
10193		{ "Front Mic", 0x0 },
10194		{ "ATAPI Mic", 0x1 },
10195		{ "Line In", 0x5 },
10196	},
10197};
10198
10199static struct hda_input_mux alc861vd_hp_capture_source = {
10200	.num_items = 2,
10201	.items = {
10202		{ "Front Mic", 0x0 },
10203		{ "ATAPI Mic", 0x1 },
10204	},
10205};
10206
10207#define alc861vd_mux_enum_info alc_mux_enum_info
10208#define alc861vd_mux_enum_get alc_mux_enum_get
10209
10210static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
10211				struct snd_ctl_elem_value *ucontrol)
10212{
10213	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10214	struct alc_spec *spec = codec->spec;
10215	const struct hda_input_mux *imux = spec->input_mux;
10216	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10217	static hda_nid_t capture_mixers[1] = { 0x22 };
10218	hda_nid_t nid = capture_mixers[adc_idx];
10219	unsigned int *cur_val = &spec->cur_mux[adc_idx];
10220	unsigned int i, idx;
10221
10222	idx = ucontrol->value.enumerated.item[0];
10223	if (idx >= imux->num_items)
10224		idx = imux->num_items - 1;
10225	if (*cur_val == idx)
10226		return 0;
10227	for (i = 0; i < imux->num_items; i++) {
10228		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10229		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10230					 imux->items[i].index,
10231					 HDA_AMP_MUTE, v);
10232	}
10233	*cur_val = idx;
10234	return 1;
10235}
10236
10237/*
10238 * 2ch mode
10239 */
10240static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
10241	{ 2, NULL }
10242};
10243
10244/*
10245 * 6ch mode
10246 */
10247static struct hda_verb alc861vd_6stack_ch6_init[] = {
10248	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10249	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10250	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10251	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10252	{ } /* end */
10253};
10254
10255/*
10256 * 8ch mode
10257 */
10258static struct hda_verb alc861vd_6stack_ch8_init[] = {
10259	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10260	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10261	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10262	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10263	{ } /* end */
10264};
10265
10266static struct hda_channel_mode alc861vd_6stack_modes[2] = {
10267	{ 6, alc861vd_6stack_ch6_init },
10268	{ 8, alc861vd_6stack_ch8_init },
10269};
10270
10271static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
10272	{
10273		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10274		.name = "Channel Mode",
10275		.info = alc_ch_mode_info,
10276		.get = alc_ch_mode_get,
10277		.put = alc_ch_mode_put,
10278	},
10279	{ } /* end */
10280};
10281
10282static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
10283	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10284	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10285
10286	{
10287		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10288		/* The multiple "Capture Source" controls confuse alsamixer
10289		 * So call somewhat different..
10290		 *FIXME: the controls appear in the "playback" view!
10291		 */
10292		/* .name = "Capture Source", */
10293		.name = "Input Source",
10294		.count = 1,
10295		.info = alc861vd_mux_enum_info,
10296		.get = alc861vd_mux_enum_get,
10297		.put = alc861vd_mux_enum_put,
10298	},
10299	{ } /* end */
10300};
10301
10302/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10303 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10304 */
10305static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10306	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10307	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10308
10309	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10310	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10311
10312	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10313				HDA_OUTPUT),
10314	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10315				HDA_OUTPUT),
10316	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10317	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10318
10319	HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10320	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10321
10322	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10323
10324	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10325	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10326	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10327
10328	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10329	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10330	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10331
10332	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10333	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10334
10335	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10336	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10337
10338	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10339	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10340
10341	{ } /* end */
10342};
10343
10344static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10345	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10346	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10347
10348	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10349
10350	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10351	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10352	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10353
10354	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10355	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10356	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10357
10358	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10359	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10360
10361	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10362	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10363
10364	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10365	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10366
10367	{ } /* end */
10368};
10369
10370static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10371	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10372	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10373	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10374
10375	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10376
10377	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10378	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10379	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10380
10381	HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10382	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10383	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10384
10385	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10386	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10387
10388	{ } /* end */
10389};
10390
10391/* Pin assignment: Front=0x14, HP = 0x15,
10392 *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10393 */
10394static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10395	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10396	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10397	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10398	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10399	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10400	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10401	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10402	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10403	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10404	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10405	{ } /* end */
10406};
10407
10408/* Pin assignment: Speaker=0x14, Line-out = 0x15,
10409 *                 Front Mic=0x18, ATAPI Mic = 0x19,
10410 */
10411static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
10412	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10413	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10414	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10415	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10416	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10417	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10418	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10419	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10420
10421	{ } /* end */
10422};
10423
10424/*
10425 * generic initialization of ADC, input mixers and output mixers
10426 */
10427static struct hda_verb alc861vd_volume_init_verbs[] = {
10428	/*
10429	 * Unmute ADC0 and set the default input to mic-in
10430	 */
10431	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10432	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10433
10434	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10435	 * the analog-loopback mixer widget
10436	 */
10437	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10438	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10439	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10440	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10441	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10442	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10443
10444	/* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10445	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10446	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10447	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10448	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10449
10450	/*
10451	 * Set up output mixers (0x02 - 0x05)
10452	 */
10453	/* set vol=0 to output mixers */
10454	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10455	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10456	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10457	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10458
10459	/* set up input amps for analog loopback */
10460	/* Amp Indices: DAC = 0, mixer = 1 */
10461	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10462	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10463	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10464	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10465	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10466	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10467	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10468	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10469
10470	{ }
10471};
10472
10473/*
10474 * 3-stack pin configuration:
10475 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10476 */
10477static struct hda_verb alc861vd_3stack_init_verbs[] = {
10478	/*
10479	 * Set pin mode and muting
10480	 */
10481	/* set front pin widgets 0x14 for output */
10482	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10483	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10484	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10485
10486	/* Mic (rear) pin: input vref at 80% */
10487	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10488	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10489	/* Front Mic pin: input vref at 80% */
10490	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10491	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10492	/* Line In pin: input */
10493	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10494	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10495	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10496	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10497	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10498	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10499	/* CD pin widget for input */
10500	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10501
10502	{ }
10503};
10504
10505/*
10506 * 6-stack pin configuration:
10507 */
10508static struct hda_verb alc861vd_6stack_init_verbs[] = {
10509	/*
10510	 * Set pin mode and muting
10511	 */
10512	/* set front pin widgets 0x14 for output */
10513	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10514	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10515	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10516
10517	/* Rear Pin: output 1 (0x0d) */
10518	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10519	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10520	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10521	/* CLFE Pin: output 2 (0x0e) */
10522	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10523	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10524	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10525	/* Side Pin: output 3 (0x0f) */
10526	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10527	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10528	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10529
10530	/* Mic (rear) pin: input vref at 80% */
10531	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10532	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10533	/* Front Mic pin: input vref at 80% */
10534	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10535	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10536	/* Line In pin: input */
10537	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10538	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10539	/* Line-2 In: Headphone output (output 0 - 0x0c) */
10540	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10541	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10542	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10543	/* CD pin widget for input */
10544	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10545
10546	{ }
10547};
10548
10549static struct hda_verb alc861vd_eapd_verbs[] = {
10550	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10551	{ }
10552};
10553
10554static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10555	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10556	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10558	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10559	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10560	{}
10561};
10562
10563/* toggle speaker-output according to the hp-jack state */
10564static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10565{
10566	unsigned int present;
10567	unsigned char bits;
10568
10569	present = snd_hda_codec_read(codec, 0x1b, 0,
10570				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10571	bits = present ? HDA_AMP_MUTE : 0;
10572	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10573				 HDA_AMP_MUTE, bits);
10574}
10575
10576static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10577{
10578	unsigned int present;
10579	unsigned char bits;
10580
10581	present = snd_hda_codec_read(codec, 0x18, 0,
10582				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10583	bits = present ? HDA_AMP_MUTE : 0;
10584	snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
10585				 HDA_AMP_MUTE, bits);
10586}
10587
10588static void alc861vd_lenovo_automute(struct hda_codec *codec)
10589{
10590	alc861vd_lenovo_hp_automute(codec);
10591	alc861vd_lenovo_mic_automute(codec);
10592}
10593
10594static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
10595					unsigned int res)
10596{
10597	switch (res >> 26) {
10598	case ALC880_HP_EVENT:
10599		alc861vd_lenovo_hp_automute(codec);
10600		break;
10601	case ALC880_MIC_EVENT:
10602		alc861vd_lenovo_mic_automute(codec);
10603		break;
10604	}
10605}
10606
10607static struct hda_verb alc861vd_dallas_verbs[] = {
10608	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10609	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10610	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10611	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10612
10613	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10614	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10615	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10616	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10617	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10618	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10619	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10620	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10621
10622	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10623	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10624	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10625	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10626	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10627	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10628	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10629	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10630
10631	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10632	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10633	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10634	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10635	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10636	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10637	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10638	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10639
10640	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10641	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10642	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10643	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10644
10645	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10646	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10647	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10648
10649	{ } /* end */
10650};
10651
10652/* toggle speaker-output according to the hp-jack state */
10653static void alc861vd_dallas_automute(struct hda_codec *codec)
10654{
10655	unsigned int present;
10656
10657	present = snd_hda_codec_read(codec, 0x15, 0,
10658				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10659	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10660				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10661}
10662
10663static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
10664{
10665	if ((res >> 26) == ALC880_HP_EVENT)
10666		alc861vd_dallas_automute(codec);
10667}
10668
10669#ifdef CONFIG_SND_HDA_POWER_SAVE
10670#define alc861vd_loopbacks	alc880_loopbacks
10671#endif
10672
10673/* pcm configuration: identiacal with ALC880 */
10674#define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
10675#define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
10676#define alc861vd_pcm_digital_playback	alc880_pcm_digital_playback
10677#define alc861vd_pcm_digital_capture	alc880_pcm_digital_capture
10678
10679/*
10680 * configuration and preset
10681 */
10682static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
10683	[ALC660VD_3ST]		= "3stack-660",
10684	[ALC660VD_3ST_DIG]	= "3stack-660-digout",
10685	[ALC861VD_3ST]		= "3stack",
10686	[ALC861VD_3ST_DIG]	= "3stack-digout",
10687	[ALC861VD_6ST_DIG]	= "6stack-digout",
10688	[ALC861VD_LENOVO]	= "lenovo",
10689	[ALC861VD_DALLAS]	= "dallas",
10690	[ALC861VD_HP]		= "hp",
10691	[ALC861VD_AUTO]		= "auto",
10692};
10693
10694static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
10695	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
10696	SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
10697	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
10698	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
10699	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
10700
10701	/*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
10702	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
10703	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
10704	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
10705	SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
10706	SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
10707	SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
10708	SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
10709	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
10710	{}
10711};
10712
10713static struct alc_config_preset alc861vd_presets[] = {
10714	[ALC660VD_3ST] = {
10715		.mixers = { alc861vd_3st_mixer },
10716		.init_verbs = { alc861vd_volume_init_verbs,
10717				 alc861vd_3stack_init_verbs },
10718		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10719		.dac_nids = alc660vd_dac_nids,
10720		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10721		.adc_nids = alc861vd_adc_nids,
10722		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10723		.channel_mode = alc861vd_3stack_2ch_modes,
10724		.input_mux = &alc861vd_capture_source,
10725	},
10726	[ALC660VD_3ST_DIG] = {
10727		.mixers = { alc861vd_3st_mixer },
10728		.init_verbs = { alc861vd_volume_init_verbs,
10729				 alc861vd_3stack_init_verbs },
10730		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10731		.dac_nids = alc660vd_dac_nids,
10732		.dig_out_nid = ALC861VD_DIGOUT_NID,
10733		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10734		.adc_nids = alc861vd_adc_nids,
10735		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10736		.channel_mode = alc861vd_3stack_2ch_modes,
10737		.input_mux = &alc861vd_capture_source,
10738	},
10739	[ALC861VD_3ST] = {
10740		.mixers = { alc861vd_3st_mixer },
10741		.init_verbs = { alc861vd_volume_init_verbs,
10742				 alc861vd_3stack_init_verbs },
10743		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10744		.dac_nids = alc861vd_dac_nids,
10745		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10746		.channel_mode = alc861vd_3stack_2ch_modes,
10747		.input_mux = &alc861vd_capture_source,
10748	},
10749	[ALC861VD_3ST_DIG] = {
10750		.mixers = { alc861vd_3st_mixer },
10751		.init_verbs = { alc861vd_volume_init_verbs,
10752		 		 alc861vd_3stack_init_verbs },
10753		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10754		.dac_nids = alc861vd_dac_nids,
10755		.dig_out_nid = ALC861VD_DIGOUT_NID,
10756		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10757		.channel_mode = alc861vd_3stack_2ch_modes,
10758		.input_mux = &alc861vd_capture_source,
10759	},
10760	[ALC861VD_6ST_DIG] = {
10761		.mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
10762		.init_verbs = { alc861vd_volume_init_verbs,
10763				alc861vd_6stack_init_verbs },
10764		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10765		.dac_nids = alc861vd_dac_nids,
10766		.dig_out_nid = ALC861VD_DIGOUT_NID,
10767		.num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
10768		.channel_mode = alc861vd_6stack_modes,
10769		.input_mux = &alc861vd_capture_source,
10770	},
10771	[ALC861VD_LENOVO] = {
10772		.mixers = { alc861vd_lenovo_mixer },
10773		.init_verbs = { alc861vd_volume_init_verbs,
10774				alc861vd_3stack_init_verbs,
10775				alc861vd_eapd_verbs,
10776				alc861vd_lenovo_unsol_verbs },
10777		.num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
10778		.dac_nids = alc660vd_dac_nids,
10779		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10780		.adc_nids = alc861vd_adc_nids,
10781		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10782		.channel_mode = alc861vd_3stack_2ch_modes,
10783		.input_mux = &alc861vd_capture_source,
10784		.unsol_event = alc861vd_lenovo_unsol_event,
10785		.init_hook = alc861vd_lenovo_automute,
10786	},
10787	[ALC861VD_DALLAS] = {
10788		.mixers = { alc861vd_dallas_mixer },
10789		.init_verbs = { alc861vd_dallas_verbs },
10790		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10791		.dac_nids = alc861vd_dac_nids,
10792		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10793		.adc_nids = alc861vd_adc_nids,
10794		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10795		.channel_mode = alc861vd_3stack_2ch_modes,
10796		.input_mux = &alc861vd_dallas_capture_source,
10797		.unsol_event = alc861vd_dallas_unsol_event,
10798		.init_hook = alc861vd_dallas_automute,
10799	},
10800	[ALC861VD_HP] = {
10801		.mixers = { alc861vd_hp_mixer },
10802		.init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
10803		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
10804		.dac_nids = alc861vd_dac_nids,
10805		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
10806		.dig_out_nid = ALC861VD_DIGOUT_NID,
10807		.adc_nids = alc861vd_adc_nids,
10808		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
10809		.channel_mode = alc861vd_3stack_2ch_modes,
10810		.input_mux = &alc861vd_hp_capture_source,
10811		.unsol_event = alc861vd_dallas_unsol_event,
10812		.init_hook = alc861vd_dallas_automute,
10813	},
10814};
10815
10816/*
10817 * BIOS auto configuration
10818 */
10819static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
10820				hda_nid_t nid, int pin_type, int dac_idx)
10821{
10822	/* set as output */
10823	snd_hda_codec_write(codec, nid, 0,
10824				AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
10825	snd_hda_codec_write(codec, nid, 0,
10826				AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
10827}
10828
10829static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
10830{
10831	struct alc_spec *spec = codec->spec;
10832	int i;
10833
10834	alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
10835	for (i = 0; i <= HDA_SIDE; i++) {
10836		hda_nid_t nid = spec->autocfg.line_out_pins[i];
10837		int pin_type = get_pin_type(spec->autocfg.line_out_type);
10838		if (nid)
10839			alc861vd_auto_set_output_and_unmute(codec, nid,
10840							    pin_type, i);
10841	}
10842}
10843
10844
10845static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
10846{
10847	struct alc_spec *spec = codec->spec;
10848	hda_nid_t pin;
10849
10850	pin = spec->autocfg.hp_pins[0];
10851	if (pin) /* connect to front and  use dac 0 */
10852		alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
10853}
10854
10855#define alc861vd_is_input_pin(nid)	alc880_is_input_pin(nid)
10856#define ALC861VD_PIN_CD_NID		ALC880_PIN_CD_NID
10857
10858static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
10859{
10860	struct alc_spec *spec = codec->spec;
10861	int i;
10862
10863	for (i = 0; i < AUTO_PIN_LAST; i++) {
10864		hda_nid_t nid = spec->autocfg.input_pins[i];
10865		if (alc861vd_is_input_pin(nid)) {
10866			snd_hda_codec_write(codec, nid, 0,
10867					AC_VERB_SET_PIN_WIDGET_CONTROL,
10868					i <= AUTO_PIN_FRONT_MIC ?
10869							PIN_VREF80 : PIN_IN);
10870			if (nid != ALC861VD_PIN_CD_NID)
10871				snd_hda_codec_write(codec, nid, 0,
10872						AC_VERB_SET_AMP_GAIN_MUTE,
10873						AMP_OUT_MUTE);
10874		}
10875	}
10876}
10877
10878#define alc861vd_idx_to_mixer_vol(nid)		((nid) + 0x02)
10879#define alc861vd_idx_to_mixer_switch(nid)	((nid) + 0x0c)
10880
10881/* add playback controls from the parsed DAC table */
10882/* Based on ALC880 version. But ALC861VD has separate,
10883 * different NIDs for mute/unmute switch and volume control */
10884static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10885					     const struct auto_pin_cfg *cfg)
10886{
10887	char name[32];
10888	static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
10889	hda_nid_t nid_v, nid_s;
10890	int i, err;
10891
10892	for (i = 0; i < cfg->line_outs; i++) {
10893		if (!spec->multiout.dac_nids[i])
10894			continue;
10895		nid_v = alc861vd_idx_to_mixer_vol(
10896				alc880_dac_to_idx(
10897					spec->multiout.dac_nids[i]));
10898		nid_s = alc861vd_idx_to_mixer_switch(
10899				alc880_dac_to_idx(
10900					spec->multiout.dac_nids[i]));
10901
10902		if (i == 2) {
10903			/* Center/LFE */
10904			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10905					  "Center Playback Volume",
10906					  HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
10907							      HDA_OUTPUT));
10908			if (err < 0)
10909				return err;
10910			err = add_control(spec, ALC_CTL_WIDGET_VOL,
10911					  "LFE Playback Volume",
10912					  HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
10913							      HDA_OUTPUT));
10914			if (err < 0)
10915				return err;
10916			err = add_control(spec, ALC_CTL_BIND_MUTE,
10917					  "Center Playback Switch",
10918					  HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
10919							      HDA_INPUT));
10920			if (err < 0)
10921				return err;
10922			err = add_control(spec, ALC_CTL_BIND_MUTE,
10923					  "LFE Playback Switch",
10924					  HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
10925							      HDA_INPUT));
10926			if (err < 0)
10927				return err;
10928		} else {
10929			sprintf(name, "%s Playback Volume", chname[i]);
10930			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10931					  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
10932							      HDA_OUTPUT));
10933			if (err < 0)
10934				return err;
10935			sprintf(name, "%s Playback Switch", chname[i]);
10936			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10937					  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
10938							      HDA_INPUT));
10939			if (err < 0)
10940				return err;
10941		}
10942	}
10943	return 0;
10944}
10945
10946/* add playback controls for speaker and HP outputs */
10947/* Based on ALC880 version. But ALC861VD has separate,
10948 * different NIDs for mute/unmute switch and volume control */
10949static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
10950					hda_nid_t pin, const char *pfx)
10951{
10952	hda_nid_t nid_v, nid_s;
10953	int err;
10954	char name[32];
10955
10956	if (!pin)
10957		return 0;
10958
10959	if (alc880_is_fixed_pin(pin)) {
10960		nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
10961		/* specify the DAC as the extra output */
10962		if (!spec->multiout.hp_nid)
10963			spec->multiout.hp_nid = nid_v;
10964		else
10965			spec->multiout.extra_out_nid[0] = nid_v;
10966		/* control HP volume/switch on the output mixer amp */
10967		nid_v = alc861vd_idx_to_mixer_vol(
10968				alc880_fixed_pin_idx(pin));
10969		nid_s = alc861vd_idx_to_mixer_switch(
10970				alc880_fixed_pin_idx(pin));
10971
10972		sprintf(name, "%s Playback Volume", pfx);
10973		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10974				  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
10975		if (err < 0)
10976			return err;
10977		sprintf(name, "%s Playback Switch", pfx);
10978		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10979				  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
10980		if (err < 0)
10981			return err;
10982	} else if (alc880_is_multi_pin(pin)) {
10983		/* set manual connection */
10984		/* we have only a switch on HP-out PIN */
10985		sprintf(name, "%s Playback Switch", pfx);
10986		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10987				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
10988		if (err < 0)
10989			return err;
10990	}
10991	return 0;
10992}
10993
10994/* parse the BIOS configuration and set up the alc_spec
10995 * return 1 if successful, 0 if the proper config is not found,
10996 * or a negative error code
10997 * Based on ALC880 version - had to change it to override
10998 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10999static int alc861vd_parse_auto_config(struct hda_codec *codec)
11000{
11001	struct alc_spec *spec = codec->spec;
11002	int err;
11003	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
11004
11005	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11006					   alc861vd_ignore);
11007	if (err < 0)
11008		return err;
11009	if (!spec->autocfg.line_outs)
11010		return 0; /* can't find valid BIOS pin config */
11011
11012	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11013	if (err < 0)
11014		return err;
11015	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
11016	if (err < 0)
11017		return err;
11018	err = alc861vd_auto_create_extra_out(spec,
11019					     spec->autocfg.speaker_pins[0],
11020					     "Speaker");
11021	if (err < 0)
11022		return err;
11023	err = alc861vd_auto_create_extra_out(spec,
11024					     spec->autocfg.hp_pins[0],
11025					     "Headphone");
11026	if (err < 0)
11027		return err;
11028	err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
11029	if (err < 0)
11030		return err;
11031
11032	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11033
11034	if (spec->autocfg.dig_out_pin)
11035		spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
11036
11037	if (spec->kctl_alloc)
11038		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11039
11040	spec->init_verbs[spec->num_init_verbs++]
11041		= alc861vd_volume_init_verbs;
11042
11043	spec->num_mux_defs = 1;
11044	spec->input_mux = &spec->private_imux;
11045
11046	return 1;
11047}
11048
11049/* additional initialization for auto-configuration model */
11050static void alc861vd_auto_init(struct hda_codec *codec)
11051{
11052	alc861vd_auto_init_multi_out(codec);
11053	alc861vd_auto_init_hp_out(codec);
11054	alc861vd_auto_init_analog_input(codec);
11055}
11056
11057static int patch_alc861vd(struct hda_codec *codec)
11058{
11059	struct alc_spec *spec;
11060	int err, board_config;
11061
11062	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11063	if (spec == NULL)
11064		return -ENOMEM;
11065
11066	codec->spec = spec;
11067
11068	board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
11069						  alc861vd_models,
11070						  alc861vd_cfg_tbl);
11071
11072	if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
11073		printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
11074			"ALC861VD, trying auto-probe from BIOS...\n");
11075		board_config = ALC861VD_AUTO;
11076	}
11077
11078	if (board_config == ALC861VD_AUTO) {
11079		/* automatic parse from the BIOS config */
11080		err = alc861vd_parse_auto_config(codec);
11081		if (err < 0) {
11082			alc_free(codec);
11083			return err;
11084		} else if (!err) {
11085			printk(KERN_INFO
11086			       "hda_codec: Cannot set up configuration "
11087			       "from BIOS.  Using base mode...\n");
11088			board_config = ALC861VD_3ST;
11089		}
11090	}
11091
11092	if (board_config != ALC861VD_AUTO)
11093		setup_preset(spec, &alc861vd_presets[board_config]);
11094
11095	spec->stream_name_analog = "ALC861VD Analog";
11096	spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
11097	spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
11098
11099	spec->stream_name_digital = "ALC861VD Digital";
11100	spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
11101	spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
11102
11103	spec->adc_nids = alc861vd_adc_nids;
11104	spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
11105
11106	spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
11107	spec->num_mixers++;
11108
11109	codec->patch_ops = alc_patch_ops;
11110
11111	if (board_config == ALC861VD_AUTO)
11112		spec->init_hook = alc861vd_auto_init;
11113#ifdef CONFIG_SND_HDA_POWER_SAVE
11114	if (!spec->loopback.amplist)
11115		spec->loopback.amplist = alc861vd_loopbacks;
11116#endif
11117
11118	return 0;
11119}
11120
11121/*
11122 * ALC662 support
11123 *
11124 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
11125 * configuration.  Each pin widget can choose any input DACs and a mixer.
11126 * Each ADC is connected from a mixer of all inputs.  This makes possible
11127 * 6-channel independent captures.
11128 *
11129 * In addition, an independent DAC for the multi-playback (not used in this
11130 * driver yet).
11131 */
11132#define ALC662_DIGOUT_NID	0x06
11133#define ALC662_DIGIN_NID	0x0a
11134
11135static hda_nid_t alc662_dac_nids[4] = {
11136	/* front, rear, clfe, rear_surr */
11137	0x02, 0x03, 0x04
11138};
11139
11140static hda_nid_t alc662_adc_nids[1] = {
11141	/* ADC1-2 */
11142	0x09,
11143};
11144/* input MUX */
11145/* FIXME: should be a matrix-type input source selection */
11146
11147static struct hda_input_mux alc662_capture_source = {
11148	.num_items = 4,
11149	.items = {
11150		{ "Mic", 0x0 },
11151		{ "Front Mic", 0x1 },
11152		{ "Line", 0x2 },
11153		{ "CD", 0x4 },
11154	},
11155};
11156
11157static struct hda_input_mux alc662_lenovo_101e_capture_source = {
11158	.num_items = 2,
11159	.items = {
11160		{ "Mic", 0x1 },
11161		{ "Line", 0x2 },
11162	},
11163};
11164#define alc662_mux_enum_info alc_mux_enum_info
11165#define alc662_mux_enum_get alc_mux_enum_get
11166
11167static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
11168			       struct snd_ctl_elem_value *ucontrol)
11169{
11170	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11171	struct alc_spec *spec = codec->spec;
11172	const struct hda_input_mux *imux = spec->input_mux;
11173	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11174	static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
11175	hda_nid_t nid = capture_mixers[adc_idx];
11176	unsigned int *cur_val = &spec->cur_mux[adc_idx];
11177	unsigned int i, idx;
11178
11179	idx = ucontrol->value.enumerated.item[0];
11180	if (idx >= imux->num_items)
11181		idx = imux->num_items - 1;
11182	if (*cur_val == idx)
11183		return 0;
11184	for (i = 0; i < imux->num_items; i++) {
11185		unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11186		snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11187					 imux->items[i].index,
11188					 HDA_AMP_MUTE, v);
11189	}
11190	*cur_val = idx;
11191	return 1;
11192}
11193/*
11194 * 2ch mode
11195 */
11196static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
11197	{ 2, NULL }
11198};
11199
11200/*
11201 * 2ch mode
11202 */
11203static struct hda_verb alc662_3ST_ch2_init[] = {
11204	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
11205	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11206	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
11207	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11208	{ } /* end */
11209};
11210
11211/*
11212 * 6ch mode
11213 */
11214static struct hda_verb alc662_3ST_ch6_init[] = {
11215	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11216	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11217	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
11218	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11219	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11220	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
11221	{ } /* end */
11222};
11223
11224static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
11225	{ 2, alc662_3ST_ch2_init },
11226	{ 6, alc662_3ST_ch6_init },
11227};
11228
11229/*
11230 * 2ch mode
11231 */
11232static struct hda_verb alc662_sixstack_ch6_init[] = {
11233	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11234	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11235	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11236	{ } /* end */
11237};
11238
11239/*
11240 * 6ch mode
11241 */
11242static struct hda_verb alc662_sixstack_ch8_init[] = {
11243	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11244	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11245	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11246	{ } /* end */
11247};
11248
11249static struct hda_channel_mode alc662_5stack_modes[2] = {
11250	{ 2, alc662_sixstack_ch6_init },
11251	{ 6, alc662_sixstack_ch8_init },
11252};
11253
11254/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11255 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11256 */
11257
11258static struct snd_kcontrol_new alc662_base_mixer[] = {
11259	/* output mixer control */
11260	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11261	HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
11262	HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11263	HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11264	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11265	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11266	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11267	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11268	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11269
11270	/*Input mixer control */
11271	HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
11272	HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
11273	HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
11274	HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
11275	HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
11276	HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
11277	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
11278	HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
11279
11280	/* Capture mixer control */
11281	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11282	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11283	{
11284		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11285		.name = "Capture Source",
11286		.count = 1,
11287		.info = alc_mux_enum_info,
11288		.get = alc_mux_enum_get,
11289		.put = alc_mux_enum_put,
11290	},
11291	{ } /* end */
11292};
11293
11294static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
11295	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11296	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11297	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11298	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11299	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11300	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11301	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11302	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11303	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11304	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11305	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11306	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11307	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11308	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11309	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11310	{
11311		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11312		/* .name = "Capture Source", */
11313		.name = "Input Source",
11314		.count = 1,
11315		.info = alc662_mux_enum_info,
11316		.get = alc662_mux_enum_get,
11317		.put = alc662_mux_enum_put,
11318	},
11319	{ } /* end */
11320};
11321
11322static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11323	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11324	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11325	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11326	HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11327	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11328	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11329	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11330	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11331	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11332	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11333	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11334	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11335	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11336	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11337	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11338	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11339	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11340	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11341	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11342	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11343	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11344	{
11345		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11346		/* .name = "Capture Source", */
11347		.name = "Input Source",
11348		.count = 1,
11349		.info = alc662_mux_enum_info,
11350		.get = alc662_mux_enum_get,
11351		.put = alc662_mux_enum_put,
11352	},
11353	{ } /* end */
11354};
11355
11356static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11357	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11358	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11359	HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11360	HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11361	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11362	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11363	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11364	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11365	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11366	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11367	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11368	{
11369		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11370		/* .name = "Capture Source", */
11371		.name = "Input Source",
11372		.count = 1,
11373		.info = alc662_mux_enum_info,
11374		.get = alc662_mux_enum_get,
11375		.put = alc662_mux_enum_put,
11376	},
11377	{ } /* end */
11378};
11379
11380static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11381	{
11382		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11383		.name = "Channel Mode",
11384		.info = alc_ch_mode_info,
11385		.get = alc_ch_mode_get,
11386		.put = alc_ch_mode_put,
11387	},
11388	{ } /* end */
11389};
11390
11391static struct hda_verb alc662_init_verbs[] = {
11392	/* ADC: mute amp left and right */
11393	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11394	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11395	/* Front mixer: unmute input/output amp left and right (volume = 0) */
11396
11397	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11398	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11399	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11400	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11401	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11402
11403	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11404	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11405	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11406	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11407	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11408	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11409
11410	/* Front Pin: output 0 (0x0c) */
11411	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11412	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11413
11414	/* Rear Pin: output 1 (0x0d) */
11415	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11416	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11417
11418	/* CLFE Pin: output 2 (0x0e) */
11419	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11420	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11421
11422	/* Mic (rear) pin: input vref at 80% */
11423	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11424	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11425	/* Front Mic pin: input vref at 80% */
11426	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11427	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11428	/* Line In pin: input */
11429	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11430	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11431	/* Line-2 In: Headphone output (output 0 - 0x0c) */
11432	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11433	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11434	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11435	/* CD pin widget for input */
11436	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11437
11438	/* FIXME: use matrix-type input source selection */
11439	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11440	/* Input mixer */
11441	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11442	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11443	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11444	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11445	{ }
11446};
11447
11448static struct hda_verb alc662_sue_init_verbs[] = {
11449	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11450	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11451        {}
11452};
11453
11454/*
11455 * generic initialization of ADC, input mixers and output mixers
11456 */
11457static struct hda_verb alc662_auto_init_verbs[] = {
11458	/*
11459	 * Unmute ADC and set the default input to mic-in
11460	 */
11461	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11462	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11463
11464	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11465	 * mixer widget
11466	 * Note: PASD motherboards uses the Line In 2 as the input for front
11467	 * panel mic (mic 2)
11468	 */
11469	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11470	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11471	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11472	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11473	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11474	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11475
11476	/*
11477	 * Set up output mixers (0x0c - 0x0f)
11478	 */
11479	/* set vol=0 to output mixers */
11480	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11481	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11482	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11483
11484	/* set up input amps for analog loopback */
11485	/* Amp Indices: DAC = 0, mixer = 1 */
11486	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11487	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11488	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11489	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11490	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11491	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11492
11493
11494	/* FIXME: use matrix-type input source selection */
11495	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11496	/* Input mixer */
11497	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11498	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11499	{ }
11500};
11501
11502/* capture mixer elements */
11503static struct snd_kcontrol_new alc662_capture_mixer[] = {
11504	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11505	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11506	{
11507		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11508		/* The multiple "Capture Source" controls confuse alsamixer
11509		 * So call somewhat different..
11510		 * FIXME: the controls appear in the "playback" view!
11511		 */
11512		/* .name = "Capture Source", */
11513		.name = "Input Source",
11514		.count = 1,
11515		.info = alc882_mux_enum_info,
11516		.get = alc882_mux_enum_get,
11517		.put = alc882_mux_enum_put,
11518	},
11519	{ } /* end */
11520};
11521
11522static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11523{
11524	unsigned int present;
11525	unsigned char bits;
11526
11527	present = snd_hda_codec_read(codec, 0x14, 0,
11528				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11529	bits = present ? HDA_AMP_MUTE : 0;
11530	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11531				 HDA_AMP_MUTE, bits);
11532}
11533
11534static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11535{
11536	unsigned int present;
11537	unsigned char bits;
11538
11539 	present = snd_hda_codec_read(codec, 0x1b, 0,
11540				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11541	bits = present ? HDA_AMP_MUTE : 0;
11542	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11543				 HDA_AMP_MUTE, bits);
11544	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11545				 HDA_AMP_MUTE, bits);
11546}
11547
11548static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
11549					   unsigned int res)
11550{
11551	if ((res >> 26) == ALC880_HP_EVENT)
11552		alc662_lenovo_101e_all_automute(codec);
11553	if ((res >> 26) == ALC880_FRONT_EVENT)
11554		alc662_lenovo_101e_ispeaker_automute(codec);
11555}
11556
11557#ifdef CONFIG_SND_HDA_POWER_SAVE
11558#define alc662_loopbacks	alc880_loopbacks
11559#endif
11560
11561
11562/* pcm configuration: identiacal with ALC880 */
11563#define alc662_pcm_analog_playback	alc880_pcm_analog_playback
11564#define alc662_pcm_analog_capture	alc880_pcm_analog_capture
11565#define alc662_pcm_digital_playback	alc880_pcm_digital_playback
11566#define alc662_pcm_digital_capture	alc880_pcm_digital_capture
11567
11568/*
11569 * configuration and preset
11570 */
11571static const char *alc662_models[ALC662_MODEL_LAST] = {
11572	[ALC662_3ST_2ch_DIG]	= "3stack-dig",
11573	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",
11574	[ALC662_3ST_6ch]	= "3stack-6ch",
11575	[ALC662_5ST_DIG]	= "6stack-dig",
11576	[ALC662_LENOVO_101E]	= "lenovo-101e",
11577	[ALC662_AUTO]		= "auto",
11578};
11579
11580static struct snd_pci_quirk alc662_cfg_tbl[] = {
11581	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
11582	{}
11583};
11584
11585static struct alc_config_preset alc662_presets[] = {
11586	[ALC662_3ST_2ch_DIG] = {
11587		.mixers = { alc662_3ST_2ch_mixer },
11588		.init_verbs = { alc662_init_verbs },
11589		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11590		.dac_nids = alc662_dac_nids,
11591		.dig_out_nid = ALC662_DIGOUT_NID,
11592		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11593		.adc_nids = alc662_adc_nids,
11594		.dig_in_nid = ALC662_DIGIN_NID,
11595		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11596		.channel_mode = alc662_3ST_2ch_modes,
11597		.input_mux = &alc662_capture_source,
11598	},
11599	[ALC662_3ST_6ch_DIG] = {
11600		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11601		.init_verbs = { alc662_init_verbs },
11602		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11603		.dac_nids = alc662_dac_nids,
11604		.dig_out_nid = ALC662_DIGOUT_NID,
11605		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11606		.adc_nids = alc662_adc_nids,
11607		.dig_in_nid = ALC662_DIGIN_NID,
11608		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11609		.channel_mode = alc662_3ST_6ch_modes,
11610		.need_dac_fix = 1,
11611		.input_mux = &alc662_capture_source,
11612	},
11613	[ALC662_3ST_6ch] = {
11614		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
11615		.init_verbs = { alc662_init_verbs },
11616		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11617		.dac_nids = alc662_dac_nids,
11618		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11619		.adc_nids = alc662_adc_nids,
11620		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
11621		.channel_mode = alc662_3ST_6ch_modes,
11622		.need_dac_fix = 1,
11623		.input_mux = &alc662_capture_source,
11624	},
11625	[ALC662_5ST_DIG] = {
11626		.mixers = { alc662_base_mixer, alc662_chmode_mixer },
11627		.init_verbs = { alc662_init_verbs },
11628		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11629		.dac_nids = alc662_dac_nids,
11630		.dig_out_nid = ALC662_DIGOUT_NID,
11631		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11632		.adc_nids = alc662_adc_nids,
11633		.dig_in_nid = ALC662_DIGIN_NID,
11634		.num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
11635		.channel_mode = alc662_5stack_modes,
11636		.input_mux = &alc662_capture_source,
11637	},
11638	[ALC662_LENOVO_101E] = {
11639		.mixers = { alc662_lenovo_101e_mixer },
11640		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
11641		.num_dacs = ARRAY_SIZE(alc662_dac_nids),
11642		.dac_nids = alc662_dac_nids,
11643		.num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
11644		.adc_nids = alc662_adc_nids,
11645		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
11646		.channel_mode = alc662_3ST_2ch_modes,
11647		.input_mux = &alc662_lenovo_101e_capture_source,
11648		.unsol_event = alc662_lenovo_101e_unsol_event,
11649		.init_hook = alc662_lenovo_101e_all_automute,
11650	},
11651
11652};
11653
11654
11655/*
11656 * BIOS auto configuration
11657 */
11658
11659/* add playback controls from the parsed DAC table */
11660static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
11661					     const struct auto_pin_cfg *cfg)
11662{
11663	char name[32];
11664	static const char *chname[4] = {
11665		"Front", "Surround", NULL /*CLFE*/, "Side"
11666	};
11667	hda_nid_t nid;
11668	int i, err;
11669
11670	for (i = 0; i < cfg->line_outs; i++) {
11671		if (!spec->multiout.dac_nids[i])
11672			continue;
11673		nid = alc880_idx_to_mixer(i);
11674		if (i == 2) {
11675			/* Center/LFE */
11676			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11677					  "Center Playback Volume",
11678					  HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11679							      HDA_OUTPUT));
11680			if (err < 0)
11681				return err;
11682			err = add_control(spec, ALC_CTL_WIDGET_VOL,
11683					  "LFE Playback Volume",
11684					  HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11685							      HDA_OUTPUT));
11686			if (err < 0)
11687				return err;
11688			err = add_control(spec, ALC_CTL_BIND_MUTE,
11689					  "Center Playback Switch",
11690					  HDA_COMPOSE_AMP_VAL(nid, 1, 2,
11691							      HDA_INPUT));
11692			if (err < 0)
11693				return err;
11694			err = add_control(spec, ALC_CTL_BIND_MUTE,
11695					  "LFE Playback Switch",
11696					  HDA_COMPOSE_AMP_VAL(nid, 2, 2,
11697							      HDA_INPUT));
11698			if (err < 0)
11699				return err;
11700		} else {
11701			sprintf(name, "%s Playback Volume", chname[i]);
11702			err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11703					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11704							      HDA_OUTPUT));
11705			if (err < 0)
11706				return err;
11707			sprintf(name, "%s Playback Switch", chname[i]);
11708			err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11709					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,
11710							      HDA_INPUT));
11711			if (err < 0)
11712				return err;
11713		}
11714	}
11715	return 0;
11716}
11717
11718/* add playback controls for speaker and HP outputs */
11719static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
11720					const char *pfx)
11721{
11722	hda_nid_t nid;
11723	int err;
11724	char name[32];
11725
11726	if (!pin)
11727		return 0;
11728
11729	if (alc880_is_fixed_pin(pin)) {
11730		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11731                /* printk("DAC nid=%x\n",nid); */
11732		/* specify the DAC as the extra output */
11733		if (!spec->multiout.hp_nid)
11734			spec->multiout.hp_nid = nid;
11735		else
11736			spec->multiout.extra_out_nid[0] = nid;
11737		/* control HP volume/switch on the output mixer amp */
11738		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11739		sprintf(name, "%s Playback Volume", pfx);
11740		err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11741				  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11742		if (err < 0)
11743			return err;
11744		sprintf(name, "%s Playback Switch", pfx);
11745		err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11746				  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
11747		if (err < 0)
11748			return err;
11749	} else if (alc880_is_multi_pin(pin)) {
11750		/* set manual connection */
11751		/* we have only a switch on HP-out PIN */
11752		sprintf(name, "%s Playback Switch", pfx);
11753		err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11754				  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11755		if (err < 0)
11756			return err;
11757	}
11758	return 0;
11759}
11760
11761/* create playback/capture controls for input pins */
11762static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
11763						const struct auto_pin_cfg *cfg)
11764{
11765	struct hda_input_mux *imux = &spec->private_imux;
11766	int i, err, idx;
11767
11768	for (i = 0; i < AUTO_PIN_LAST; i++) {
11769		if (alc880_is_input_pin(cfg->input_pins[i])) {
11770			idx = alc880_input_pin_idx(cfg->input_pins[i]);
11771			err = new_analog_input(spec, cfg->input_pins[i],
11772					       auto_pin_cfg_labels[i],
11773					       idx, 0x0b);
11774			if (err < 0)
11775				return err;
11776			imux->items[imux->num_items].label =
11777				auto_pin_cfg_labels[i];
11778			imux->items[imux->num_items].index =
11779				alc880_input_pin_idx(cfg->input_pins[i]);
11780			imux->num_items++;
11781		}
11782	}
11783	return 0;
11784}
11785
11786static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
11787					      hda_nid_t nid, int pin_type,
11788					      int dac_idx)
11789{
11790	/* set as output */
11791	snd_hda_codec_write(codec, nid, 0,
11792			    AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11793	snd_hda_codec_write(codec, nid, 0,
11794			    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11795	/* need the manual connection? */
11796	if (alc880_is_multi_pin(nid)) {
11797		struct alc_spec *spec = codec->spec;
11798		int idx = alc880_multi_pin_idx(nid);
11799		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
11800				    AC_VERB_SET_CONNECT_SEL,
11801				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
11802	}
11803}
11804
11805static void alc662_auto_init_multi_out(struct hda_codec *codec)
11806{
11807	struct alc_spec *spec = codec->spec;
11808	int i;
11809
11810	for (i = 0; i <= HDA_SIDE; i++) {
11811		hda_nid_t nid = spec->autocfg.line_out_pins[i];
11812		int pin_type = get_pin_type(spec->autocfg.line_out_type);
11813		if (nid)
11814			alc662_auto_set_output_and_unmute(codec, nid, pin_type,
11815							  i);
11816	}
11817}
11818
11819static void alc662_auto_init_hp_out(struct hda_codec *codec)
11820{
11821	struct alc_spec *spec = codec->spec;
11822	hda_nid_t pin;
11823
11824	pin = spec->autocfg.hp_pins[0];
11825	if (pin) /* connect to front */
11826		/* use dac 0 */
11827		alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11828}
11829
11830#define alc662_is_input_pin(nid)	alc880_is_input_pin(nid)
11831#define ALC662_PIN_CD_NID		ALC880_PIN_CD_NID
11832
11833static void alc662_auto_init_analog_input(struct hda_codec *codec)
11834{
11835	struct alc_spec *spec = codec->spec;
11836	int i;
11837
11838	for (i = 0; i < AUTO_PIN_LAST; i++) {
11839		hda_nid_t nid = spec->autocfg.input_pins[i];
11840		if (alc662_is_input_pin(nid)) {
11841			snd_hda_codec_write(codec, nid, 0,
11842					    AC_VERB_SET_PIN_WIDGET_CONTROL,
11843					    (i <= AUTO_PIN_FRONT_MIC ?
11844					     PIN_VREF80 : PIN_IN));
11845			if (nid != ALC662_PIN_CD_NID)
11846				snd_hda_codec_write(codec, nid, 0,
11847						    AC_VERB_SET_AMP_GAIN_MUTE,
11848						    AMP_OUT_MUTE);
11849		}
11850	}
11851}
11852
11853static int alc662_parse_auto_config(struct hda_codec *codec)
11854{
11855	struct alc_spec *spec = codec->spec;
11856	int err;
11857	static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
11858
11859	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11860					   alc662_ignore);
11861	if (err < 0)
11862		return err;
11863	if (!spec->autocfg.line_outs)
11864		return 0; /* can't find valid BIOS pin config */
11865
11866	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11867	if (err < 0)
11868		return err;
11869	err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
11870	if (err < 0)
11871		return err;
11872	err = alc662_auto_create_extra_out(spec,
11873					   spec->autocfg.speaker_pins[0],
11874					   "Speaker");
11875	if (err < 0)
11876		return err;
11877	err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11878					   "Headphone");
11879	if (err < 0)
11880		return err;
11881	err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
11882	if (err < 0)
11883		return err;
11884
11885	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11886
11887	if (spec->autocfg.dig_out_pin)
11888		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
11889
11890	if (spec->kctl_alloc)
11891		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11892
11893	spec->num_mux_defs = 1;
11894	spec->input_mux = &spec->private_imux;
11895
11896	spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
11897	spec->mixers[spec->num_mixers] = alc662_capture_mixer;
11898	spec->num_mixers++;
11899	return 1;
11900}
11901
11902/* additional initialization for auto-configuration model */
11903static void alc662_auto_init(struct hda_codec *codec)
11904{
11905	alc662_auto_init_multi_out(codec);
11906	alc662_auto_init_hp_out(codec);
11907	alc662_auto_init_analog_input(codec);
11908}
11909
11910static int patch_alc662(struct hda_codec *codec)
11911{
11912	struct alc_spec *spec;
11913	int err, board_config;
11914
11915	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11916	if (!spec)
11917		return -ENOMEM;
11918
11919	codec->spec = spec;
11920
11921	board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
11922						  alc662_models,
11923			  	                  alc662_cfg_tbl);
11924	if (board_config < 0) {
11925		printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
11926		       "trying auto-probe from BIOS...\n");
11927		board_config = ALC662_AUTO;
11928	}
11929
11930	if (board_config == ALC662_AUTO) {
11931		/* automatic parse from the BIOS config */
11932		err = alc662_parse_auto_config(codec);
11933		if (err < 0) {
11934			alc_free(codec);
11935			return err;
11936		} else if (!err) {
11937			printk(KERN_INFO
11938			       "hda_codec: Cannot set up configuration "
11939			       "from BIOS.  Using base mode...\n");
11940			board_config = ALC662_3ST_2ch_DIG;
11941		}
11942	}
11943
11944	if (board_config != ALC662_AUTO)
11945		setup_preset(spec, &alc662_presets[board_config]);
11946
11947	spec->stream_name_analog = "ALC662 Analog";
11948	spec->stream_analog_playback = &alc662_pcm_analog_playback;
11949	spec->stream_analog_capture = &alc662_pcm_analog_capture;
11950
11951	spec->stream_name_digital = "ALC662 Digital";
11952	spec->stream_digital_playback = &alc662_pcm_digital_playback;
11953	spec->stream_digital_capture = &alc662_pcm_digital_capture;
11954
11955	if (!spec->adc_nids && spec->input_mux) {
11956		spec->adc_nids = alc662_adc_nids;
11957		spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
11958	}
11959
11960	codec->patch_ops = alc_patch_ops;
11961	if (board_config == ALC662_AUTO)
11962		spec->init_hook = alc662_auto_init;
11963#ifdef CONFIG_SND_HDA_POWER_SAVE
11964	if (!spec->loopback.amplist)
11965		spec->loopback.amplist = alc662_loopbacks;
11966#endif
11967
11968	return 0;
11969}
11970
11971/*
11972 * patch entries
11973 */
11974struct hda_codec_preset snd_hda_preset_realtek[] = {
11975	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
11976	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
11977	{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
11978	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
11979	  .patch = patch_alc861 },
11980	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
11981	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
11982	{ .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
11983	{ .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
11984	  .patch = patch_alc883 },
11985	{ .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
11986	  .patch = patch_alc662 },
11987	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
11988	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
11989	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
11990	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
11991	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
11992	{} /* terminator */
11993};
11994