patch_realtek.c revision 16ded525389c31256bcc9fd44352ab799b60b7fc
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 PeiSen Hou <pshou@realtek.com.tw>
7 *                    Takashi Iwai <tiwai@suse.de>
8 *
9 *  This driver is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This driver is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22 */
23
24#include <sound/driver.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/pci.h>
29#include <sound/core.h>
30#include "hda_codec.h"
31#include "hda_local.h"
32
33
34/* ALC880 board config type */
35enum {
36	ALC880_3ST,
37	ALC880_3ST_DIG,
38	ALC880_5ST,
39	ALC880_5ST_DIG,
40	ALC880_W810,
41	ALC880_Z71V,
42	ALC880_TEST,
43	ALC880_6ST_DIG,
44	ALC880_F1734,
45	ALC880_ASUS,
46	ALC880_ASUS_DIG,
47	ALC880_ASUS_W1V,
48	ALC880_UNIWILL_DIG,
49	ALC880_MODEL_LAST /* last tag */
50};
51
52/* ALC260 models */
53enum {
54	ALC260_BASIC,
55	ALC260_HP,
56	ALC260_MODEL_LAST /* last tag */
57};
58
59struct alc_spec {
60	/* codec parameterization */
61	unsigned int front_panel: 1;	/* indicates the board has a front panel;
62					 * not referred currently for any purpose,
63					 * though...
64					 */
65
66	snd_kcontrol_new_t *mixers[2];	/* mixer arrays */
67	unsigned int num_mixers;
68
69	struct hda_verb *init_verbs;	/* initialization verbs
70					 * don't forget NULL termination!
71					 */
72
73	char *stream_name_analog;	/* analog PCM stream */
74	struct hda_pcm_stream *stream_analog_playback;
75	struct hda_pcm_stream *stream_analog_capture;
76
77	char *stream_name_digital;	/* digital PCM stream */
78	struct hda_pcm_stream *stream_digital_playback;
79	struct hda_pcm_stream *stream_digital_capture;
80
81	/* playback */
82	struct hda_multi_out multiout;	/* playback set-up
83					 * max_channels, dacs must be set
84					 * dig_out_nid and hp_nid are optional
85					 */
86
87	/* capture */
88	unsigned int num_adc_nids;
89	hda_nid_t *adc_nids;
90	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
91
92	/* capture source */
93	const struct hda_input_mux *input_mux;
94	unsigned int cur_mux[3];
95
96	/* channel model */
97	const struct alc_channel_mode *channel_mode;
98	int num_channel_mode;
99
100	/* PCM information */
101	struct hda_pcm pcm_rec[2];	/* used in alc_build_pcms() */
102
103	struct semaphore bind_mutex;	/* for bound controls */
104};
105
106/* DAC/ADC assignment */
107
108static hda_nid_t alc880_dac_nids[4] = {
109	/* front, rear, clfe, rear_surr */
110	0x02, 0x05, 0x04, 0x03
111};
112
113static hda_nid_t alc880_6st_dac_nids[4] = {
114	/* front, rear, clfe, rear_surr */
115	0x02, 0x03, 0x04, 0x05
116};
117
118static hda_nid_t alc880_w810_dac_nids[3] = {
119	/* front, rear/surround, clfe */
120	0x02, 0x03, 0x04
121};
122
123static hda_nid_t alc880_z71v_dac_nids[1] = {
124	/* front only? */
125	0x02
126};
127
128#if 0
129/* The datasheet says the node 0x07 is connected from inputs,
130 * but it shows zero connection in the real implementation on some devices.
131 */
132static hda_nid_t alc880_adc_nids[3] = {
133	/* ADC0-2 */
134	0x07, 0x08, 0x09,
135};
136#else
137static hda_nid_t alc880_adc_nids[2] = {
138	/* ADC1-2 */
139	0x08, 0x09,
140};
141#endif
142
143#define ALC880_DIGOUT_NID	0x06
144#define ALC880_DIGIN_NID	0x0a
145
146static hda_nid_t alc260_dac_nids[1] = {
147	/* front */
148	0x02,
149};
150
151static hda_nid_t alc260_adc_nids[1] = {
152	/* ADC0 */
153	0x04,
154};
155
156static hda_nid_t alc260_hp_adc_nids[1] = {
157	/* ADC1 */
158	0x05,
159};
160
161#define ALC260_DIGOUT_NID	0x03
162#define ALC260_DIGIN_NID	0x06
163
164static struct hda_input_mux alc880_capture_source = {
165	.num_items = 4,
166	.items = {
167		{ "Mic", 0x0 },
168		{ "Front Mic", 0x3 },
169		{ "Line", 0x2 },
170		{ "CD", 0x4 },
171	},
172};
173
174//pshou 05/24/05
175static struct hda_input_mux alc880_6stack_capture_source = {
176	.num_items = 4,
177	.items = {
178		{ "Mic", 0x0 },
179		{ "Front Mic", 0x1 },
180		{ "Line", 0x2 },
181		{ "CD", 0x4 },
182	},
183};
184
185static struct hda_input_mux alc260_capture_source = {
186	.num_items = 4,
187	.items = {
188		{ "Mic", 0x0 },
189		{ "Front Mic", 0x1 },
190		{ "Line", 0x2 },
191		{ "CD", 0x4 },
192	},
193};
194
195/*
196 * input MUX handling
197 */
198static int alc_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
199{
200	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
201	struct alc_spec *spec = codec->spec;
202	return snd_hda_input_mux_info(spec->input_mux, uinfo);
203}
204
205static int alc_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
206{
207	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
208	struct alc_spec *spec = codec->spec;
209	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
210
211	ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
212	return 0;
213}
214
215static int alc_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
216{
217	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
218	struct alc_spec *spec = codec->spec;
219	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
220	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
221				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
222}
223
224/*
225 * channel mode setting
226 */
227struct alc_channel_mode {
228	int channels;
229	const struct hda_verb *sequence;
230};
231
232
233/*
234 * channel source setting (2/6 channel selection for 3-stack)
235 */
236
237/*
238 * set the path ways for 2 channel output
239 * need to set the codec line out and mic 1 pin widgets to inputs
240 */
241static struct hda_verb alc880_threestack_ch2_init[] = {
242	/* set pin widget 1Ah (line in) for input */
243	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
244	/* set pin widget 18h (mic1) for input, for mic also enable the vref */
245	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
246	/* mute the output for Line In PW */
247	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
248	/* mute for Mic1 PW */
249	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
250	{ } /* end */
251};
252
253/*
254 * 6ch mode
255 * need to set the codec line out and mic 1 pin widgets to outputs
256 */
257static struct hda_verb alc880_threestack_ch6_init[] = {
258	/* set pin widget 1Ah (line in) for output */
259	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
260	/* set pin widget 18h (mic1) for output */
261	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
262	/* unmute the output for Line In PW */
263	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
264	/* unmute for Mic1 PW */
265	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
266	/* for rear channel output using Line In 1
267	 * set select widget connection (nid = 0x12) - to summer node
268	 * for rear NID = 0x0f...offset 3 in connection list
269	 */
270	{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x3 },
271	/* for Mic1 - retask for center/lfe */
272	/* set select widget connection (nid = 0x10) - to summer node for
273	 * front CLFE NID = 0x0e...offset 2 in connection list
274	 */
275	{ 0x10, AC_VERB_SET_CONNECT_SEL, 0x2 },
276	{ } /* end */
277};
278
279static struct alc_channel_mode alc880_threestack_modes[2] = {
280	{ 2, alc880_threestack_ch2_init },
281	{ 6, alc880_threestack_ch6_init },
282};
283
284
285/*
286 * channel source setting (6/8 channel selection for 5-stack)
287 */
288
289/* set the path ways for 6 channel output
290 * need to set the codec line out and mic 1 pin widgets to inputs
291 */
292static struct hda_verb alc880_fivestack_ch6_init[] = {
293	/* set pin widget 1Ah (line in) for input */
294	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
295	/* mute the output for Line In PW */
296	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
297	{ } /* end */
298};
299
300/* need to set the codec line out and mic 1 pin widgets to outputs */
301static struct hda_verb alc880_fivestack_ch8_init[] = {
302	/* set pin widget 1Ah (line in) for output */
303	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
304	/* unmute the output for Line In PW */
305	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
306	/* output for surround channel output using Line In 1 */
307	/* set select widget connection (nid = 0x12) - to summer node
308	 * for surr_rear NID = 0x0d...offset 1 in connection list
309	 */
310	{ 0x12, AC_VERB_SET_CONNECT_SEL, 0x1 },
311	{ } /* end */
312};
313
314static struct alc_channel_mode alc880_fivestack_modes[2] = {
315	{ 6, alc880_fivestack_ch6_init },
316	{ 8, alc880_fivestack_ch8_init },
317};
318
319/*
320 * channel source setting for W810 system
321 *
322 * W810 has rear IO for:
323 * Front (DAC 02)
324 * Surround (DAC 03)
325 * Center/LFE (DAC 04)
326 * Digital out (06)
327 *
328 * The system also has a pair of internal speakers, and a headphone jack.
329 * These are both connected to Line2 on the codec, hence to DAC 02.
330 *
331 * There is a variable resistor to control the speaker or headphone
332 * volume. This is a hardware-only device without a software API.
333 *
334 * Plugging headphones in will disable the internal speakers. This is
335 * implemented in hardware, not via the driver using jack sense. In
336 * a similar fashion, plugging into the rear socket marked "front" will
337 * disable both the speakers and headphones.
338 *
339 * For input, there's a microphone jack, and an "audio in" jack.
340 * These may not do anything useful with this driver yet, because I
341 * haven't setup any initialization verbs for these yet...
342 */
343
344static struct alc_channel_mode alc880_w810_modes[1] = {
345	{ 6, NULL }
346};
347
348static struct alc_channel_mode alc880_z71v_modes[1] = {
349	{ 2, NULL }
350};
351
352//pshou 05/19/05
353static struct alc_channel_mode alc880_sixstack_modes[1] = {
354	{ 8, NULL },
355};
356
357/*
358 */
359static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
360{
361	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362	struct alc_spec *spec = codec->spec;
363	int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
364
365	snd_assert(spec->channel_mode, return -ENXIO);
366	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
367	uinfo->count = 1;
368	uinfo->value.enumerated.items = items;
369	if (uinfo->value.enumerated.item >= items)
370		uinfo->value.enumerated.item = items - 1;
371	sprintf(uinfo->value.enumerated.name, "%dch",
372		spec->channel_mode[uinfo->value.enumerated.item].channels);
373	return 0;
374}
375
376static int alc880_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
377{
378	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
379	struct alc_spec *spec = codec->spec;
380	int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
381	int i;
382
383	snd_assert(spec->channel_mode, return -ENXIO);
384	for (i = 0; i < items; i++) {
385		if (spec->multiout.max_channels == spec->channel_mode[i].channels) {
386			ucontrol->value.enumerated.item[0] = i;
387			break;
388		}
389	}
390	return 0;
391}
392
393static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
394{
395	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
396	struct alc_spec *spec = codec->spec;
397	int mode;
398
399	snd_assert(spec->channel_mode, return -ENXIO);
400	mode = ucontrol->value.enumerated.item[0] ? 1 : 0;
401	if (spec->multiout.max_channels == spec->channel_mode[mode].channels &&
402	    ! codec->in_resume)
403		return 0;
404
405	/* change the current channel setting */
406	spec->multiout.max_channels = spec->channel_mode[mode].channels;
407	if (spec->channel_mode[mode].sequence)
408		snd_hda_sequence_write(codec, spec->channel_mode[mode].sequence);
409
410	return 1;
411}
412
413
414/*
415 * bound volume controls
416 *
417 * bind multiple volumes (# indices, from 0)
418 */
419
420#define AMP_VAL_IDX_SHIFT	19
421#define AMP_VAL_IDX_MASK	(0x0f<<19)
422
423static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
424{
425	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
426	struct alc_spec *spec = codec->spec;
427	unsigned long pval;
428
429	down(&spec->bind_mutex);
430	pval = kcontrol->private_value;
431	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
432	snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
433	kcontrol->private_value = pval;
434	up(&spec->bind_mutex);
435	return 0;
436}
437
438static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
439{
440	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
441	struct alc_spec *spec = codec->spec;
442	unsigned long pval;
443
444	down(&spec->bind_mutex);
445	pval = kcontrol->private_value;
446	kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
447	snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
448	kcontrol->private_value = pval;
449	up(&spec->bind_mutex);
450	return 0;
451}
452
453static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
454{
455	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
456	struct alc_spec *spec = codec->spec;
457	unsigned long pval;
458	int i, indices, change = 0;
459
460	down(&spec->bind_mutex);
461	pval = kcontrol->private_value;
462	indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
463	for (i = 0; i < indices; i++) {
464		kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
465		change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
466	}
467	kcontrol->private_value = pval;
468	up(&spec->bind_mutex);
469	return change;
470}
471
472#define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
473	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
474	  .info = alc_bind_switch_info, \
475	  .get = alc_bind_switch_get, \
476	  .put = alc_bind_switch_put, \
477	  .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
478
479#define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
480
481/*
482 */
483
484/* 3-stack mode
485 * Pin assignment: Front=0x14, Line-In/Rear=0x1a, Mic/CLFE=0x18, F-Mic=0x1b
486 *                 HP=0x19
487 */
488static snd_kcontrol_new_t alc880_base_mixer[] = {
489	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
490	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
491	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
492	ALC_BIND_MUTE("Surround Playback Switch", 0x1a, 2, HDA_INPUT),
493	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
494	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
495	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
496	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
497	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
498	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
499	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
500	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
501	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
502	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
503	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
504	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
505	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
506	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
507	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
508	ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
509	/* We don't use NID 0x07 - see above */
510	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
511	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
512	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
513	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
514	{
515		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
516		/* The multiple "Capture Source" controls confuse alsamixer
517		 * So call somewhat different..
518		 * FIXME: the controls appear in the "playback" view!
519		 */
520		/* .name = "Capture Source", */
521		.name = "Input Source",
522		.count = 2,
523		.info = alc_mux_enum_info,
524		.get = alc_mux_enum_get,
525		.put = alc_mux_enum_put,
526	},
527	{
528		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
529		.name = "Channel Mode",
530		.info = alc880_ch_mode_info,
531		.get = alc880_ch_mode_get,
532		.put = alc880_ch_mode_put,
533	},
534	{ } /* end */
535};
536
537/* 5-stack mode
538 * Pin assignment: Front=0x14, Rear=0x17, CLFE=0x16
539 *                 Line-In/Side=0x1a, Mic=0x18, F-Mic=0x1b, HP=0x19
540 */
541static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
542	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
543	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
544	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
545	ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
546	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
547	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
548	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
549	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
550	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
551	ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
552	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
553	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
554	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
555	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
556	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
557	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
558	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
559	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
560	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
561	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
562	/* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), */
563	HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
564	/* We don't use NID 0x07 - see above */
565	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
566	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
567	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
568	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
569	{
570		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
571		/* The multiple "Capture Source" controls confuse alsamixer
572		 * So call somewhat different..
573		 * FIXME: the controls appear in the "playback" view!
574		 */
575		/* .name = "Capture Source", */
576		.name = "Input Source",
577		.count = 2,
578		.info = alc_mux_enum_info,
579		.get = alc_mux_enum_get,
580		.put = alc_mux_enum_put,
581	},
582	{
583		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
584		.name = "Channel Mode",
585		.info = alc880_ch_mode_info,
586		.get = alc880_ch_mode_get,
587		.put = alc880_ch_mode_put,
588	},
589	{ } /* end */
590};
591
592static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
593	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
594	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
595	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
596	HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
597	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
598	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
599	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
600	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
601	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
602	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
603	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
604	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
605	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
606	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
607	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
608	{
609		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
610		/* The multiple "Capture Source" controls confuse alsamixer
611		 * So call somewhat different..
612		 * FIXME: the controls appear in the "playback" view!
613		 */
614		/* .name = "Capture Source", */
615		.name = "Input Source",
616		.count = 3,
617		.info = alc_mux_enum_info,
618		.get = alc_mux_enum_get,
619		.put = alc_mux_enum_put,
620	},
621	{ } /* end */
622};
623
624static snd_kcontrol_new_t alc880_z71v_mixer[] = {
625	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
626	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
627	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
628	ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
629	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
630	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
631	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
632	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
633	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
634	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
635	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
636	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
637	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
638	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
639	{
640		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
641		/* The multiple "Capture Source" controls confuse alsamixer
642		 * So call somewhat different..
643		 * FIXME: the controls appear in the "playback" view!
644		 */
645		/* .name = "Capture Source", */
646		.name = "Input Source",
647		.count = 3,
648		.info = alc_mux_enum_info,
649		.get = alc_mux_enum_get,
650		.put = alc_mux_enum_put,
651	},
652	{ } /* end */
653};
654
655//pshou 05/24/05
656static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
657	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
658	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
659	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
660	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
661	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
662	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
663	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
664	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
665	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
666	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
667	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
668	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
669	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
670	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
671	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
672	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
673	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
674	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
675	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
676	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
677	/* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), */
678	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
679	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
680	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
681	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
682	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
683	{
684		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
685		/* The multiple "Capture Source" controls confuse alsamixer
686		 * So call somewhat different..
687		 * FIXME: the controls appear in the "playback" view!
688		 */
689		/* .name = "Capture Source", */
690		.name = "Input Source",
691		.count = 2,
692		.info = alc_mux_enum_info,
693		.get = alc_mux_enum_get,
694		.put = alc_mux_enum_put,
695	},
696	{
697		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
698		.name = "Channel Mode",
699		.info = alc880_ch_mode_info,
700		.get = alc880_ch_mode_get,
701		.put = alc880_ch_mode_put,
702	},
703	{ } /* end */
704};
705
706// 03/08/05  Fujitsu
707static snd_kcontrol_new_t alc880_2_jack_mixer[] = {
708	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
709	ALC_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
710	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
711	ALC_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
712	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
713	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
714	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
715	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
716	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
717	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
718	{
719		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
720		/* The multiple "Capture Source" controls confuse alsamixer
721		 * So call somewhat different..
722		 * FIXME: the controls appear in the "playback" view!
723		 */
724		/* .name = "Capture Source", */
725		.name = "Input Source",
726		.count = 1,
727		.info = alc_mux_enum_info,
728		.get = alc_mux_enum_get,
729		.put = alc_mux_enum_put,
730	},
731	{ } /* end */
732};
733
734//pshou 04/24/05
735static snd_kcontrol_new_t alc880_asus_mixer[] = {
736	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
737	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
738	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
739	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
740	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
741	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
742	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
743	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
744	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
745	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
746	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
747	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
748	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
749	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
750	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
751	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
752	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
753	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
754	{
755		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
756		/* The multiple "Capture Source" controls confuse alsamixer
757		 * So call somewhat different..
758		 * FIXME: the controls appear in the "playback" view!
759		 */
760		/* .name = "Capture Source", */
761		.name = "Input Source",
762		.count = 2,
763		.info = alc_mux_enum_info,
764		.get = alc_mux_enum_get,
765		.put = alc_mux_enum_put,
766	},
767	{
768		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
769		.name = "Channel Mode",
770		.info = alc880_ch_mode_info,
771		.get = alc880_ch_mode_get,
772		.put = alc880_ch_mode_put,
773	},
774	{ } /* end */
775};
776
777// pshou 05/03/05
778static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = {
779	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
780	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
781	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
782	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
783	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
784	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
785	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
786	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
787	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
788	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
789	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
790	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
791	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
792	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
793	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
794	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
795	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
796	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
797	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
798	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
799	{
800		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
801		/* The multiple "Capture Source" controls confuse alsamixer
802		 * So call somewhat different..
803		 * FIXME: the controls appear in the "playback" view!
804		 */
805		/* .name = "Capture Source", */
806		.name = "Input Source",
807		.count = 2,
808		.info = alc_mux_enum_info,
809		.get = alc_mux_enum_get,
810		.put = alc_mux_enum_put,
811	},
812	{
813		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
814		.name = "Channel Mode",
815		.info = alc880_ch_mode_info,
816		.get = alc880_ch_mode_get,
817		.put = alc880_ch_mode_put,
818	},
819	{ } /* end */
820};
821/*
822 */
823static int alc_build_controls(struct hda_codec *codec)
824{
825	struct alc_spec *spec = codec->spec;
826	int err;
827	int i;
828
829	for (i = 0; i < spec->num_mixers; i++) {
830		err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
831		if (err < 0)
832			return err;
833	}
834
835	if (spec->multiout.dig_out_nid) {
836		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
837		if (err < 0)
838			return err;
839	}
840	if (spec->dig_in_nid) {
841		err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
842		if (err < 0)
843			return err;
844	}
845	return 0;
846}
847
848/*
849 * initialize the codec volumes, etc
850 */
851
852#define AMP_IN_MUTE(idx)	(0x7080 | ((idx)<<8))
853#define AMP_IN_UNMUTE(idx)	(0x7000 | ((idx)<<8))
854#define AMP_OUT_MUTE	0xb080
855#define AMP_OUT_UNMUTE	0xb000
856#define AMP_OUT_ZERO	0xb000
857#define PIN_IN		0x20
858#define PIN_VREF80	0x24
859#define PIN_VREF50	0x21
860#define PIN_OUT		0x40
861#define PIN_HP		0xc0
862
863static struct hda_verb alc880_init_verbs_three_stack[] = {
864	/* Set pin widgets for output */
865	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
866	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
867	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
868	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
869	/* Line In pin widget for input */
870	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
871	/* CD pin widget for input */
872	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
873	/* Mic1 (rear panel) pin widget for input and vref at 80% */
874	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
875	/* Mic2 (front panel) pin widget for input and vref at 80% */
876	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
877	/* unmute capture amp left and right */
878	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
879	/* set connection select to mic in */
880	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
881	/* unmute capture1 amp left and right */
882	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
883	/* set connection select to mic in */
884	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
885	/* unmute capture2 amp left and right */
886	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
887	/* set connection select to mic in */
888	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
889	/* set vol=0 front mixer amp */
890	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
891	/* unmute front-out pin widget amp (no gain on this amp) */
892	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
893	/* set vol=0 rear mixer amp */
894	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
895	/* mute line-in pin widget amp left and right (no gain on this amp) */
896	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
897	/* set vol=0 clfe mixer amp */
898	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
899	/* mute mic pin widget amp left and right (no gain on this amp) */
900	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
901
902	/* using rear surround as the path for headphone output */
903	/* set vol=0 rear surround mixer amp */
904	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
905	/* PASD 3 stack boards use the Mic 2 as the headphone output */
906	/* need to program the selector associated with the Mic 2 pin widget to
907	 * surround path (index 0x01) for headphone output */
908	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
909	/* unmute pin widget amp left and right (no gain on this amp) */
910	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
911	/* need to retask the Mic 2 pin widget to output */
912	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
913
914	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B)
915	 * to support the input path of analog loopback
916	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
917	 * mic (mic 2)
918	 */
919	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
920	/* mute CD */
921	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
922	/* unmute Line In */
923	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
924	/* mute Mic 1 */
925	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
926	/* mute Line In 2 (for PASD boards Mic 2) */
927	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
928
929	/* Unmute input amps for the line out paths to support the output path of
930	 * analog loopback
931	 * the mixers on the output path has 2 inputs, one from the DAC and one
932	 * from the mixer
933	 */
934	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
935	/* Unmute Front out path */
936	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
937	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
938	/* Unmute Surround (used as HP) out path */
939	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
940	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
941	/* Unmute C/LFE out path */
942	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
943	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
944	/* Unmute rear Surround out path */
945	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
946	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
947
948	{ }
949};
950
951static struct hda_verb alc880_init_verbs_five_stack[] = {
952	/* Set pin widgets for output */
953	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
954	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
955	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
956	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
957	/* Line In pin widget for input */
958	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
959	/* CD pin widget for input */
960	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
961	/* Mic1 (rear panel) pin widget for input and vref at 80% */
962	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
963	/* Mic2 (front panel) pin widget for input and vref at 80% */
964	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
965	/* mute capture amp left and right */
966	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
967	/* set connection select to mic in */
968	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
969	/* mute amp1 left and right */
970	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
971	/* set connection select to mic in */
972	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
973	/* mute amp left and right */
974	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
975	/* set connection select to mic in */
976	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
977	/* set vol=0 front mixer amp */
978	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
979	/* unmute front-out pin widget amp (no gain on this amp) */
980	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
981	/* set vol=0 rear mixer amp */
982	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
983	/* unmute rear-out pin widget (no gain on this amp) */
984	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
985	/* set vol=0 clfe mixer amp */
986	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
987	/* unmute clfe-pin widget amp (no gain on this amp) */
988	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
989
990	/* using rear surround as the path for headphone output */
991	/* set vol=0 rear surround mixer amp */
992	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
993	/* PASD 3 stack boards use the Mic 2 as the headphone output */
994	/* need to program the selector associated with the Mic 2 pin widget to
995	 * surround path (index 0x01) for headphone output
996	 */
997	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
998	/* mute pin widget amp left and right (no gain on this amp) */
999	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1000	/* need to retask the Mic 2 pin widget to output */
1001	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1002
1003	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
1004	 * widget(nid=0x0B) to support the input path of analog loopback
1005	 */
1006	/* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
1007	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
1008	/* unmute CD */
1009	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1010	/* unmute Line In */
1011	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1012	/* unmute Mic 1 */
1013	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1014	/* unmute Line In 2 (for PASD boards Mic 2) */
1015	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1016
1017	/* Unmute input amps for the line out paths to support the output path of
1018	 * analog loopback
1019	 * the mixers on the output path has 2 inputs, one from the DAC and
1020	 * one from the mixer
1021	 */
1022	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1023	/* Unmute Front out path */
1024	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1025	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1026	/* Unmute Surround (used as HP) out path */
1027	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1028	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1029	/* Unmute C/LFE out path */
1030	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1031	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1032	/* Unmute rear Surround out path */
1033	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1034	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1035
1036	{ }
1037};
1038
1039static struct hda_verb alc880_w810_init_verbs[] = {
1040	/* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1041	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1042
1043	/* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
1044	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1045
1046	/* front channel selector/amp: output 0: unmuted, max volume */
1047	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1048
1049	/* front out pin: muted, (no volume selection)  */
1050	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1051
1052	/* front out pin: NOT headphone enable, out enable, vref disabled */
1053	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1054
1055
1056	/* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1057	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1058
1059	/* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */
1060	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1061
1062	/* surround channel selector/amp: output 0: unmuted, max volume */
1063	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1064
1065	/* surround out pin: muted, (no volume selection)  */
1066	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1067
1068	/* surround out pin: NOT headphone enable, out enable, vref disabled */
1069	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1070
1071
1072	/* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1073	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1074
1075	/* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */
1076	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1077
1078	/* c/lfe channel selector/amp: output 0: unmuted, max volume */
1079	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1080
1081	/* c/lfe out pin: muted, (no volume selection)  */
1082	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1083
1084	/* c/lfe out pin: NOT headphone enable, out enable, vref disabled */
1085	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1086
1087
1088	/* hphone/speaker input selector: front DAC */
1089	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1090
1091	/* hphone/speaker out pin: muted, (no volume selection)  */
1092	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1093
1094	/* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */
1095	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1096
1097
1098	{ }
1099};
1100
1101static struct hda_verb alc880_z71v_init_verbs[] = {
1102	/* front channel selector/amp: muted, DAC and mix (no vol) */
1103	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1104	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1105	/* front channel selector/amp: output 0: vol=0 */
1106	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1107	/* front out pin: unmuted, (no volume selection)  */
1108	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1109	/* front out pin: NOT headphone enable, out enable, vref disabled */
1110	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1111	/* headphone channel selector/amp: muted, DAC and mix (no vol) */
1112	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1113	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1114	/* headphone channel selector/amp: output 0: vol=0 */
1115	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1116	/* headphone out pin: muted, (no volume selection) */
1117	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1118	/* headpohne out pin: headphone enable, out enable, vref disabled */
1119	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1120
1121	/* Line In pin widget for input */
1122	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1123	/* CD pin widget for input */
1124	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1125	/* Mic1 (rear panel) pin widget for input and vref at 80% */
1126	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1127	/* Mic2 (front panel) pin widget for input and vref at 80% */
1128	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1129	/* unmute amp left and right */
1130	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1131	/* set connection select to mic in */
1132	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1133	/* unmute amp left and right */
1134	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1135	/* set connection select to mic in */
1136	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1137	/* unmute amp left and right */
1138	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1139	/* set connection select to mic in */
1140	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1141	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
1142	 * widget(nid=0x0B) to support the input path of analog loopback
1143	 */
1144	/* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
1145	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
1146	/* unmute CD */
1147	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1148	/* unmute Line In */
1149	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1150	/* unmute Mic 1 */
1151	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1152	/* unmute Line In 2 (for PASD boards Mic 2) */
1153	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1154
1155	{ }
1156};
1157
1158//pshou 05/24/05
1159static struct hda_verb alc880_six_stack_init_verbs[] = {
1160	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1161	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1162	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1163	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1164	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1165	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1166	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1167	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1168	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1169
1170	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1171	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1172	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1173	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1174
1175	/* unmute amp left and right */
1176	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1177	{0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
1178	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1179	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1180	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1181	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1182	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1183	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1184	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1185	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1186	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1187
1188	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
1189	 * widget(nid=0x0B) to support the input path of analog loopback
1190	 */
1191	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1192	/* unmute Line In */
1193	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1194	/* unmute Mic 1 */
1195	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1196	/* unmute Mic 2  */
1197	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1198
1199	/* Unmute Front out path */
1200	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1201	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1202	/* Unmute Surround (used as HP) out path */
1203	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1204	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1205	/* Unmute C/LFE out path */
1206	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1207	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mute */
1208	/* Unmute rear Surround out path */
1209	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1210	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1211
1212	{ }
1213};
1214
1215static struct hda_verb alc880_2_jack_init_verbs[] = {
1216	/* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
1217	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1218	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1219	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1220	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1221	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1222	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1223	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1224	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1225	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1226	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1227	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1228	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1229	{0x07, AC_VERB_SET_CONNECT_SEL, 0x02},
1230	{0x0C, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1231	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1232	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1233	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1234	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1235	{0x1B, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1236	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1237	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1238	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1239	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1240	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1241	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1242	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1243
1244	{ }
1245};
1246
1247static struct hda_verb alc880_asus_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	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1255	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1256	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1257	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1258	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1259	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1260	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1261	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1262
1263	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
1264	/* unmute CD */
1265	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1266	/* unmute Line In */
1267	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1268	/* unmute Mic 1 */
1269	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1270	/* unmute Line In 2 (for PASD boards Mic 2) */
1271	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1272
1273	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1274	/* Unmute Front out path */
1275	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1276	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1277	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1278	/* Unmute Surround (used as HP) out path */
1279	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1280	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1281	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1282	/* Unmute C/LFE out path */
1283	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1284	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1285	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1286
1287	{ }
1288};
1289
1290
1291static int alc_init(struct hda_codec *codec)
1292{
1293	struct alc_spec *spec = codec->spec;
1294	snd_hda_sequence_write(codec, spec->init_verbs);
1295	return 0;
1296}
1297
1298#ifdef CONFIG_PM
1299/*
1300 * resume
1301 */
1302static int alc_resume(struct hda_codec *codec)
1303{
1304	struct alc_spec *spec = codec->spec;
1305	int i;
1306
1307	alc_init(codec);
1308	for (i = 0; i < spec->num_mixers; i++) {
1309		snd_hda_resume_ctls(codec, spec->mixers[i]);
1310	}
1311	if (spec->multiout.dig_out_nid)
1312		snd_hda_resume_spdif_out(codec);
1313	if (spec->dig_in_nid)
1314		snd_hda_resume_spdif_in(codec);
1315
1316	return 0;
1317}
1318#endif
1319
1320/*
1321 * Analog playback callbacks
1322 */
1323static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
1324				    struct hda_codec *codec,
1325				    snd_pcm_substream_t *substream)
1326{
1327	struct alc_spec *spec = codec->spec;
1328	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
1329}
1330
1331static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1332				       struct hda_codec *codec,
1333				       unsigned int stream_tag,
1334				       unsigned int format,
1335				       snd_pcm_substream_t *substream)
1336{
1337	struct alc_spec *spec = codec->spec;
1338	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1339						format, substream);
1340}
1341
1342static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1343				       struct hda_codec *codec,
1344				       snd_pcm_substream_t *substream)
1345{
1346	struct alc_spec *spec = codec->spec;
1347	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1348}
1349
1350/*
1351 * Digital out
1352 */
1353static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1354					struct hda_codec *codec,
1355					snd_pcm_substream_t *substream)
1356{
1357	struct alc_spec *spec = codec->spec;
1358	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1359}
1360
1361static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1362					 struct hda_codec *codec,
1363					 snd_pcm_substream_t *substream)
1364{
1365	struct alc_spec *spec = codec->spec;
1366	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1367}
1368
1369/*
1370 * Analog capture
1371 */
1372static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1373				      struct hda_codec *codec,
1374				      unsigned int stream_tag,
1375				      unsigned int format,
1376				      snd_pcm_substream_t *substream)
1377{
1378	struct alc_spec *spec = codec->spec;
1379
1380	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1381				   stream_tag, 0, format);
1382	return 0;
1383}
1384
1385static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1386				      struct hda_codec *codec,
1387				      snd_pcm_substream_t *substream)
1388{
1389	struct alc_spec *spec = codec->spec;
1390
1391	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1392	return 0;
1393}
1394
1395
1396/*
1397 */
1398static struct hda_pcm_stream alc880_pcm_analog_playback = {
1399	.substreams = 1,
1400	.channels_min = 2,
1401	.channels_max = 8,
1402	.nid = 0x02, /* NID to query formats and rates */
1403	.ops = {
1404		.open = alc880_playback_pcm_open,
1405		.prepare = alc880_playback_pcm_prepare,
1406		.cleanup = alc880_playback_pcm_cleanup
1407	},
1408};
1409
1410static struct hda_pcm_stream alc880_pcm_analog_capture = {
1411	.substreams = 2,
1412	.channels_min = 2,
1413	.channels_max = 2,
1414	.nid = 0x08, /* NID to query formats and rates
1415		      * (0x07 might be broken on some devices)
1416		      */
1417	.ops = {
1418		.prepare = alc880_capture_pcm_prepare,
1419		.cleanup = alc880_capture_pcm_cleanup
1420	},
1421};
1422
1423static struct hda_pcm_stream alc880_pcm_digital_playback = {
1424	.substreams = 1,
1425	.channels_min = 2,
1426	.channels_max = 2,
1427	/* NID is set in alc_build_pcms */
1428	.ops = {
1429		.open = alc880_dig_playback_pcm_open,
1430		.close = alc880_dig_playback_pcm_close
1431	},
1432};
1433
1434static struct hda_pcm_stream alc880_pcm_digital_capture = {
1435	.substreams = 1,
1436	.channels_min = 2,
1437	.channels_max = 2,
1438	/* NID is set in alc_build_pcms */
1439};
1440
1441static int alc_build_pcms(struct hda_codec *codec)
1442{
1443	struct alc_spec *spec = codec->spec;
1444	struct hda_pcm *info = spec->pcm_rec;
1445	int i;
1446
1447	codec->num_pcms = 1;
1448	codec->pcm_info = info;
1449
1450	info->name = spec->stream_name_analog;
1451	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1452	info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1453
1454	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1455	for (i = 0; i < spec->num_channel_mode; i++) {
1456		if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1457		    info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1458		}
1459	}
1460
1461	if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1462		codec->num_pcms++;
1463		info++;
1464		info->name = spec->stream_name_digital;
1465		if (spec->multiout.dig_out_nid) {
1466			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
1467			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1468		}
1469		if (spec->dig_in_nid) {
1470			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
1471			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1472		}
1473	}
1474
1475	return 0;
1476}
1477
1478static void alc_free(struct hda_codec *codec)
1479{
1480	kfree(codec->spec);
1481}
1482
1483/*
1484 */
1485static struct hda_codec_ops alc_patch_ops = {
1486	.build_controls = alc_build_controls,
1487	.build_pcms = alc_build_pcms,
1488	.init = alc_init,
1489	.free = alc_free,
1490#ifdef CONFIG_PM
1491	.resume = alc_resume,
1492#endif
1493};
1494
1495
1496/*
1497 * Test configuration for debugging
1498 *
1499 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
1500 * enum controls.
1501 */
1502#ifdef CONFIG_SND_DEBUG
1503static hda_nid_t alc880_test_dac_nids[4] = {
1504	0x02, 0x03, 0x04, 0x05
1505};
1506
1507static struct hda_input_mux alc880_test_capture_source = {
1508	.num_items = 5,
1509	.items = {
1510		{ "In-1", 0x0 },
1511		{ "In-2", 0x1 },
1512		{ "In-3", 0x2 },
1513		{ "In-4", 0x3 },
1514		{ "CD", 0x4 },
1515	},
1516};
1517
1518static struct alc_channel_mode alc880_test_modes[4] = {
1519	{ 2, NULL },
1520	{ 4, NULL },
1521	{ 6, NULL },
1522	{ 8, NULL },
1523};
1524
1525static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1526{
1527	static char *texts[] = {
1528		"N/A", "Line Out", "HP Out",
1529		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1530	};
1531	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1532	uinfo->count = 1;
1533	uinfo->value.enumerated.items = 8;
1534	if (uinfo->value.enumerated.item >= 8)
1535		uinfo->value.enumerated.item = 7;
1536	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1537	return 0;
1538}
1539
1540static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1541{
1542	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1543	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1544	unsigned int pin_ctl, item = 0;
1545
1546	pin_ctl = snd_hda_codec_read(codec, nid, 0,
1547				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1548	if (pin_ctl & AC_PINCTL_OUT_EN) {
1549		if (pin_ctl & AC_PINCTL_HP_EN)
1550			item = 2;
1551		else
1552			item = 1;
1553	} else if (pin_ctl & AC_PINCTL_IN_EN) {
1554		switch (pin_ctl & AC_PINCTL_VREFEN) {
1555		case AC_PINCTL_VREF_HIZ: item = 3; break;
1556		case AC_PINCTL_VREF_50:  item = 4; break;
1557		case AC_PINCTL_VREF_GRD: item = 5; break;
1558		case AC_PINCTL_VREF_80:  item = 6; break;
1559		case AC_PINCTL_VREF_100: item = 7; break;
1560		}
1561	}
1562	ucontrol->value.enumerated.item[0] = item;
1563	return 0;
1564}
1565
1566static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1567{
1568	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1569	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1570	static unsigned int ctls[] = {
1571		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1572		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1573		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1574		AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1575		AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1576		AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1577	};
1578	unsigned int old_ctl, new_ctl;
1579
1580	old_ctl = snd_hda_codec_read(codec, nid, 0,
1581				     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1582	new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1583	if (old_ctl != new_ctl) {
1584		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
1585		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1586				    ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
1587		return 1;
1588	}
1589	return 0;
1590}
1591
1592static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1593{
1594	static char *texts[] = {
1595		"Front", "Surround", "CLFE", "Side"
1596	};
1597	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1598	uinfo->count = 1;
1599	uinfo->value.enumerated.items = 4;
1600	if (uinfo->value.enumerated.item >= 4)
1601		uinfo->value.enumerated.item = 3;
1602	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1603	return 0;
1604}
1605
1606static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1607{
1608	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1609	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1610	unsigned int sel;
1611
1612	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1613	ucontrol->value.enumerated.item[0] = sel & 3;
1614	return 0;
1615}
1616
1617static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1618{
1619	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1620	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1621	unsigned int sel;
1622
1623	sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1624	if (ucontrol->value.enumerated.item[0] != sel) {
1625		sel = ucontrol->value.enumerated.item[0] & 3;
1626		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
1627		return 1;
1628	}
1629	return 0;
1630}
1631
1632#define PIN_CTL_TEST(xname,nid) {			\
1633		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
1634			.name = xname,		       \
1635			.info = alc_test_pin_ctl_info, \
1636			.get = alc_test_pin_ctl_get,   \
1637			.put = alc_test_pin_ctl_put,   \
1638			.private_value = nid	       \
1639			}
1640
1641#define PIN_SRC_TEST(xname,nid) {			\
1642		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,	\
1643			.name = xname,		       \
1644			.info = alc_test_pin_src_info, \
1645			.get = alc_test_pin_src_get,   \
1646			.put = alc_test_pin_src_put,   \
1647			.private_value = nid	       \
1648			}
1649
1650static snd_kcontrol_new_t alc880_test_mixer[] = {
1651	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1652	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1653	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1654	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1655	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1656	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1657	ALC_BIND_MUTE("CLFE Playback Volume", 0x0e, 2, HDA_INPUT),
1658	ALC_BIND_MUTE("Side Playback Volume", 0x0f, 2, HDA_INPUT),
1659	PIN_CTL_TEST("Front Pin Mode", 0x14),
1660	PIN_CTL_TEST("Surround Pin Mode", 0x15),
1661	PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1662	PIN_CTL_TEST("Side Pin Mode", 0x17),
1663	PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1664	PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1665	PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1666	PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1667	PIN_SRC_TEST("In-1 Pin Source", 0x18),
1668	PIN_SRC_TEST("In-2 Pin Source", 0x19),
1669	PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1670	PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1671	HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1672	HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1673	HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1674	HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1675	HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1676	HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1677	HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1678	HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1679	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1680	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1681	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1682	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1683	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1684	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1685	{
1686		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1687		.name = "Input Source",
1688		.count = 2,
1689		.info = alc_mux_enum_info,
1690		.get = alc_mux_enum_get,
1691		.put = alc_mux_enum_put,
1692	},
1693	{
1694		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1695		.name = "Channel Mode",
1696		.info = alc880_ch_mode_info,
1697		.get = alc880_ch_mode_get,
1698		.put = alc880_ch_mode_put,
1699	},
1700	{ } /* end */
1701};
1702
1703static struct hda_verb alc880_test_init_verbs[] = {
1704	/* Unmute inputs of 0x0c - 0x0f */
1705	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1706	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1707	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1708	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1709	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1710	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1711	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1712	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1713	/* Vol output for 0x0c-0x0f */
1714	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1715	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1716	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1717	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1718	/* Set output pins 0x14-0x17 */
1719	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1720	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1721	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1722	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1723	/* Unmute output pins 0x14-0x17 */
1724	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1725	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1727	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1728	/* Set input pins 0x18-0x1c */
1729	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1730	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1731	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1732	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1733	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1734	/* Mute input pins 0x18-0x1b */
1735	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1736	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1737	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1738	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1739	/* ADC set up */
1740	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1741	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1742	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1743	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1744	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1745	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1746	/* Analog input/passthru */
1747	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1748	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1749	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1750	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1751	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1752	{ }
1753};
1754#endif
1755
1756/*
1757 */
1758
1759static struct hda_board_config alc880_cfg_tbl[] = {
1760	/* Back 3 jack, front 2 jack */
1761	{ .modelname = "3stack", .config = ALC880_3ST },
1762	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
1763	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
1764	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
1765	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
1766	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
1767	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
1768	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
1769	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
1770	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
1771	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
1772	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
1773	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
1774	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
1775	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
1776	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
1777	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
1778	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
1779	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
1780	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
1781	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
1782	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
1783	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
1784	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
1785	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
1786	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
1787	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
1788	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
1789	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
1790	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
1791	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
1792	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
1793	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
1794
1795	/* Back 3 jack, front 2 jack (Internal add Aux-In) */
1796	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
1797	{ .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST },
1798
1799	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
1800	{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
1801	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
1802
1803	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
1804	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
1805	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
1806	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
1807
1808	/* Back 5 jack, front 2 jack */
1809	{ .modelname = "5stack", .config = ALC880_5ST },
1810	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
1811	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
1812	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
1813	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
1814	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
1815
1816	/* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
1817	{ .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
1818	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
1819	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
1820	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
1821	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
1822	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
1823	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
1824	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
1825	{ .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
1826	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
1827	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG },
1828	{ .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
1829	{ .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG },
1830
1831	{ .modelname = "w810", .config = ALC880_W810 },
1832	{ .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
1833
1834	{ .modelname = "z71v", .config = ALC880_Z71V },
1835	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
1836
1837	{ .modelname = "6statack-digout", .config = ALC880_6ST_DIG },
1838	{ .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
1839	{ .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
1840	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
1841	{ .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
1842
1843	{ .modelname = "asua", .config = ALC880_ASUS },
1844	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
1845	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
1846	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
1847	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
1848	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
1849	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
1850	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
1851	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
1852	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
1853	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
1854
1855	{ .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
1856	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
1857
1858	{ .modelname = "F1734", .config = ALC880_F1734 },
1859	{ .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
1860
1861#ifdef CONFIG_SND_DEBUG
1862	{ .modelname = "test", .config = ALC880_TEST },
1863#endif
1864
1865	{}
1866};
1867
1868/*
1869 * configuration template - to be copied to the spec instance
1870 */
1871struct alc_config_preset {
1872	snd_kcontrol_new_t *mixers;
1873	unsigned int front_panel: 1;	/* optional */
1874	unsigned int gpio_payload;	/* optional */
1875	struct hda_verb *init_verbs;
1876	unsigned int num_dacs;
1877	hda_nid_t *dac_nids;
1878	hda_nid_t dig_out_nid;		/* optional */
1879	hda_nid_t hp_nid;		/* optional */
1880	unsigned int num_adc_nids;
1881	hda_nid_t *adc_nids;
1882	unsigned int num_channel_mode;
1883	const struct alc_channel_mode *channel_mode;
1884	const struct hda_input_mux *input_mux;
1885};
1886
1887static struct alc_config_preset alc880_presets[] = {
1888	[ALC880_3ST] = {
1889		.mixers = alc880_base_mixer,
1890		.init_verbs = alc880_init_verbs_three_stack,
1891		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
1892		.front_panel = 1,
1893		.dac_nids = alc880_dac_nids,
1894		.hp_nid = 0x03,
1895		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1896		.adc_nids = alc880_adc_nids,
1897		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1898		.channel_mode = alc880_threestack_modes,
1899		.input_mux = &alc880_capture_source,
1900	},
1901	[ALC880_3ST_DIG] = {
1902		.mixers = alc880_base_mixer,
1903		.init_verbs = alc880_init_verbs_three_stack,
1904		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
1905		.front_panel = 1,
1906		.dac_nids = alc880_dac_nids,
1907		.dig_out_nid = ALC880_DIGOUT_NID,
1908		.hp_nid = 0x03,
1909		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1910		.adc_nids = alc880_adc_nids,
1911		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1912		.channel_mode = alc880_threestack_modes,
1913		.input_mux = &alc880_capture_source,
1914	},
1915	[ALC880_5ST] = {
1916		.mixers = alc880_five_stack_mixer,
1917		.init_verbs = alc880_init_verbs_five_stack,
1918		.front_panel = 1,
1919		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
1920		.dac_nids = alc880_dac_nids,
1921		.hp_nid = 0x03,
1922		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1923		.adc_nids = alc880_adc_nids,
1924		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1925		.channel_mode = alc880_fivestack_modes,
1926		.input_mux = &alc880_capture_source,
1927	},
1928	[ALC880_5ST_DIG] = {
1929		.mixers = alc880_five_stack_mixer,
1930		.init_verbs = alc880_init_verbs_five_stack,
1931		.front_panel = 1,
1932		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
1933		.dac_nids = alc880_dac_nids,
1934		.dig_out_nid = ALC880_DIGOUT_NID,
1935		.hp_nid = 0x03,
1936		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1937		.adc_nids = alc880_adc_nids,
1938		.num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1939		.channel_mode = alc880_fivestack_modes,
1940		.input_mux = &alc880_capture_source,
1941	},
1942	[ALC880_6ST_DIG] = {
1943		.mixers = alc880_six_stack_mixer,
1944		.init_verbs = alc880_six_stack_init_verbs,
1945		.front_panel = 1,
1946		.num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1947		.dac_nids = alc880_6st_dac_nids,
1948		.dig_out_nid = ALC880_DIGOUT_NID,
1949		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1950		.adc_nids = alc880_adc_nids,
1951		.num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1952		.channel_mode = alc880_sixstack_modes,
1953		.input_mux = &alc880_6stack_capture_source,
1954	},
1955	[ALC880_W810] = {
1956		.mixers = alc880_w810_base_mixer,
1957		.init_verbs = alc880_w810_init_verbs,
1958		.gpio_payload = 0x2,
1959		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1960		.dac_nids = alc880_w810_dac_nids,
1961		.dig_out_nid = ALC880_DIGOUT_NID,
1962		// No dedicated headphone socket - it's shared with built-in speakers.
1963		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1964		.adc_nids = alc880_adc_nids,
1965		.num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1966		.channel_mode = alc880_w810_modes,
1967		.input_mux = &alc880_capture_source,
1968	},
1969	[ALC880_Z71V] = {
1970		.mixers = alc880_z71v_mixer,
1971		.init_verbs = alc880_z71v_init_verbs,
1972		.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1973		.dac_nids = alc880_z71v_dac_nids,
1974		.dig_out_nid = ALC880_DIGOUT_NID,
1975		.hp_nid = 0x03,
1976		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1977		.adc_nids = alc880_adc_nids,
1978		.num_channel_mode = ARRAY_SIZE(alc880_z71v_modes),
1979		.channel_mode = alc880_z71v_modes,
1980		.input_mux = &alc880_capture_source,
1981	},
1982	[ALC880_F1734] = {
1983		.mixers = alc880_2_jack_mixer,
1984		.init_verbs = alc880_2_jack_init_verbs,
1985		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
1986		.dac_nids = alc880_dac_nids,
1987		.hp_nid = 0x03,
1988		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
1989		.adc_nids = alc880_adc_nids,
1990		.num_channel_mode = ARRAY_SIZE(alc880_z71v_modes),
1991		.channel_mode = alc880_z71v_modes,
1992		.input_mux = &alc880_capture_source,
1993	},
1994	[ALC880_ASUS] = {
1995		.mixers = alc880_asus_mixer,
1996		.init_verbs = alc880_asus_init_verbs,
1997		.gpio_payload = 0x1,
1998		.front_panel = 1,
1999		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2000		.dac_nids = alc880_w810_dac_nids,
2001		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2002		.adc_nids = alc880_adc_nids,
2003		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2004		.channel_mode = alc880_threestack_modes,
2005		.input_mux = &alc880_capture_source,
2006	},
2007	[ALC880_ASUS_DIG] = {
2008		.mixers = alc880_asus_mixer,
2009		.init_verbs = alc880_asus_init_verbs,
2010		.gpio_payload = 0x1,
2011		.front_panel = 1,
2012		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2013		.dac_nids = alc880_w810_dac_nids,
2014		.dig_out_nid = ALC880_DIGOUT_NID,
2015		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2016		.adc_nids = alc880_adc_nids,
2017		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2018		.channel_mode = alc880_threestack_modes,
2019		.input_mux = &alc880_capture_source,
2020	},
2021	[ALC880_ASUS_W1V] = {
2022		.mixers = alc880_asus_w1v_mixer,
2023		.init_verbs = alc880_asus_init_verbs,
2024		.gpio_payload = 0x1,
2025		.front_panel = 1,
2026		.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2027		.dac_nids = alc880_w810_dac_nids,
2028		.dig_out_nid = ALC880_DIGOUT_NID,
2029		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2030		.adc_nids = alc880_adc_nids,
2031		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2032		.channel_mode = alc880_threestack_modes,
2033		.input_mux = &alc880_capture_source,
2034	},
2035	[ALC880_UNIWILL_DIG] = {
2036		.mixers = alc880_asus_mixer,
2037		.init_verbs = alc880_asus_init_verbs,
2038		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
2039		.dac_nids = alc880_dac_nids,
2040		.dig_out_nid = ALC880_DIGOUT_NID,
2041		.hp_nid = 0x03,
2042		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2043		.adc_nids = alc880_adc_nids,
2044		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2045		.channel_mode = alc880_threestack_modes,
2046		.input_mux = &alc880_capture_source,
2047	},
2048#ifdef CONFIG_SND_DEBUG
2049	[ALC880_TEST] = {
2050		.mixers = alc880_test_mixer,
2051		.init_verbs = alc880_test_init_verbs,
2052		.num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
2053		.dac_nids = alc880_test_dac_nids,
2054		.dig_out_nid = ALC880_DIGOUT_NID,
2055		.num_adc_nids = ARRAY_SIZE(alc880_adc_nids),
2056		.adc_nids = alc880_adc_nids,
2057		.num_channel_mode = ARRAY_SIZE(alc880_test_modes),
2058		.channel_mode = alc880_test_modes,
2059		.input_mux = &alc880_test_capture_source,
2060	},
2061#endif
2062};
2063
2064static int patch_alc880(struct hda_codec *codec)
2065{
2066	struct alc_spec *spec;
2067	int board_config;
2068	const struct alc_config_preset *preset;
2069
2070	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
2071	if (spec == NULL)
2072		return -ENOMEM;
2073
2074	init_MUTEX(&spec->bind_mutex);
2075	codec->spec = spec;
2076
2077	board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
2078	if (board_config < 0 || board_config >= ALC880_MODEL_LAST) {
2079		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n");
2080		board_config = ALC880_3ST;
2081	}
2082	preset = &alc880_presets[board_config];
2083
2084	spec->mixers[spec->num_mixers] = preset->mixers;
2085	snd_assert(spec->mixers[0], kfree(spec);return -EINVAL);
2086	spec->num_mixers++;
2087
2088	/* some MBs need GPIO setup */
2089	if (preset->gpio_payload) {
2090		/* Enable mask and set output */
2091		snd_hda_codec_write(codec, codec->afg, 0,
2092				    AC_VERB_SET_GPIO_MASK, preset->gpio_payload);
2093		snd_hda_codec_write(codec, codec->afg, 0,
2094				    AC_VERB_SET_GPIO_DIRECTION, preset->gpio_payload);
2095		snd_hda_codec_write(codec, codec->afg, 0,
2096				    AC_VERB_SET_GPIO_DATA, preset->gpio_payload);
2097	}
2098
2099	spec->front_panel = preset->front_panel;
2100	spec->init_verbs = preset->init_verbs;
2101	spec->channel_mode = preset->channel_mode;
2102	spec->num_channel_mode = preset->num_channel_mode;
2103
2104	spec->stream_name_analog = "ALC880 Analog";
2105	spec->stream_analog_playback = &alc880_pcm_analog_playback;
2106	spec->stream_analog_capture = &alc880_pcm_analog_capture;
2107
2108	spec->stream_name_digital = "ALC880 Digital";
2109	spec->stream_digital_playback = &alc880_pcm_digital_playback;
2110	spec->stream_digital_capture = &alc880_pcm_digital_capture;
2111
2112	spec->multiout.max_channels = spec->channel_mode[0].channels;
2113
2114	spec->multiout.num_dacs = preset->num_dacs;
2115	spec->multiout.dac_nids = preset->adc_nids;
2116	spec->multiout.dig_out_nid = preset->dig_out_nid;
2117	spec->multiout.hp_nid = preset->hp_nid;
2118
2119	spec->input_mux = preset->input_mux;
2120	spec->num_adc_nids = preset->num_adc_nids;
2121	spec->adc_nids = preset->adc_nids;
2122
2123	codec->patch_ops = alc_patch_ops;
2124
2125	return 0;
2126}
2127
2128/*
2129 * ALC260 support
2130 */
2131
2132/*
2133 * This is just place-holder, so there's something for alc_build_pcms to look
2134 * at when it calculates the maximum number of channels. ALC260 has no mixer
2135 * element which allows changing the channel mode, so the verb list is
2136 * never used.
2137 */
2138static struct alc_channel_mode alc260_modes[1] = {
2139	{ 2, NULL },
2140};
2141
2142snd_kcontrol_new_t alc260_base_mixer[] = {
2143	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2144	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
2145	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2146	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2147	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2148	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2149	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2150	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2151	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
2152	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
2153	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
2154	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
2155	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2156	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
2157	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2158	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
2159	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
2160	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
2161	{
2162		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2163		.name = "Capture Source",
2164		.info = alc_mux_enum_info,
2165		.get = alc_mux_enum_get,
2166		.put = alc_mux_enum_put,
2167	},
2168	{ } /* end */
2169};
2170
2171snd_kcontrol_new_t alc260_hp_mixer[] = {
2172	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
2173	ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
2174	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
2175	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
2176	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
2177	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
2178	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
2179	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
2180	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
2181	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
2182	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
2183	ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
2184	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2185	ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
2186	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
2187	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
2188	{
2189		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2190		.name = "Capture Source",
2191		.info = alc_mux_enum_info,
2192		.get = alc_mux_enum_get,
2193		.put = alc_mux_enum_put,
2194	},
2195	{ } /* end */
2196};
2197
2198static struct hda_verb alc260_init_verbs[] = {
2199	/* Line In pin widget for input */
2200	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2201	/* CD pin widget for input */
2202	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2203	/* Mic1 (rear panel) pin widget for input and vref at 80% */
2204	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2205	/* Mic2 (front panel) pin widget for input and vref at 80% */
2206	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2207	/* LINE-2 is used for line-out in rear */
2208	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2209	/* select line-out */
2210	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2211	/* LINE-OUT pin */
2212	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2213	/* enable HP */
2214	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2215	/* enable Mono */
2216	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2217	/* mute capture amp left and right */
2218	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2219	/* set connection select to line in (default select for this ADC) */
2220	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
2221	/* mute capture amp left and right */
2222	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2223	/* set connection select to line in (default select for this ADC) */
2224	{0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
2225	/* set vol=0 Line-Out mixer amp left and right */
2226	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2227	/* unmute pin widget amp left and right (no gain on this amp) */
2228	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229	/* set vol=0 HP mixer amp left and right */
2230	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2231	/* unmute pin widget amp left and right (no gain on this amp) */
2232	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233	/* set vol=0 Mono mixer amp left and right */
2234	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2235	/* unmute pin widget amp left and right (no gain on this amp) */
2236	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2237	/* unmute LINE-2 out pin */
2238	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2239	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
2240	/* mute CD */
2241	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2242	/* mute Line In */
2243	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2244	/* mute Mic */
2245	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2246	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
2247	/* mute Front out path */
2248	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2249	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2250	/* mute Headphone out path */
2251	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2252	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2253	/* mute Mono out path */
2254	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2255	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2256	{ }
2257};
2258
2259static struct hda_pcm_stream alc260_pcm_analog_playback = {
2260	.substreams = 1,
2261	.channels_min = 2,
2262	.channels_max = 2,
2263	.nid = 0x2,
2264};
2265
2266static struct hda_pcm_stream alc260_pcm_analog_capture = {
2267	.substreams = 1,
2268	.channels_min = 2,
2269	.channels_max = 2,
2270	.nid = 0x4,
2271};
2272
2273static struct hda_board_config alc260_cfg_tbl[] = {
2274	{ .modelname = "hp", .config = ALC260_HP },
2275	{ .pci_subvendor = 0x103c, .config = ALC260_HP },
2276	{}
2277};
2278
2279static int patch_alc260(struct hda_codec *codec)
2280{
2281	struct alc_spec *spec;
2282	int board_config;
2283
2284	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
2285	if (spec == NULL)
2286		return -ENOMEM;
2287
2288	init_MUTEX(&spec->bind_mutex);
2289	codec->spec = spec;
2290
2291	board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
2292	if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
2293		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");
2294		board_config = ALC260_BASIC;
2295	}
2296
2297	switch (board_config) {
2298	case ALC260_HP:
2299		spec->mixers[spec->num_mixers] = alc260_base_mixer;
2300		spec->num_mixers++;
2301		break;
2302	default:
2303		spec->mixers[spec->num_mixers] = alc260_base_mixer;
2304		spec->num_mixers++;
2305		break;
2306	}
2307
2308	spec->init_verbs = alc260_init_verbs;
2309	spec->channel_mode = alc260_modes;
2310	spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
2311
2312	spec->stream_name_analog = "ALC260 Analog";
2313	spec->stream_analog_playback = &alc260_pcm_analog_playback;
2314	spec->stream_analog_capture = &alc260_pcm_analog_capture;
2315
2316	spec->multiout.max_channels = spec->channel_mode[0].channels;
2317	spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
2318	spec->multiout.dac_nids = alc260_dac_nids;
2319
2320	spec->input_mux = &alc260_capture_source;
2321	switch (board_config) {
2322	case ALC260_HP:
2323		spec->stream_analog_capture->nid = 5;
2324		spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
2325		spec->adc_nids = alc260_hp_adc_nids;
2326		break;
2327	default:
2328		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
2329		spec->adc_nids = alc260_adc_nids;
2330		break;
2331	}
2332
2333	codec->patch_ops = alc_patch_ops;
2334
2335	return 0;
2336}
2337
2338/*
2339 * ALC882 support
2340 *
2341 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
2342 * configuration.  Each pin widget can choose any input DACs and a mixer.
2343 * Each ADC is connected from a mixer of all inputs.  This makes possible
2344 * 6-channel independent captures.
2345 *
2346 * In addition, an independent DAC for the multi-playback (not used in this
2347 * driver yet).
2348 */
2349
2350static struct alc_channel_mode alc882_ch_modes[1] = {
2351	{ 8, NULL }
2352};
2353
2354static hda_nid_t alc882_dac_nids[4] = {
2355	/* front, rear, clfe, rear_surr */
2356	0x02, 0x03, 0x04, 0x05
2357};
2358
2359static hda_nid_t alc882_adc_nids[3] = {
2360	/* ADC0-2 */
2361	0x07, 0x08, 0x09,
2362};
2363
2364/* input MUX */
2365/* FIXME: should be a matrix-type input source selection */
2366
2367static struct hda_input_mux alc882_capture_source = {
2368	.num_items = 4,
2369	.items = {
2370		{ "Mic", 0x0 },
2371		{ "Front Mic", 0x1 },
2372		{ "Line", 0x2 },
2373		{ "CD", 0x4 },
2374	},
2375};
2376
2377#define alc882_mux_enum_info alc_mux_enum_info
2378#define alc882_mux_enum_get alc_mux_enum_get
2379
2380static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
2381{
2382	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2383	struct alc_spec *spec = codec->spec;
2384	const struct hda_input_mux *imux = spec->input_mux;
2385	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2386	static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
2387	hda_nid_t nid = capture_mixers[adc_idx];
2388	unsigned int *cur_val = &spec->cur_mux[adc_idx];
2389	unsigned int i, idx;
2390
2391	idx = ucontrol->value.enumerated.item[0];
2392	if (idx >= imux->num_items)
2393		idx = imux->num_items - 1;
2394	if (*cur_val == idx && ! codec->in_resume)
2395		return 0;
2396	for (i = 0; i < imux->num_items; i++) {
2397		unsigned int v = (i == idx) ? 0x7000 : 0x7080;
2398		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2399				    v | (imux->items[i].index << 8));
2400	}
2401	*cur_val = idx;
2402	return 1;
2403}
2404
2405/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
2406 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
2407 */
2408static snd_kcontrol_new_t alc882_base_mixer[] = {
2409	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2410	ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2411	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2412	ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2413	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2414	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2415	ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2416	ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_OUTPUT),
2417	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2418	ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2419	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2420	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2421	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2422	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2423	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2424	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2425	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2426	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2427	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2428	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
2429	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
2430	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
2431	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
2432	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
2433	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
2434	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
2435	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
2436	{
2437		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2438		/* .name = "Capture Source", */
2439		.name = "Input Source",
2440		.count = 3,
2441		.info = alc882_mux_enum_info,
2442		.get = alc882_mux_enum_get,
2443		.put = alc882_mux_enum_put,
2444	},
2445	{ } /* end */
2446};
2447
2448static struct hda_verb alc882_init_verbs[] = {
2449	/* Front mixer: unmute input/output amp left and right (volume = 0) */
2450	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2451	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2452	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2453	/* Rear mixer */
2454	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2455	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2456	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2457	/* CLFE mixer */
2458	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2459	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2460	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2461	/* Side mixer */
2462	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2463	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2464	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2465
2466	/* Front Pin: to output mode */
2467	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2468	/* Front Pin: mute amp left and right (no volume) */
2469	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2470	/* select Front mixer (0x0c, index 0) */
2471	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2472	/* Rear Pin */
2473	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2474	/* Rear Pin: mute amp left and right (no volume) */
2475	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2476	/* select Rear mixer (0x0d, index 1) */
2477	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
2478	/* CLFE Pin */
2479	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2480	/* CLFE Pin: mute amp left and right (no volume) */
2481	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2482	/* select CLFE mixer (0x0e, index 2) */
2483	{0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2484	/* Side Pin */
2485	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2486	/* Side Pin: mute amp left and right (no volume) */
2487	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2488	/* select Side mixer (0x0f, index 3) */
2489	{0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2490	/* Headphone Pin */
2491	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2492	/* Headphone Pin: mute amp left and right (no volume) */
2493	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2494	/* select Front mixer (0x0c, index 0) */
2495	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2496	/* Mic (rear) pin widget for input and vref at 80% */
2497	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2498	/* Front Mic pin widget for input and vref at 80% */
2499	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2500	/* Line In pin widget for input */
2501	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2502	/* CD pin widget for input */
2503	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2504
2505	/* FIXME: use matrix-type input source selection */
2506	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
2507	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
2508	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2509	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2510	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2511	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2512	/* Input mixer2 */
2513	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2514	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2515	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2516	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2517	/* Input mixer3 */
2518	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2519	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2520	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2521	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2522	/* ADC1: mute amp left and right */
2523	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2524	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2525	/* ADC2: mute amp left and right */
2526	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2527	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2528	/* ADC3: mute amp left and right */
2529	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2530	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2531
2532	{ }
2533};
2534
2535static int patch_alc882(struct hda_codec *codec)
2536{
2537	struct alc_spec *spec;
2538
2539	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
2540	if (spec == NULL)
2541		return -ENOMEM;
2542
2543	init_MUTEX(&spec->bind_mutex);
2544	codec->spec = spec;
2545
2546	spec->mixers[spec->num_mixers] = alc882_base_mixer;
2547	spec->num_mixers++;
2548
2549	spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
2550	spec->dig_in_nid = ALC880_DIGIN_NID;
2551	spec->front_panel = 1;
2552	spec->init_verbs = alc882_init_verbs;
2553	spec->channel_mode = alc882_ch_modes;
2554	spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
2555
2556	spec->stream_name_analog = "ALC882 Analog";
2557	spec->stream_analog_playback = &alc880_pcm_analog_playback;
2558	spec->stream_analog_capture = &alc880_pcm_analog_capture;
2559
2560	spec->stream_name_digital = "ALC882 Digital";
2561	spec->stream_digital_playback = &alc880_pcm_digital_playback;
2562	spec->stream_digital_capture = &alc880_pcm_digital_capture;
2563
2564	spec->multiout.max_channels = spec->channel_mode[0].channels;
2565	spec->multiout.num_dacs = ARRAY_SIZE(alc882_dac_nids);
2566	spec->multiout.dac_nids = alc882_dac_nids;
2567
2568	spec->input_mux = &alc882_capture_source;
2569	spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
2570	spec->adc_nids = alc882_adc_nids;
2571
2572	codec->patch_ops = alc_patch_ops;
2573
2574	return 0;
2575}
2576
2577/*
2578 * patch entries
2579 */
2580struct hda_codec_preset snd_hda_preset_realtek[] = {
2581	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
2582 	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
2583	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
2584	{} /* terminator */
2585};
2586