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