[ALSA] hda-codec - Allow sub_device=0 in board config check
[linux-2.6] / sound / pci / hda / patch_realtek.c
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 */
35 enum {
36         ALC880_MINIMAL,
37         ALC880_3ST,
38         ALC880_3ST_DIG,
39         ALC880_5ST,
40         ALC880_5ST_DIG,
41         ALC880_W810,
42         ALC880_Z71V,
43         ALC880_TEST,
44 };
45
46 struct alc_spec {
47         /* codec parameterization */
48         unsigned int front_panel: 1;
49
50         snd_kcontrol_new_t* mixers[2];
51         unsigned int num_mixers;
52
53         struct hda_verb *init_verbs;
54
55         char* stream_name_analog;
56         struct hda_pcm_stream *stream_analog_playback;
57         struct hda_pcm_stream *stream_analog_capture;
58
59         char* stream_name_digital;
60         struct hda_pcm_stream *stream_digital_playback;
61         struct hda_pcm_stream *stream_digital_capture;
62
63         /* playback */
64         struct hda_multi_out multiout;
65
66         /* capture */
67         unsigned int num_adc_nids;
68         hda_nid_t *adc_nids;
69         hda_nid_t dig_in_nid;
70
71         /* capture source */
72         const struct hda_input_mux *input_mux;
73         unsigned int cur_mux[3];
74
75         /* channel model */
76         const struct alc_channel_mode *channel_mode;
77         int num_channel_mode;
78
79         /* PCM information */
80         struct hda_pcm pcm_rec[2];
81
82         struct semaphore bind_mutex;
83 };
84
85 /* DAC/ADC assignment */
86
87 static hda_nid_t alc880_dac_nids[4] = {
88         /* front, rear, clfe, rear_surr */
89         0x02, 0x05, 0x04, 0x03
90 };
91
92 static hda_nid_t alc880_w810_dac_nids[3] = {
93         /* front, rear/surround, clfe */
94         0x02, 0x03, 0x04
95 };
96
97 static hda_nid_t alc880_z71v_dac_nids[1] = {
98         /* front only? */
99         0x02
100 };
101
102 #if 0
103 /* The datasheet says the node 0x07 is connected from inputs,
104  * but it shows zero connection in the real implementation on some devices.
105  */
106 static hda_nid_t alc880_adc_nids[3] = {
107         /* ADC0-2 */
108         0x07, 0x08, 0x09,
109 };
110 #else
111 static hda_nid_t alc880_adc_nids[2] = {
112         /* ADC1-2 */
113         0x08, 0x09,
114 };
115 #endif
116
117 #define ALC880_DIGOUT_NID       0x06
118 #define ALC880_DIGIN_NID        0x0a
119
120 static hda_nid_t alc260_dac_nids[1] = {
121         /* front */
122         0x02,
123 };
124
125 static hda_nid_t alc260_adc_nids[2] = {
126         /* ADC0-1 */
127         0x04, 0x05,
128 };
129
130 #define ALC260_DIGOUT_NID       0x03
131 #define ALC260_DIGIN_NID        0x06
132
133 static struct hda_input_mux alc880_capture_source = {
134         .num_items = 4,
135         .items = {
136                 { "Mic", 0x0 },
137                 { "Front Mic", 0x3 },
138                 { "Line", 0x2 },
139                 { "CD", 0x4 },
140         },
141 };
142
143 static struct hda_input_mux alc260_capture_source = {
144         .num_items = 4,
145         .items = {
146                 { "Mic", 0x0 },
147                 { "Front Mic", 0x1 },
148                 { "Line", 0x2 },
149                 { "CD", 0x4 },
150         },
151 };
152
153 /*
154  * input MUX handling
155  */
156 static int alc_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
157 {
158         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
159         struct alc_spec *spec = codec->spec;
160         return snd_hda_input_mux_info(spec->input_mux, uinfo);
161 }
162
163 static int alc_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
164 {
165         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
166         struct alc_spec *spec = codec->spec;
167         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
168
169         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
170         return 0;
171 }
172
173 static int alc_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
174 {
175         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
176         struct alc_spec *spec = codec->spec;
177         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
178         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
179                                      spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
180 }
181
182 /*
183  * channel mode setting
184  */
185 struct alc_channel_mode {
186         int channels;
187         const struct hda_verb *sequence;
188 };
189
190
191 /*
192  * channel source setting (2/6 channel selection for 3-stack)
193  */
194
195 /*
196  * set the path ways for 2 channel output
197  * need to set the codec line out and mic 1 pin widgets to inputs
198  */
199 static struct hda_verb alc880_threestack_ch2_init[] = {
200         /* set pin widget 1Ah (line in) for input */
201         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
202         /* set pin widget 18h (mic1) for input, for mic also enable the vref */
203         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
204         /* mute the output for Line In PW */
205         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
206         /* mute for Mic1 PW */
207         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
208         { } /* end */
209 };
210
211 /*
212  * 6ch mode
213  * need to set the codec line out and mic 1 pin widgets to outputs
214  */
215 static struct hda_verb alc880_threestack_ch6_init[] = {
216         /* set pin widget 1Ah (line in) for output */
217         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
218         /* set pin widget 18h (mic1) for output */
219         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
220         /* unmute the output for Line In PW */
221         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
222         /* unmute for Mic1 PW */
223         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000 },
224         /* for rear channel output using Line In 1
225          * set select widget connection (nid = 0x12) - to summer node
226          * for rear NID = 0x0f...offset 3 in connection list
227          */
228         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x3 },
229         /* for Mic1 - retask for center/lfe */
230         /* set select widget connection (nid = 0x10) - to summer node for
231          * front CLFE NID = 0x0e...offset 2 in connection list
232          */
233         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x2 },
234         { } /* end */
235 };
236
237 static struct alc_channel_mode alc880_threestack_modes[2] = {
238         { 2, alc880_threestack_ch2_init },
239         { 6, alc880_threestack_ch6_init },
240 };
241
242
243 /*
244  * channel source setting (6/8 channel selection for 5-stack)
245  */
246
247 /* set the path ways for 6 channel output
248  * need to set the codec line out and mic 1 pin widgets to inputs
249  */
250 static struct hda_verb alc880_fivestack_ch6_init[] = {
251         /* set pin widget 1Ah (line in) for input */
252         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
253         /* mute the output for Line In PW */
254         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
255         { } /* end */
256 };
257
258 /* need to set the codec line out and mic 1 pin widgets to outputs */
259 static struct hda_verb alc880_fivestack_ch8_init[] = {
260         /* set pin widget 1Ah (line in) for output */
261         { 0x1a, 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         /* output for surround channel output using Line In 1 */
265         /* set select widget connection (nid = 0x12) - to summer node
266          * for surr_rear NID = 0x0d...offset 1 in connection list
267          */
268         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x1 },
269         { } /* end */
270 };
271
272 static struct alc_channel_mode alc880_fivestack_modes[2] = {
273         { 6, alc880_fivestack_ch6_init },
274         { 8, alc880_fivestack_ch8_init },
275 };
276
277 /*
278  * channel source setting for W810 system
279  *
280  * W810 has rear IO for:
281  * Front (DAC 02)
282  * Surround (DAC 03)
283  * Center/LFE (DAC 04)
284  * Digital out (06)
285  *
286  * The system also has a pair of internal speakers, and a headphone jack.
287  * These are both connected to Line2 on the codec, hence to DAC 02.
288  * 
289  * There is a variable resistor to control the speaker or headphone
290  * volume. This is a hardware-only device without a software API.
291  *
292  * Plugging headphones in will disable the internal speakers. This is
293  * implemented in hardware, not via the driver using jack sense. In
294  * a similar fashion, plugging into the rear socket marked "front" will
295  * disable both the speakers and headphones.
296  *
297  * For input, there's a microphone jack, and an "audio in" jack.
298  * These may not do anything useful with this driver yet, because I
299  * haven't setup any initialization verbs for these yet...
300  */
301
302 static struct alc_channel_mode alc880_w810_modes[1] = {
303         { 6, NULL }
304 };
305
306 static struct alc_channel_mode alc880_z71v_modes[1] = {
307         { 2, NULL }
308 };
309
310 /*
311  */
312 static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
313 {
314         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
315         struct alc_spec *spec = codec->spec;
316         int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
317
318         snd_assert(spec->channel_mode, return -ENXIO);
319         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
320         uinfo->count = 1;
321         uinfo->value.enumerated.items = items;
322         if (uinfo->value.enumerated.item >= items)
323                 uinfo->value.enumerated.item = items - 1;
324         sprintf(uinfo->value.enumerated.name, "%dch",
325                 spec->channel_mode[uinfo->value.enumerated.item].channels);
326         return 0;
327 }
328
329 static int alc880_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
330 {
331         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
332         struct alc_spec *spec = codec->spec;
333         int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
334         int i;
335
336         snd_assert(spec->channel_mode, return -ENXIO);
337         for (i = 0; i < items; i++) {
338                 if (spec->multiout.max_channels == spec->channel_mode[i].channels) {
339                         ucontrol->value.enumerated.item[0] = i;
340                         break;
341                 }
342         }
343         return 0;
344 }
345
346 static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
347 {
348         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
349         struct alc_spec *spec = codec->spec;
350         int mode;
351
352         snd_assert(spec->channel_mode, return -ENXIO);
353         mode = ucontrol->value.enumerated.item[0] ? 1 : 0;
354         if (spec->multiout.max_channels == spec->channel_mode[mode].channels &&
355             ! codec->in_resume)
356                 return 0;
357
358         /* change the current channel setting */
359         spec->multiout.max_channels = spec->channel_mode[mode].channels;
360         if (spec->channel_mode[mode].sequence)
361                 snd_hda_sequence_write(codec, spec->channel_mode[mode].sequence);
362
363         return 1;
364 }
365
366
367 /*
368  * bound volume controls
369  *
370  * bind multiple volumes (# indices, from 0)
371  */
372
373 #define AMP_VAL_IDX_SHIFT       19
374 #define AMP_VAL_IDX_MASK        (0x0f<<19)
375
376 static int alc_bind_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
377 {
378         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
379         struct alc_spec *spec = codec->spec;
380         unsigned long pval;
381
382         down(&spec->bind_mutex);
383         pval = kcontrol->private_value;
384         kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
385         snd_hda_mixer_amp_switch_info(kcontrol, uinfo);
386         kcontrol->private_value = pval;
387         up(&spec->bind_mutex);
388         return 0;
389 }
390
391 static int alc_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
392 {
393         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
394         struct alc_spec *spec = codec->spec;
395         unsigned long pval;
396
397         down(&spec->bind_mutex);
398         pval = kcontrol->private_value;
399         kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
400         snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
401         kcontrol->private_value = pval;
402         up(&spec->bind_mutex);
403         return 0;
404 }
405
406 static int alc_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
407 {
408         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
409         struct alc_spec *spec = codec->spec;
410         unsigned long pval;
411         int i, indices, change = 0;
412
413         down(&spec->bind_mutex);
414         pval = kcontrol->private_value;
415         indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
416         for (i = 0; i < indices; i++) {
417                 kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT);
418                 change |= snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
419         }
420         kcontrol->private_value = pval;
421         up(&spec->bind_mutex);
422         return change;
423 }
424
425 #define ALC_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
426         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
427           .info = alc_bind_switch_info, \
428           .get = alc_bind_switch_get, \
429           .put = alc_bind_switch_put, \
430           .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
431
432 #define ALC_BIND_MUTE(xname,nid,indices,dir) ALC_BIND_MUTE_MONO(xname,nid,3,indices,dir)
433
434 /*
435  */
436
437 /* 3-stack mode
438  * Pin assignment: Front=0x14, Line-In/Rear=0x1a, Mic/CLFE=0x18, F-Mic=0x1b
439  *                 HP=0x19
440  */
441 static snd_kcontrol_new_t alc880_base_mixer[] = {
442         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
443         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
444         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
445         ALC_BIND_MUTE("Surround Playback Switch", 0x1a, 2, HDA_INPUT),
446         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
447         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
448         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
449         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
450         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
451         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
452         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
453         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
454         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
455         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
456         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
457         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
458         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
459         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
460         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
461         ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
462         /* We don't use NID 0x07 - see above */
463         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
464         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
465         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
466         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
467         {
468                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
469                 /* The multiple "Capture Source" controls confuse alsamixer
470                  * So call somewhat different..
471                  * FIXME: the controls appear in the "playback" view!
472                  */
473                 /* .name = "Capture Source", */
474                 .name = "Input Source",
475                 .count = 2,
476                 .info = alc_mux_enum_info,
477                 .get = alc_mux_enum_get,
478                 .put = alc_mux_enum_put,
479         },
480         {
481                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
482                 .name = "Channel Mode",
483                 .info = alc880_ch_mode_info,
484                 .get = alc880_ch_mode_get,
485                 .put = alc880_ch_mode_put,
486         },
487         { } /* end */
488 };
489
490 /* 5-stack mode
491  * Pin assignment: Front=0x14, Rear=0x17, CLFE=0x16
492  *                 Line-In/Side=0x1a, Mic=0x18, F-Mic=0x1b, HP=0x19
493  */
494 static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
495         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
496         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
497         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
498         ALC_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
499         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
500         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
501         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
502         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
503         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
504         ALC_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
505         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
506         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
507         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
508         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
509         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
510         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
511         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
512         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
513         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
514         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
515         /* HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), */
516         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
517         /* We don't use NID 0x07 - see above */
518         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
519         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
520         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
521         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
522         {
523                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
524                 /* The multiple "Capture Source" controls confuse alsamixer
525                  * So call somewhat different..
526                  * FIXME: the controls appear in the "playback" view!
527                  */
528                 /* .name = "Capture Source", */
529                 .name = "Input Source",
530                 .count = 2,
531                 .info = alc_mux_enum_info,
532                 .get = alc_mux_enum_get,
533                 .put = alc_mux_enum_put,
534         },
535         {
536                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
537                 .name = "Channel Mode",
538                 .info = alc880_ch_mode_info,
539                 .get = alc880_ch_mode_get,
540                 .put = alc880_ch_mode_put,
541         },
542         { } /* end */
543 };
544
545 static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
546         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
547         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
548         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
549         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
550         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
551         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
552         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
553         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
554         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
555         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
556         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
557         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
558         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
559         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
560         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
561         {
562                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
563                 /* The multiple "Capture Source" controls confuse alsamixer
564                  * So call somewhat different..
565                  * FIXME: the controls appear in the "playback" view!
566                  */
567                 /* .name = "Capture Source", */
568                 .name = "Input Source",
569                 .count = 3,
570                 .info = alc_mux_enum_info,
571                 .get = alc_mux_enum_get,
572                 .put = alc_mux_enum_put,
573         },
574         { } /* end */
575 };
576
577 static snd_kcontrol_new_t alc880_z71v_mixer[] = {
578         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
579         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
580         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
581         ALC_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
582         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
583         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
584         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
585         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
586         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
587         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
588         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
589         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
590         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
591         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
592         {
593                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
594                 /* The multiple "Capture Source" controls confuse alsamixer
595                  * So call somewhat different..
596                  * FIXME: the controls appear in the "playback" view!
597                  */
598                 /* .name = "Capture Source", */
599                 .name = "Input Source",
600                 .count = 3,
601                 .info = alc_mux_enum_info,
602                 .get = alc_mux_enum_get,
603                 .put = alc_mux_enum_put,
604         },
605         { } /* end */
606 };
607
608 /*
609  */
610 static int alc_build_controls(struct hda_codec *codec)
611 {
612         struct alc_spec *spec = codec->spec;
613         int err;
614         int i;
615
616         for (i = 0; i < spec->num_mixers; i++) {
617                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
618                 if (err < 0)
619                         return err;
620         }
621
622         if (spec->multiout.dig_out_nid) {
623                 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
624                 if (err < 0)
625                         return err;
626         }
627         if (spec->dig_in_nid) {
628                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
629                 if (err < 0)
630                         return err;
631         }
632         return 0;
633 }
634
635 /*
636  * initialize the codec volumes, etc
637  */
638
639 #define AMP_IN_MUTE(idx)        (0x7080 | ((idx)<<8))
640 #define AMP_IN_UNMUTE(idx)      (0x7000 | ((idx)<<8))
641 #define AMP_OUT_MUTE    0xb080
642 #define AMP_OUT_UNMUTE  0xb000
643 #define AMP_OUT_ZERO    0xb000
644 #define PIN_IN          0x20
645 #define PIN_VREF        0x24
646 #define PIN_OUT         0x40
647 #define PIN_HP          0xc0
648
649 static struct hda_verb alc880_init_verbs_three_stack[] = {
650         /* Set pin widgets for output */
651         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
652         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
653         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
654         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
655         /* Line In pin widget for input */
656         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
657         /* CD pin widget for input */
658         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
659         /* Mic1 (rear panel) pin widget for input and vref at 80% */
660         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
661         /* Mic2 (front panel) pin widget for input and vref at 80% */
662         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
663         /* unmute capture amp left and right */
664         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
665         /* set connection select to mic in */
666         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
667         /* unmute capture1 amp left and right */
668         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
669         /* set connection select to mic in */
670         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
671         /* unmute capture2 amp left and right */
672         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
673         /* set connection select to mic in */
674         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
675         /* set vol=0 front mixer amp */
676         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
677         /* unmute front-out pin widget amp (no gain on this amp) */
678         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
679         /* set vol=0 rear mixer amp */
680         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
681         /* mute line-in pin widget amp left and right (no gain on this amp) */
682         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
683         /* set vol=0 clfe mixer amp */
684         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
685         /* mute mic pin widget amp left and right (no gain on this amp) */
686         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
687
688         /* using rear surround as the path for headphone output */
689         /* set vol=0 rear surround mixer amp */
690         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
691         /* PASD 3 stack boards use the Mic 2 as the headphone output */
692         /* need to program the selector associated with the Mic 2 pin widget to
693          * surround path (index 0x01) for headphone output */
694         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
695         /* unmute pin widget amp left and right (no gain on this amp) */
696         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
697         /* need to retask the Mic 2 pin widget to output */
698         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
699
700         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B)
701          * to support the input path of analog loopback
702          * Note: PASD motherboards uses the Line In 2 as the input for front panel
703          * mic (mic 2)
704          */
705         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
706         /* mute CD */
707         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
708         /* unmute Line In */
709         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
710         /* mute Mic 1 */
711         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
712         /* mute Line In 2 (for PASD boards Mic 2) */
713         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
714
715         /* Unmute input amps for the line out paths to support the output path of
716          * analog loopback
717          * the mixers on the output path has 2 inputs, one from the DAC and one
718          * from the mixer
719          */
720         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
721         /* Unmute Front out path */
722         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
723         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
724         /* Unmute Surround (used as HP) out path */
725         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
726         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
727         /* Unmute C/LFE out path */
728         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
729         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
730         /* Unmute rear Surround out path */
731         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
732         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
733
734         { }
735 };
736
737 static struct hda_verb alc880_init_verbs_five_stack[] = {
738         /* Set pin widgets for output */
739         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
740         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
741         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
742         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
743         /* Line In pin widget for input */
744         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
745         /* CD pin widget for input */
746         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
747         /* Mic1 (rear panel) pin widget for input and vref at 80% */
748         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
749         /* Mic2 (front panel) pin widget for input and vref at 80% */
750         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
751         /* mute capture amp left and right */
752         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
753         /* set connection select to mic in */
754         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
755         /* mute amp1 left and right */
756         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
757         /* set connection select to mic in */
758         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
759         /* mute amp left and right */
760         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
761         /* set connection select to mic in */
762         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
763         /* set vol=0 front mixer amp */
764         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
765         /* unmute front-out pin widget amp (no gain on this amp) */
766         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
767         /* set vol=0 rear mixer amp */
768         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
769         /* unmute rear-out pin widget (no gain on this amp) */
770         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
771         /* set vol=0 clfe mixer amp */
772         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
773         /* unmute clfe-pin widget amp (no gain on this amp) */
774         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
775
776         /* using rear surround as the path for headphone output */
777         /* set vol=0 rear surround mixer amp */
778         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
779         /* PASD 3 stack boards use the Mic 2 as the headphone output */
780         /* need to program the selector associated with the Mic 2 pin widget to
781          * surround path (index 0x01) for headphone output
782          */
783         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
784         /* mute pin widget amp left and right (no gain on this amp) */
785         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
786         /* need to retask the Mic 2 pin widget to output */
787         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
788
789         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
790          * widget(nid=0x0B) to support the input path of analog loopback
791          */
792         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
793         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
794         /* unmute CD */
795         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
796         /* unmute Line In */
797         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
798         /* unmute Mic 1 */
799         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
800         /* unmute Line In 2 (for PASD boards Mic 2) */
801         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
802
803         /* Unmute input amps for the line out paths to support the output path of
804          * analog loopback
805          * the mixers on the output path has 2 inputs, one from the DAC and
806          * one from the mixer
807          */
808         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
809         /* Unmute Front out path */
810         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
811         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
812         /* Unmute Surround (used as HP) out path */
813         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
814         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
815         /* Unmute C/LFE out path */
816         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
817         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
818         /* Unmute rear Surround out path */
819         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
820         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
821
822         { }
823 };
824
825 static struct hda_verb alc880_w810_init_verbs[] = {
826         /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
827         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
828
829         /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
830         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
831
832         /* front channel selector/amp: output 0: unmuted, max volume */
833         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
834
835         /* front out pin: muted, (no volume selection)  */
836         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
837
838         /* front out pin: NOT headphone enable, out enable, vref disabled */
839         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
840
841
842         /* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
843         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
844
845         /* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */
846         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
847
848         /* surround channel selector/amp: output 0: unmuted, max volume */
849         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
850
851         /* surround out pin: muted, (no volume selection)  */
852         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
853
854         /* surround out pin: NOT headphone enable, out enable, vref disabled */
855         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
856
857
858         /* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
859         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
860
861         /* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */
862         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
863
864         /* c/lfe channel selector/amp: output 0: unmuted, max volume */
865         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
866
867         /* c/lfe out pin: muted, (no volume selection)  */
868         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
869
870         /* c/lfe out pin: NOT headphone enable, out enable, vref disabled */
871         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
872
873
874         /* hphone/speaker input selector: front DAC */
875         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
876
877         /* hphone/speaker out pin: muted, (no volume selection)  */
878         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
879
880         /* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */
881         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
882
883
884         { }
885 };
886
887 static struct hda_verb alc880_z71v_init_verbs[] = {
888         /* front channel selector/amp: muted, DAC and mix (no vol) */
889         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
890         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
891         /* front channel selector/amp: output 0: vol=0 */
892         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
893         /* front out pin: unmuted, (no volume selection)  */
894         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895         /* front out pin: NOT headphone enable, out enable, vref disabled */
896         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
897         /* headphone channel selector/amp: muted, DAC and mix (no vol) */
898         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
899         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
900         /* headphone channel selector/amp: output 0: vol=0 */
901         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
902         /* headphone out pin: muted, (no volume selection) */
903         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
904         /* headpohne out pin: headphone enable, out enable, vref disabled */
905         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
906
907         /* Line In pin widget for input */
908         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
909         /* CD pin widget for input */
910         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
911         /* Mic1 (rear panel) pin widget for input and vref at 80% */
912         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
913         /* Mic2 (front panel) pin widget for input and vref at 80% */
914         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
915         /* unmute amp left and right */
916         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
917         /* set connection select to mic in */
918         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
919         /* unmute amp left and right */
920         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
921         /* set connection select to mic in */
922         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
923         /* unmute amp left and right */
924         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
925         /* set connection select to mic in */
926         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
927         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
928          * widget(nid=0x0B) to support the input path of analog loopback
929          */
930         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
931         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
932         /* unmute CD */
933         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
934         /* unmute Line In */
935         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
936         /* unmute Mic 1 */
937         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
938         /* unmute Line In 2 (for PASD boards Mic 2) */
939         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
940
941         { }
942 };
943
944 static int alc_init(struct hda_codec *codec)
945 {
946         struct alc_spec *spec = codec->spec;
947         snd_hda_sequence_write(codec, spec->init_verbs);
948         return 0;
949 }
950
951 #ifdef CONFIG_PM
952 /*
953  * resume
954  */
955 static int alc_resume(struct hda_codec *codec)
956 {
957         struct alc_spec *spec = codec->spec;
958         int i;
959
960         alc_init(codec);
961         for (i = 0; i < spec->num_mixers; i++) {
962                 snd_hda_resume_ctls(codec, spec->mixers[i]);
963         }
964         if (spec->multiout.dig_out_nid)
965                 snd_hda_resume_spdif_out(codec);
966         if (spec->dig_in_nid)
967                 snd_hda_resume_spdif_in(codec);
968
969         return 0;
970 }
971 #endif
972
973 /*
974  * Analog playback callbacks
975  */
976 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
977                                     struct hda_codec *codec,
978                                     snd_pcm_substream_t *substream)
979 {
980         struct alc_spec *spec = codec->spec;
981         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
982 }
983
984 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
985                                        struct hda_codec *codec,
986                                        unsigned int stream_tag,
987                                        unsigned int format,
988                                        snd_pcm_substream_t *substream)
989 {
990         struct alc_spec *spec = codec->spec;
991         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
992                                                 format, substream);
993 }
994
995 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
996                                        struct hda_codec *codec,
997                                        snd_pcm_substream_t *substream)
998 {
999         struct alc_spec *spec = codec->spec;
1000         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1001 }
1002
1003 /*
1004  * Digital out
1005  */
1006 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1007                                         struct hda_codec *codec,
1008                                         snd_pcm_substream_t *substream)
1009 {
1010         struct alc_spec *spec = codec->spec;
1011         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1012 }
1013
1014 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1015                                          struct hda_codec *codec,
1016                                          snd_pcm_substream_t *substream)
1017 {
1018         struct alc_spec *spec = codec->spec;
1019         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1020 }
1021
1022 /*
1023  * Analog capture
1024  */
1025 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1026                                       struct hda_codec *codec,
1027                                       unsigned int stream_tag,
1028                                       unsigned int format,
1029                                       snd_pcm_substream_t *substream)
1030 {
1031         struct alc_spec *spec = codec->spec;
1032
1033         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1034                                    stream_tag, 0, format);
1035         return 0;
1036 }
1037
1038 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1039                                       struct hda_codec *codec,
1040                                       snd_pcm_substream_t *substream)
1041 {
1042         struct alc_spec *spec = codec->spec;
1043
1044         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1045         return 0;
1046 }
1047
1048
1049 /*
1050  */
1051 static struct hda_pcm_stream alc880_pcm_analog_playback = {
1052         .substreams = 1,
1053         .channels_min = 2,
1054         .channels_max = 8,
1055         .nid = 0x02, /* NID to query formats and rates */
1056         .ops = {
1057                 .open = alc880_playback_pcm_open,
1058                 .prepare = alc880_playback_pcm_prepare,
1059                 .cleanup = alc880_playback_pcm_cleanup
1060         },
1061 };
1062
1063 static struct hda_pcm_stream alc880_pcm_analog_capture = {
1064         .substreams = 2,
1065         .channels_min = 2,
1066         .channels_max = 2,
1067         .nid = 0x08, /* NID to query formats and rates
1068                       * (0x07 might be broken on some devices)
1069                       */
1070         .ops = {
1071                 .prepare = alc880_capture_pcm_prepare,
1072                 .cleanup = alc880_capture_pcm_cleanup
1073         },
1074 };
1075
1076 static struct hda_pcm_stream alc880_pcm_digital_playback = {
1077         .substreams = 1,
1078         .channels_min = 2,
1079         .channels_max = 2,
1080         /* NID is set in alc_build_pcms */
1081         .ops = {
1082                 .open = alc880_dig_playback_pcm_open,
1083                 .close = alc880_dig_playback_pcm_close
1084         },
1085 };
1086
1087 static struct hda_pcm_stream alc880_pcm_digital_capture = {
1088         .substreams = 1,
1089         .channels_min = 2,
1090         .channels_max = 2,
1091         /* NID is set in alc_build_pcms */
1092 };
1093
1094 static int alc_build_pcms(struct hda_codec *codec)
1095 {
1096         struct alc_spec *spec = codec->spec;
1097         struct hda_pcm *info = spec->pcm_rec;
1098         int i;
1099
1100         codec->num_pcms = 1;
1101         codec->pcm_info = info;
1102
1103         info->name = spec->stream_name_analog;
1104         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1105         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1106
1107         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1108         for (i = 0; i < spec->num_channel_mode; i++) {
1109                 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1110                     info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1111                 }
1112         }
1113
1114         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1115                 codec->num_pcms++;
1116                 info++;
1117                 info->name = spec->stream_name_digital;
1118                 if (spec->multiout.dig_out_nid) {
1119                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
1120                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1121                 }
1122                 if (spec->dig_in_nid) {
1123                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
1124                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1125                 }
1126         }
1127
1128         return 0;
1129 }
1130
1131 static void alc_free(struct hda_codec *codec)
1132 {
1133         kfree(codec->spec);
1134 }
1135
1136 /*
1137  */
1138 static struct hda_codec_ops alc_patch_ops = {
1139         .build_controls = alc_build_controls,
1140         .build_pcms = alc_build_pcms,
1141         .init = alc_init,
1142         .free = alc_free,
1143 #ifdef CONFIG_PM
1144         .resume = alc_resume,
1145 #endif
1146 };
1147
1148
1149 /*
1150  * Test configuration for debugging
1151  *
1152  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
1153  * enum controls.
1154  */
1155 #ifdef CONFIG_SND_DEBUG
1156 static hda_nid_t alc880_test_dac_nids[4] = {
1157         0x02, 0x03, 0x04, 0x05
1158 };
1159
1160 static struct hda_input_mux alc880_test_capture_source = {
1161         .num_items = 5,
1162         .items = {
1163                 { "In-1", 0x0 },
1164                 { "In-2", 0x1 },
1165                 { "In-3", 0x2 },
1166                 { "In-4", 0x3 },
1167                 { "CD", 0x4 },
1168         },
1169 };
1170
1171 static struct alc_channel_mode alc880_test_modes[4] = {
1172         { 2, NULL },
1173         { 4, NULL },
1174         { 6, NULL },
1175         { 8, NULL },
1176 };
1177
1178 static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1179 {
1180         static char *texts[] = {
1181                 "N/A", "Line Out", "HP Out",
1182                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1183         };
1184         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1185         uinfo->count = 1;
1186         uinfo->value.enumerated.items = 8;
1187         if (uinfo->value.enumerated.item >= 8)
1188                 uinfo->value.enumerated.item = 7;
1189         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1190         return 0;
1191 }
1192
1193 static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1194 {
1195         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1196         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1197         unsigned int pin_ctl, item = 0;
1198
1199         pin_ctl = snd_hda_codec_read(codec, nid, 0,
1200                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1201         if (pin_ctl & AC_PINCTL_OUT_EN) {
1202                 if (pin_ctl & AC_PINCTL_HP_EN)
1203                         item = 2;
1204                 else
1205                         item = 1;
1206         } else if (pin_ctl & AC_PINCTL_IN_EN) {
1207                 switch (pin_ctl & AC_PINCTL_VREFEN) {
1208                 case AC_PINCTL_VREF_HIZ: item = 3; break;
1209                 case AC_PINCTL_VREF_50:  item = 4; break;
1210                 case AC_PINCTL_VREF_GRD: item = 5; break;
1211                 case AC_PINCTL_VREF_80:  item = 6; break;
1212                 case AC_PINCTL_VREF_100: item = 7; break;
1213                 }
1214         }
1215         ucontrol->value.enumerated.item[0] = item;
1216         return 0;
1217 }
1218
1219 static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1220 {
1221         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1222         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1223         static unsigned int ctls[] = {
1224                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1225                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1226                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1227                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1228                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1229                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1230         };
1231         unsigned int old_ctl, new_ctl;
1232
1233         old_ctl = snd_hda_codec_read(codec, nid, 0,
1234                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1235         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1236         if (old_ctl != new_ctl) {
1237                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
1238                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1239                                     ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
1240                 return 1;
1241         }
1242         return 0;
1243 }
1244
1245 static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1246 {
1247         static char *texts[] = {
1248                 "Front", "Surround", "CLFE", "Side"
1249         };
1250         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1251         uinfo->count = 1;
1252         uinfo->value.enumerated.items = 4;
1253         if (uinfo->value.enumerated.item >= 4)
1254                 uinfo->value.enumerated.item = 3;
1255         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1256         return 0;
1257 }
1258
1259 static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1260 {
1261         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1262         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1263         unsigned int sel;
1264
1265         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1266         ucontrol->value.enumerated.item[0] = sel & 3;
1267         return 0;
1268 }
1269
1270 static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1271 {
1272         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1273         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1274         unsigned int sel;
1275
1276         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1277         if (ucontrol->value.enumerated.item[0] != sel) {
1278                 sel = ucontrol->value.enumerated.item[0] & 3;
1279                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
1280                 return 1;
1281         }
1282         return 0;
1283 }
1284
1285 #define PIN_CTL_TEST(xname,nid) {                       \
1286                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1287                         .name = xname,                 \
1288                         .info = alc_test_pin_ctl_info, \
1289                         .get = alc_test_pin_ctl_get,   \
1290                         .put = alc_test_pin_ctl_put,   \
1291                         .private_value = nid           \
1292                         }
1293
1294 #define PIN_SRC_TEST(xname,nid) {                       \
1295                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1296                         .name = xname,                 \
1297                         .info = alc_test_pin_src_info, \
1298                         .get = alc_test_pin_src_get,   \
1299                         .put = alc_test_pin_src_put,   \
1300                         .private_value = nid           \
1301                         }
1302
1303 static snd_kcontrol_new_t alc880_test_mixer[] = {
1304         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1305         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1306         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1307         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1308         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1309         ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1310         ALC_BIND_MUTE("CLFE Playback Volume", 0x0e, 2, HDA_INPUT),
1311         ALC_BIND_MUTE("Side Playback Volume", 0x0f, 2, HDA_INPUT),
1312         PIN_CTL_TEST("Front Pin Mode", 0x14),
1313         PIN_CTL_TEST("Surround Pin Mode", 0x15),
1314         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1315         PIN_CTL_TEST("Side Pin Mode", 0x17),
1316         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1317         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1318         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1319         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1320         PIN_SRC_TEST("In-1 Pin Source", 0x18),
1321         PIN_SRC_TEST("In-2 Pin Source", 0x19),
1322         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1323         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1324         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1325         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1326         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1327         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1328         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1329         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1330         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1331         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1332         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1333         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1334         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1335         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1336         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1337         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1338         {
1339                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1340                 .name = "Input Source",
1341                 .count = 2,
1342                 .info = alc_mux_enum_info,
1343                 .get = alc_mux_enum_get,
1344                 .put = alc_mux_enum_put,
1345         },
1346         {
1347                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1348                 .name = "Channel Mode",
1349                 .info = alc880_ch_mode_info,
1350                 .get = alc880_ch_mode_get,
1351                 .put = alc880_ch_mode_put,
1352         },
1353         { } /* end */
1354 };
1355
1356 static struct hda_verb alc880_test_init_verbs[] = {
1357         /* Unmute inputs of 0x0c - 0x0f */
1358         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1359         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1360         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1361         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1362         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1363         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1364         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1365         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1366         /* Vol output for 0x0c-0x0f */
1367         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1368         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1369         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1370         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1371         /* Set output pins 0x14-0x17 */
1372         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1373         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1374         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1375         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376         /* Unmute output pins 0x14-0x17 */
1377         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1378         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1379         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1380         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1381         /* Set input pins 0x18-0x1c */
1382         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
1383         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
1384         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1385         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1386         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1387         /* Mute input pins 0x18-0x1b */
1388         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1389         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1390         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1391         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1392         /* ADC set up */
1393         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1394         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1395         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1396         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1397         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1398         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1399         /* Analog input/passthru */
1400         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1401         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1402         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1403         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1404         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1405         { }
1406 };
1407 #endif
1408
1409 /*
1410  */
1411
1412 static struct hda_board_config alc880_cfg_tbl[] = {
1413         /* Back 3 jack, front 2 jack */
1414         { .modelname = "3stack", .config = ALC880_3ST },
1415         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
1416         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
1417         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
1418         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
1419         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
1420         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
1421         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
1422         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
1423         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
1424         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
1425         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
1426         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
1427         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
1428         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
1429         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
1430         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
1431         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
1432         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
1433         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
1434         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
1435         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
1436         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
1437         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
1438         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
1439         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
1440         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
1441         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
1442         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
1443         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
1444         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
1445         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
1446         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
1447
1448         /* Back 3 jack, front 2 jack (Internal add Aux-In) */
1449         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
1450
1451         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
1452         { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
1453         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
1454
1455         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
1456         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
1457         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
1458         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
1459
1460         /* Back 5 jack, front 2 jack */
1461         { .modelname = "5stack", .config = ALC880_5ST },
1462         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
1463         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
1464         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
1465         { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
1466
1467         /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
1468         { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
1469         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
1470         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
1471         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
1472         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
1473         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
1474         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
1475         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
1476         { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
1477
1478         { .modelname = "w810", .config = ALC880_W810 },
1479         { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
1480
1481         { .modelname = "z71v", .config = ALC880_Z71V },
1482         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
1483
1484 #ifdef CONFIG_SND_DEBUG
1485         { .modelname = "test", .config = ALC880_TEST },
1486 #endif
1487
1488         {}
1489 };
1490
1491 static int patch_alc880(struct hda_codec *codec)
1492 {
1493         struct alc_spec *spec;
1494         int board_config;
1495
1496         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1497         if (spec == NULL)
1498                 return -ENOMEM;
1499
1500         init_MUTEX(&spec->bind_mutex);
1501         codec->spec = spec;
1502
1503         board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
1504         if (board_config < 0) {
1505                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n");
1506                 board_config = ALC880_MINIMAL;
1507         }
1508
1509         switch (board_config) {
1510         case ALC880_W810:
1511                 spec->mixers[spec->num_mixers] = alc880_w810_base_mixer;
1512                 spec->num_mixers++;
1513                 break;
1514         case ALC880_5ST:
1515         case ALC880_5ST_DIG:
1516                 spec->mixers[spec->num_mixers] = alc880_five_stack_mixer;
1517                 spec->num_mixers++;
1518                 break;
1519         case ALC880_Z71V:
1520                 spec->mixers[spec->num_mixers] = alc880_z71v_mixer;
1521                 spec->num_mixers++;
1522                 break;
1523 #ifdef CONFIG_SND_DEBUG
1524         case ALC880_TEST:
1525                 spec->mixers[spec->num_mixers] = alc880_test_mixer;
1526                 spec->num_mixers++;
1527                 break;
1528 #endif
1529         default:
1530                 spec->mixers[spec->num_mixers] = alc880_base_mixer;
1531                 spec->num_mixers++;
1532                 break;
1533         }
1534
1535         switch (board_config) {
1536         case ALC880_3ST_DIG:
1537         case ALC880_5ST_DIG:
1538         case ALC880_W810:
1539         case ALC880_Z71V:
1540         case ALC880_TEST:
1541                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1542                 break;
1543         default:
1544                 break;
1545         }
1546
1547         switch (board_config) {
1548         case ALC880_3ST:
1549         case ALC880_3ST_DIG:
1550         case ALC880_5ST:
1551         case ALC880_5ST_DIG:
1552         case ALC880_W810:
1553                 spec->front_panel = 1;
1554                 break;
1555         default:
1556                 break;
1557         }
1558
1559         switch (board_config) {
1560         case ALC880_5ST:
1561         case ALC880_5ST_DIG:
1562                 spec->init_verbs = alc880_init_verbs_five_stack;
1563                 spec->channel_mode = alc880_fivestack_modes;
1564                 spec->num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes);
1565                 break;
1566         case ALC880_W810:
1567                 spec->init_verbs = alc880_w810_init_verbs;
1568                 spec->channel_mode = alc880_w810_modes;
1569                 spec->num_channel_mode = ARRAY_SIZE(alc880_w810_modes);
1570                 break;
1571         case ALC880_Z71V:
1572                 spec->init_verbs = alc880_z71v_init_verbs;
1573                 spec->channel_mode = alc880_z71v_modes;
1574                 spec->num_channel_mode = ARRAY_SIZE(alc880_z71v_modes);
1575                 break;
1576 #ifdef CONFIG_SND_DEBUG
1577         case ALC880_TEST:
1578                 spec->init_verbs = alc880_test_init_verbs;
1579                 spec->channel_mode = alc880_test_modes;
1580                 spec->num_channel_mode = ARRAY_SIZE(alc880_test_modes);
1581                 break;
1582 #endif
1583         default:
1584                 spec->init_verbs = alc880_init_verbs_three_stack;
1585                 spec->channel_mode = alc880_threestack_modes;
1586                 spec->num_channel_mode = ARRAY_SIZE(alc880_threestack_modes);
1587                 break;
1588         }
1589
1590         spec->stream_name_analog = "ALC880 Analog";
1591         spec->stream_analog_playback = &alc880_pcm_analog_playback;
1592         spec->stream_analog_capture = &alc880_pcm_analog_capture;
1593
1594         spec->stream_name_digital = "ALC880 Digital";
1595         spec->stream_digital_playback = &alc880_pcm_digital_playback;
1596         spec->stream_digital_capture = &alc880_pcm_digital_capture;
1597
1598         spec->multiout.max_channels = spec->channel_mode[0].channels;
1599
1600         switch (board_config) {
1601         case ALC880_W810:
1602                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids);
1603                 spec->multiout.dac_nids = alc880_w810_dac_nids;
1604                 // No dedicated headphone socket - it's shared with built-in speakers.
1605                 break;
1606         case ALC880_Z71V:
1607                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids);
1608                 spec->multiout.dac_nids = alc880_z71v_dac_nids;
1609                 spec->multiout.hp_nid = 0x03;
1610                 break;
1611 #ifdef CONFIG_SND_DEBUG
1612         case ALC880_TEST:
1613                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_test_dac_nids);
1614                 spec->multiout.dac_nids = alc880_test_dac_nids;
1615                 spec->input_mux = &alc880_test_capture_source;
1616                 break;
1617 #endif
1618         default:
1619                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_dac_nids);
1620                 spec->multiout.dac_nids = alc880_dac_nids;
1621                 spec->multiout.hp_nid = 0x03; /* rear-surround NID */
1622                 break;
1623         }
1624
1625         if (! spec->input_mux)
1626                 spec->input_mux = &alc880_capture_source;
1627         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
1628         spec->adc_nids = alc880_adc_nids;
1629
1630         codec->patch_ops = alc_patch_ops;
1631
1632         return 0;
1633 }
1634
1635 /*
1636  * ALC260 support
1637  */
1638
1639 /*
1640  * This is just place-holder, so there's something for alc_build_pcms to look
1641  * at when it calculates the maximum number of channels. ALC260 has no mixer
1642  * element which allows changing the channel mode, so the verb list is
1643  * never used.
1644  */
1645 static struct alc_channel_mode alc260_modes[1] = {
1646         { 2, NULL },
1647 };
1648
1649 snd_kcontrol_new_t alc260_base_mixer[] = {
1650         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
1651         ALC_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
1652         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
1653         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
1654         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
1655         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
1656         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
1657         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
1658         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
1659         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
1660         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
1661         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
1662         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
1663         ALC_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
1664         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
1665         ALC_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_OUTPUT),
1666         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
1667         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
1668         {
1669                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1670                 .name = "Capture Source",
1671                 .info = alc_mux_enum_info,
1672                 .get = alc_mux_enum_get,
1673                 .put = alc_mux_enum_put,
1674         },
1675         { } /* end */
1676 };
1677
1678 static struct hda_verb alc260_init_verbs[] = {
1679         /* Line In pin widget for input */
1680         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1681         /* CD pin widget for input */
1682         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1683         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1684         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
1685         /* Mic2 (front panel) pin widget for input and vref at 80% */
1686         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
1687         /* LINE-2 is used for line-out in rear */
1688         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689         /* select line-out */
1690         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1691         /* LINE-OUT pin */
1692         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693         /* enable HP */
1694         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1695         /* enable Mono */
1696         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1697         /* mute capture amp left and right */
1698         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1699         /* set connection select to line in (default select for this ADC) */
1700         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
1701         /* set vol=0 Line-Out mixer amp left and right */
1702         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1703         /* unmute pin widget amp left and right (no gain on this amp) */
1704         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1705         /* set vol=0 HP mixer amp left and right */
1706         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1707         /* unmute pin widget amp left and right (no gain on this amp) */
1708         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1709         /* set vol=0 Mono mixer amp left and right */
1710         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1711         /* unmute pin widget amp left and right (no gain on this amp) */
1712         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1713         /* unmute LINE-2 out pin */
1714         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1715         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
1716         /* mute CD */
1717         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1718         /* mute Line In */
1719         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1720         /* mute Mic */
1721         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1722         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1723         /* mute Front out path */
1724         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1725         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1726         /* mute Headphone out path */
1727         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1728         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1729         /* mute Mono out path */
1730         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1731         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1732         { }
1733 };
1734
1735 static struct hda_pcm_stream alc260_pcm_analog_playback = {
1736         .substreams = 1,
1737         .channels_min = 2,
1738         .channels_max = 2,
1739         .nid = 0x2,
1740 };
1741
1742 static struct hda_pcm_stream alc260_pcm_analog_capture = {
1743         .substreams = 1,
1744         .channels_min = 2,
1745         .channels_max = 2,
1746         .nid = 0x4,
1747 };
1748
1749 static int patch_alc260(struct hda_codec *codec)
1750 {
1751         struct alc_spec *spec;
1752
1753         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1754         if (spec == NULL)
1755                 return -ENOMEM;
1756
1757         init_MUTEX(&spec->bind_mutex);
1758         codec->spec = spec;
1759
1760         spec->mixers[spec->num_mixers] = alc260_base_mixer;
1761         spec->num_mixers++;
1762
1763         spec->init_verbs = alc260_init_verbs;
1764         spec->channel_mode = alc260_modes;
1765         spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
1766
1767         spec->stream_name_analog = "ALC260 Analog";
1768         spec->stream_analog_playback = &alc260_pcm_analog_playback;
1769         spec->stream_analog_capture = &alc260_pcm_analog_capture;
1770
1771         spec->multiout.max_channels = spec->channel_mode[0].channels;
1772         spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
1773         spec->multiout.dac_nids = alc260_dac_nids;
1774
1775         spec->input_mux = &alc260_capture_source;
1776         spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
1777         spec->adc_nids = alc260_adc_nids;
1778
1779         codec->patch_ops = alc_patch_ops;
1780
1781         return 0;
1782 }
1783
1784 /*
1785  * ALC882 support
1786  *
1787  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1788  * configuration.  Each pin widget can choose any input DACs and a mixer.
1789  * Each ADC is connected from a mixer of all inputs.  This makes possible
1790  * 6-channel independent captures.
1791  *
1792  * In addition, an independent DAC for the multi-playback (not used in this
1793  * driver yet).
1794  */
1795
1796 static struct alc_channel_mode alc882_ch_modes[1] = {
1797         { 8, NULL }
1798 };
1799
1800 static hda_nid_t alc882_dac_nids[4] = {
1801         /* front, rear, clfe, rear_surr */
1802         0x02, 0x03, 0x04, 0x05
1803 };
1804
1805 static hda_nid_t alc882_adc_nids[3] = {
1806         /* ADC0-2 */
1807         0x07, 0x08, 0x09,
1808 };
1809
1810 /* input MUX */
1811 /* FIXME: should be a matrix-type input source selection */
1812
1813 static struct hda_input_mux alc882_capture_source = {
1814         .num_items = 4,
1815         .items = {
1816                 { "Mic", 0x0 },
1817                 { "Front Mic", 0x1 },
1818                 { "Line", 0x2 },
1819                 { "CD", 0x4 },
1820         },
1821 };
1822
1823 #define alc882_mux_enum_info alc_mux_enum_info
1824 #define alc882_mux_enum_get alc_mux_enum_get
1825
1826 static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1827 {
1828         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1829         struct alc_spec *spec = codec->spec;
1830         const struct hda_input_mux *imux = spec->input_mux;
1831         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1832         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
1833         hda_nid_t nid = capture_mixers[adc_idx];
1834         unsigned int *cur_val = &spec->cur_mux[adc_idx];
1835         unsigned int i, idx;
1836
1837         idx = ucontrol->value.enumerated.item[0];
1838         if (idx >= imux->num_items)
1839                 idx = imux->num_items - 1;
1840         if (*cur_val == idx && ! codec->in_resume)
1841                 return 0;
1842         for (i = 0; i < imux->num_items; i++) {
1843                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
1844                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1845                                     v | (imux->items[i].index << 8));
1846         }
1847         *cur_val = idx;
1848         return 1;
1849 }
1850
1851 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
1852  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
1853  */
1854 static snd_kcontrol_new_t alc882_base_mixer[] = {
1855         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1856         ALC_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1857         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1858         ALC_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1859         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1860         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1861         ALC_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1862         ALC_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_OUTPUT),
1863         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1864         ALC_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1865         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1866         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1867         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1868         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1869         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1870         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1871         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1872         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1873         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1874         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1875         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1876         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1877         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1878         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1879         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1880         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1881         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1882         {
1883                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1884                 /* .name = "Capture Source", */
1885                 .name = "Input Source",
1886                 .count = 3,
1887                 .info = alc882_mux_enum_info,
1888                 .get = alc882_mux_enum_get,
1889                 .put = alc882_mux_enum_put,
1890         },
1891         { } /* end */
1892 };
1893
1894 static struct hda_verb alc882_init_verbs[] = {
1895         /* Front mixer: unmute input/output amp left and right (volume = 0) */
1896         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1897         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1898         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1899         /* Rear mixer */
1900         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1901         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1902         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1903         /* CLFE mixer */
1904         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1905         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1906         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1907         /* Side mixer */
1908         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1909         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1910         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1911
1912         /* Front Pin: to output mode */
1913         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1914         /* Front Pin: mute amp left and right (no volume) */
1915         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1916         /* select Front mixer (0x0c, index 0) */
1917         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1918         /* Rear Pin */
1919         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1920         /* Rear Pin: mute amp left and right (no volume) */
1921         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1922         /* select Rear mixer (0x0d, index 1) */
1923         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
1924         /* CLFE Pin */
1925         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1926         /* CLFE Pin: mute amp left and right (no volume) */
1927         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1928         /* select CLFE mixer (0x0e, index 2) */
1929         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1930         /* Side Pin */
1931         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1932         /* Side Pin: mute amp left and right (no volume) */
1933         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1934         /* select Side mixer (0x0f, index 3) */
1935         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1936         /* Headphone Pin */
1937         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1938         /* Headphone Pin: mute amp left and right (no volume) */
1939         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1940         /* select Front mixer (0x0c, index 0) */
1941         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1942         /* Mic (rear) pin widget for input and vref at 80% */
1943         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
1944         /* Front Mic pin widget for input and vref at 80% */
1945         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF},
1946         /* Line In pin widget for input */
1947         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1948         /* CD pin widget for input */
1949         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1950
1951         /* FIXME: use matrix-type input source selection */
1952         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1953         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1954         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1955         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1956         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1957         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1958         /* Input mixer2 */
1959         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1960         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1961         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1962         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1963         /* Input mixer3 */
1964         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1965         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1966         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1967         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1968         /* ADC1: mute amp left and right */
1969         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1970         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1971         /* ADC2: mute amp left and right */
1972         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1973         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1974         /* ADC3: mute amp left and right */
1975         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1976         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1977
1978         { }
1979 };
1980
1981 static int patch_alc882(struct hda_codec *codec)
1982 {
1983         struct alc_spec *spec;
1984
1985         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1986         if (spec == NULL)
1987                 return -ENOMEM;
1988
1989         init_MUTEX(&spec->bind_mutex);
1990         codec->spec = spec;
1991
1992         spec->mixers[spec->num_mixers] = alc882_base_mixer;
1993         spec->num_mixers++;
1994
1995         spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1996         spec->dig_in_nid = ALC880_DIGIN_NID;
1997         spec->front_panel = 1;
1998         spec->init_verbs = alc882_init_verbs;
1999         spec->channel_mode = alc882_ch_modes;
2000         spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
2001
2002         spec->stream_name_analog = "ALC882 Analog";
2003         spec->stream_analog_playback = &alc880_pcm_analog_playback;
2004         spec->stream_analog_capture = &alc880_pcm_analog_capture;
2005
2006         spec->stream_name_digital = "ALC882 Digital";
2007         spec->stream_digital_playback = &alc880_pcm_digital_playback;
2008         spec->stream_digital_capture = &alc880_pcm_digital_capture;
2009
2010         spec->multiout.max_channels = spec->channel_mode[0].channels;
2011         spec->multiout.num_dacs = ARRAY_SIZE(alc882_dac_nids);
2012         spec->multiout.dac_nids = alc882_dac_nids;
2013
2014         spec->input_mux = &alc882_capture_source;
2015         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
2016         spec->adc_nids = alc882_adc_nids;
2017
2018         codec->patch_ops = alc_patch_ops;
2019
2020         return 0;
2021 }
2022
2023 /*
2024  * patch entries
2025  */
2026 struct hda_codec_preset snd_hda_preset_realtek[] = {
2027         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
2028         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
2029         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
2030         {} /* terminator */
2031 };