patch_realtek.c revision a1e8d2da03b3a1017aab01d49666ec9b67927de5
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
36/* ALC880 board config type */
37enum {
38	ALC880_3ST,
39	ALC880_3ST_DIG,
40	ALC880_5ST,
41	ALC880_5ST_DIG,
42	ALC880_W810,
43	ALC880_Z71V,
44	ALC880_6ST,
45	ALC880_6ST_DIG,
46	ALC880_F1734,
47	ALC880_ASUS,
48	ALC880_ASUS_DIG,
49	ALC880_ASUS_W1V,
50	ALC880_ASUS_DIG2,
51	ALC880_UNIWILL_DIG,
52	ALC880_CLEVO,
53	ALC880_TCL_S700,
54	ALC880_LG,
55	ALC880_LG_LW,
56#ifdef CONFIG_SND_DEBUG
57	ALC880_TEST,
58#endif
59	ALC880_AUTO,
60	ALC880_MODEL_LAST /* last tag */
61};
62
63/* ALC260 models */
64enum {
65	ALC260_BASIC,
66	ALC260_HP,
67	ALC260_HP_3013,
68	ALC260_FUJITSU_S702X,
69	ALC260_ACER,
70#ifdef CONFIG_SND_DEBUG
71	ALC260_TEST,
72#endif
73	ALC260_AUTO,
74	ALC260_MODEL_LAST /* last tag */
75};
76
77/* ALC262 models */
78enum {
79	ALC262_BASIC,
80	ALC262_FUJITSU,
81	ALC262_AUTO,
82	ALC262_MODEL_LAST /* last tag */
83};
84
85/* ALC861 models */
86enum {
87	ALC861_3ST,
88	ALC861_3ST_DIG,
89	ALC861_6ST_DIG,
90	ALC861_AUTO,
91	ALC861_MODEL_LAST,
92};
93
94/* ALC882 models */
95enum {
96	ALC882_3ST_DIG,
97	ALC882_6ST_DIG,
98	ALC882_AUTO,
99	ALC882_MODEL_LAST,
100};
101
102/* for GPIO Poll */
103#define GPIO_MASK	0x03
104
105struct alc_spec {
106	/* codec parameterization */
107	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
108	unsigned int num_mixers;
109
110	const struct hda_verb *init_verbs[5];	/* initialization verbs
111						 * don't forget NULL termination!
112						 */
113	unsigned int num_init_verbs;
114
115	char *stream_name_analog;	/* analog PCM stream */
116	struct hda_pcm_stream *stream_analog_playback;
117	struct hda_pcm_stream *stream_analog_capture;
118
119	char *stream_name_digital;	/* digital PCM stream */
120	struct hda_pcm_stream *stream_digital_playback;
121	struct hda_pcm_stream *stream_digital_capture;
122
123	/* playback */
124	struct hda_multi_out multiout;	/* playback set-up
125					 * max_channels, dacs must be set
126					 * dig_out_nid and hp_nid are optional
127					 */
128
129	/* capture */
130	unsigned int num_adc_nids;
131	hda_nid_t *adc_nids;
132	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
133
134	/* capture source */
135	unsigned int num_mux_defs;
136	const struct hda_input_mux *input_mux;
137	unsigned int cur_mux[3];
138
139	/* channel model */
140	const struct hda_channel_mode *channel_mode;
141	int num_channel_mode;
142
143	/* PCM information */
144	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */
145
146	/* dynamic controls, init_verbs and input_mux */
147	struct auto_pin_cfg autocfg;
148	unsigned int num_kctl_alloc, num_kctl_used;
149	struct snd_kcontrol_new *kctl_alloc;
150	struct hda_input_mux private_imux;
151	hda_nid_t private_dac_nids[5];
152
153	/* hooks */
154	void (*init_hook)(struct hda_codec *codec);
155	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
156
157	/* for pin sensing */
158	unsigned int sense_updated: 1;
159	unsigned int jack_present: 1;
160};
161
162/*
163 * configuration template - to be copied to the spec instance
164 */
165struct alc_config_preset {
166	struct snd_kcontrol_new *mixers[5]; /* should be identical size with spec */
167	const struct hda_verb *init_verbs[5];
168	unsigned int num_dacs;
169	hda_nid_t *dac_nids;
170	hda_nid_t dig_out_nid;		/* optional */
171	hda_nid_t hp_nid;		/* optional */
172	unsigned int num_adc_nids;
173	hda_nid_t *adc_nids;
174	hda_nid_t dig_in_nid;
175	unsigned int num_channel_mode;
176	const struct hda_channel_mode *channel_mode;
177	unsigned int num_mux_defs;
178	const struct hda_input_mux *input_mux;
179	void (*unsol_event)(struct hda_codec *, unsigned int);
180	void (*init_hook)(struct hda_codec *);
181};
182
183
184/*
185 * input MUX handling
186 */
187static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
188{
189	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
190	struct alc_spec *spec = codec->spec;
191	unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
192	if (mux_idx >= spec->num_mux_defs)
193		mux_idx = 0;
194	return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
195}
196
197static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
198{
199	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
200	struct alc_spec *spec = codec->spec;
201	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
202
203	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
204	return 0;
205}
206
207static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
208{
209	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
210	struct alc_spec *spec = codec->spec;
211	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
212	unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
213	return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
214				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
215}
216
217
218/*
219 * channel mode setting
220 */
221static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
222{
223	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
224	struct alc_spec *spec = codec->spec;
225	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
226				    spec->num_channel_mode);
227}
228
229static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
230{
231	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
232	struct alc_spec *spec = codec->spec;
233	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
234				   spec->num_channel_mode, spec->multiout.max_channels);
235}
236
237static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
238{
239	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
240	struct alc_spec *spec = codec->spec;
241	return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
242				   spec->num_channel_mode, &spec->multiout.max_channels);
243}
244
245/*
246 * Control the mode of pin widget settings via the mixer.  "pc" is used
247 * instead of "%" to avoid consequences of accidently treating the % as
248 * being part of a format specifier.  Maximum allowed length of a value is
249 * 63 characters plus NULL terminator.
250 *
251 * Note: some retasking pin complexes seem to ignore requests for input
252 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
253 * are requested.  Therefore order this list so that this behaviour will not
254 * cause problems when mixer clients move through the enum sequentially.
255 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
256 * March 2006.
257 */
258static char *alc_pin_mode_names[] = {
259	"Mic 50pc bias", "Mic 80pc bias",
260	"Line in", "Line out", "Headphone out",
261};
262static unsigned char alc_pin_mode_values[] = {
263	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
264};
265/* The control can present all 5 options, or it can limit the options based
266 * in the pin being assumed to be exclusively an input or an output pin.  In
267 * addition, "input" pins may or may not process the mic bias option
268 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
269 * accept requests for bias as of chip versions up to March 2006) and/or
270 * wiring in the computer.
271 */
272#define ALC_PIN_DIR_IN              0x00
273#define ALC_PIN_DIR_OUT             0x01
274#define ALC_PIN_DIR_INOUT           0x02
275#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
276#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
277
278/* Info about the pin modes supported by the different pin direction modes.
279 * For each direction the minimum and maximum values are given.
280 */
281static signed char alc_pin_mode_dir_info[5][2] = {
282	{ 0, 2 },    /* ALC_PIN_DIR_IN */
283	{ 3, 4 },    /* ALC_PIN_DIR_OUT */
284	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */
285	{ 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
286	{ 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
287};
288#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
289#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
290#define alc_pin_mode_n_items(_dir) \
291	(alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
292
293static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
294{
295	unsigned int item_num = uinfo->value.enumerated.item;
296	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
297
298	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
299	uinfo->count = 1;
300	uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
301
302	if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
303		item_num = alc_pin_mode_min(dir);
304	strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
305	return 0;
306}
307
308static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
309{
310	unsigned int i;
311	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
312	hda_nid_t nid = kcontrol->private_value & 0xffff;
313	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
314	long *valp = ucontrol->value.integer.value;
315	unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
316
317	/* Find enumerated value for current pinctl setting */
318	i = alc_pin_mode_min(dir);
319	while (alc_pin_mode_values[i]!=pinctl && i<=alc_pin_mode_max(dir))
320		i++;
321	*valp = i<=alc_pin_mode_max(dir)?i:alc_pin_mode_min(dir);
322	return 0;
323}
324
325static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
326{
327	signed int change;
328	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
329	hda_nid_t nid = kcontrol->private_value & 0xffff;
330	unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
331	long val = *ucontrol->value.integer.value;
332	unsigned int pinctl = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_PIN_WIDGET_CONTROL,0x00);
333
334	if (val<alc_pin_mode_min(dir) || val>alc_pin_mode_max(dir))
335		val = alc_pin_mode_min(dir);
336
337	change = pinctl != alc_pin_mode_values[val];
338	if (change) {
339		/* Set pin mode to that requested */
340		snd_hda_codec_write(codec,nid,0,AC_VERB_SET_PIN_WIDGET_CONTROL,
341			alc_pin_mode_values[val]);
342
343		/* Also enable the retasking pin's input/output as required
344		 * for the requested pin mode.  Enum values of 2 or less are
345		 * input modes.
346		 *
347		 * Dynamically switching the input/output buffers probably
348		 * reduces noise slightly (particularly on input) so we'll
349		 * do it.  However, having both input and output buffers
350		 * enabled simultaneously doesn't seem to be problematic if
351		 * this turns out to be necessary in the future.
352		 */
353		if (val <= 2) {
354			snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
355				AMP_OUT_MUTE);
356			snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
357				AMP_IN_UNMUTE(0));
358		} else {
359			snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
360				AMP_IN_MUTE(0));
361			snd_hda_codec_write(codec,nid,0,AC_VERB_SET_AMP_GAIN_MUTE,
362				AMP_OUT_UNMUTE);
363		}
364	}
365	return change;
366}
367
368#define ALC_PIN_MODE(xname, nid, dir) \
369	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
370	  .info = alc_pin_mode_info, \
371	  .get = alc_pin_mode_get, \
372	  .put = alc_pin_mode_put, \
373	  .private_value = nid | (dir<<16) }
374
375/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
376 * together using a mask with more than one bit set.  This control is
377 * currently used only by the ALC260 test model.  At this stage they are not
378 * needed for any "production" models.
379 */
380#ifdef CONFIG_SND_DEBUG
381static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
382{
383	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
384	uinfo->count = 1;
385	uinfo->value.integer.min = 0;
386	uinfo->value.integer.max = 1;
387	return 0;
388}
389static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
390{
391	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
392	hda_nid_t nid = kcontrol->private_value & 0xffff;
393	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
394	long *valp = ucontrol->value.integer.value;
395	unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);
396
397	*valp = (val & mask) != 0;
398	return 0;
399}
400static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
401{
402	signed int change;
403	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
404	hda_nid_t nid = kcontrol->private_value & 0xffff;
405	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
406	long val = *ucontrol->value.integer.value;
407	unsigned int gpio_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_GPIO_DATA,0x00);
408
409	/* Set/unset the masked GPIO bit(s) as needed */
410	change = (val==0?0:mask) != (gpio_data & mask);
411	if (val==0)
412		gpio_data &= ~mask;
413	else
414		gpio_data |= mask;
415	snd_hda_codec_write(codec,nid,0,AC_VERB_SET_GPIO_DATA,gpio_data);
416
417	return change;
418}
419#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
420	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
421	  .info = alc_gpio_data_info, \
422	  .get = alc_gpio_data_get, \
423	  .put = alc_gpio_data_put, \
424	  .private_value = nid | (mask<<16) }
425#endif   /* CONFIG_SND_DEBUG */
426
427/* A switch control to allow the enabling of the digital IO pins on the
428 * ALC260.  This is incredibly simplistic; the intention of this control is
429 * to provide something in the test model allowing digital outputs to be
430 * identified if present.  If models are found which can utilise these
431 * outputs a more complete mixer control can be devised for those models if
432 * necessary.
433 */
434#ifdef CONFIG_SND_DEBUG
435static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
436{
437	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
438	uinfo->count = 1;
439	uinfo->value.integer.min = 0;
440	uinfo->value.integer.max = 1;
441	return 0;
442}
443static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
444{
445	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
446	hda_nid_t nid = kcontrol->private_value & 0xffff;
447	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
448	long *valp = ucontrol->value.integer.value;
449	unsigned int val = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00);
450
451	*valp = (val & mask) != 0;
452	return 0;
453}
454static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
455{
456	signed int change;
457	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
458	hda_nid_t nid = kcontrol->private_value & 0xffff;
459	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
460	long val = *ucontrol->value.integer.value;
461	unsigned int ctrl_data = snd_hda_codec_read(codec,nid,0,AC_VERB_GET_DIGI_CONVERT,0x00);
462
463	/* Set/unset the masked control bit(s) as needed */
464	change = (val==0?0:mask) != (ctrl_data & mask);
465	if (val==0)
466		ctrl_data &= ~mask;
467	else
468		ctrl_data |= mask;
469	snd_hda_codec_write(codec,nid,0,AC_VERB_SET_DIGI_CONVERT_1,ctrl_data);
470
471	return change;
472}
473#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
474	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
475	  .info = alc_spdif_ctrl_info, \
476	  .get = alc_spdif_ctrl_get, \
477	  .put = alc_spdif_ctrl_put, \
478	  .private_value = nid | (mask<<16) }
479#endif   /* CONFIG_SND_DEBUG */
480
481/*
482 * set up from the preset table
483 */
484static void setup_preset(struct alc_spec *spec, const struct alc_config_preset *preset)
485{
486	int i;
487
488	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
489		spec->mixers[spec->num_mixers++] = preset->mixers[i];
490	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; i++)
491		spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i];
492
493	spec->channel_mode = preset->channel_mode;
494	spec->num_channel_mode = preset->num_channel_mode;
495
496	spec->multiout.max_channels = spec->channel_mode[0].channels;
497
498	spec->multiout.num_dacs = preset->num_dacs;
499	spec->multiout.dac_nids = preset->dac_nids;
500	spec->multiout.dig_out_nid = preset->dig_out_nid;
501	spec->multiout.hp_nid = preset->hp_nid;
502
503	spec->num_mux_defs = preset->num_mux_defs;
504	if (! spec->num_mux_defs)
505		spec->num_mux_defs = 1;
506	spec->input_mux = preset->input_mux;
507
508	spec->num_adc_nids = preset->num_adc_nids;
509	spec->adc_nids = preset->adc_nids;
510	spec->dig_in_nid = preset->dig_in_nid;
511
512	spec->unsol_event = preset->unsol_event;
513	spec->init_hook = preset->init_hook;
514}
515
516/*
517 * ALC880 3-stack model
518 *
519 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
520 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, F-Mic = 0x1b
521 *                 HP = 0x19
522 */
523
524static hda_nid_t alc880_dac_nids[4] = {
525	/* front, rear, clfe, rear_surr */
526	0x02, 0x05, 0x04, 0x03
527};
528
529static hda_nid_t alc880_adc_nids[3] = {
530	/* ADC0-2 */
531	0x07, 0x08, 0x09,
532};
533
534/* The datasheet says the node 0x07 is connected from inputs,
535 * but it shows zero connection in the real implementation on some devices.
536 * Note: this is a 915GAV bug, fixed on 915GLV
537 */
538static hda_nid_t alc880_adc_nids_alt[2] = {
539	/* ADC1-2 */
540	0x08, 0x09,
541};
542
543#define ALC880_DIGOUT_NID	0x06
544#define ALC880_DIGIN_NID	0x0a
545
546static struct hda_input_mux alc880_capture_source = {
547	.num_items = 4,
548	.items = {
549		{ "Mic", 0x0 },
550		{ "Front Mic", 0x3 },
551		{ "Line", 0x2 },
552		{ "CD", 0x4 },
553	},
554};
555
556/* channel source setting (2/6 channel selection for 3-stack) */
557/* 2ch mode */
558static struct hda_verb alc880_threestack_ch2_init[] = {
559	/* set line-in to input, mute it */
560	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
561	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
562	/* set mic-in to input vref 80%, mute it */
563	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
564	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
565	{ } /* end */
566};
567
568/* 6ch mode */
569static struct hda_verb alc880_threestack_ch6_init[] = {
570	/* set line-in to output, unmute it */
571	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
572	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
573	/* set mic-in to output, unmute it */
574	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
575	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
576	{ } /* end */
577};
578
579static struct hda_channel_mode alc880_threestack_modes[2] = {
580	{ 2, alc880_threestack_ch2_init },
581	{ 6, alc880_threestack_ch6_init },
582};
583
584static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
585	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
586	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
587	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
588	HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
589	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
590	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
591	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
592	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
593	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
594	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
595	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
596	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
597	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
598	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
599	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
600	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
601	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
602	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
603	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
604	{
605		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
606		.name = "Channel Mode",
607		.info = alc_ch_mode_info,
608		.get = alc_ch_mode_get,
609		.put = alc_ch_mode_put,
610	},
611	{ } /* end */
612};
613
614/* capture mixer elements */
615static struct snd_kcontrol_new alc880_capture_mixer[] = {
616	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
617	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
618	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
619	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
620	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
621	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
622	{
623		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
624		/* The multiple "Capture Source" controls confuse alsamixer
625		 * So call somewhat different..
626		 * FIXME: the controls appear in the "playback" view!
627		 */
628		/* .name = "Capture Source", */
629		.name = "Input Source",
630		.count = 3,
631		.info = alc_mux_enum_info,
632		.get = alc_mux_enum_get,
633		.put = alc_mux_enum_put,
634	},
635	{ } /* end */
636};
637
638/* capture mixer elements (in case NID 0x07 not available) */
639static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
640	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
641	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
642	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
643	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
644	{
645		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
646		/* The multiple "Capture Source" controls confuse alsamixer
647		 * So call somewhat different..
648		 * FIXME: the controls appear in the "playback" view!
649		 */
650		/* .name = "Capture Source", */
651		.name = "Input Source",
652		.count = 2,
653		.info = alc_mux_enum_info,
654		.get = alc_mux_enum_get,
655		.put = alc_mux_enum_put,
656	},
657	{ } /* end */
658};
659
660
661
662/*
663 * ALC880 5-stack model
664 *
665 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), Side = 0x02 (0xd)
666 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
667 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
668 */
669
670/* additional mixers to alc880_three_stack_mixer */
671static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
672	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
673	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
674	{ } /* end */
675};
676
677/* channel source setting (6/8 channel selection for 5-stack) */
678/* 6ch mode */
679static struct hda_verb alc880_fivestack_ch6_init[] = {
680	/* set line-in to input, mute it */
681	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
682	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
683	{ } /* end */
684};
685
686/* 8ch mode */
687static struct hda_verb alc880_fivestack_ch8_init[] = {
688	/* set line-in to output, unmute it */
689	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
690	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
691	{ } /* end */
692};
693
694static struct hda_channel_mode alc880_fivestack_modes[2] = {
695	{ 6, alc880_fivestack_ch6_init },
696	{ 8, alc880_fivestack_ch8_init },
697};
698
699
700/*
701 * ALC880 6-stack model
702 *
703 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), Side = 0x05 (0x0f)
704 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
705 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
706 */
707
708static hda_nid_t alc880_6st_dac_nids[4] = {
709	/* front, rear, clfe, rear_surr */
710	0x02, 0x03, 0x04, 0x05
711};
712
713static struct hda_input_mux alc880_6stack_capture_source = {
714	.num_items = 4,
715	.items = {
716		{ "Mic", 0x0 },
717		{ "Front Mic", 0x1 },
718		{ "Line", 0x2 },
719		{ "CD", 0x4 },
720	},
721};
722
723/* fixed 8-channels */
724static struct hda_channel_mode alc880_sixstack_modes[1] = {
725	{ 8, NULL },
726};
727
728static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
729	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
730	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
731	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
732	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
733	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
734	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
735	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
736	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
737	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
738	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
739	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
740	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
741	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
742	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
743	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
744	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
745	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
746	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
747	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
748	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
749	{
750		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
751		.name = "Channel Mode",
752		.info = alc_ch_mode_info,
753		.get = alc_ch_mode_get,
754		.put = alc_ch_mode_put,
755	},
756	{ } /* end */
757};
758
759
760/*
761 * ALC880 W810 model
762 *
763 * W810 has rear IO for:
764 * Front (DAC 02)
765 * Surround (DAC 03)
766 * Center/LFE (DAC 04)
767 * Digital out (06)
768 *
769 * The system also has a pair of internal speakers, and a headphone jack.
770 * These are both connected to Line2 on the codec, hence to DAC 02.
771 *
772 * There is a variable resistor to control the speaker or headphone
773 * volume. This is a hardware-only device without a software API.
774 *
775 * Plugging headphones in will disable the internal speakers. This is
776 * implemented in hardware, not via the driver using jack sense. In
777 * a similar fashion, plugging into the rear socket marked "front" will
778 * disable both the speakers and headphones.
779 *
780 * For input, there's a microphone jack, and an "audio in" jack.
781 * These may not do anything useful with this driver yet, because I
782 * haven't setup any initialization verbs for these yet...
783 */
784
785static hda_nid_t alc880_w810_dac_nids[3] = {
786	/* front, rear/surround, clfe */
787	0x02, 0x03, 0x04
788};
789
790/* fixed 6 channels */
791static struct hda_channel_mode alc880_w810_modes[1] = {
792	{ 6, NULL }
793};
794
795/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
796static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
797	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
798	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
799	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
800	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
801	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
802	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
803	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
804	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
805	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
806	{ } /* end */
807};
808
809
810/*
811 * Z710V model
812 *
813 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
814 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), Line = 0x1a
815 */
816
817static hda_nid_t alc880_z71v_dac_nids[1] = {
818	0x02
819};
820#define ALC880_Z71V_HP_DAC	0x03
821
822/* fixed 2 channels */
823static struct hda_channel_mode alc880_2_jack_modes[1] = {
824	{ 2, NULL }
825};
826
827static struct snd_kcontrol_new alc880_z71v_mixer[] = {
828	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
829	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
830	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
831	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
832	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
833	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
834	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
835	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
836	{ } /* end */
837};
838
839
840/* FIXME! */
841/*
842 * ALC880 F1734 model
843 *
844 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
845 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
846 */
847
848static hda_nid_t alc880_f1734_dac_nids[1] = {
849	0x03
850};
851#define ALC880_F1734_HP_DAC	0x02
852
853static struct snd_kcontrol_new alc880_f1734_mixer[] = {
854	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
855	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
856	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
857	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
858	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
859	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
860	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
861	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
862	{ } /* end */
863};
864
865
866/* FIXME! */
867/*
868 * ALC880 ASUS model
869 *
870 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
871 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
872 *  Mic = 0x18, Line = 0x1a
873 */
874
875#define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
876#define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
877
878static struct snd_kcontrol_new alc880_asus_mixer[] = {
879	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
880	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
881	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
882	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
883	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
884	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
885	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
886	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
887	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
888	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
889	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
890	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
891	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
892	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
893	{
894		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
895		.name = "Channel Mode",
896		.info = alc_ch_mode_info,
897		.get = alc_ch_mode_get,
898		.put = alc_ch_mode_put,
899	},
900	{ } /* end */
901};
902
903/* FIXME! */
904/*
905 * ALC880 ASUS W1V model
906 *
907 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
908 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
909 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
910 */
911
912/* additional mixers to alc880_asus_mixer */
913static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
914	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
915	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
916	{ } /* end */
917};
918
919/* additional mixers to alc880_asus_mixer */
920static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
921	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
922	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
923	{ } /* end */
924};
925
926/* TCL S700 */
927static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
928	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
929	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
930	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
931	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
932	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
933	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
934	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
935	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
936	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
937	{
938		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
939		/* The multiple "Capture Source" controls confuse alsamixer
940		 * So call somewhat different..
941		 * FIXME: the controls appear in the "playback" view!
942		 */
943		/* .name = "Capture Source", */
944		.name = "Input Source",
945		.count = 1,
946		.info = alc_mux_enum_info,
947		.get = alc_mux_enum_get,
948		.put = alc_mux_enum_put,
949	},
950	{ } /* end */
951};
952
953/*
954 * build control elements
955 */
956static int alc_build_controls(struct hda_codec *codec)
957{
958	struct alc_spec *spec = codec->spec;
959	int err;
960	int i;
961
962	for (i = 0; i < spec->num_mixers; i++) {
963		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
964		if (err < 0)
965			return err;
966	}
967
968	if (spec->multiout.dig_out_nid) {
969		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
970		if (err < 0)
971			return err;
972	}
973	if (spec->dig_in_nid) {
974		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
975		if (err < 0)
976			return err;
977	}
978	return 0;
979}
980
981
982/*
983 * initialize the codec volumes, etc
984 */
985
986/*
987 * generic initialization of ADC, input mixers and output mixers
988 */
989static struct hda_verb alc880_volume_init_verbs[] = {
990	/*
991	 * Unmute ADC0-2 and set the default input to mic-in
992	 */
993	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
994	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
995	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
996	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
997	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
998	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
999
1000	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1001	 * mixer widget
1002	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
1003	 * mic (mic 2)
1004	 */
1005	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1006	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1007	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1008	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1009	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1010	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1011
1012	/*
1013	 * Set up output mixers (0x0c - 0x0f)
1014	 */
1015	/* set vol=0 to output mixers */
1016	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1017	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1018	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1019	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1020	/* set up input amps for analog loopback */
1021	/* Amp Indices: DAC = 0, mixer = 1 */
1022	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1023	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1024	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1025	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1026	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1027	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1028	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1029	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1030
1031	{ }
1032};
1033
1034/*
1035 * 3-stack pin configuration:
1036 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1037 */
1038static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1039	/*
1040	 * preset connection lists of input pins
1041	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1042	 */
1043	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1044	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1045	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1046
1047	/*
1048	 * Set pin mode and muting
1049	 */
1050	/* set front pin widgets 0x14 for output */
1051	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1052	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1053	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1054	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1055	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1056	/* Mic2 (as headphone out) for HP output */
1057	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1058	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1059	/* Line In pin widget for input */
1060	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1061	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1062	/* Line2 (as front mic) pin widget for input and vref at 80% */
1063	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1064	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1065	/* CD pin widget for input */
1066	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1067
1068	{ }
1069};
1070
1071/*
1072 * 5-stack pin configuration:
1073 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1074 * line-in/side = 0x1a, f-mic = 0x1b
1075 */
1076static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1077	/*
1078	 * preset connection lists of input pins
1079	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1080	 */
1081	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1082	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1083
1084	/*
1085	 * Set pin mode and muting
1086	 */
1087	/* set pin widgets 0x14-0x17 for output */
1088	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1089	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1090	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1091	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1092	/* unmute pins for output (no gain on this amp) */
1093	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1094	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1095	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1096	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1097
1098	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1099	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1100	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1101	/* Mic2 (as headphone out) for HP output */
1102	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1103	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1104	/* Line In pin widget for input */
1105	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1106	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1107	/* Line2 (as front mic) pin widget for input and vref at 80% */
1108	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1109	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1110	/* CD pin widget for input */
1111	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1112
1113	{ }
1114};
1115
1116/*
1117 * W810 pin configuration:
1118 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1119 */
1120static struct hda_verb alc880_pin_w810_init_verbs[] = {
1121	/* hphone/speaker input selector: front DAC */
1122	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1123
1124	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1125	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1126	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1127	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1128	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1129	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1130
1131	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1132	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1133
1134	{ }
1135};
1136
1137/*
1138 * Z71V pin configuration:
1139 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1140 */
1141static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1142	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1143	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1144	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1145	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1146
1147	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1148	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1149	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1150	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1151
1152	{ }
1153};
1154
1155/*
1156 * 6-stack pin configuration:
1157 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, f-mic = 0x19,
1158 * line = 0x1a, HP = 0x1b
1159 */
1160static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1161	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1162
1163	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1164	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1165	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1166	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1167	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1168	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1169	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1170	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1171
1172	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1173	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1174	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1175	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1176	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1177	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1178	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1179	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1180	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1181
1182	{ }
1183};
1184
1185/* FIXME! */
1186/*
1187 * F1734 pin configuration:
1188 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1189 */
1190static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1191	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1192	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1193	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1194	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1195
1196	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1197	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1198	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1199	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1200
1201	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1202	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1203	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1204	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1205	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1206	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1207	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1208	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1209	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1210
1211	{ }
1212};
1213
1214/* FIXME! */
1215/*
1216 * ASUS pin configuration:
1217 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1218 */
1219static struct hda_verb alc880_pin_asus_init_verbs[] = {
1220	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1221	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1222	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1223	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1224
1225	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1226	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1227	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1228	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1229	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1230	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1231	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1232	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1233
1234	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1235	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1236	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1237	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1238	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1239	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1240	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1241	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1242	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1243
1244	{ }
1245};
1246
1247/* Enable GPIO mask and set output */
1248static struct hda_verb alc880_gpio1_init_verbs[] = {
1249	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1250	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1251	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1252
1253	{ }
1254};
1255
1256/* Enable GPIO mask and set output */
1257static struct hda_verb alc880_gpio2_init_verbs[] = {
1258	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1259	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1260	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1261
1262	{ }
1263};
1264
1265/* Clevo m520g init */
1266static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1267	/* headphone output */
1268	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1269	/* line-out */
1270	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1271	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1272	/* Line-in */
1273	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1274	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1275	/* CD */
1276	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1277	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1278	/* Mic1 (rear panel) */
1279	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1280	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1281	/* Mic2 (front panel) */
1282	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1283	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1284	/* headphone */
1285	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1286	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1287        /* change to EAPD mode */
1288	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1289	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1290
1291	{ }
1292};
1293
1294static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1295	/* Headphone output */
1296	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1297	/* Front output*/
1298	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1299	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1300
1301	/* Line In pin widget for input */
1302	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1303	/* CD pin widget for input */
1304	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1305	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1306	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1307
1308	/* change to EAPD mode */
1309	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1310	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1311
1312	{ }
1313};
1314
1315/*
1316 * LG m1 express dual
1317 *
1318 * Pin assignment:
1319 *   Rear Line-In/Out (blue): 0x14
1320 *   Build-in Mic-In: 0x15
1321 *   Speaker-out: 0x17
1322 *   HP-Out (green): 0x1b
1323 *   Mic-In/Out (red): 0x19
1324 *   SPDIF-Out: 0x1e
1325 */
1326
1327/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1328static hda_nid_t alc880_lg_dac_nids[3] = {
1329	0x05, 0x02, 0x03
1330};
1331
1332/* seems analog CD is not working */
1333static struct hda_input_mux alc880_lg_capture_source = {
1334	.num_items = 3,
1335	.items = {
1336		{ "Mic", 0x1 },
1337		{ "Line", 0x5 },
1338		{ "Internal Mic", 0x6 },
1339	},
1340};
1341
1342/* 2,4,6 channel modes */
1343static struct hda_verb alc880_lg_ch2_init[] = {
1344	/* set line-in and mic-in to input */
1345	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1346	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1347	{ }
1348};
1349
1350static struct hda_verb alc880_lg_ch4_init[] = {
1351	/* set line-in to out and mic-in to input */
1352	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1353	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1354	{ }
1355};
1356
1357static struct hda_verb alc880_lg_ch6_init[] = {
1358	/* set line-in and mic-in to output */
1359	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1360	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1361	{ }
1362};
1363
1364static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1365	{ 2, alc880_lg_ch2_init },
1366	{ 4, alc880_lg_ch4_init },
1367	{ 6, alc880_lg_ch6_init },
1368};
1369
1370static struct snd_kcontrol_new alc880_lg_mixer[] = {
1371	/* FIXME: it's not really "master" but front channels */
1372	HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1373	HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1374	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1375	HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1376	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1377	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1378	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1379	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1380	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1381	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1382	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1383	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1384	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1385	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1386	{
1387		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1388		.name = "Channel Mode",
1389		.info = alc_ch_mode_info,
1390		.get = alc_ch_mode_get,
1391		.put = alc_ch_mode_put,
1392	},
1393	{ } /* end */
1394};
1395
1396static struct hda_verb alc880_lg_init_verbs[] = {
1397	/* set capture source to mic-in */
1398	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1399	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1400	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1401	/* mute all amp mixer inputs */
1402	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1403	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
1404	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1405	/* line-in to input */
1406	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1407	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1408	/* built-in mic */
1409	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1410	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1411	/* speaker-out */
1412	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1413	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1414	/* mic-in to input */
1415	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1416	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1417	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1418	/* HP-out */
1419	{0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1420	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1421	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1422	/* jack sense */
1423	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1424	{ }
1425};
1426
1427/* toggle speaker-output according to the hp-jack state */
1428static void alc880_lg_automute(struct hda_codec *codec)
1429{
1430	unsigned int present;
1431
1432	present = snd_hda_codec_read(codec, 0x1b, 0,
1433				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1434	snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0,
1435				 0x80, present ? 0x80 : 0);
1436	snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0,
1437				 0x80, present ? 0x80 : 0);
1438}
1439
1440static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
1441{
1442	/* Looks like the unsol event is incompatible with the standard
1443	 * definition.  4bit tag is placed at 28 bit!
1444	 */
1445	if ((res >> 28) == 0x01)
1446		alc880_lg_automute(codec);
1447}
1448
1449/*
1450 * LG LW20
1451 *
1452 * Pin assignment:
1453 *   Speaker-out: 0x14
1454 *   Mic-In: 0x18
1455 *   Built-in Mic-In: 0x19 (?)
1456 *   HP-Out: 0x1b
1457 *   SPDIF-Out: 0x1e
1458 */
1459
1460/* seems analog CD is not working */
1461static struct hda_input_mux alc880_lg_lw_capture_source = {
1462	.num_items = 2,
1463	.items = {
1464		{ "Mic", 0x0 },
1465		{ "Internal Mic", 0x1 },
1466	},
1467};
1468
1469static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1470	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1471	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1472	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1473	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1474	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1475	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1476	{ } /* end */
1477};
1478
1479static struct hda_verb alc880_lg_lw_init_verbs[] = {
1480	/* set capture source to mic-in */
1481	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1482	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1483	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1484	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
1485	/* speaker-out */
1486	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1487	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1488	/* HP-out */
1489	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1490	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1491	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1492	/* mic-in to input */
1493	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1494	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495	/* built-in mic */
1496	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1497	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498	/* jack sense */
1499	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
1500	{ }
1501};
1502
1503/* toggle speaker-output according to the hp-jack state */
1504static void alc880_lg_lw_automute(struct hda_codec *codec)
1505{
1506	unsigned int present;
1507
1508	present = snd_hda_codec_read(codec, 0x1b, 0,
1509				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1510	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
1511				 0x80, present ? 0x80 : 0);
1512	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
1513				 0x80, present ? 0x80 : 0);
1514}
1515
1516static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
1517{
1518	/* Looks like the unsol event is incompatible with the standard
1519	 * definition.  4bit tag is placed at 28 bit!
1520	 */
1521	if ((res >> 28) == 0x01)
1522		alc880_lg_lw_automute(codec);
1523}
1524
1525/*
1526 * Common callbacks
1527 */
1528
1529static int alc_init(struct hda_codec *codec)
1530{
1531	struct alc_spec *spec = codec->spec;
1532	unsigned int i;
1533
1534	for (i = 0; i < spec->num_init_verbs; i++)
1535		snd_hda_sequence_write(codec, spec->init_verbs[i]);
1536
1537	if (spec->init_hook)
1538		spec->init_hook(codec);
1539
1540	return 0;
1541}
1542
1543static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1544{
1545	struct alc_spec *spec = codec->spec;
1546
1547	if (spec->unsol_event)
1548		spec->unsol_event(codec, res);
1549}
1550
1551#ifdef CONFIG_PM
1552/*
1553 * resume
1554 */
1555static int alc_resume(struct hda_codec *codec)
1556{
1557	struct alc_spec *spec = codec->spec;
1558	int i;
1559
1560	alc_init(codec);
1561	for (i = 0; i < spec->num_mixers; i++)
1562		snd_hda_resume_ctls(codec, spec->mixers[i]);
1563	if (spec->multiout.dig_out_nid)
1564		snd_hda_resume_spdif_out(codec);
1565	if (spec->dig_in_nid)
1566		snd_hda_resume_spdif_in(codec);
1567
1568	return 0;
1569}
1570#endif
1571
1572/*
1573 * Analog playback callbacks
1574 */
1575static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
1576				    struct hda_codec *codec,
1577				    struct snd_pcm_substream *substream)
1578{
1579	struct alc_spec *spec = codec->spec;
1580	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1581}
1582
1583static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1584				       struct hda_codec *codec,
1585				       unsigned int stream_tag,
1586				       unsigned int format,
1587				       struct snd_pcm_substream *substream)
1588{
1589	struct alc_spec *spec = codec->spec;
1590	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1591						format, substream);
1592}
1593
1594static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1595				       struct hda_codec *codec,
1596				       struct snd_pcm_substream *substream)
1597{
1598	struct alc_spec *spec = codec->spec;
1599	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1600}
1601
1602/*
1603 * Digital out
1604 */
1605static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1606					struct hda_codec *codec,
1607					struct snd_pcm_substream *substream)
1608{
1609	struct alc_spec *spec = codec->spec;
1610	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1611}
1612
1613static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1614					 struct hda_codec *codec,
1615					 struct snd_pcm_substream *substream)
1616{
1617	struct alc_spec *spec = codec->spec;
1618	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1619}
1620
1621/*
1622 * Analog capture
1623 */
1624static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1625				      struct hda_codec *codec,
1626				      unsigned int stream_tag,
1627				      unsigned int format,
1628				      struct snd_pcm_substream *substream)
1629{
1630	struct alc_spec *spec = codec->spec;
1631
1632	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1633				   stream_tag, 0, format);
1634	return 0;
1635}
1636
1637static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1638				      struct hda_codec *codec,
1639				      struct snd_pcm_substream *substream)
1640{
1641	struct alc_spec *spec = codec->spec;
1642
1643	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1644	return 0;
1645}
1646
1647
1648/*
1649 */
1650static struct hda_pcm_stream alc880_pcm_analog_playback = {
1651	.substreams = 1,
1652	.channels_min = 2,
1653	.channels_max = 8,
1654	/* NID is set in alc_build_pcms */
1655	.ops = {
1656		.open = alc880_playback_pcm_open,
1657		.prepare = alc880_playback_pcm_prepare,
1658		.cleanup = alc880_playback_pcm_cleanup
1659	},
1660};
1661
1662static struct hda_pcm_stream alc880_pcm_analog_capture = {
1663	.substreams = 2,
1664	.channels_min = 2,
1665	.channels_max = 2,
1666	/* NID is set in alc_build_pcms */
1667	.ops = {
1668		.prepare = alc880_capture_pcm_prepare,
1669		.cleanup = alc880_capture_pcm_cleanup
1670	},
1671};
1672
1673static struct hda_pcm_stream alc880_pcm_digital_playback = {
1674	.substreams = 1,
1675	.channels_min = 2,
1676	.channels_max = 2,
1677	/* NID is set in alc_build_pcms */
1678	.ops = {
1679		.open = alc880_dig_playback_pcm_open,
1680		.close = alc880_dig_playback_pcm_close
1681	},
1682};
1683
1684static struct hda_pcm_stream alc880_pcm_digital_capture = {
1685	.substreams = 1,
1686	.channels_min = 2,
1687	.channels_max = 2,
1688	/* NID is set in alc_build_pcms */
1689};
1690
1691/* Used by alc_build_pcms to flag that a PCM has no playback stream */
1692static struct hda_pcm_stream alc_pcm_null_playback = {
1693	.substreams = 0,
1694	.channels_min = 0,
1695	.channels_max = 0,
1696};
1697
1698static int alc_build_pcms(struct hda_codec *codec)
1699{
1700	struct alc_spec *spec = codec->spec;
1701	struct hda_pcm *info = spec->pcm_rec;
1702	int i;
1703
1704	codec->num_pcms = 1;
1705	codec->pcm_info = info;
1706
1707	info->name = spec->stream_name_analog;
1708	if (spec->stream_analog_playback) {
1709		snd_assert(spec->multiout.dac_nids, return -EINVAL);
1710		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1711		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
1712	}
1713	if (spec->stream_analog_capture) {
1714		snd_assert(spec->adc_nids, return -EINVAL);
1715		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1716		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1717	}
1718
1719	if (spec->channel_mode) {
1720		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1721		for (i = 0; i < spec->num_channel_mode; i++) {
1722			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1723				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1724			}
1725		}
1726	}
1727
1728	/* If the use of more than one ADC is requested for the current
1729	 * model, configure a second analog capture-only PCM.
1730	 */
1731	if (spec->num_adc_nids > 1) {
1732		codec->num_pcms++;
1733		info++;
1734		info->name = spec->stream_name_analog;
1735		/* No playback stream for second PCM */
1736		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
1737		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
1738		if (spec->stream_analog_capture) {
1739			snd_assert(spec->adc_nids, return -EINVAL);
1740			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1741			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
1742		}
1743	}
1744
1745	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1746		codec->num_pcms++;
1747		info++;
1748		info->name = spec->stream_name_digital;
1749		if (spec->multiout.dig_out_nid &&
1750		    spec->stream_digital_playback) {
1751			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
1752			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1753		}
1754		if (spec->dig_in_nid &&
1755		    spec->stream_digital_capture) {
1756			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
1757			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1758		}
1759	}
1760
1761	return 0;
1762}
1763
1764static void alc_free(struct hda_codec *codec)
1765{
1766	struct alc_spec *spec = codec->spec;
1767	unsigned int i;
1768
1769	if (! spec)
1770		return;
1771
1772	if (spec->kctl_alloc) {
1773		for (i = 0; i < spec->num_kctl_used; i++)
1774			kfree(spec->kctl_alloc[i].name);
1775		kfree(spec->kctl_alloc);
1776	}
1777	kfree(spec);
1778}
1779
1780/*
1781 */
1782static struct hda_codec_ops alc_patch_ops = {
1783	.build_controls = alc_build_controls,
1784	.build_pcms = alc_build_pcms,
1785	.init = alc_init,
1786	.free = alc_free,
1787	.unsol_event = alc_unsol_event,
1788#ifdef CONFIG_PM
1789	.resume = alc_resume,
1790#endif
1791};
1792
1793
1794/*
1795 * Test configuration for debugging
1796 *
1797 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
1798 * enum controls.
1799 */
1800#ifdef CONFIG_SND_DEBUG
1801static hda_nid_t alc880_test_dac_nids[4] = {
1802	0x02, 0x03, 0x04, 0x05
1803};
1804
1805static struct hda_input_mux alc880_test_capture_source = {
1806	.num_items = 7,
1807	.items = {
1808		{ "In-1", 0x0 },
1809		{ "In-2", 0x1 },
1810		{ "In-3", 0x2 },
1811		{ "In-4", 0x3 },
1812		{ "CD", 0x4 },
1813		{ "Front", 0x5 },
1814		{ "Surround", 0x6 },
1815	},
1816};
1817
1818static struct hda_channel_mode alc880_test_modes[4] = {
1819	{ 2, NULL },
1820	{ 4, NULL },
1821	{ 6, NULL },
1822	{ 8, NULL },
1823};
1824
1825static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1826{
1827	static char *texts[] = {
1828		"N/A", "Line Out", "HP Out",
1829		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1830	};
1831	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1832	uinfo->count = 1;
1833	uinfo->value.enumerated.items = 8;
1834	if (uinfo->value.enumerated.item >= 8)
1835		uinfo->value.enumerated.item = 7;
1836	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1837	return 0;
1838}
1839
1840static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1841{
1842	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1843	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1844	unsigned int pin_ctl, item = 0;
1845
1846	pin_ctl = snd_hda_codec_read(codec, nid, 0,
1847				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1848	if (pin_ctl & AC_PINCTL_OUT_EN) {
1849		if (pin_ctl & AC_PINCTL_HP_EN)
1850			item = 2;
1851		else
1852			item = 1;
1853	} else if (pin_ctl & AC_PINCTL_IN_EN) {
1854		switch (pin_ctl & AC_PINCTL_VREFEN) {
1855		case AC_PINCTL_VREF_HIZ: item = 3; break;
1856		case AC_PINCTL_VREF_50:  item = 4; break;
1857		case AC_PINCTL_VREF_GRD: item = 5; break;
1858		case AC_PINCTL_VREF_80:  item = 6; break;
1859		case AC_PINCTL_VREF_100: item = 7; break;
1860		}
1861	}
1862	ucontrol->value.enumerated.item[0] = item;
1863	return 0;
1864}
1865
1866static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1867{
1868	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1869	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1870	static unsigned int ctls[] = {
1871		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1872		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1873		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1874		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1875		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1876		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1877	};
1878	unsigned int old_ctl, new_ctl;
1879
1880	old_ctl = snd_hda_codec_read(codec, nid, 0,
1881				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1882	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1883	if (old_ctl != new_ctl) {
1884		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
1885		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1886				    ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
1887		return 1;
1888	}
1889	return 0;
1890}
1891
1892static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1893{
1894	static char *texts[] = {
1895		"Front", "Surround", "CLFE", "Side"
1896	};
1897	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1898	uinfo->count = 1;
1899	uinfo->value.enumerated.items = 4;
1900	if (uinfo->value.enumerated.item >= 4)
1901		uinfo->value.enumerated.item = 3;
1902	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1903	return 0;
1904}
1905
1906static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1907{
1908	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1909	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1910	unsigned int sel;
1911
1912	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1913	ucontrol->value.enumerated.item[0] = sel & 3;
1914	return 0;
1915}
1916
1917static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1918{
1919	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1920	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1921	unsigned int sel;
1922
1923	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1924	if (ucontrol->value.enumerated.item[0] != sel) {
1925		sel = ucontrol->value.enumerated.item[0] & 3;
1926		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
1927		return 1;
1928	}
1929	return 0;
1930}
1931
1932#define PIN_CTL_TEST(xname,nid) {			\
1933		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
1934			.name = xname,		       \
1935			.info = alc_test_pin_ctl_info, \
1936			.get = alc_test_pin_ctl_get,   \
1937			.put = alc_test_pin_ctl_put,   \
1938			.private_value = nid	       \
1939			}
1940
1941#define PIN_SRC_TEST(xname,nid) {			\
1942		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
1943			.name = xname,		       \
1944			.info = alc_test_pin_src_info, \
1945			.get = alc_test_pin_src_get,   \
1946			.put = alc_test_pin_src_put,   \
1947			.private_value = nid	       \
1948			}
1949
1950static struct snd_kcontrol_new alc880_test_mixer[] = {
1951	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1952	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1953	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1954	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1955	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1956	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1957	HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1958	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1959	PIN_CTL_TEST("Front Pin Mode", 0x14),
1960	PIN_CTL_TEST("Surround Pin Mode", 0x15),
1961	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1962	PIN_CTL_TEST("Side Pin Mode", 0x17),
1963	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1964	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1965	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1966	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1967	PIN_SRC_TEST("In-1 Pin Source", 0x18),
1968	PIN_SRC_TEST("In-2 Pin Source", 0x19),
1969	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1970	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1971	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1972	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1973	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1974	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1975	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1976	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1977	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1978	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1979	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1980	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1981	{
1982		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1983		.name = "Channel Mode",
1984		.info = alc_ch_mode_info,
1985		.get = alc_ch_mode_get,
1986		.put = alc_ch_mode_put,
1987	},
1988	{ } /* end */
1989};
1990
1991static struct hda_verb alc880_test_init_verbs[] = {
1992	/* Unmute inputs of 0x0c - 0x0f */
1993	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1994	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1995	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1996	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1997	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1998	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1999	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2000	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2001	/* Vol output for 0x0c-0x0f */
2002	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2003	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2004	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2005	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2006	/* Set output pins 0x14-0x17 */
2007	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2008	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2009	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2010	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2011	/* Unmute output pins 0x14-0x17 */
2012	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2013	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2014	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2015	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2016	/* Set input pins 0x18-0x1c */
2017	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2018	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2019	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2020	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2021	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2022	/* Mute input pins 0x18-0x1b */
2023	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2024	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2025	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2026	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2027	/* ADC set up */
2028	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2029	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2030	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2031	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2032	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2033	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2034	/* Analog input/passthru */
2035	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2036	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2037	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2038	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2039	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2040	{ }
2041};
2042#endif
2043
2044/*
2045 */
2046
2047static struct hda_board_config alc880_cfg_tbl[] = {
2048	/* Back 3 jack, front 2 jack */
2049	{ .modelname = "3stack", .config = ALC880_3ST },
2050	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
2051	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
2052	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
2053	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
2054	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
2055	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
2056	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
2057	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
2058	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
2059	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
2060	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
2061	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
2062	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
2063	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
2064	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
2065	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
2066	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
2067	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
2068	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
2069	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
2070	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
2071	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
2072	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
2073	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
2074	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
2075	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
2076	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
2077	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
2078	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
2079	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
2080	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
2081	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
2082	/* TCL S700 */
2083	{ .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 },
2084
2085	/* Back 3 jack, front 2 jack (Internal add Aux-In) */
2086	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
2087	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST },
2088	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST },
2089
2090	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
2091	{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
2092	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
2093	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG },
2094	/* Clevo m520G NB */
2095	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, .config = ALC880_CLEVO },
2096
2097	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
2098	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
2099	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
2100	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
2101
2102	/* Back 5 jack, front 2 jack */
2103	{ .modelname = "5stack", .config = ALC880_5ST },
2104	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
2105	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
2106	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
2107	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
2108	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
2109
2110	/* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
2111	{ .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
2112	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
2113	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
2114	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
2115	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
2116	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
2117	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
2118	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
2119	{ .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
2120	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
2121	{ .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560,
2122	  .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */
2123	/* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */
2124	{ .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
2125	/* note subvendor = 0 below */
2126	/* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */
2127
2128	{ .modelname = "w810", .config = ALC880_W810 },
2129	{ .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
2130
2131	{ .modelname = "z71v", .config = ALC880_Z71V },
2132	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
2133
2134	{ .modelname = "6stack", .config = ALC880_6ST },
2135	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */
2136	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST },
2137	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
2138	{ .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */
2139
2140	{ .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
2141	{ .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
2142	{ .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
2143	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
2144	{ .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
2145	{ .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG },
2146	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG },
2147	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG },
2148	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
2149	{ .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
2150	{ .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */
2151
2152	{ .modelname = "asus", .config = ALC880_ASUS },
2153	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
2154	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
2155	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
2156	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
2157	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG },
2158	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
2159	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
2160	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
2161	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
2162	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
2163	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
2164	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */
2165	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
2166
2167	{ .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
2168	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
2169
2170	{ .modelname = "F1734", .config = ALC880_F1734 },
2171	{ .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
2172	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 },
2173
2174	{ .modelname = "lg", .config = ALC880_LG },
2175	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2176
2177	{ .modelname = "lg-lw", .config = ALC880_LG_LW },
2178	{ .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
2179
2180#ifdef CONFIG_SND_DEBUG
2181	{ .modelname = "test", .config = ALC880_TEST },
2182#endif
2183	{ .modelname = "auto", .config = ALC880_AUTO },
2184
2185	{}
2186};
2187
2188/*
2189 * ALC880 codec presets
2190 */
2191static struct alc_config_preset alc880_presets[] = {
2192	[ALC880_3ST] = {
2193		.mixers = { alc880_three_stack_mixer },
2194		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2195		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2196		.dac_nids = alc880_dac_nids,
2197		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2198		.channel_mode = alc880_threestack_modes,
2199		.input_mux = &alc880_capture_source,
2200	},
2201	[ALC880_3ST_DIG] = {
2202		.mixers = { alc880_three_stack_mixer },
2203		.init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs },
2204		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2205		.dac_nids = alc880_dac_nids,
2206		.dig_out_nid = ALC880_DIGOUT_NID,
2207		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2208		.channel_mode = alc880_threestack_modes,
2209		.input_mux = &alc880_capture_source,
2210	},
2211	[ALC880_TCL_S700] = {
2212		.mixers = { alc880_tcl_s700_mixer },
2213		.init_verbs = { alc880_volume_init_verbs,
2214				alc880_pin_tcl_S700_init_verbs,
2215				alc880_gpio2_init_verbs },
2216		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2217		.dac_nids = alc880_dac_nids,
2218		.hp_nid = 0x03,
2219		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2220		.channel_mode = alc880_2_jack_modes,
2221		.input_mux = &alc880_capture_source,
2222	},
2223	[ALC880_5ST] = {
2224		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
2225		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2226		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2227		.dac_nids = alc880_dac_nids,
2228		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2229		.channel_mode = alc880_fivestack_modes,
2230		.input_mux = &alc880_capture_source,
2231	},
2232	[ALC880_5ST_DIG] = {
2233		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer },
2234		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
2235		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2236		.dac_nids = alc880_dac_nids,
2237		.dig_out_nid = ALC880_DIGOUT_NID,
2238		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2239		.channel_mode = alc880_fivestack_modes,
2240		.input_mux = &alc880_capture_source,
2241	},
2242	[ALC880_6ST] = {
2243		.mixers = { alc880_six_stack_mixer },
2244		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2245		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2246		.dac_nids = alc880_6st_dac_nids,
2247		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2248		.channel_mode = alc880_sixstack_modes,
2249		.input_mux = &alc880_6stack_capture_source,
2250	},
2251	[ALC880_6ST_DIG] = {
2252		.mixers = { alc880_six_stack_mixer },
2253		.init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs },
2254		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2255		.dac_nids = alc880_6st_dac_nids,
2256		.dig_out_nid = ALC880_DIGOUT_NID,
2257		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2258		.channel_mode = alc880_sixstack_modes,
2259		.input_mux = &alc880_6stack_capture_source,
2260	},
2261	[ALC880_W810] = {
2262		.mixers = { alc880_w810_base_mixer },
2263		.init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs,
2264				alc880_gpio2_init_verbs },
2265		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2266		.dac_nids = alc880_w810_dac_nids,
2267		.dig_out_nid = ALC880_DIGOUT_NID,
2268		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2269		.channel_mode = alc880_w810_modes,
2270		.input_mux = &alc880_capture_source,
2271	},
2272	[ALC880_Z71V] = {
2273		.mixers = { alc880_z71v_mixer },
2274		.init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs },
2275		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2276		.dac_nids = alc880_z71v_dac_nids,
2277		.dig_out_nid = ALC880_DIGOUT_NID,
2278		.hp_nid = 0x03,
2279		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2280		.channel_mode = alc880_2_jack_modes,
2281		.input_mux = &alc880_capture_source,
2282	},
2283	[ALC880_F1734] = {
2284		.mixers = { alc880_f1734_mixer },
2285		.init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs },
2286		.num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2287		.dac_nids = alc880_f1734_dac_nids,
2288		.hp_nid = 0x02,
2289		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2290		.channel_mode = alc880_2_jack_modes,
2291		.input_mux = &alc880_capture_source,
2292	},
2293	[ALC880_ASUS] = {
2294		.mixers = { alc880_asus_mixer },
2295		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2296				alc880_gpio1_init_verbs },
2297		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2298		.dac_nids = alc880_asus_dac_nids,
2299		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2300		.channel_mode = alc880_asus_modes,
2301		.input_mux = &alc880_capture_source,
2302	},
2303	[ALC880_ASUS_DIG] = {
2304		.mixers = { alc880_asus_mixer },
2305		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2306				alc880_gpio1_init_verbs },
2307		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2308		.dac_nids = alc880_asus_dac_nids,
2309		.dig_out_nid = ALC880_DIGOUT_NID,
2310		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2311		.channel_mode = alc880_asus_modes,
2312		.input_mux = &alc880_capture_source,
2313	},
2314	[ALC880_ASUS_DIG2] = {
2315		.mixers = { alc880_asus_mixer },
2316		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2317				alc880_gpio2_init_verbs }, /* use GPIO2 */
2318		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2319		.dac_nids = alc880_asus_dac_nids,
2320		.dig_out_nid = ALC880_DIGOUT_NID,
2321		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2322		.channel_mode = alc880_asus_modes,
2323		.input_mux = &alc880_capture_source,
2324	},
2325	[ALC880_ASUS_W1V] = {
2326		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2327		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
2328				alc880_gpio1_init_verbs },
2329		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2330		.dac_nids = alc880_asus_dac_nids,
2331		.dig_out_nid = ALC880_DIGOUT_NID,
2332		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2333		.channel_mode = alc880_asus_modes,
2334		.input_mux = &alc880_capture_source,
2335	},
2336	[ALC880_UNIWILL_DIG] = {
2337		.mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2338		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs },
2339		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2340		.dac_nids = alc880_asus_dac_nids,
2341		.dig_out_nid = ALC880_DIGOUT_NID,
2342		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2343		.channel_mode = alc880_asus_modes,
2344		.input_mux = &alc880_capture_source,
2345	},
2346	[ALC880_CLEVO] = {
2347		.mixers = { alc880_three_stack_mixer },
2348		.init_verbs = { alc880_volume_init_verbs,
2349				alc880_pin_clevo_init_verbs },
2350		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2351		.dac_nids = alc880_dac_nids,
2352		.hp_nid = 0x03,
2353		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2354		.channel_mode = alc880_threestack_modes,
2355		.input_mux = &alc880_capture_source,
2356	},
2357	[ALC880_LG] = {
2358		.mixers = { alc880_lg_mixer },
2359		.init_verbs = { alc880_volume_init_verbs,
2360				alc880_lg_init_verbs },
2361		.num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
2362		.dac_nids = alc880_lg_dac_nids,
2363		.dig_out_nid = ALC880_DIGOUT_NID,
2364		.num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
2365		.channel_mode = alc880_lg_ch_modes,
2366		.input_mux = &alc880_lg_capture_source,
2367		.unsol_event = alc880_lg_unsol_event,
2368		.init_hook = alc880_lg_automute,
2369	},
2370	[ALC880_LG_LW] = {
2371		.mixers = { alc880_lg_lw_mixer },
2372		.init_verbs = { alc880_volume_init_verbs,
2373				alc880_lg_lw_init_verbs },
2374		.num_dacs = 1,
2375		.dac_nids = alc880_dac_nids,
2376		.dig_out_nid = ALC880_DIGOUT_NID,
2377		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2378		.channel_mode = alc880_2_jack_modes,
2379		.input_mux = &alc880_lg_lw_capture_source,
2380		.unsol_event = alc880_lg_lw_unsol_event,
2381		.init_hook = alc880_lg_lw_automute,
2382	},
2383#ifdef CONFIG_SND_DEBUG
2384	[ALC880_TEST] = {
2385		.mixers = { alc880_test_mixer },
2386		.init_verbs = { alc880_test_init_verbs },
2387		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2388		.dac_nids = alc880_test_dac_nids,
2389		.dig_out_nid = ALC880_DIGOUT_NID,
2390		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2391		.channel_mode = alc880_test_modes,
2392		.input_mux = &alc880_test_capture_source,
2393	},
2394#endif
2395};
2396
2397/*
2398 * Automatic parse of I/O pins from the BIOS configuration
2399 */
2400
2401#define NUM_CONTROL_ALLOC	32
2402#define NUM_VERB_ALLOC		32
2403
2404enum {
2405	ALC_CTL_WIDGET_VOL,
2406	ALC_CTL_WIDGET_MUTE,
2407	ALC_CTL_BIND_MUTE,
2408};
2409static struct snd_kcontrol_new alc880_control_templates[] = {
2410	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2411	HDA_CODEC_MUTE(NULL, 0, 0, 0),
2412	HDA_BIND_MUTE(NULL, 0, 0, 0),
2413};
2414
2415/* add dynamic controls */
2416static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
2417{
2418	struct snd_kcontrol_new *knew;
2419
2420	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
2421		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
2422
2423		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
2424		if (! knew)
2425			return -ENOMEM;
2426		if (spec->kctl_alloc) {
2427			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2428			kfree(spec->kctl_alloc);
2429		}
2430		spec->kctl_alloc = knew;
2431		spec->num_kctl_alloc = num;
2432	}
2433
2434	knew = &spec->kctl_alloc[spec->num_kctl_used];
2435	*knew = alc880_control_templates[type];
2436	knew->name = kstrdup(name, GFP_KERNEL);
2437	if (! knew->name)
2438		return -ENOMEM;
2439	knew->private_value = val;
2440	spec->num_kctl_used++;
2441	return 0;
2442}
2443
2444#define alc880_is_fixed_pin(nid)	((nid) >= 0x14 && (nid) <= 0x17)
2445#define alc880_fixed_pin_idx(nid)	((nid) - 0x14)
2446#define alc880_is_multi_pin(nid)	((nid) >= 0x18)
2447#define alc880_multi_pin_idx(nid)	((nid) - 0x18)
2448#define alc880_is_input_pin(nid)	((nid) >= 0x18)
2449#define alc880_input_pin_idx(nid)	((nid) - 0x18)
2450#define alc880_idx_to_dac(nid)		((nid) + 0x02)
2451#define alc880_dac_to_idx(nid)		((nid) - 0x02)
2452#define alc880_idx_to_mixer(nid)	((nid) + 0x0c)
2453#define alc880_idx_to_selector(nid)	((nid) + 0x10)
2454#define ALC880_PIN_CD_NID		0x1c
2455
2456/* fill in the dac_nids table from the parsed pin configuration */
2457static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
2458{
2459	hda_nid_t nid;
2460	int assigned[4];
2461	int i, j;
2462
2463	memset(assigned, 0, sizeof(assigned));
2464	spec->multiout.dac_nids = spec->private_dac_nids;
2465
2466	/* check the pins hardwired to audio widget */
2467	for (i = 0; i < cfg->line_outs; i++) {
2468		nid = cfg->line_out_pins[i];
2469		if (alc880_is_fixed_pin(nid)) {
2470			int idx = alc880_fixed_pin_idx(nid);
2471			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
2472			assigned[idx] = 1;
2473		}
2474	}
2475	/* left pins can be connect to any audio widget */
2476	for (i = 0; i < cfg->line_outs; i++) {
2477		nid = cfg->line_out_pins[i];
2478		if (alc880_is_fixed_pin(nid))
2479			continue;
2480		/* search for an empty channel */
2481		for (j = 0; j < cfg->line_outs; j++) {
2482			if (! assigned[j]) {
2483				spec->multiout.dac_nids[i] = alc880_idx_to_dac(j);
2484				assigned[j] = 1;
2485				break;
2486			}
2487		}
2488	}
2489	spec->multiout.num_dacs = cfg->line_outs;
2490	return 0;
2491}
2492
2493/* add playback controls from the parsed DAC table */
2494static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
2495					     const struct auto_pin_cfg *cfg)
2496{
2497	char name[32];
2498	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
2499	hda_nid_t nid;
2500	int i, err;
2501
2502	for (i = 0; i < cfg->line_outs; i++) {
2503		if (! spec->multiout.dac_nids[i])
2504			continue;
2505		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
2506		if (i == 2) {
2507			/* Center/LFE */
2508			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume",
2509					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
2510				return err;
2511			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume",
2512					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
2513				return err;
2514			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
2515					       HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0)
2516				return err;
2517			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
2518					       HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0)
2519				return err;
2520		} else {
2521			sprintf(name, "%s Playback Volume", chname[i]);
2522			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2523					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2524				return err;
2525			sprintf(name, "%s Playback Switch", chname[i]);
2526			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2527					       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2528				return err;
2529		}
2530	}
2531	return 0;
2532}
2533
2534/* add playback controls for speaker and HP outputs */
2535static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
2536					const char *pfx)
2537{
2538	hda_nid_t nid;
2539	int err;
2540	char name[32];
2541
2542	if (! pin)
2543		return 0;
2544
2545	if (alc880_is_fixed_pin(pin)) {
2546		nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
2547		/* specify the DAC as the extra output */
2548		if (! spec->multiout.hp_nid)
2549			spec->multiout.hp_nid = nid;
2550		else
2551			spec->multiout.extra_out_nid[0] = nid;
2552		/* control HP volume/switch on the output mixer amp */
2553		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
2554		sprintf(name, "%s Playback Volume", pfx);
2555		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2556				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
2557			return err;
2558		sprintf(name, "%s Playback Switch", pfx);
2559		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
2560				       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2561			return err;
2562	} else if (alc880_is_multi_pin(pin)) {
2563		/* set manual connection */
2564		/* we have only a switch on HP-out PIN */
2565		sprintf(name, "%s Playback Switch", pfx);
2566		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2567				       HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
2568			return err;
2569	}
2570	return 0;
2571}
2572
2573/* create input playback/capture controls for the given pin */
2574static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
2575			    int idx, hda_nid_t mix_nid)
2576{
2577	char name[32];
2578	int err;
2579
2580	sprintf(name, "%s Playback Volume", ctlname);
2581	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
2582			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2583		return err;
2584	sprintf(name, "%s Playback Switch", ctlname);
2585	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
2586			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
2587		return err;
2588	return 0;
2589}
2590
2591/* create playback/capture controls for input pins */
2592static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
2593						const struct auto_pin_cfg *cfg)
2594{
2595	struct hda_input_mux *imux = &spec->private_imux;
2596	int i, err, idx;
2597
2598	for (i = 0; i < AUTO_PIN_LAST; i++) {
2599		if (alc880_is_input_pin(cfg->input_pins[i])) {
2600			idx = alc880_input_pin_idx(cfg->input_pins[i]);
2601			err = new_analog_input(spec, cfg->input_pins[i],
2602					       auto_pin_cfg_labels[i],
2603					       idx, 0x0b);
2604			if (err < 0)
2605				return err;
2606			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2607			imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
2608			imux->num_items++;
2609		}
2610	}
2611	return 0;
2612}
2613
2614static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
2615					      hda_nid_t nid, int pin_type,
2616					      int dac_idx)
2617{
2618	/* set as output */
2619	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
2620	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
2621	/* need the manual connection? */
2622	if (alc880_is_multi_pin(nid)) {
2623		struct alc_spec *spec = codec->spec;
2624		int idx = alc880_multi_pin_idx(nid);
2625		snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
2626				    AC_VERB_SET_CONNECT_SEL,
2627				    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
2628	}
2629}
2630
2631static void alc880_auto_init_multi_out(struct hda_codec *codec)
2632{
2633	struct alc_spec *spec = codec->spec;
2634	int i;
2635
2636	for (i = 0; i < spec->autocfg.line_outs; i++) {
2637		hda_nid_t nid = spec->autocfg.line_out_pins[i];
2638		alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
2639	}
2640}
2641
2642static void alc880_auto_init_extra_out(struct hda_codec *codec)
2643{
2644	struct alc_spec *spec = codec->spec;
2645	hda_nid_t pin;
2646
2647	pin = spec->autocfg.speaker_pins[0];
2648	if (pin) /* connect to front */
2649		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
2650	pin = spec->autocfg.hp_pin;
2651	if (pin) /* connect to front */
2652		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
2653}
2654
2655static void alc880_auto_init_analog_input(struct hda_codec *codec)
2656{
2657	struct alc_spec *spec = codec->spec;
2658	int i;
2659
2660	for (i = 0; i < AUTO_PIN_LAST; i++) {
2661		hda_nid_t nid = spec->autocfg.input_pins[i];
2662		if (alc880_is_input_pin(nid)) {
2663			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2664					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
2665			if (nid != ALC880_PIN_CD_NID)
2666				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2667						    AMP_OUT_MUTE);
2668		}
2669	}
2670}
2671
2672/* parse the BIOS configuration and set up the alc_spec */
2673/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
2674static int alc880_parse_auto_config(struct hda_codec *codec)
2675{
2676	struct alc_spec *spec = codec->spec;
2677	int err;
2678	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
2679
2680	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
2681						alc880_ignore)) < 0)
2682		return err;
2683	if (! spec->autocfg.line_outs)
2684		return 0; /* can't find valid BIOS pin config */
2685
2686	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
2687	    (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
2688	    (err = alc880_auto_create_extra_out(spec,
2689						spec->autocfg.speaker_pins[0],
2690						"Speaker")) < 0 ||
2691	    (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin,
2692						"Headphone")) < 0 ||
2693	    (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
2694		return err;
2695
2696	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2697
2698	if (spec->autocfg.dig_out_pin)
2699		spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
2700	if (spec->autocfg.dig_in_pin)
2701		spec->dig_in_nid = ALC880_DIGIN_NID;
2702
2703	if (spec->kctl_alloc)
2704		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
2705
2706	spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
2707
2708	spec->num_mux_defs = 1;
2709	spec->input_mux = &spec->private_imux;
2710
2711	return 1;
2712}
2713
2714/* additional initialization for auto-configuration model */
2715static void alc880_auto_init(struct hda_codec *codec)
2716{
2717	alc880_auto_init_multi_out(codec);
2718	alc880_auto_init_extra_out(codec);
2719	alc880_auto_init_analog_input(codec);
2720}
2721
2722/*
2723 * OK, here we have finally the patch for ALC880
2724 */
2725
2726static int patch_alc880(struct hda_codec *codec)
2727{
2728	struct alc_spec *spec;
2729	int board_config;
2730	int err;
2731
2732	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2733	if (spec == NULL)
2734		return -ENOMEM;
2735
2736	codec->spec = spec;
2737
2738	board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
2739	if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {
2740		printk(KERN_INFO "hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...\n");
2741		board_config = ALC880_AUTO;
2742	}
2743
2744	if (board_config == ALC880_AUTO) {
2745		/* automatic parse from the BIOS config */
2746		err = alc880_parse_auto_config(codec);
2747		if (err < 0) {
2748			alc_free(codec);
2749			return err;
2750		} else if (! err) {
2751			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 3-stack mode...\n");
2752			board_config = ALC880_3ST;
2753		}
2754	}
2755
2756	if (board_config != ALC880_AUTO)
2757		setup_preset(spec, &alc880_presets[board_config]);
2758
2759	spec->stream_name_analog = "ALC880 Analog";
2760	spec->stream_analog_playback = &alc880_pcm_analog_playback;
2761	spec->stream_analog_capture = &alc880_pcm_analog_capture;
2762
2763	spec->stream_name_digital = "ALC880 Digital";
2764	spec->stream_digital_playback = &alc880_pcm_digital_playback;
2765	spec->stream_digital_capture = &alc880_pcm_digital_capture;
2766
2767	if (! spec->adc_nids && spec->input_mux) {
2768		/* check whether NID 0x07 is valid */
2769		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
2770		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
2771		if (wcap != AC_WID_AUD_IN) {
2772			spec->adc_nids = alc880_adc_nids_alt;
2773			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
2774			spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer;
2775			spec->num_mixers++;
2776		} else {
2777			spec->adc_nids = alc880_adc_nids;
2778			spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
2779			spec->mixers[spec->num_mixers] = alc880_capture_mixer;
2780			spec->num_mixers++;
2781		}
2782	}
2783
2784	codec->patch_ops = alc_patch_ops;
2785	if (board_config == ALC880_AUTO)
2786		spec->init_hook = alc880_auto_init;
2787
2788	return 0;
2789}
2790
2791
2792/*
2793 * ALC260 support
2794 */
2795
2796static hda_nid_t alc260_dac_nids[1] = {
2797	/* front */
2798	0x02,
2799};
2800
2801static hda_nid_t alc260_adc_nids[1] = {
2802	/* ADC0 */
2803	0x04,
2804};
2805
2806static hda_nid_t alc260_adc_nids_alt[1] = {
2807	/* ADC1 */
2808	0x05,
2809};
2810
2811static hda_nid_t alc260_hp_adc_nids[2] = {
2812	/* ADC1, 0 */
2813	0x05, 0x04
2814};
2815
2816/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
2817 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
2818 */
2819static hda_nid_t alc260_dual_adc_nids[2] = {
2820	/* ADC0, ADC1 */
2821	0x04, 0x05
2822};
2823
2824#define ALC260_DIGOUT_NID	0x03
2825#define ALC260_DIGIN_NID	0x06
2826
2827static struct hda_input_mux alc260_capture_source = {
2828	.num_items = 4,
2829	.items = {
2830		{ "Mic", 0x0 },
2831		{ "Front Mic", 0x1 },
2832		{ "Line", 0x2 },
2833		{ "CD", 0x4 },
2834	},
2835};
2836
2837/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
2838 * headphone jack and the internal CD lines since these are the only pins at
2839 * which audio can appear.  For flexibility, also allow the option of
2840 * recording the mixer output on the second ADC (ADC0 doesn't have a
2841 * connection to the mixer output).
2842 */
2843static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
2844	{
2845		.num_items = 3,
2846		.items = {
2847			{ "Mic/Line", 0x0 },
2848			{ "CD", 0x4 },
2849			{ "Headphone", 0x2 },
2850		},
2851	},
2852	{
2853		.num_items = 4,
2854		.items = {
2855			{ "Mic/Line", 0x0 },
2856			{ "CD", 0x4 },
2857			{ "Headphone", 0x2 },
2858			{ "Mixer", 0x5 },
2859		},
2860	},
2861
2862};
2863
2864/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
2865 * the Fujitsu S702x, but jacks are marked differently.
2866 */
2867static struct hda_input_mux alc260_acer_capture_sources[2] = {
2868	{
2869		.num_items = 4,
2870		.items = {
2871			{ "Mic", 0x0 },
2872			{ "Line", 0x2 },
2873			{ "CD", 0x4 },
2874			{ "Headphone", 0x5 },
2875		},
2876	},
2877	{
2878		.num_items = 5,
2879		.items = {
2880			{ "Mic", 0x0 },
2881			{ "Line", 0x2 },
2882			{ "CD", 0x4 },
2883			{ "Headphone", 0x6 },
2884			{ "Mixer", 0x5 },
2885		},
2886	},
2887};
2888/*
2889 * This is just place-holder, so there's something for alc_build_pcms to look
2890 * at when it calculates the maximum number of channels. ALC260 has no mixer
2891 * element which allows changing the channel mode, so the verb list is
2892 * never used.
2893 */
2894static struct hda_channel_mode alc260_modes[1] = {
2895	{ 2, NULL },
2896};
2897
2898
2899/* Mixer combinations
2900 *
2901 * basic: base_output + input + pc_beep + capture
2902 * HP: base_output + input + capture_alt
2903 * HP_3013: hp_3013 + input + capture
2904 * fujitsu: fujitsu + capture
2905 * acer: acer + capture
2906 */
2907
2908static struct snd_kcontrol_new alc260_base_output_mixer[] = {
2909	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2910	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
2911	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2912	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
2913	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2914	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
2915	{ } /* end */
2916};
2917
2918static struct snd_kcontrol_new alc260_input_mixer[] = {
2919	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2920	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2921	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2922	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2923	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2924	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2925	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
2926	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
2927	{ } /* end */
2928};
2929
2930static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
2931	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
2932	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
2933	{ } /* end */
2934};
2935
2936static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
2937	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2938	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
2939	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
2940	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
2941	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2942	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2943	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2944	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
2945	{ } /* end */
2946};
2947
2948/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
2949 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
2950 */
2951static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
2952	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2953	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
2954	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
2955	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2956	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2957	HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
2958	HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
2959	ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
2960	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
2961	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
2962	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2963	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
2964	{ } /* end */
2965};
2966
2967/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
2968 * versions of the ALC260 don't act on requests to enable mic bias from NID
2969 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
2970 * datasheet doesn't mention this restriction.  At this stage it's not clear
2971 * whether this behaviour is intentional or is a hardware bug in chip
2972 * revisions available in early 2006.  Therefore for now allow the
2973 * "Headphone Jack Mode" control to span all choices, but if it turns out
2974 * that the lack of mic bias for this NID is intentional we could change the
2975 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
2976 *
2977 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
2978 * don't appear to make the mic bias available from the "line" jack, even
2979 * though the NID used for this jack (0x14) can supply it.  The theory is
2980 * that perhaps Acer have included blocking capacitors between the ALC260
2981 * and the output jack.  If this turns out to be the case for all such
2982 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
2983 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
2984 */
2985static struct snd_kcontrol_new alc260_acer_mixer[] = {
2986	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2987	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
2988	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
2989	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2990	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2991	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2992	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2993	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
2994	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2995	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2996	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
2997	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
2998	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
2999	{ } /* end */
3000};
3001
3002/* capture mixer elements */
3003static struct snd_kcontrol_new alc260_capture_mixer[] = {
3004	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3005	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3006	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3007	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3008	{
3009		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3010		/* The multiple "Capture Source" controls confuse alsamixer
3011		 * So call somewhat different..
3012		 * FIXME: the controls appear in the "playback" view!
3013		 */
3014		/* .name = "Capture Source", */
3015		.name = "Input Source",
3016		.count = 2,
3017		.info = alc_mux_enum_info,
3018		.get = alc_mux_enum_get,
3019		.put = alc_mux_enum_put,
3020	},
3021	{ } /* end */
3022};
3023
3024static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3025	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3026	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3027	{
3028		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3029		/* The multiple "Capture Source" controls confuse alsamixer
3030		 * So call somewhat different..
3031		 * FIXME: the controls appear in the "playback" view!
3032		 */
3033		/* .name = "Capture Source", */
3034		.name = "Input Source",
3035		.count = 1,
3036		.info = alc_mux_enum_info,
3037		.get = alc_mux_enum_get,
3038		.put = alc_mux_enum_put,
3039	},
3040	{ } /* end */
3041};
3042
3043/*
3044 * initialization verbs
3045 */
3046static struct hda_verb alc260_init_verbs[] = {
3047	/* Line In pin widget for input */
3048	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3049	/* CD pin widget for input */
3050	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3051	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3052	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3053	/* Mic2 (front panel) pin widget for input and vref at 80% */
3054	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3055	/* LINE-2 is used for line-out in rear */
3056	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3057	/* select line-out */
3058	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3059	/* LINE-OUT pin */
3060	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3061	/* enable HP */
3062	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3063	/* enable Mono */
3064	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3065	/* mute capture amp left and right */
3066	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3067	/* set connection select to line in (default select for this ADC) */
3068	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3069	/* mute capture amp left and right */
3070	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3071	/* set connection select to line in (default select for this ADC) */
3072	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3073	/* set vol=0 Line-Out mixer amp left and right */
3074	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3075	/* unmute pin widget amp left and right (no gain on this amp) */
3076	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3077	/* set vol=0 HP mixer amp left and right */
3078	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3079	/* unmute pin widget amp left and right (no gain on this amp) */
3080	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3081	/* set vol=0 Mono mixer amp left and right */
3082	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3083	/* unmute pin widget amp left and right (no gain on this amp) */
3084	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3085	/* unmute LINE-2 out pin */
3086	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3087	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3088	/* mute CD */
3089	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3090	/* mute Line In */
3091	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3092	/* mute Mic */
3093	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3094	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3095	/* mute Front out path */
3096	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3097	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3098	/* mute Headphone out path */
3099	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3100	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3101	/* mute Mono out path */
3102	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3103	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3104	{ }
3105};
3106
3107static struct hda_verb alc260_hp_init_verbs[] = {
3108	/* Headphone and output */
3109	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3110	/* mono output */
3111	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3112	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3113	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3114	/* Mic2 (front panel) pin widget for input and vref at 80% */
3115	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3116	/* Line In pin widget for input */
3117	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3118	/* Line-2 pin widget for output */
3119	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3120	/* CD pin widget for input */
3121	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3122	/* unmute amp left and right */
3123	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3124	/* set connection select to line in (default select for this ADC) */
3125	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3126	/* unmute Line-Out mixer amp left and right (volume = 0) */
3127	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3128	/* mute pin widget amp left and right (no gain on this amp) */
3129	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3130	/* unmute HP mixer amp left and right (volume = 0) */
3131	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3132	/* mute pin widget amp left and right (no gain on this amp) */
3133	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3134	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3135	/* unmute CD */
3136	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3137	/* unmute Line In */
3138	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3139	/* unmute Mic */
3140	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3141	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3142	/* Unmute Front out path */
3143	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3144	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3145	/* Unmute Headphone out path */
3146	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3147	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3148	/* Unmute Mono out path */
3149	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3150	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3151	{ }
3152};
3153
3154static struct hda_verb alc260_hp_3013_init_verbs[] = {
3155	/* Line out and output */
3156	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3157	/* mono output */
3158	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3159	/* Mic1 (rear panel) pin widget for input and vref at 80% */
3160	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3161	/* Mic2 (front panel) pin widget for input and vref at 80% */
3162	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3163	/* Line In pin widget for input */
3164	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3165	/* Headphone pin widget for output */
3166	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3167	/* CD pin widget for input */
3168	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3169	/* unmute amp left and right */
3170	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3171	/* set connection select to line in (default select for this ADC) */
3172	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3173	/* unmute Line-Out mixer amp left and right (volume = 0) */
3174	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3175	/* mute pin widget amp left and right (no gain on this amp) */
3176	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3177	/* unmute HP mixer amp left and right (volume = 0) */
3178	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3179	/* mute pin widget amp left and right (no gain on this amp) */
3180	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3181	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
3182	/* unmute CD */
3183	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
3184	/* unmute Line In */
3185	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
3186	/* unmute Mic */
3187	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3188	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3189	/* Unmute Front out path */
3190	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3191	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3192	/* Unmute Headphone out path */
3193	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3194	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3195	/* Unmute Mono out path */
3196	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3197	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3198	{ }
3199};
3200
3201/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3202 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3203 * audio = 0x16, internal speaker = 0x10.
3204 */
3205static struct hda_verb alc260_fujitsu_init_verbs[] = {
3206	/* Disable all GPIOs */
3207	{0x01, AC_VERB_SET_GPIO_MASK, 0},
3208	/* Internal speaker is connected to headphone pin */
3209	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3210	/* Headphone/Line-out jack connects to Line1 pin; make it an output */
3211	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3212	/* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3213	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3214	/* Ensure all other unused pins are disabled and muted. */
3215	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3216	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3217	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3218	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3219	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3220	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3221	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3222	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3223
3224	/* Disable digital (SPDIF) pins */
3225	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3226	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3227
3228	/* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3229	 * when acting as an output.
3230	 */
3231	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3232
3233	/* Start with output sum widgets muted and their output gains at min */
3234	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3235	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3236	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3237	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3238	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3239	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3240	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3241	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3242	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3243
3244	/* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3245	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3246	/* Unmute Line1 pin widget output buffer since it starts as an output.
3247	 * If the pin mode is changed by the user the pin mode control will
3248	 * take care of enabling the pin's input/output buffers as needed.
3249	 * Therefore there's no need to enable the input buffer at this
3250	 * stage.
3251	 */
3252	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3253	/* Unmute input buffer of pin widget used for Line-in (no equiv
3254	 * mixer ctrl)
3255	 */
3256	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3257
3258	/* Mute capture amp left and right */
3259	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3260	/* Set ADC connection select to match default mixer setting - line
3261	 * in (on mic1 pin)
3262	 */
3263	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3264
3265	/* Do the same for the second ADC: mute capture input amp and
3266	 * set ADC connection to line in (on mic1 pin)
3267	 */
3268	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3269	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3270
3271	/* Mute all inputs to mixer widget (even unconnected ones) */
3272	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3273	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3274	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3275	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3276	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3277	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3278	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3279	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3280
3281	{ }
3282};
3283
3284/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3285 * similar laptops (adapted from Fujitsu init verbs).
3286 */
3287static struct hda_verb alc260_acer_init_verbs[] = {
3288	/* On TravelMate laptops, GPIO 0 enables the internal speaker and
3289	 * the headphone jack.  Turn this on and rely on the standard mute
3290	 * methods whenever the user wants to turn these outputs off.
3291	 */
3292	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
3293	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
3294	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
3295	/* Internal speaker/Headphone jack is connected to Line-out pin */
3296	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3297	/* Internal microphone/Mic jack is connected to Mic1 pin */
3298	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3299	/* Line In jack is connected to Line1 pin */
3300	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3301	/* Ensure all other unused pins are disabled and muted. */
3302	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3303	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3304	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3305	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3306	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3307	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3308	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3309	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3310	/* Disable digital (SPDIF) pins */
3311	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3312	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3313
3314	/* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3315	 * bus when acting as outputs.
3316	 */
3317	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3318	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3319
3320	/* Start with output sum widgets muted and their output gains at min */
3321	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3322	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3323	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3324	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3325	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3326	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3327	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3328	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3329	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3330
3331	/* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
3332	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3333	/* Unmute Mic1 and Line1 pin widget input buffers since they start as
3334	 * inputs. If the pin mode is changed by the user the pin mode control
3335	 * will take care of enabling the pin's input/output buffers as needed.
3336	 * Therefore there's no need to enable the input buffer at this
3337	 * stage.
3338	 */
3339	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3340	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3341
3342	/* Mute capture amp left and right */
3343	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3344	/* Set ADC connection select to match default mixer setting - mic
3345	 * (on mic1 pin)
3346	 */
3347	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3348
3349	/* Do similar with the second ADC: mute capture input amp and
3350	 * set ADC connection to mic to match ALSA's default state.
3351	 */
3352	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3353	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3354
3355	/* Mute all inputs to mixer widget (even unconnected ones) */
3356	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3357	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3358	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3359	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3360	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3361	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3362	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3363	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3364
3365	{ }
3366};
3367
3368/* Test configuration for debugging, modelled after the ALC880 test
3369 * configuration.
3370 */
3371#ifdef CONFIG_SND_DEBUG
3372static hda_nid_t alc260_test_dac_nids[1] = {
3373	0x02,
3374};
3375static hda_nid_t alc260_test_adc_nids[2] = {
3376	0x04, 0x05,
3377};
3378/* For testing the ALC260, each input MUX needs its own definition since
3379 * the signal assignments are different.  This assumes that the first ADC
3380 * is NID 0x04.
3381 */
3382static struct hda_input_mux alc260_test_capture_sources[2] = {
3383	{
3384		.num_items = 7,
3385		.items = {
3386			{ "MIC1 pin", 0x0 },
3387			{ "MIC2 pin", 0x1 },
3388			{ "LINE1 pin", 0x2 },
3389			{ "LINE2 pin", 0x3 },
3390			{ "CD pin", 0x4 },
3391			{ "LINE-OUT pin", 0x5 },
3392			{ "HP-OUT pin", 0x6 },
3393		},
3394        },
3395	{
3396		.num_items = 8,
3397		.items = {
3398			{ "MIC1 pin", 0x0 },
3399			{ "MIC2 pin", 0x1 },
3400			{ "LINE1 pin", 0x2 },
3401			{ "LINE2 pin", 0x3 },
3402			{ "CD pin", 0x4 },
3403			{ "Mixer", 0x5 },
3404			{ "LINE-OUT pin", 0x6 },
3405			{ "HP-OUT pin", 0x7 },
3406		},
3407        },
3408};
3409static struct snd_kcontrol_new alc260_test_mixer[] = {
3410	/* Output driver widgets */
3411	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3412	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3413	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3414	HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
3415	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3416	HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
3417
3418	/* Modes for retasking pin widgets
3419	 * Note: the ALC260 doesn't seem to act on requests to enable mic
3420         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
3421         * mention this restriction.  At this stage it's not clear whether
3422         * this behaviour is intentional or is a hardware bug in chip
3423         * revisions available at least up until early 2006.  Therefore for
3424         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
3425         * choices, but if it turns out that the lack of mic bias for these
3426         * NIDs is intentional we could change their modes from
3427         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3428	 */
3429	ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
3430	ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
3431	ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
3432	ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
3433	ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
3434	ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
3435
3436	/* Loopback mixer controls */
3437	HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
3438	HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
3439	HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
3440	HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
3441	HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
3442	HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
3443	HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
3444	HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
3445	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3446	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3447	HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3448	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3449	HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
3450	HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
3451	HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
3452	HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
3453
3454	/* Controls for GPIO pins, assuming they are configured as outputs */
3455	ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
3456	ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
3457	ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
3458	ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
3459
3460	/* Switches to allow the digital IO pins to be enabled.  The datasheet
3461	 * is ambigious as to which NID is which; testing on laptops which
3462	 * make this output available should provide clarification.
3463	 */
3464	ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
3465	ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
3466
3467	{ } /* end */
3468};
3469static struct hda_verb alc260_test_init_verbs[] = {
3470	/* Enable all GPIOs as outputs with an initial value of 0 */
3471	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
3472	{0x01, AC_VERB_SET_GPIO_DATA, 0x00},
3473	{0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
3474
3475	/* Enable retasking pins as output, initially without power amp */
3476	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3477	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3478	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3479	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3480	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3481	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3482
3483	/* Disable digital (SPDIF) pins initially, but users can enable
3484	 * them via a mixer switch.  In the case of SPDIF-out, this initverb
3485	 * payload also sets the generation to 0, output to be in "consumer"
3486	 * PCM format, copyright asserted, no pre-emphasis and no validity
3487	 * control.
3488	 */
3489	{0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
3490	{0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
3491
3492	/* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
3493	 * OUT1 sum bus when acting as an output.
3494	 */
3495	{0x0b, AC_VERB_SET_CONNECT_SEL, 0},
3496	{0x0c, AC_VERB_SET_CONNECT_SEL, 0},
3497	{0x0d, AC_VERB_SET_CONNECT_SEL, 0},
3498	{0x0e, AC_VERB_SET_CONNECT_SEL, 0},
3499
3500	/* Start with output sum widgets muted and their output gains at min */
3501	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3502	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3503	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3504	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3505	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3506	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3507	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3508	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3509	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3510
3511	/* Unmute retasking pin widget output buffers since the default
3512	 * state appears to be output.  As the pin mode is changed by the
3513	 * user the pin mode control will take care of enabling the pin's
3514	 * input/output buffers as needed.
3515	 */
3516	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3517	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3518	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3519	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3521	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3522	/* Also unmute the mono-out pin widget */
3523	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3524
3525	/* Mute capture amp left and right */
3526	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3527	/* Set ADC connection select to match default mixer setting (mic1
3528	 * pin)
3529	 */
3530	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3531
3532	/* Do the same for the second ADC: mute capture input amp and
3533	 * set ADC connection to mic1 pin
3534	 */
3535	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3536	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3537
3538	/* Mute all inputs to mixer widget (even unconnected ones) */
3539	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
3540	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
3541	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
3542	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
3543	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
3544	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3545	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
3546	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
3547
3548	{ }
3549};
3550#endif
3551
3552static struct hda_pcm_stream alc260_pcm_analog_playback = {
3553	.substreams = 1,
3554	.channels_min = 2,
3555	.channels_max = 2,
3556};
3557
3558static struct hda_pcm_stream alc260_pcm_analog_capture = {
3559	.substreams = 1,
3560	.channels_min = 2,
3561	.channels_max = 2,
3562};
3563
3564#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
3565#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
3566
3567/*
3568 * for BIOS auto-configuration
3569 */
3570
3571static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
3572					const char *pfx)
3573{
3574	hda_nid_t nid_vol;
3575	unsigned long vol_val, sw_val;
3576	char name[32];
3577	int err;
3578
3579	if (nid >= 0x0f && nid < 0x11) {
3580		nid_vol = nid - 0x7;
3581		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3582		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3583	} else if (nid == 0x11) {
3584		nid_vol = nid - 0x7;
3585		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
3586		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
3587	} else if (nid >= 0x12 && nid <= 0x15) {
3588		nid_vol = 0x08;
3589		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
3590		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3591	} else
3592		return 0; /* N/A */
3593
3594	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
3595	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
3596		return err;
3597	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
3598	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
3599		return err;
3600	return 1;
3601}
3602
3603/* add playback controls from the parsed DAC table */
3604static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
3605					     const struct auto_pin_cfg *cfg)
3606{
3607	hda_nid_t nid;
3608	int err;
3609
3610	spec->multiout.num_dacs = 1;
3611	spec->multiout.dac_nids = spec->private_dac_nids;
3612	spec->multiout.dac_nids[0] = 0x02;
3613
3614	nid = cfg->line_out_pins[0];
3615	if (nid) {
3616		err = alc260_add_playback_controls(spec, nid, "Front");
3617		if (err < 0)
3618			return err;
3619	}
3620
3621	nid = cfg->speaker_pins[0];
3622	if (nid) {
3623		err = alc260_add_playback_controls(spec, nid, "Speaker");
3624		if (err < 0)
3625			return err;
3626	}
3627
3628	nid = cfg->hp_pin;
3629	if (nid) {
3630		err = alc260_add_playback_controls(spec, nid, "Headphone");
3631		if (err < 0)
3632			return err;
3633	}
3634	return 0;
3635}
3636
3637/* create playback/capture controls for input pins */
3638static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
3639						const struct auto_pin_cfg *cfg)
3640{
3641	struct hda_input_mux *imux = &spec->private_imux;
3642	int i, err, idx;
3643
3644	for (i = 0; i < AUTO_PIN_LAST; i++) {
3645		if (cfg->input_pins[i] >= 0x12) {
3646			idx = cfg->input_pins[i] - 0x12;
3647			err = new_analog_input(spec, cfg->input_pins[i],
3648					       auto_pin_cfg_labels[i], idx, 0x07);
3649			if (err < 0)
3650				return err;
3651			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3652			imux->items[imux->num_items].index = idx;
3653			imux->num_items++;
3654		}
3655		if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
3656			idx = cfg->input_pins[i] - 0x09;
3657			err = new_analog_input(spec, cfg->input_pins[i],
3658					       auto_pin_cfg_labels[i], idx, 0x07);
3659			if (err < 0)
3660				return err;
3661			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3662			imux->items[imux->num_items].index = idx;
3663			imux->num_items++;
3664		}
3665	}
3666	return 0;
3667}
3668
3669static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
3670					      hda_nid_t nid, int pin_type,
3671					      int sel_idx)
3672{
3673	/* set as output */
3674	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
3675	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3676	/* need the manual connection? */
3677	if (nid >= 0x12) {
3678		int idx = nid - 0x12;
3679		snd_hda_codec_write(codec, idx + 0x0b, 0,
3680				    AC_VERB_SET_CONNECT_SEL, sel_idx);
3681
3682	}
3683}
3684
3685static void alc260_auto_init_multi_out(struct hda_codec *codec)
3686{
3687	struct alc_spec *spec = codec->spec;
3688	hda_nid_t nid;
3689
3690	nid = spec->autocfg.line_out_pins[0];
3691	if (nid)
3692		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3693
3694	nid = spec->autocfg.speaker_pins[0];
3695	if (nid)
3696		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3697
3698	nid = spec->autocfg.hp_pin;
3699	if (nid)
3700		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
3701}
3702
3703#define ALC260_PIN_CD_NID		0x16
3704static void alc260_auto_init_analog_input(struct hda_codec *codec)
3705{
3706	struct alc_spec *spec = codec->spec;
3707	int i;
3708
3709	for (i = 0; i < AUTO_PIN_LAST; i++) {
3710		hda_nid_t nid = spec->autocfg.input_pins[i];
3711		if (nid >= 0x12) {
3712			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3713					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
3714			if (nid != ALC260_PIN_CD_NID)
3715				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3716						    AMP_OUT_MUTE);
3717		}
3718	}
3719}
3720
3721/*
3722 * generic initialization of ADC, input mixers and output mixers
3723 */
3724static struct hda_verb alc260_volume_init_verbs[] = {
3725	/*
3726	 * Unmute ADC0-1 and set the default input to mic-in
3727	 */
3728	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
3729	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3730	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
3731	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3732
3733	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3734	 * mixer widget
3735	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
3736	 * mic (mic 2)
3737	 */
3738	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3739	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3740	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3741	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3742	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3743	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3744
3745	/*
3746	 * Set up output mixers (0x08 - 0x0a)
3747	 */
3748	/* set vol=0 to output mixers */
3749	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3750	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3751	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3752	/* set up input amps for analog loopback */
3753	/* Amp Indices: DAC = 0, mixer = 1 */
3754	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3755	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3756	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3757	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3758	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3759	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3760
3761	{ }
3762};
3763
3764static int alc260_parse_auto_config(struct hda_codec *codec)
3765{
3766	struct alc_spec *spec = codec->spec;
3767	unsigned int wcap;
3768	int err;
3769	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
3770
3771	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3772						alc260_ignore)) < 0)
3773		return err;
3774	if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
3775		return err;
3776	if (! spec->kctl_alloc)
3777		return 0; /* can't find valid BIOS pin config */
3778	if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
3779		return err;
3780
3781	spec->multiout.max_channels = 2;
3782
3783	if (spec->autocfg.dig_out_pin)
3784		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
3785	if (spec->kctl_alloc)
3786		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3787
3788	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
3789
3790	spec->num_mux_defs = 1;
3791	spec->input_mux = &spec->private_imux;
3792
3793	/* check whether NID 0x04 is valid */
3794	wcap = get_wcaps(codec, 0x04);
3795	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
3796	if (wcap != AC_WID_AUD_IN) {
3797		spec->adc_nids = alc260_adc_nids_alt;
3798		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
3799		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
3800	} else {
3801		spec->adc_nids = alc260_adc_nids;
3802		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
3803		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
3804	}
3805	spec->num_mixers++;
3806
3807	return 1;
3808}
3809
3810/* additional initialization for auto-configuration model */
3811static void alc260_auto_init(struct hda_codec *codec)
3812{
3813	alc260_auto_init_multi_out(codec);
3814	alc260_auto_init_analog_input(codec);
3815}
3816
3817/*
3818 * ALC260 configurations
3819 */
3820static struct hda_board_config alc260_cfg_tbl[] = {
3821	{ .modelname = "basic", .config = ALC260_BASIC },
3822	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb,
3823	  .config = ALC260_BASIC }, /* Sony VAIO */
3824	{ .pci_subvendor = 0x152d, .pci_subdevice = 0x0729,
3825	  .config = ALC260_BASIC }, /* CTL Travel Master U553W */
3826	{ .modelname = "hp", .config = ALC260_HP },
3827	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
3828	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
3829	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP },
3830	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
3831	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
3832	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
3833	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP },
3834	{ .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X },
3835	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X },
3836	{ .modelname = "acer", .config = ALC260_ACER },
3837	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER },
3838#ifdef CONFIG_SND_DEBUG
3839	{ .modelname = "test", .config = ALC260_TEST },
3840#endif
3841	{ .modelname = "auto", .config = ALC260_AUTO },
3842	{}
3843};
3844
3845static struct alc_config_preset alc260_presets[] = {
3846	[ALC260_BASIC] = {
3847		.mixers = { alc260_base_output_mixer,
3848			    alc260_input_mixer,
3849			    alc260_pc_beep_mixer,
3850			    alc260_capture_mixer },
3851		.init_verbs = { alc260_init_verbs },
3852		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
3853		.dac_nids = alc260_dac_nids,
3854		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
3855		.adc_nids = alc260_adc_nids,
3856		.num_channel_mode = ARRAY_SIZE(alc260_modes),
3857		.channel_mode = alc260_modes,
3858		.input_mux = &alc260_capture_source,
3859	},
3860	[ALC260_HP] = {
3861		.mixers = { alc260_base_output_mixer,
3862			    alc260_input_mixer,
3863			    alc260_capture_alt_mixer },
3864		.init_verbs = { alc260_hp_init_verbs },
3865		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
3866		.dac_nids = alc260_dac_nids,
3867		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
3868		.adc_nids = alc260_hp_adc_nids,
3869		.num_channel_mode = ARRAY_SIZE(alc260_modes),
3870		.channel_mode = alc260_modes,
3871		.input_mux = &alc260_capture_source,
3872	},
3873	[ALC260_HP_3013] = {
3874		.mixers = { alc260_hp_3013_mixer,
3875			    alc260_input_mixer,
3876			    alc260_capture_alt_mixer },
3877		.init_verbs = { alc260_hp_3013_init_verbs },
3878		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
3879		.dac_nids = alc260_dac_nids,
3880		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
3881		.adc_nids = alc260_hp_adc_nids,
3882		.num_channel_mode = ARRAY_SIZE(alc260_modes),
3883		.channel_mode = alc260_modes,
3884		.input_mux = &alc260_capture_source,
3885	},
3886	[ALC260_FUJITSU_S702X] = {
3887		.mixers = { alc260_fujitsu_mixer,
3888			    alc260_capture_mixer },
3889		.init_verbs = { alc260_fujitsu_init_verbs },
3890		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
3891		.dac_nids = alc260_dac_nids,
3892		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
3893		.adc_nids = alc260_dual_adc_nids,
3894		.num_channel_mode = ARRAY_SIZE(alc260_modes),
3895		.channel_mode = alc260_modes,
3896		.num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
3897		.input_mux = alc260_fujitsu_capture_sources,
3898	},
3899	[ALC260_ACER] = {
3900		.mixers = { alc260_acer_mixer,
3901			    alc260_capture_mixer },
3902		.init_verbs = { alc260_acer_init_verbs },
3903		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
3904		.dac_nids = alc260_dac_nids,
3905		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
3906		.adc_nids = alc260_dual_adc_nids,
3907		.num_channel_mode = ARRAY_SIZE(alc260_modes),
3908		.channel_mode = alc260_modes,
3909		.num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
3910		.input_mux = alc260_acer_capture_sources,
3911	},
3912#ifdef CONFIG_SND_DEBUG
3913	[ALC260_TEST] = {
3914		.mixers = { alc260_test_mixer,
3915			    alc260_capture_mixer },
3916		.init_verbs = { alc260_test_init_verbs },
3917		.num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
3918		.dac_nids = alc260_test_dac_nids,
3919		.num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
3920		.adc_nids = alc260_test_adc_nids,
3921		.num_channel_mode = ARRAY_SIZE(alc260_modes),
3922		.channel_mode = alc260_modes,
3923		.num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
3924		.input_mux = alc260_test_capture_sources,
3925	},
3926#endif
3927};
3928
3929static int patch_alc260(struct hda_codec *codec)
3930{
3931	struct alc_spec *spec;
3932	int err, board_config;
3933
3934	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3935	if (spec == NULL)
3936		return -ENOMEM;
3937
3938	codec->spec = spec;
3939
3940	board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
3941	if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
3942		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");
3943		board_config = ALC260_AUTO;
3944	}
3945
3946	if (board_config == ALC260_AUTO) {
3947		/* automatic parse from the BIOS config */
3948		err = alc260_parse_auto_config(codec);
3949		if (err < 0) {
3950			alc_free(codec);
3951			return err;
3952		} else if (! err) {
3953			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
3954			board_config = ALC260_BASIC;
3955		}
3956	}
3957
3958	if (board_config != ALC260_AUTO)
3959		setup_preset(spec, &alc260_presets[board_config]);
3960
3961	spec->stream_name_analog = "ALC260 Analog";
3962	spec->stream_analog_playback = &alc260_pcm_analog_playback;
3963	spec->stream_analog_capture = &alc260_pcm_analog_capture;
3964
3965	spec->stream_name_digital = "ALC260 Digital";
3966	spec->stream_digital_playback = &alc260_pcm_digital_playback;
3967	spec->stream_digital_capture = &alc260_pcm_digital_capture;
3968
3969	codec->patch_ops = alc_patch_ops;
3970	if (board_config == ALC260_AUTO)
3971		spec->init_hook = alc260_auto_init;
3972
3973	return 0;
3974}
3975
3976
3977/*
3978 * ALC882 support
3979 *
3980 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
3981 * configuration.  Each pin widget can choose any input DACs and a mixer.
3982 * Each ADC is connected from a mixer of all inputs.  This makes possible
3983 * 6-channel independent captures.
3984 *
3985 * In addition, an independent DAC for the multi-playback (not used in this
3986 * driver yet).
3987 */
3988#define ALC882_DIGOUT_NID	0x06
3989#define ALC882_DIGIN_NID	0x0a
3990
3991static struct hda_channel_mode alc882_ch_modes[1] = {
3992	{ 8, NULL }
3993};
3994
3995static hda_nid_t alc882_dac_nids[4] = {
3996	/* front, rear, clfe, rear_surr */
3997	0x02, 0x03, 0x04, 0x05
3998};
3999
4000/* identical with ALC880 */
4001#define alc882_adc_nids		alc880_adc_nids
4002#define alc882_adc_nids_alt	alc880_adc_nids_alt
4003
4004/* input MUX */
4005/* FIXME: should be a matrix-type input source selection */
4006
4007static struct hda_input_mux alc882_capture_source = {
4008	.num_items = 4,
4009	.items = {
4010		{ "Mic", 0x0 },
4011		{ "Front Mic", 0x1 },
4012		{ "Line", 0x2 },
4013		{ "CD", 0x4 },
4014	},
4015};
4016#define alc882_mux_enum_info alc_mux_enum_info
4017#define alc882_mux_enum_get alc_mux_enum_get
4018
4019static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
4020{
4021	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4022	struct alc_spec *spec = codec->spec;
4023	const struct hda_input_mux *imux = spec->input_mux;
4024	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4025	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4026	hda_nid_t nid = capture_mixers[adc_idx];
4027	unsigned int *cur_val = &spec->cur_mux[adc_idx];
4028	unsigned int i, idx;
4029
4030	idx = ucontrol->value.enumerated.item[0];
4031	if (idx >= imux->num_items)
4032		idx = imux->num_items - 1;
4033	if (*cur_val == idx && ! codec->in_resume)
4034		return 0;
4035	for (i = 0; i < imux->num_items; i++) {
4036		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
4037		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4038				    v | (imux->items[i].index << 8));
4039	}
4040	*cur_val = idx;
4041	return 1;
4042}
4043
4044/*
4045 * 6ch mode
4046 */
4047static struct hda_verb alc882_sixstack_ch6_init[] = {
4048	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
4049	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4050	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4051	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4052	{ } /* end */
4053};
4054
4055/*
4056 * 8ch mode
4057 */
4058static struct hda_verb alc882_sixstack_ch8_init[] = {
4059	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4060	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4061	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4062	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
4063	{ } /* end */
4064};
4065
4066static struct hda_channel_mode alc882_sixstack_modes[2] = {
4067	{ 6, alc882_sixstack_ch6_init },
4068	{ 8, alc882_sixstack_ch8_init },
4069};
4070
4071/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4072 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4073 */
4074static struct snd_kcontrol_new alc882_base_mixer[] = {
4075	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4076	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4077	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4078	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4079	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4080	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4081	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4082	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4083	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4084	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4085	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
4086	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4087	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4088	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4089	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4090	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4091	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4092	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4093	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4094	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4095	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
4096	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
4097	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
4098	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
4099	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
4100	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
4101	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
4102	{
4103		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4104		/* .name = "Capture Source", */
4105		.name = "Input Source",
4106		.count = 3,
4107		.info = alc882_mux_enum_info,
4108		.get = alc882_mux_enum_get,
4109		.put = alc882_mux_enum_put,
4110	},
4111	{ } /* end */
4112};
4113
4114static struct snd_kcontrol_new alc882_chmode_mixer[] = {
4115	{
4116		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4117		.name = "Channel Mode",
4118		.info = alc_ch_mode_info,
4119		.get = alc_ch_mode_get,
4120		.put = alc_ch_mode_put,
4121	},
4122	{ } /* end */
4123};
4124
4125static struct hda_verb alc882_init_verbs[] = {
4126	/* Front mixer: unmute input/output amp left and right (volume = 0) */
4127	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4128	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4129	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4130	/* Rear mixer */
4131	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4132	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4133	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4134	/* CLFE mixer */
4135	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4136	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4137	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4138	/* Side mixer */
4139	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4140	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4141	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4142
4143	/* Front Pin: output 0 (0x0c) */
4144	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4145	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4146	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4147	/* Rear Pin: output 1 (0x0d) */
4148	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4149	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4150	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4151	/* CLFE Pin: output 2 (0x0e) */
4152	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4153	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4154	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
4155	/* Side Pin: output 3 (0x0f) */
4156	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4157	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4158	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
4159	/* Mic (rear) pin: input vref at 80% */
4160	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4161	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4162	/* Front Mic pin: input vref at 80% */
4163	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4164	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4165	/* Line In pin: input */
4166	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4167	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4168	/* Line-2 In: Headphone output (output 0 - 0x0c) */
4169	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4170	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4171	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
4172	/* CD pin widget for input */
4173	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4174
4175	/* FIXME: use matrix-type input source selection */
4176	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4177	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4178	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4179	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4180	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4181	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4182	/* Input mixer2 */
4183	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4184	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4185	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4186	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4187	/* Input mixer3 */
4188	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4189	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4190	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4191	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4192	/* ADC1: mute amp left and right */
4193	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4194	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4195	/* ADC2: mute amp left and right */
4196	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4197	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4198	/* ADC3: mute amp left and right */
4199	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4200	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4201
4202	{ }
4203};
4204
4205/*
4206 * generic initialization of ADC, input mixers and output mixers
4207 */
4208static struct hda_verb alc882_auto_init_verbs[] = {
4209	/*
4210	 * Unmute ADC0-2 and set the default input to mic-in
4211	 */
4212	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4213	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4214	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4215	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4216	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4217	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4218
4219	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4220	 * mixer widget
4221	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4222	 * mic (mic 2)
4223	 */
4224	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4225	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4226	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4227	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4228	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4229	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4230
4231	/*
4232	 * Set up output mixers (0x0c - 0x0f)
4233	 */
4234	/* set vol=0 to output mixers */
4235	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4236	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4237	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4238	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4239	/* set up input amps for analog loopback */
4240	/* Amp Indices: DAC = 0, mixer = 1 */
4241	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4242	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4243	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4244	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4245	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4246	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4247	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4248	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4249	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4250	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4251
4252	/* FIXME: use matrix-type input source selection */
4253	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4254	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4255	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4256	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4257	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4258	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4259	/* Input mixer2 */
4260	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4261	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4262	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4263	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4264	/* Input mixer3 */
4265	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4266	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4267	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4268	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4269
4270	{ }
4271};
4272
4273/* capture mixer elements */
4274static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
4275	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
4276	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
4277	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
4278	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
4279	{
4280		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4281		/* The multiple "Capture Source" controls confuse alsamixer
4282		 * So call somewhat different..
4283		 * FIXME: the controls appear in the "playback" view!
4284		 */
4285		/* .name = "Capture Source", */
4286		.name = "Input Source",
4287		.count = 2,
4288		.info = alc882_mux_enum_info,
4289		.get = alc882_mux_enum_get,
4290		.put = alc882_mux_enum_put,
4291	},
4292	{ } /* end */
4293};
4294
4295static struct snd_kcontrol_new alc882_capture_mixer[] = {
4296	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
4297	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
4298	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
4299	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
4300	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
4301	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
4302	{
4303		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4304		/* The multiple "Capture Source" controls confuse alsamixer
4305		 * So call somewhat different..
4306		 * FIXME: the controls appear in the "playback" view!
4307		 */
4308		/* .name = "Capture Source", */
4309		.name = "Input Source",
4310		.count = 3,
4311		.info = alc882_mux_enum_info,
4312		.get = alc882_mux_enum_get,
4313		.put = alc882_mux_enum_put,
4314	},
4315	{ } /* end */
4316};
4317
4318/* pcm configuration: identiacal with ALC880 */
4319#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
4320#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
4321#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
4322#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
4323
4324/*
4325 * configuration and preset
4326 */
4327static struct hda_board_config alc882_cfg_tbl[] = {
4328	{ .modelname = "3stack-dig", .config = ALC882_3ST_DIG },
4329	{ .modelname = "6stack-dig", .config = ALC882_6ST_DIG },
4330	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI  */
4331	{ .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */
4332	{ .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */
4333	{ .modelname = "auto", .config = ALC882_AUTO },
4334	{}
4335};
4336
4337static struct alc_config_preset alc882_presets[] = {
4338	[ALC882_3ST_DIG] = {
4339		.mixers = { alc882_base_mixer },
4340		.init_verbs = { alc882_init_verbs },
4341		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4342		.dac_nids = alc882_dac_nids,
4343		.dig_out_nid = ALC882_DIGOUT_NID,
4344		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
4345		.adc_nids = alc882_adc_nids,
4346		.dig_in_nid = ALC882_DIGIN_NID,
4347		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
4348		.channel_mode = alc882_ch_modes,
4349		.input_mux = &alc882_capture_source,
4350	},
4351	[ALC882_6ST_DIG] = {
4352		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
4353		.init_verbs = { alc882_init_verbs },
4354		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
4355		.dac_nids = alc882_dac_nids,
4356		.dig_out_nid = ALC882_DIGOUT_NID,
4357		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
4358		.adc_nids = alc882_adc_nids,
4359		.dig_in_nid = ALC882_DIGIN_NID,
4360		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
4361		.channel_mode = alc882_sixstack_modes,
4362		.input_mux = &alc882_capture_source,
4363	},
4364};
4365
4366
4367/*
4368 * BIOS auto configuration
4369 */
4370static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
4371					      hda_nid_t nid, int pin_type,
4372					      int dac_idx)
4373{
4374	/* set as output */
4375	struct alc_spec *spec = codec->spec;
4376	int idx;
4377
4378	if (spec->multiout.dac_nids[dac_idx] == 0x25)
4379		idx = 4;
4380	else
4381		idx = spec->multiout.dac_nids[dac_idx] - 2;
4382
4383	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
4384	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
4385	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
4386
4387}
4388
4389static void alc882_auto_init_multi_out(struct hda_codec *codec)
4390{
4391	struct alc_spec *spec = codec->spec;
4392	int i;
4393
4394	for (i = 0; i <= HDA_SIDE; i++) {
4395		hda_nid_t nid = spec->autocfg.line_out_pins[i];
4396		if (nid)
4397			alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
4398	}
4399}
4400
4401static void alc882_auto_init_hp_out(struct hda_codec *codec)
4402{
4403	struct alc_spec *spec = codec->spec;
4404	hda_nid_t pin;
4405
4406	pin = spec->autocfg.hp_pin;
4407	if (pin) /* connect to front */
4408		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
4409}
4410
4411#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
4412#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
4413
4414static void alc882_auto_init_analog_input(struct hda_codec *codec)
4415{
4416	struct alc_spec *spec = codec->spec;
4417	int i;
4418
4419	for (i = 0; i < AUTO_PIN_LAST; i++) {
4420		hda_nid_t nid = spec->autocfg.input_pins[i];
4421		if (alc882_is_input_pin(nid)) {
4422			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4423					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
4424			if (nid != ALC882_PIN_CD_NID)
4425				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4426						    AMP_OUT_MUTE);
4427		}
4428	}
4429}
4430
4431/* almost identical with ALC880 parser... */
4432static int alc882_parse_auto_config(struct hda_codec *codec)
4433{
4434	struct alc_spec *spec = codec->spec;
4435	int err = alc880_parse_auto_config(codec);
4436
4437	if (err < 0)
4438		return err;
4439	else if (err > 0)
4440		/* hack - override the init verbs */
4441		spec->init_verbs[0] = alc882_auto_init_verbs;
4442	return err;
4443}
4444
4445/* additional initialization for auto-configuration model */
4446static void alc882_auto_init(struct hda_codec *codec)
4447{
4448	alc882_auto_init_multi_out(codec);
4449	alc882_auto_init_hp_out(codec);
4450	alc882_auto_init_analog_input(codec);
4451}
4452
4453/*
4454 *  ALC882 Headphone poll in 3.5.1a or 3.5.2
4455 */
4456
4457static int patch_alc882(struct hda_codec *codec)
4458{
4459	struct alc_spec *spec;
4460	int err, board_config;
4461
4462	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4463	if (spec == NULL)
4464		return -ENOMEM;
4465
4466	codec->spec = spec;
4467
4468	board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl);
4469
4470	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
4471		printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n");
4472		board_config = ALC882_AUTO;
4473	}
4474
4475	if (board_config == ALC882_AUTO) {
4476		/* automatic parse from the BIOS config */
4477		err = alc882_parse_auto_config(codec);
4478		if (err < 0) {
4479			alc_free(codec);
4480			return err;
4481		} else if (! err) {
4482			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
4483			board_config = ALC882_3ST_DIG;
4484		}
4485	}
4486
4487	if (board_config != ALC882_AUTO)
4488		setup_preset(spec, &alc882_presets[board_config]);
4489
4490	spec->stream_name_analog = "ALC882 Analog";
4491	spec->stream_analog_playback = &alc882_pcm_analog_playback;
4492	spec->stream_analog_capture = &alc882_pcm_analog_capture;
4493
4494	spec->stream_name_digital = "ALC882 Digital";
4495	spec->stream_digital_playback = &alc882_pcm_digital_playback;
4496	spec->stream_digital_capture = &alc882_pcm_digital_capture;
4497
4498	if (! spec->adc_nids && spec->input_mux) {
4499		/* check whether NID 0x07 is valid */
4500		unsigned int wcap = get_wcaps(codec, 0x07);
4501		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4502		if (wcap != AC_WID_AUD_IN) {
4503			spec->adc_nids = alc882_adc_nids_alt;
4504			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
4505			spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
4506			spec->num_mixers++;
4507		} else {
4508			spec->adc_nids = alc882_adc_nids;
4509			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
4510			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
4511			spec->num_mixers++;
4512		}
4513	}
4514
4515	codec->patch_ops = alc_patch_ops;
4516	if (board_config == ALC882_AUTO)
4517		spec->init_hook = alc882_auto_init;
4518
4519	return 0;
4520}
4521
4522/*
4523 * ALC262 support
4524 */
4525
4526#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
4527#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
4528
4529#define alc262_dac_nids		alc260_dac_nids
4530#define alc262_adc_nids		alc882_adc_nids
4531#define alc262_adc_nids_alt	alc882_adc_nids_alt
4532
4533#define alc262_modes		alc260_modes
4534#define alc262_capture_source	alc882_capture_source
4535
4536static struct snd_kcontrol_new alc262_base_mixer[] = {
4537	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4538	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
4539	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4540	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4541	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4542	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4543	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4544	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4545	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4546	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4547	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
4548	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
4549	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
4550	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4551	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4552	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
4553	{ } /* end */
4554};
4555
4556#define alc262_capture_mixer		alc882_capture_mixer
4557#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
4558
4559/*
4560 * generic initialization of ADC, input mixers and output mixers
4561 */
4562static struct hda_verb alc262_init_verbs[] = {
4563	/*
4564	 * Unmute ADC0-2 and set the default input to mic-in
4565	 */
4566	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4567	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4568	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4569	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4570	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4571	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4572
4573	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4574	 * mixer widget
4575	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4576	 * mic (mic 2)
4577	 */
4578	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4579	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4580	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4581	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4582	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4583	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4584
4585	/*
4586	 * Set up output mixers (0x0c - 0x0e)
4587	 */
4588	/* set vol=0 to output mixers */
4589	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4590	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4591	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4592	/* set up input amps for analog loopback */
4593	/* Amp Indices: DAC = 0, mixer = 1 */
4594	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4595	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4596	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4597	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4598	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4599	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4600
4601	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4602	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4603	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4604	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4605	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4606	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4607
4608	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4609	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4610	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4611	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4612	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4613
4614	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
4615	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4616
4617	/* FIXME: use matrix-type input source selection */
4618	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4619	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4620	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4621	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4622	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4623	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4624	/* Input mixer2 */
4625	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4626	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4627	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4628	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4629	/* Input mixer3 */
4630	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4631	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4632	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4633	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4634
4635	{ }
4636};
4637
4638/*
4639 * fujitsu model
4640 *  0x14 = headphone/spdif-out, 0x15 = internal speaker
4641 */
4642
4643#define ALC_HP_EVENT	0x37
4644
4645static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
4646	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
4647	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4648	{}
4649};
4650
4651static struct hda_input_mux alc262_fujitsu_capture_source = {
4652	.num_items = 2,
4653	.items = {
4654		{ "Mic", 0x0 },
4655		{ "CD", 0x4 },
4656	},
4657};
4658
4659/* mute/unmute internal speaker according to the hp jack and mute state */
4660static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
4661{
4662	struct alc_spec *spec = codec->spec;
4663	unsigned int mute;
4664
4665	if (force || ! spec->sense_updated) {
4666		unsigned int present;
4667		/* need to execute and sync at first */
4668		snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
4669		present = snd_hda_codec_read(codec, 0x14, 0,
4670				    	 AC_VERB_GET_PIN_SENSE, 0);
4671		spec->jack_present = (present & 0x80000000) != 0;
4672		spec->sense_updated = 1;
4673	}
4674	if (spec->jack_present) {
4675		/* mute internal speaker */
4676		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
4677					 0x80, 0x80);
4678		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
4679					 0x80, 0x80);
4680	} else {
4681		/* unmute internal speaker if necessary */
4682		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
4683		snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
4684					 0x80, mute & 0x80);
4685		mute = snd_hda_codec_amp_read(codec, 0x14, 1, HDA_OUTPUT, 0);
4686		snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
4687					 0x80, mute & 0x80);
4688	}
4689}
4690
4691/* unsolicited event for HP jack sensing */
4692static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
4693				       unsigned int res)
4694{
4695	if ((res >> 26) != ALC_HP_EVENT)
4696		return;
4697	alc262_fujitsu_automute(codec, 1);
4698}
4699
4700/* bind volumes of both NID 0x0c and 0x0d */
4701static int alc262_fujitsu_master_vol_put(struct snd_kcontrol *kcontrol,
4702					 struct snd_ctl_elem_value *ucontrol)
4703{
4704	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4705	long *valp = ucontrol->value.integer.value;
4706	int change;
4707
4708	change = snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
4709					  0x7f, valp[0] & 0x7f);
4710	change |= snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
4711					   0x7f, valp[1] & 0x7f);
4712	snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
4713				 0x7f, valp[0] & 0x7f);
4714	snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
4715				 0x7f, valp[1] & 0x7f);
4716	return change;
4717}
4718
4719/* bind hp and internal speaker mute (with plug check) */
4720static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
4721					 struct snd_ctl_elem_value *ucontrol)
4722{
4723	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4724	long *valp = ucontrol->value.integer.value;
4725	int change;
4726
4727	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
4728					  0x80, valp[0] ? 0 : 0x80);
4729	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
4730					   0x80, valp[1] ? 0 : 0x80);
4731	if (change || codec->in_resume)
4732		alc262_fujitsu_automute(codec, codec->in_resume);
4733	return change;
4734}
4735
4736static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
4737	{
4738		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4739		.name = "Master Playback Volume",
4740		.info = snd_hda_mixer_amp_volume_info,
4741		.get = snd_hda_mixer_amp_volume_get,
4742		.put = alc262_fujitsu_master_vol_put,
4743		.private_value = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
4744	},
4745	{
4746		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4747		.name = "Master Playback Switch",
4748		.info = snd_hda_mixer_amp_switch_info,
4749		.get = snd_hda_mixer_amp_switch_get,
4750		.put = alc262_fujitsu_master_sw_put,
4751		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
4752	},
4753	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
4754	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
4755	HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4756	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4757	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4758	{ } /* end */
4759};
4760
4761/* add playback controls from the parsed DAC table */
4762static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
4763{
4764	hda_nid_t nid;
4765	int err;
4766
4767	spec->multiout.num_dacs = 1;	/* only use one dac */
4768	spec->multiout.dac_nids = spec->private_dac_nids;
4769	spec->multiout.dac_nids[0] = 2;
4770
4771	nid = cfg->line_out_pins[0];
4772	if (nid) {
4773		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
4774				       HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
4775			return err;
4776		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
4777				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4778			return err;
4779	}
4780
4781	nid = cfg->speaker_pins[0];
4782	if (nid) {
4783		if (nid == 0x16) {
4784			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
4785					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
4786				return err;
4787			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
4788					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
4789				return err;
4790		} else {
4791			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
4792					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4793				return err;
4794		}
4795	}
4796	nid = cfg->hp_pin;
4797	if (nid) {
4798		/* spec->multiout.hp_nid = 2; */
4799		if (nid == 0x16) {
4800			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
4801					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
4802				return err;
4803			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
4804					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
4805				return err;
4806		} else {
4807			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
4808					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
4809				return err;
4810		}
4811	}
4812	return 0;
4813}
4814
4815/* identical with ALC880 */
4816#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
4817
4818/*
4819 * generic initialization of ADC, input mixers and output mixers
4820 */
4821static struct hda_verb alc262_volume_init_verbs[] = {
4822	/*
4823	 * Unmute ADC0-2 and set the default input to mic-in
4824	 */
4825	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4826	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4827	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4828	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4829	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4830	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4831
4832	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4833	 * mixer widget
4834	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
4835	 * mic (mic 2)
4836	 */
4837	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4838	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4839	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4840	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4841	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4842	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
4843
4844	/*
4845	 * Set up output mixers (0x0c - 0x0f)
4846	 */
4847	/* set vol=0 to output mixers */
4848	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4849	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4850	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4851
4852	/* set up input amps for analog loopback */
4853	/* Amp Indices: DAC = 0, mixer = 1 */
4854	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4855	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4856	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4857	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4858	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4859	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4860
4861	/* FIXME: use matrix-type input source selection */
4862	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4863	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4864	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4865	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4866	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4867	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4868	/* Input mixer2 */
4869	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4870	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4871	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4872	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4873	/* Input mixer3 */
4874	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4875	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
4876	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
4877	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
4878
4879	{ }
4880};
4881
4882/* pcm configuration: identiacal with ALC880 */
4883#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
4884#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
4885#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
4886#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
4887
4888/*
4889 * BIOS auto configuration
4890 */
4891static int alc262_parse_auto_config(struct hda_codec *codec)
4892{
4893	struct alc_spec *spec = codec->spec;
4894	int err;
4895	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
4896
4897	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4898						alc262_ignore)) < 0)
4899		return err;
4900	if (! spec->autocfg.line_outs)
4901		return 0; /* can't find valid BIOS pin config */
4902	if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
4903	    (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
4904		return err;
4905
4906	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4907
4908	if (spec->autocfg.dig_out_pin)
4909		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
4910	if (spec->autocfg.dig_in_pin)
4911		spec->dig_in_nid = ALC262_DIGIN_NID;
4912
4913	if (spec->kctl_alloc)
4914		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4915
4916	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
4917	spec->num_mux_defs = 1;
4918	spec->input_mux = &spec->private_imux;
4919
4920	return 1;
4921}
4922
4923#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
4924#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
4925#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
4926
4927
4928/* init callback for auto-configuration model -- overriding the default init */
4929static void alc262_auto_init(struct hda_codec *codec)
4930{
4931	alc262_auto_init_multi_out(codec);
4932	alc262_auto_init_hp_out(codec);
4933	alc262_auto_init_analog_input(codec);
4934}
4935
4936/*
4937 * configuration and preset
4938 */
4939static struct hda_board_config alc262_cfg_tbl[] = {
4940	{ .modelname = "basic", .config = ALC262_BASIC },
4941	{ .modelname = "fujitsu", .config = ALC262_FUJITSU },
4942	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, .config = ALC262_FUJITSU },
4943	{ .modelname = "auto", .config = ALC262_AUTO },
4944	{}
4945};
4946
4947static struct alc_config_preset alc262_presets[] = {
4948	[ALC262_BASIC] = {
4949		.mixers = { alc262_base_mixer },
4950		.init_verbs = { alc262_init_verbs },
4951		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
4952		.dac_nids = alc262_dac_nids,
4953		.hp_nid = 0x03,
4954		.num_channel_mode = ARRAY_SIZE(alc262_modes),
4955		.channel_mode = alc262_modes,
4956		.input_mux = &alc262_capture_source,
4957	},
4958	[ALC262_FUJITSU] = {
4959		.mixers = { alc262_fujitsu_mixer },
4960		.init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
4961		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
4962		.dac_nids = alc262_dac_nids,
4963		.hp_nid = 0x03,
4964		.dig_out_nid = ALC262_DIGOUT_NID,
4965		.num_channel_mode = ARRAY_SIZE(alc262_modes),
4966		.channel_mode = alc262_modes,
4967		.input_mux = &alc262_fujitsu_capture_source,
4968		.unsol_event = alc262_fujitsu_unsol_event,
4969	},
4970};
4971
4972static int patch_alc262(struct hda_codec *codec)
4973{
4974	struct alc_spec *spec;
4975	int board_config;
4976	int err;
4977
4978	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
4979	if (spec == NULL)
4980		return -ENOMEM;
4981
4982	codec->spec = spec;
4983#if 0
4984	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
4985	{
4986	int tmp;
4987	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
4988	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
4989	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
4990	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
4991	}
4992#endif
4993
4994	board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl);
4995	if (board_config < 0 || board_config >= ALC262_MODEL_LAST) {
4996		printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n");
4997		board_config = ALC262_AUTO;
4998	}
4999
5000	if (board_config == ALC262_AUTO) {
5001		/* automatic parse from the BIOS config */
5002		err = alc262_parse_auto_config(codec);
5003		if (err < 0) {
5004			alc_free(codec);
5005			return err;
5006		} else if (! err) {
5007			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
5008			board_config = ALC262_BASIC;
5009		}
5010	}
5011
5012	if (board_config != ALC262_AUTO)
5013		setup_preset(spec, &alc262_presets[board_config]);
5014
5015	spec->stream_name_analog = "ALC262 Analog";
5016	spec->stream_analog_playback = &alc262_pcm_analog_playback;
5017	spec->stream_analog_capture = &alc262_pcm_analog_capture;
5018
5019	spec->stream_name_digital = "ALC262 Digital";
5020	spec->stream_digital_playback = &alc262_pcm_digital_playback;
5021	spec->stream_digital_capture = &alc262_pcm_digital_capture;
5022
5023	if (! spec->adc_nids && spec->input_mux) {
5024		/* check whether NID 0x07 is valid */
5025		unsigned int wcap = get_wcaps(codec, 0x07);
5026
5027		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5028		if (wcap != AC_WID_AUD_IN) {
5029			spec->adc_nids = alc262_adc_nids_alt;
5030			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
5031			spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
5032			spec->num_mixers++;
5033		} else {
5034			spec->adc_nids = alc262_adc_nids;
5035			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
5036			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
5037			spec->num_mixers++;
5038		}
5039	}
5040
5041	codec->patch_ops = alc_patch_ops;
5042	if (board_config == ALC262_AUTO)
5043		spec->init_hook = alc262_auto_init;
5044
5045	return 0;
5046}
5047
5048
5049/*
5050 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
5051 */
5052
5053/*
5054 * set the path ways for 2 channel output
5055 * need to set the codec line out and mic 1 pin widgets to inputs
5056 */
5057static struct hda_verb alc861_threestack_ch2_init[] = {
5058	/* set pin widget 1Ah (line in) for input */
5059	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
5060	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
5061	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
5062
5063        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
5064        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, //mic
5065        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, //line in
5066	{ } /* end */
5067};
5068/*
5069 * 6ch mode
5070 * need to set the codec line out and mic 1 pin widgets to outputs
5071 */
5072static struct hda_verb alc861_threestack_ch6_init[] = {
5073	/* set pin widget 1Ah (line in) for output (Back Surround)*/
5074	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
5075	/* set pin widget 18h (mic1) for output (CLFE)*/
5076	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
5077
5078	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
5079        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
5080
5081        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
5082        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, //mic
5083        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, //line in
5084	{ } /* end */
5085};
5086
5087static struct hda_channel_mode alc861_threestack_modes[2] = {
5088	{ 2, alc861_threestack_ch2_init },
5089	{ 6, alc861_threestack_ch6_init },
5090};
5091
5092/* patch-ALC861 */
5093
5094static struct snd_kcontrol_new alc861_base_mixer[] = {
5095        /* output mixer control */
5096	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
5097	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
5098	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
5099	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
5100	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
5101
5102        /*Input mixer control */
5103	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
5104	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
5105	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
5106	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
5107	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
5108	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
5109	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
5110	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
5111	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
5112	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
5113
5114        /* Capture mixer control */
5115	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5116	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5117	{
5118		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5119		.name = "Capture Source",
5120		.count = 1,
5121		.info = alc_mux_enum_info,
5122		.get = alc_mux_enum_get,
5123		.put = alc_mux_enum_put,
5124	},
5125	{ } /* end */
5126};
5127
5128static struct snd_kcontrol_new alc861_3ST_mixer[] = {
5129        /* output mixer control */
5130	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
5131	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
5132	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
5133	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
5134	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
5135
5136	/* Input mixer control */
5137	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
5138	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
5139	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
5140	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
5141	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
5142	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
5143	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
5144	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
5145	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
5146	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
5147
5148	/* Capture mixer control */
5149	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5150	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5151	{
5152		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5153		.name = "Capture Source",
5154		.count = 1,
5155		.info = alc_mux_enum_info,
5156		.get = alc_mux_enum_get,
5157		.put = alc_mux_enum_put,
5158	},
5159	{
5160		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5161		.name = "Channel Mode",
5162		.info = alc_ch_mode_info,
5163		.get = alc_ch_mode_get,
5164		.put = alc_ch_mode_put,
5165                .private_value = ARRAY_SIZE(alc861_threestack_modes),
5166	},
5167	{ } /* end */
5168};
5169
5170/*
5171 * generic initialization of ADC, input mixers and output mixers
5172 */
5173static struct hda_verb alc861_base_init_verbs[] = {
5174	/*
5175	 * Unmute ADC0 and set the default input to mic-in
5176	 */
5177	/* port-A for surround (rear panel) */
5178	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
5179	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
5180	/* port-B for mic-in (rear panel) with vref */
5181	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
5182	/* port-C for line-in (rear panel) */
5183	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
5184	/* port-D for Front */
5185	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
5186	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
5187	/* port-E for HP out (front panel) */
5188	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
5189	/* route front PCM to HP */
5190	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
5191	/* port-F for mic-in (front panel) with vref */
5192	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
5193	/* port-G for CLFE (rear panel) */
5194	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
5195	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
5196	/* port-H for side (rear panel) */
5197	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
5198	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
5199	/* CD-in */
5200	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
5201	/* route front mic to ADC1*/
5202	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5203	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5204
5205	/* Unmute DAC0~3 & spdif out*/
5206	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5207	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5208	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5209	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5210	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5211
5212	/* Unmute Mixer 14 (mic) 1c (Line in)*/
5213	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5214        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5215	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5216        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5217
5218	/* Unmute Stereo Mixer 15 */
5219	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5220	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5221	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5222	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
5223
5224	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5225	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5226	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5227	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5228	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5229	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5230	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5231	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5232	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
5233        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5234
5235	{ }
5236};
5237
5238static struct hda_verb alc861_threestack_init_verbs[] = {
5239	/*
5240	 * Unmute ADC0 and set the default input to mic-in
5241	 */
5242	/* port-A for surround (rear panel) */
5243	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5244	/* port-B for mic-in (rear panel) with vref */
5245	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
5246	/* port-C for line-in (rear panel) */
5247	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
5248	/* port-D for Front */
5249	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
5250	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
5251	/* port-E for HP out (front panel) */
5252	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
5253	/* route front PCM to HP */
5254	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
5255	/* port-F for mic-in (front panel) with vref */
5256	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
5257	/* port-G for CLFE (rear panel) */
5258	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5259	/* port-H for side (rear panel) */
5260	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5261	/* CD-in */
5262	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
5263	/* route front mic to ADC1*/
5264	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5265	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5266	/* Unmute DAC0~3 & spdif out*/
5267	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5268	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5269	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5270	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5271	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5272
5273	/* Unmute Mixer 14 (mic) 1c (Line in)*/
5274	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5275        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5276	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5277        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5278
5279	/* Unmute Stereo Mixer 15 */
5280	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5281	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5282	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5283	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
5284
5285	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5286	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5287	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5288	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5289	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5290	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5291	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5292	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5293	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
5294        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5295	{ }
5296};
5297/*
5298 * generic initialization of ADC, input mixers and output mixers
5299 */
5300static struct hda_verb alc861_auto_init_verbs[] = {
5301	/*
5302	 * Unmute ADC0 and set the default input to mic-in
5303	 */
5304//	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5305	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5306
5307	/* Unmute DAC0~3 & spdif out*/
5308	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5309	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5310	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5311	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5312	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5313
5314	/* Unmute Mixer 14 (mic) 1c (Line in)*/
5315	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5316	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5317	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5318	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5319
5320	/* Unmute Stereo Mixer 15 */
5321	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5322	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5323	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5324	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
5325
5326	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5327	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5328	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5329	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5330	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5331	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5332	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5333	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5334
5335	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5336	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5337	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5338	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5339	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5340	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5341	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
5342	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
5343
5344	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	// set Mic 1
5345
5346	{ }
5347};
5348
5349/* pcm configuration: identiacal with ALC880 */
5350#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
5351#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
5352#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
5353#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
5354
5355
5356#define ALC861_DIGOUT_NID	0x07
5357
5358static struct hda_channel_mode alc861_8ch_modes[1] = {
5359	{ 8, NULL }
5360};
5361
5362static hda_nid_t alc861_dac_nids[4] = {
5363	/* front, surround, clfe, side */
5364	0x03, 0x06, 0x05, 0x04
5365};
5366
5367static hda_nid_t alc861_adc_nids[1] = {
5368	/* ADC0-2 */
5369	0x08,
5370};
5371
5372static struct hda_input_mux alc861_capture_source = {
5373	.num_items = 5,
5374	.items = {
5375		{ "Mic", 0x0 },
5376		{ "Front Mic", 0x3 },
5377		{ "Line", 0x1 },
5378		{ "CD", 0x4 },
5379		{ "Mixer", 0x5 },
5380	},
5381};
5382
5383/* fill in the dac_nids table from the parsed pin configuration */
5384static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
5385{
5386	int i;
5387	hda_nid_t nid;
5388
5389	spec->multiout.dac_nids = spec->private_dac_nids;
5390	for (i = 0; i < cfg->line_outs; i++) {
5391		nid = cfg->line_out_pins[i];
5392		if (nid) {
5393			if (i >= ARRAY_SIZE(alc861_dac_nids))
5394				continue;
5395			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
5396		}
5397	}
5398	spec->multiout.num_dacs = cfg->line_outs;
5399	return 0;
5400}
5401
5402/* add playback controls from the parsed DAC table */
5403static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
5404					     const struct auto_pin_cfg *cfg)
5405{
5406	char name[32];
5407	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
5408	hda_nid_t nid;
5409	int i, idx, err;
5410
5411	for (i = 0; i < cfg->line_outs; i++) {
5412		nid = spec->multiout.dac_nids[i];
5413		if (! nid)
5414			continue;
5415		if (nid == 0x05) {
5416			/* Center/LFE */
5417			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
5418					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
5419				return err;
5420			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
5421					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
5422				return err;
5423		} else {
5424			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
5425				if (nid == alc861_dac_nids[idx])
5426					break;
5427			sprintf(name, "%s Playback Switch", chname[idx]);
5428			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
5429					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
5430				return err;
5431		}
5432	}
5433	return 0;
5434}
5435
5436static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
5437{
5438	int err;
5439	hda_nid_t nid;
5440
5441	if (! pin)
5442		return 0;
5443
5444	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
5445		nid = 0x03;
5446		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
5447				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
5448			return err;
5449		spec->multiout.hp_nid = nid;
5450	}
5451	return 0;
5452}
5453
5454/* create playback/capture controls for input pins */
5455static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
5456{
5457	struct hda_input_mux *imux = &spec->private_imux;
5458	int i, err, idx, idx1;
5459
5460	for (i = 0; i < AUTO_PIN_LAST; i++) {
5461		switch(cfg->input_pins[i]) {
5462		case 0x0c:
5463			idx1 = 1;
5464			idx = 2;	// Line In
5465			break;
5466		case 0x0f:
5467			idx1 = 2;
5468			idx = 2;	// Line In
5469			break;
5470		case 0x0d:
5471			idx1 = 0;
5472			idx = 1;	// Mic In
5473			break;
5474		case 0x10:
5475			idx1 = 3;
5476			idx = 1;	// Mic In
5477			break;
5478		case 0x11:
5479			idx1 = 4;
5480			idx = 0;	// CD
5481			break;
5482		default:
5483			continue;
5484		}
5485
5486		err = new_analog_input(spec, cfg->input_pins[i],
5487				       auto_pin_cfg_labels[i], idx, 0x15);
5488		if (err < 0)
5489			return err;
5490
5491		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
5492		imux->items[imux->num_items].index = idx1;
5493		imux->num_items++;
5494	}
5495	return 0;
5496}
5497
5498static struct snd_kcontrol_new alc861_capture_mixer[] = {
5499	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5500	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5501
5502	{
5503		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5504		/* The multiple "Capture Source" controls confuse alsamixer
5505		 * So call somewhat different..
5506		 *FIXME: the controls appear in the "playback" view!
5507		 */
5508		/* .name = "Capture Source", */
5509		.name = "Input Source",
5510		.count = 1,
5511		.info = alc_mux_enum_info,
5512		.get = alc_mux_enum_get,
5513		.put = alc_mux_enum_put,
5514	},
5515	{ } /* end */
5516};
5517
5518static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
5519					      int pin_type, int dac_idx)
5520{
5521	/* set as output */
5522
5523	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
5524	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
5525
5526}
5527
5528static void alc861_auto_init_multi_out(struct hda_codec *codec)
5529{
5530	struct alc_spec *spec = codec->spec;
5531	int i;
5532
5533	for (i = 0; i < spec->autocfg.line_outs; i++) {
5534		hda_nid_t nid = spec->autocfg.line_out_pins[i];
5535		if (nid)
5536			alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
5537	}
5538}
5539
5540static void alc861_auto_init_hp_out(struct hda_codec *codec)
5541{
5542	struct alc_spec *spec = codec->spec;
5543	hda_nid_t pin;
5544
5545	pin = spec->autocfg.hp_pin;
5546	if (pin) /* connect to front */
5547		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
5548}
5549
5550static void alc861_auto_init_analog_input(struct hda_codec *codec)
5551{
5552	struct alc_spec *spec = codec->spec;
5553	int i;
5554
5555	for (i = 0; i < AUTO_PIN_LAST; i++) {
5556		hda_nid_t nid = spec->autocfg.input_pins[i];
5557		if ((nid>=0x0c) && (nid <=0x11)) {
5558			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5559					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
5560		}
5561	}
5562}
5563
5564/* parse the BIOS configuration and set up the alc_spec */
5565/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
5566static int alc861_parse_auto_config(struct hda_codec *codec)
5567{
5568	struct alc_spec *spec = codec->spec;
5569	int err;
5570	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
5571
5572	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5573						alc861_ignore)) < 0)
5574		return err;
5575	if (! spec->autocfg.line_outs)
5576		return 0; /* can't find valid BIOS pin config */
5577
5578	if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
5579	    (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
5580	    (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||
5581	    (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
5582		return err;
5583
5584	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5585
5586	if (spec->autocfg.dig_out_pin)
5587		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
5588
5589	if (spec->kctl_alloc)
5590		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5591
5592	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
5593
5594	spec->num_mux_defs = 1;
5595	spec->input_mux = &spec->private_imux;
5596
5597	spec->adc_nids = alc861_adc_nids;
5598	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
5599	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
5600	spec->num_mixers++;
5601
5602	return 1;
5603}
5604
5605/* additional initialization for auto-configuration model */
5606static void alc861_auto_init(struct hda_codec *codec)
5607{
5608	alc861_auto_init_multi_out(codec);
5609	alc861_auto_init_hp_out(codec);
5610	alc861_auto_init_analog_input(codec);
5611}
5612
5613
5614/*
5615 * configuration and preset
5616 */
5617static struct hda_board_config alc861_cfg_tbl[] = {
5618	{ .modelname = "3stack", .config = ALC861_3ST },
5619	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST },
5620	{ .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
5621	{ .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
5622	{ .modelname = "auto", .config = ALC861_AUTO },
5623	{}
5624};
5625
5626static struct alc_config_preset alc861_presets[] = {
5627	[ALC861_3ST] = {
5628		.mixers = { alc861_3ST_mixer },
5629		.init_verbs = { alc861_threestack_init_verbs },
5630		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
5631		.dac_nids = alc861_dac_nids,
5632		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
5633		.channel_mode = alc861_threestack_modes,
5634		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
5635		.adc_nids = alc861_adc_nids,
5636		.input_mux = &alc861_capture_source,
5637	},
5638	[ALC861_3ST_DIG] = {
5639		.mixers = { alc861_base_mixer },
5640		.init_verbs = { alc861_threestack_init_verbs },
5641		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
5642		.dac_nids = alc861_dac_nids,
5643		.dig_out_nid = ALC861_DIGOUT_NID,
5644		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
5645		.channel_mode = alc861_threestack_modes,
5646		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
5647		.adc_nids = alc861_adc_nids,
5648		.input_mux = &alc861_capture_source,
5649	},
5650	[ALC861_6ST_DIG] = {
5651		.mixers = { alc861_base_mixer },
5652		.init_verbs = { alc861_base_init_verbs },
5653		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
5654		.dac_nids = alc861_dac_nids,
5655		.dig_out_nid = ALC861_DIGOUT_NID,
5656		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
5657		.channel_mode = alc861_8ch_modes,
5658		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
5659		.adc_nids = alc861_adc_nids,
5660		.input_mux = &alc861_capture_source,
5661	},
5662};
5663
5664
5665static int patch_alc861(struct hda_codec *codec)
5666{
5667	struct alc_spec *spec;
5668	int board_config;
5669	int err;
5670
5671	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
5672	if (spec == NULL)
5673		return -ENOMEM;
5674
5675	codec->spec = spec;
5676
5677        board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl);
5678	if (board_config < 0 || board_config >= ALC861_MODEL_LAST) {
5679		printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n");
5680		board_config = ALC861_AUTO;
5681	}
5682
5683	if (board_config == ALC861_AUTO) {
5684		/* automatic parse from the BIOS config */
5685		err = alc861_parse_auto_config(codec);
5686		if (err < 0) {
5687			alc_free(codec);
5688			return err;
5689		} else if (! err) {
5690			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
5691		   board_config = ALC861_3ST_DIG;
5692		}
5693	}
5694
5695	if (board_config != ALC861_AUTO)
5696		setup_preset(spec, &alc861_presets[board_config]);
5697
5698	spec->stream_name_analog = "ALC861 Analog";
5699	spec->stream_analog_playback = &alc861_pcm_analog_playback;
5700	spec->stream_analog_capture = &alc861_pcm_analog_capture;
5701
5702	spec->stream_name_digital = "ALC861 Digital";
5703	spec->stream_digital_playback = &alc861_pcm_digital_playback;
5704	spec->stream_digital_capture = &alc861_pcm_digital_capture;
5705
5706	codec->patch_ops = alc_patch_ops;
5707	if (board_config == ALC861_AUTO)
5708		spec->init_hook = alc861_auto_init;
5709
5710	return 0;
5711}
5712
5713/*
5714 * patch entries
5715 */
5716struct hda_codec_preset snd_hda_preset_realtek[] = {
5717	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
5718	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
5719 	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
5720	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
5721	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
5722	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
5723	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
5724	{} /* terminator */
5725};
5726