]> err.no Git - linux-2.6/blob - sound/pci/hda/patch_realtek.c
[ALSA] Fix the analog loopback volumes of ALC codecs
[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.
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_vol_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_volume_info(kcontrol, uinfo);
386         kcontrol->private_value = pval;
387         up(&spec->bind_mutex);
388         return 0;
389 }
390
391 static int alc_bind_vol_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_volume_get(kcontrol, ucontrol);
401         kcontrol->private_value = pval;
402         up(&spec->bind_mutex);
403         return 0;
404 }
405
406 static int alc_bind_vol_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_volume_put(kcontrol, ucontrol);
419         }
420         kcontrol->private_value = pval;
421         up(&spec->bind_mutex);
422         return change;
423 }
424
425 #define ALC_BIND_VOL_MONO(xname, nid, channel, indices, direction) \
426         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
427           .info = alc_bind_vol_info, \
428           .get = alc_bind_vol_get, \
429           .put = alc_bind_vol_put, \
430           .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
431
432 #define ALC_BIND_VOL(xname,nid,indices,dir) ALC_BIND_VOL_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         ALC_BIND_VOL("Front Playback Volume", 0x0c, 2, HDA_OUTPUT),
443         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
444         ALC_BIND_VOL("Surround Playback Volume", 0x0f, 2, HDA_OUTPUT),
445         HDA_CODEC_MUTE("Surround Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
446         ALC_BIND_VOL_MONO("Center Playback Volume", 0x0e, 1, 2, HDA_OUTPUT),
447         ALC_BIND_VOL_MONO("LFE Playback Volume", 0x0e, 2, 2, HDA_OUTPUT),
448         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x18, 1, 0x0, HDA_OUTPUT),
449         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x18, 2, 0x0, HDA_OUTPUT),
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         ALC_BIND_VOL("Headphone Playback Volume", 0x0d, 2, HDA_OUTPUT),
461         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
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         ALC_BIND_VOL("Front Playback Volume", 0x0c, 2, HDA_OUTPUT),
496         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
497         ALC_BIND_VOL("Surround Playback Volume", 0x0f, 2, HDA_OUTPUT),
498         HDA_CODEC_MUTE("Surround Playback Switch", 0x17, 0x0, HDA_OUTPUT),
499         ALC_BIND_VOL_MONO("Center Playback Volume", 0x0e, 1, 2, HDA_OUTPUT),
500         ALC_BIND_VOL_MONO("LFE Playback Volume", 0x0e, 2, 2, HDA_OUTPUT),
501         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
502         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
503         ALC_BIND_VOL("Side Playback Volume", 0x0d, 2, HDA_OUTPUT),
504         HDA_CODEC_MUTE("Side Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
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         ALC_BIND_VOL("Front Playback Volume", 0x0c, 2, HDA_OUTPUT),
579         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
580         ALC_BIND_VOL("Headphone Playback Volume", 0x0d, 2, HDA_OUTPUT),
581         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
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 static struct hda_verb alc880_init_verbs_three_stack[] = {
640         /* Line In pin widget for input */
641         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
642         /* CD pin widget for input */
643         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
644         /* Mic1 (rear panel) pin widget for input and vref at 80% */
645         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
646         /* Mic2 (front panel) pin widget for input and vref at 80% */
647         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
648         /* unmute amp left and right */
649         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
650         /* set connection select to mic in */
651         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
652         /* unmute amp left and right */
653         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
654         /* set connection select to mic in */
655         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
656         /* unmute amp left and right */
657         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
658         /* set connection select to mic in */
659         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
660         /* unmute front mixer amp left (volume = 0) */
661         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
662         /* mute pin widget amp left and right (no gain on this amp) */
663         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
664         /* unmute rear mixer amp left and right (volume = 0) */
665         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
666         /* mute pin widget amp left and right (no gain on this amp) */
667         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
668         /* unmute rear mixer amp left and right (volume = 0) */
669         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
670         /* mute pin widget amp left and right (no gain on this amp) */
671         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
672
673         /* using rear surround as the path for headphone output */
674         /* unmute rear surround mixer amp left and right (volume = 0) */
675         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
676         /* PASD 3 stack boards use the Mic 2 as the headphone output */
677         /* need to program the selector associated with the Mic 2 pin widget to
678          * surround path (index 0x01) for headphone output */
679         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
680         /* mute pin widget amp left and right (no gain on this amp) */
681         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
682         /* need to retask the Mic 2 pin widget to output */
683         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
684
685         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer widget(nid=0x0B)
686          * to support the input path of analog loopback
687          * Note: PASD motherboards uses the Line In 2 as the input for front panel
688          * mic (mic 2)
689          */
690         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
691         /* unmute CD */
692         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
693         /* unmute Line In */
694         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
695         /* unmute Mic 1 */
696         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
697         /* unmute Line In 2 (for PASD boards Mic 2) */
698         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
699
700         /* Unmute input amps for the line out paths to support the output path of
701          * analog loopback
702          * the mixers on the output path has 2 inputs, one from the DAC and one
703          * from the mixer
704          */
705         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
706         /* Unmute Front out path */
707         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
708         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
709         /* Unmute Surround (used as HP) out path */
710         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
711         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
712         /* Unmute C/LFE out path */
713         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
714         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
715         /* Unmute rear Surround out path */
716         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
717         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
718
719         { }
720 };
721
722 static struct hda_verb alc880_init_verbs_five_stack[] = {
723         /* Line In pin widget for input */
724         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
725         /* CD pin widget for input */
726         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
727         /* Mic1 (rear panel) pin widget for input and vref at 80% */
728         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
729         /* Mic2 (front panel) pin widget for input and vref at 80% */
730         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
731         /* unmute amp left and right */
732         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
733         /* set connection select to mic in */
734         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
735         /* unmute amp left and right */
736         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
737         /* set connection select to mic in */
738         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
739         /* unmute amp left and right */
740         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
741         /* set connection select to mic in */
742         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
743         /* unmute front mixer amp left and right (volume = 0) */
744         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
745         /* mute pin widget amp left and right (no gain on this amp) */
746         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
747         /* five rear and clfe */
748         /* unmute rear mixer amp left and right (volume = 0)  */
749         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
750         /* mute pin widget amp left and right (no gain on this amp) */
751         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
752         /* unmute clfe mixer amp left and right (volume = 0) */
753         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
754         /* mute pin widget amp left and right (no gain on this amp) */
755         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
756
757         /* using rear surround as the path for headphone output */
758         /* unmute rear surround mixer amp left and right (volume = 0) */
759         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
760         /* PASD 3 stack boards use the Mic 2 as the headphone output */
761         /* need to program the selector associated with the Mic 2 pin widget to
762          * surround path (index 0x01) for headphone output
763          */
764         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
765         /* mute pin widget amp left and right (no gain on this amp) */
766         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
767         /* need to retask the Mic 2 pin widget to output */
768         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
769
770         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
771          * widget(nid=0x0B) to support the input path of analog loopback
772          */
773         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
774         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
775         /* unmute CD */
776         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
777         /* unmute Line In */
778         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
779         /* unmute Mic 1 */
780         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
781         /* unmute Line In 2 (for PASD boards Mic 2) */
782         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
783
784         /* Unmute input amps for the line out paths to support the output path of
785          * analog loopback
786          * the mixers on the output path has 2 inputs, one from the DAC and
787          * one from the mixer
788          */
789         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
790         /* Unmute Front out path */
791         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
792         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
793         /* Unmute Surround (used as HP) out path */
794         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
795         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
796         /* Unmute C/LFE out path */
797         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
798         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, /* mute */
799         /* Unmute rear Surround out path */
800         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
801         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
802
803         { }
804 };
805
806 static struct hda_verb alc880_w810_init_verbs[] = {
807         /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
808         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
809
810         /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
811         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
812
813         /* front channel selector/amp: output 0: unmuted, max volume */
814         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
815
816         /* front out pin: muted, (no volume selection)  */
817         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
818
819         /* front out pin: NOT headphone enable, out enable, vref disabled */
820         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
821
822
823         /* surround channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
824         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
825
826         /* surround channel selector/amp: input 1: capture mix: muted, (no volume selection) */
827         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
828
829         /* surround channel selector/amp: output 0: unmuted, max volume */
830         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
831
832         /* surround out pin: muted, (no volume selection)  */
833         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
834
835         /* surround out pin: NOT headphone enable, out enable, vref disabled */
836         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
837
838
839         /* c/lfe channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
840         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
841
842         /* c/lfe channel selector/amp: input 1: capture mix: muted, (no volume selection) */
843         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
844
845         /* c/lfe channel selector/amp: output 0: unmuted, max volume */
846         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
847
848         /* c/lfe out pin: muted, (no volume selection)  */
849         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
850
851         /* c/lfe out pin: NOT headphone enable, out enable, vref disabled */
852         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
853
854
855         /* hphone/speaker input selector: front DAC */
856         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
857
858         /* hphone/speaker out pin: muted, (no volume selection)  */
859         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
860
861         /* hphone/speaker out pin: NOT headphone enable, out enable, vref disabled */
862         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
863
864
865         { }
866 };
867
868 static struct hda_verb alc880_z71v_init_verbs[] = {
869         /* front channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
870         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
871         /* front channel selector/amp: input 1: capture mix: muted, (no volume selection) */
872         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
873         /* front channel selector/amp: output 0: unmuted, max volume */
874         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
875         /* front out pin: muted, (no volume selection)  */
876         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
877         /* front out pin: NOT headphone enable, out enable, vref disabled */
878         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
879         /* headphone channel selector/amp: input 0: DAC: unmuted, (no volume selection) */
880         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
881         /* headphone channel selector/amp: input 1: capture mix: muted, (no volume selection) */
882         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7180},
883         /* headphone channel selector/amp: output 0: unmuted, max volume */
884         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
885         /* headphone out pin: muted, (no volume selection)  */
886         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
887         /* headpohne out pin: headphone enable, out enable, vref disabled */
888         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
889
890         /* Line In pin widget for input */
891         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
892         /* CD pin widget for input */
893         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
894         /* Mic1 (rear panel) pin widget for input and vref at 80% */
895         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
896         /* Mic2 (front panel) pin widget for input and vref at 80% */
897         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
898         /* unmute amp left and right */
899         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
900         /* set connection select to mic in */
901         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
902         /* unmute amp left and right */
903         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
904         /* set connection select to mic in */
905         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
906         /* unmute amp left and right */
907         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
908         /* set connection select to mic in */
909         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
910         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) for mixer
911          * widget(nid=0x0B) to support the input path of analog loopback
912          */
913         /* Note: PASD motherboards uses the Line In 2 as the input for front panel mic (mic 2) */
914         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03*/
915         /* unmute CD */
916         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
917         /* unmute Line In */
918         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
919         /* unmute Mic 1 */
920         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
921         /* unmute Line In 2 (for PASD boards Mic 2) */
922         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
923
924         { }
925 };
926
927 static int alc_init(struct hda_codec *codec)
928 {
929         struct alc_spec *spec = codec->spec;
930         snd_hda_sequence_write(codec, spec->init_verbs);
931         return 0;
932 }
933
934 #ifdef CONFIG_PM
935 /*
936  * resume
937  */
938 static int alc_resume(struct hda_codec *codec)
939 {
940         struct alc_spec *spec = codec->spec;
941         int i;
942
943         alc_init(codec);
944         for (i = 0; i < spec->num_mixers; i++) {
945                 snd_hda_resume_ctls(codec, spec->mixers[i]);
946         }
947         if (spec->multiout.dig_out_nid)
948                 snd_hda_resume_spdif_out(codec);
949         if (spec->dig_in_nid)
950                 snd_hda_resume_spdif_in(codec);
951
952         return 0;
953 }
954 #endif
955
956 /*
957  * Analog playback callbacks
958  */
959 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
960                                     struct hda_codec *codec,
961                                     snd_pcm_substream_t *substream)
962 {
963         struct alc_spec *spec = codec->spec;
964         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
965 }
966
967 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
968                                        struct hda_codec *codec,
969                                        unsigned int stream_tag,
970                                        unsigned int format,
971                                        snd_pcm_substream_t *substream)
972 {
973         struct alc_spec *spec = codec->spec;
974         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
975                                                 format, substream);
976 }
977
978 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
979                                        struct hda_codec *codec,
980                                        snd_pcm_substream_t *substream)
981 {
982         struct alc_spec *spec = codec->spec;
983         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
984 }
985
986 /*
987  * Digital out
988  */
989 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
990                                         struct hda_codec *codec,
991                                         snd_pcm_substream_t *substream)
992 {
993         struct alc_spec *spec = codec->spec;
994         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
995 }
996
997 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
998                                          struct hda_codec *codec,
999                                          snd_pcm_substream_t *substream)
1000 {
1001         struct alc_spec *spec = codec->spec;
1002         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1003 }
1004
1005 /*
1006  * Analog capture
1007  */
1008 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1009                                       struct hda_codec *codec,
1010                                       unsigned int stream_tag,
1011                                       unsigned int format,
1012                                       snd_pcm_substream_t *substream)
1013 {
1014         struct alc_spec *spec = codec->spec;
1015
1016         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1017                                    stream_tag, 0, format);
1018         return 0;
1019 }
1020
1021 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1022                                       struct hda_codec *codec,
1023                                       snd_pcm_substream_t *substream)
1024 {
1025         struct alc_spec *spec = codec->spec;
1026
1027         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0);
1028         return 0;
1029 }
1030
1031
1032 /*
1033  */
1034 static struct hda_pcm_stream alc880_pcm_analog_playback = {
1035         .substreams = 1,
1036         .channels_min = 2,
1037         .channels_max = 8,
1038         .nid = 0x02, /* NID to query formats and rates */
1039         .ops = {
1040                 .open = alc880_playback_pcm_open,
1041                 .prepare = alc880_playback_pcm_prepare,
1042                 .cleanup = alc880_playback_pcm_cleanup
1043         },
1044 };
1045
1046 static struct hda_pcm_stream alc880_pcm_analog_capture = {
1047         .substreams = 2,
1048         .channels_min = 2,
1049         .channels_max = 2,
1050         .nid = 0x08, /* NID to query formats and rates
1051                       * (0x07 might be broken on some devices)
1052                       */
1053         .ops = {
1054                 .prepare = alc880_capture_pcm_prepare,
1055                 .cleanup = alc880_capture_pcm_cleanup
1056         },
1057 };
1058
1059 static struct hda_pcm_stream alc880_pcm_digital_playback = {
1060         .substreams = 1,
1061         .channels_min = 2,
1062         .channels_max = 2,
1063         /* NID is set in alc_build_pcms */
1064         .ops = {
1065                 .open = alc880_dig_playback_pcm_open,
1066                 .close = alc880_dig_playback_pcm_close
1067         },
1068 };
1069
1070 static struct hda_pcm_stream alc880_pcm_digital_capture = {
1071         .substreams = 1,
1072         .channels_min = 2,
1073         .channels_max = 2,
1074         /* NID is set in alc_build_pcms */
1075 };
1076
1077 static int alc_build_pcms(struct hda_codec *codec)
1078 {
1079         struct alc_spec *spec = codec->spec;
1080         struct hda_pcm *info = spec->pcm_rec;
1081         int i;
1082
1083         codec->num_pcms = 1;
1084         codec->pcm_info = info;
1085
1086         info->name = spec->stream_name_analog;
1087         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1088         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1089
1090         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
1091         for (i = 0; i < spec->num_channel_mode; i++) {
1092                 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
1093                     info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
1094                 }
1095         }
1096
1097         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1098                 codec->num_pcms++;
1099                 info++;
1100                 info->name = spec->stream_name_digital;
1101                 if (spec->multiout.dig_out_nid) {
1102                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
1103                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
1104                 }
1105                 if (spec->dig_in_nid) {
1106                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
1107                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
1108                 }
1109         }
1110
1111         return 0;
1112 }
1113
1114 static void alc_free(struct hda_codec *codec)
1115 {
1116         kfree(codec->spec);
1117 }
1118
1119 /*
1120  */
1121 static struct hda_codec_ops alc_patch_ops = {
1122         .build_controls = alc_build_controls,
1123         .build_pcms = alc_build_pcms,
1124         .init = alc_init,
1125         .free = alc_free,
1126 #ifdef CONFIG_PM
1127         .resume = alc_resume,
1128 #endif
1129 };
1130
1131
1132 /*
1133  * Test configuration for debugging
1134  *
1135  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
1136  * enum controls.
1137  */
1138 #ifdef CONFIG_SND_DEBUG
1139 static hda_nid_t alc880_test_dac_nids[4] = {
1140         0x02, 0x03, 0x04, 0x05
1141 };
1142
1143 static struct hda_input_mux alc880_test_capture_source = {
1144         .num_items = 5,
1145         .items = {
1146                 { "In-1", 0x0 },
1147                 { "In-2", 0x1 },
1148                 { "In-3", 0x2 },
1149                 { "In-4", 0x3 },
1150                 { "CD", 0x4 },
1151         },
1152 };
1153
1154 static struct alc_channel_mode alc880_test_modes[4] = {
1155         { 2, NULL },
1156         { 4, NULL },
1157         { 6, NULL },
1158         { 8, NULL },
1159 };
1160
1161 static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1162 {
1163         static char *texts[] = {
1164                 "N/A", "Line Out", "HP Out",
1165                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1166         };
1167         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1168         uinfo->count = 1;
1169         uinfo->value.enumerated.items = 8;
1170         if (uinfo->value.enumerated.item >= 8)
1171                 uinfo->value.enumerated.item = 7;
1172         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1173         return 0;
1174 }
1175
1176 static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1177 {
1178         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1179         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1180         unsigned int pin_ctl, item = 0;
1181
1182         pin_ctl = snd_hda_codec_read(codec, nid, 0,
1183                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1184         if (pin_ctl & AC_PINCTL_OUT_EN) {
1185                 if (pin_ctl & AC_PINCTL_HP_EN)
1186                         item = 2;
1187                 else
1188                         item = 1;
1189         } else if (pin_ctl & AC_PINCTL_IN_EN) {
1190                 switch (pin_ctl & AC_PINCTL_VREFEN) {
1191                 case AC_PINCTL_VREF_HIZ: item = 3; break;
1192                 case AC_PINCTL_VREF_50:  item = 4; break;
1193                 case AC_PINCTL_VREF_GRD: item = 5; break;
1194                 case AC_PINCTL_VREF_80:  item = 6; break;
1195                 case AC_PINCTL_VREF_100: item = 7; break;
1196                 }
1197         }
1198         ucontrol->value.enumerated.item[0] = item;
1199         return 0;
1200 }
1201
1202 static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1203 {
1204         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1205         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1206         static unsigned int ctls[] = {
1207                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1208                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1209                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1210                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1211                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1212                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1213         };
1214         unsigned int old_ctl, new_ctl;
1215
1216         old_ctl = snd_hda_codec_read(codec, nid, 0,
1217                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1218         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1219         if (old_ctl != new_ctl) {
1220                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, new_ctl);
1221                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1222                                     ucontrol->value.enumerated.item[0] >= 3 ? 0xb080 : 0xb000);
1223                 return 1;
1224         }
1225         return 0;
1226 }
1227
1228 static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
1229 {
1230         static char *texts[] = {
1231                 "Front", "Surround", "CLFE", "Side"
1232         };
1233         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1234         uinfo->count = 1;
1235         uinfo->value.enumerated.items = 4;
1236         if (uinfo->value.enumerated.item >= 4)
1237                 uinfo->value.enumerated.item = 3;
1238         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1239         return 0;
1240 }
1241
1242 static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1243 {
1244         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1245         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1246         unsigned int sel;
1247
1248         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1249         ucontrol->value.enumerated.item[0] = sel & 3;
1250         return 0;
1251 }
1252
1253 static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1254 {
1255         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1256         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1257         unsigned int sel;
1258
1259         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1260         if (ucontrol->value.enumerated.item[0] != sel) {
1261                 sel = ucontrol->value.enumerated.item[0] & 3;
1262                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, sel);
1263                 return 1;
1264         }
1265         return 0;
1266 }
1267
1268 #define PIN_CTL_TEST(xname,nid) {                       \
1269                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1270                         .name = xname,                 \
1271                         .info = alc_test_pin_ctl_info, \
1272                         .get = alc_test_pin_ctl_get,   \
1273                         .put = alc_test_pin_ctl_put,   \
1274                         .private_value = nid           \
1275                         }
1276
1277 #define PIN_SRC_TEST(xname,nid) {                       \
1278                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
1279                         .name = xname,                 \
1280                         .info = alc_test_pin_src_info, \
1281                         .get = alc_test_pin_src_get,   \
1282                         .put = alc_test_pin_src_put,   \
1283                         .private_value = nid           \
1284                         }
1285
1286 static snd_kcontrol_new_t alc880_test_mixer[] = {
1287         ALC_BIND_VOL("Front Playback Volume", 0x0c, 2, HDA_OUTPUT),
1288         ALC_BIND_VOL("Surround Playback Volume", 0x0d, 2, HDA_OUTPUT),
1289         ALC_BIND_VOL("CLFE Playback Volume", 0x0e, 2, HDA_OUTPUT),
1290         ALC_BIND_VOL("Side Playback Volume", 0x0f, 2, HDA_OUTPUT),
1291         PIN_CTL_TEST("Front Pin Mode", 0x14),
1292         PIN_CTL_TEST("Surround Pin Mode", 0x15),
1293         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1294         PIN_CTL_TEST("Side Pin Mode", 0x17),
1295         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1296         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1297         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1298         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1299         PIN_SRC_TEST("In-1 Pin Source", 0x18),
1300         PIN_SRC_TEST("In-2 Pin Source", 0x19),
1301         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1302         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1303         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1304         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1305         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1306         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1307         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1308         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1309         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1310         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1311         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1312         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1313         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1314         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1315         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1316         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1317         {
1318                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1319                 .name = "Input Source",
1320                 .count = 2,
1321                 .info = alc_mux_enum_info,
1322                 .get = alc_mux_enum_get,
1323                 .put = alc_mux_enum_put,
1324         },
1325         {
1326                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1327                 .name = "Channel Mode",
1328                 .info = alc880_ch_mode_info,
1329                 .get = alc880_ch_mode_get,
1330                 .put = alc880_ch_mode_put,
1331                 .private_value = ARRAY_SIZE(alc880_test_modes),
1332         },
1333         { } /* end */
1334 };
1335
1336 static struct hda_verb alc880_test_init_verbs[] = {
1337         /* Unmute inputs of 0x0c - 0x0f */
1338         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1339         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1340         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1341         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1342         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1343         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1344         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1345         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0x7100},
1346         /* Vol output for 0x0c-0x0f */
1347         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1348         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1349         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1350         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1351         /* Set output pins 0x14-0x17 */
1352         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1353         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1354         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1355         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1356         /* Unmute output pins 0x14-0x17 */
1357         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1358         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1359         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1360         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1361         /* Set input pins 0x18-0x1c */
1362         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, /* vref 80% */
1363         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1364         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1365         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1366         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1367         /* Mute input pins 0x18-0x1b */
1368         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1369         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1370         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1371         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1372         /* ADC set up */
1373         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1374         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1375         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1376         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1377         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1378         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1379         { }
1380 };
1381 #endif
1382
1383 /*
1384  */
1385
1386 static struct hda_board_config alc880_cfg_tbl[] = {
1387         /* Back 3 jack, front 2 jack */
1388         { .modelname = "3stack", .config = ALC880_3ST },
1389         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST },
1390         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST },
1391         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST },
1392         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST },
1393         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST },
1394         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST },
1395         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST },
1396         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST },
1397         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST },
1398         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST },
1399         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST },
1400         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST },
1401         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST },
1402         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST },
1403         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST },
1404         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST },
1405         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST },
1406         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST },
1407         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
1408         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
1409         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
1410         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
1411         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
1412         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
1413         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
1414         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
1415         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
1416         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
1417         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
1418         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
1419         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
1420         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
1421
1422         /* Back 3 jack, front 2 jack (Internal add Aux-In) */
1423         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
1424
1425         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
1426         { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
1427         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
1428
1429         /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
1430         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
1431         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
1432         { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
1433
1434         /* Back 5 jack, front 2 jack */
1435         { .modelname = "5stack", .config = ALC880_5ST },
1436         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
1437         { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
1438         { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
1439         { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
1440
1441         /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
1442         { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
1443         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
1444         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
1445         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
1446         { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
1447         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
1448         { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
1449         { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
1450         { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
1451
1452         { .modelname = "w810", .config = ALC880_W810 },
1453         { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
1454
1455         { .modelname = "z71v", .config = ALC880_Z71V },
1456         { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
1457
1458 #ifdef CONFIG_SND_DEBUG
1459         { .modelname = "test", .config = ALC880_TEST },
1460 #endif
1461
1462         {}
1463 };
1464
1465 static int patch_alc880(struct hda_codec *codec)
1466 {
1467         struct alc_spec *spec;
1468         int board_config;
1469
1470         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1471         if (spec == NULL)
1472                 return -ENOMEM;
1473
1474         init_MUTEX(&spec->bind_mutex);
1475         codec->spec = spec;
1476
1477         board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl);
1478         if (board_config < 0) {
1479                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC880\n");
1480                 board_config = ALC880_MINIMAL;
1481         }
1482
1483         switch (board_config) {
1484         case ALC880_W810:
1485                 spec->mixers[spec->num_mixers] = alc880_w810_base_mixer;
1486                 spec->num_mixers++;
1487                 break;
1488         case ALC880_5ST:
1489         case ALC880_5ST_DIG:
1490                 spec->mixers[spec->num_mixers] = alc880_five_stack_mixer;
1491                 spec->num_mixers++;
1492                 break;
1493         case ALC880_Z71V:
1494                 spec->mixers[spec->num_mixers] = alc880_z71v_mixer;
1495                 spec->num_mixers++;
1496                 break;
1497 #ifdef CONFIG_SND_DEBUG
1498         case ALC880_TEST:
1499                 spec->mixers[spec->num_mixers] = alc880_test_mixer;
1500                 spec->num_mixers++;
1501                 break;
1502 #endif
1503         default:
1504                 spec->mixers[spec->num_mixers] = alc880_base_mixer;
1505                 spec->num_mixers++;
1506                 break;
1507         }
1508
1509         switch (board_config) {
1510         case ALC880_3ST_DIG:
1511         case ALC880_5ST_DIG:
1512         case ALC880_W810:
1513         case ALC880_Z71V:
1514         case ALC880_TEST:
1515                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1516                 break;
1517         default:
1518                 break;
1519         }
1520
1521         switch (board_config) {
1522         case ALC880_3ST:
1523         case ALC880_3ST_DIG:
1524         case ALC880_5ST:
1525         case ALC880_5ST_DIG:
1526         case ALC880_W810:
1527                 spec->front_panel = 1;
1528                 break;
1529         default:
1530                 break;
1531         }
1532
1533         switch (board_config) {
1534         case ALC880_5ST:
1535         case ALC880_5ST_DIG:
1536                 spec->init_verbs = alc880_init_verbs_five_stack;
1537                 spec->channel_mode = alc880_fivestack_modes;
1538                 spec->num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes);
1539                 break;
1540         case ALC880_W810:
1541                 spec->init_verbs = alc880_w810_init_verbs;
1542                 spec->channel_mode = alc880_w810_modes;
1543                 spec->num_channel_mode = ARRAY_SIZE(alc880_w810_modes);
1544                 break;
1545         case ALC880_Z71V:
1546                 spec->init_verbs = alc880_z71v_init_verbs;
1547                 spec->channel_mode = alc880_z71v_modes;
1548                 spec->num_channel_mode = ARRAY_SIZE(alc880_z71v_modes);
1549                 break;
1550 #ifdef CONFIG_SND_DEBUG
1551         case ALC880_TEST:
1552                 spec->init_verbs = alc880_test_init_verbs;
1553                 spec->channel_mode = alc880_test_modes;
1554                 spec->num_channel_mode = ARRAY_SIZE(alc880_test_modes);
1555                 break;
1556 #endif
1557         default:
1558                 spec->init_verbs = alc880_init_verbs_three_stack;
1559                 spec->channel_mode = alc880_threestack_modes;
1560                 spec->num_channel_mode = ARRAY_SIZE(alc880_threestack_modes);
1561                 break;
1562         }
1563
1564         spec->stream_name_analog = "ALC880 Analog";
1565         spec->stream_analog_playback = &alc880_pcm_analog_playback;
1566         spec->stream_analog_capture = &alc880_pcm_analog_capture;
1567
1568         spec->stream_name_digital = "ALC880 Digital";
1569         spec->stream_digital_playback = &alc880_pcm_digital_playback;
1570         spec->stream_digital_capture = &alc880_pcm_digital_capture;
1571
1572         spec->multiout.max_channels = spec->channel_mode[0].channels;
1573
1574         switch (board_config) {
1575         case ALC880_W810:
1576                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_w810_dac_nids);
1577                 spec->multiout.dac_nids = alc880_w810_dac_nids;
1578                 // No dedicated headphone socket - it's shared with built-in speakers.
1579                 break;
1580         case ALC880_Z71V:
1581                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids);
1582                 spec->multiout.dac_nids = alc880_z71v_dac_nids;
1583                 spec->multiout.hp_nid = 0x03;
1584                 break;
1585 #ifdef CONFIG_SND_DEBUG
1586         case ALC880_TEST:
1587                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_test_dac_nids);
1588                 spec->multiout.dac_nids = alc880_test_dac_nids;
1589                 spec->input_mux = &alc880_test_capture_source;
1590                 break;
1591 #endif
1592         default:
1593                 spec->multiout.num_dacs = ARRAY_SIZE(alc880_dac_nids);
1594                 spec->multiout.dac_nids = alc880_dac_nids;
1595                 spec->multiout.hp_nid = 0x03; /* rear-surround NID */
1596                 break;
1597         }
1598
1599         if (! spec->input_mux)
1600                 spec->input_mux = &alc880_capture_source;
1601         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
1602         spec->adc_nids = alc880_adc_nids;
1603
1604         codec->patch_ops = alc_patch_ops;
1605
1606         return 0;
1607 }
1608
1609 /*
1610  * ALC260 support
1611  */
1612
1613 /*
1614  * This is just place-holder, so there's something for alc_build_pcms to look
1615  * at when it calculates the maximum number of channels. ALC260 has no mixer
1616  * element which allows changing the channel mode, so the verb list is
1617  * never used.
1618  */
1619 static struct alc_channel_mode alc260_modes[1] = {
1620         { 2, NULL },
1621 };
1622
1623 snd_kcontrol_new_t alc260_base_mixer[] = {
1624         ALC_BIND_VOL("Front Playback Volume", 0x08, 2, HDA_OUTPUT),
1625         /* use LINE2 for the output */
1626         /* HDA_CODEC_MUTE("Front Playback Switch", 0x0f, 0x0, HDA_OUTPUT), */
1627         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1628         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
1629         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
1630         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
1631         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
1632         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
1633         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
1634         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
1635         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
1636         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
1637         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
1638         ALC_BIND_VOL("Headphone Playback Volume", 0x09, 2, HDA_OUTPUT),
1639         HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
1640         ALC_BIND_VOL_MONO("Mono Playback Volume", 0x0a, 1, 2, HDA_OUTPUT),
1641         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
1642         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
1643         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
1644         {
1645                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1646                 .name = "Capture Source",
1647                 .info = alc_mux_enum_info,
1648                 .get = alc_mux_enum_get,
1649                 .put = alc_mux_enum_put,
1650         },
1651         { } /* end */
1652 };
1653
1654 static struct hda_verb alc260_init_verbs[] = {
1655         /* Line In pin widget for input */
1656         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1657         /* CD pin widget for input */
1658         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1659         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1660         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1661         /* Mic2 (front panel) pin widget for input and vref at 80% */
1662         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1663         /* LINE-2 is used for line-out in rear */
1664         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1665         /* select line-out */
1666         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1667         /* LINE-OUT pin */
1668         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1669         /* enable HP */
1670         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1671         /* enable Mono */
1672         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1673         /* unmute amp left and right */
1674         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1675         /* set connection select to line in (default select for this ADC) */
1676         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
1677         /* unmute Line-Out mixer amp left and right (volume = 0) */
1678         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1679         /* mute pin widget amp left and right (no gain on this amp) */
1680         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1681         /* unmute HP mixer amp left and right (volume = 0) */
1682         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1683         /* mute pin widget amp left and right (no gain on this amp) */
1684         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1685         /* unmute Mono mixer amp left and right (volume = 0) */
1686         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1687         /* mute pin widget amp left and right (no gain on this amp) */
1688         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1689         /* mute LINE-2 out */
1690         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1691         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
1692         /* unmute CD */
1693         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1694         /* unmute Line In */
1695         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1696         /* unmute Mic */
1697         {0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1698         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
1699         /* Unmute Front out path */
1700         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1701         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1702         /* Unmute Headphone out path */
1703         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1704         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1705         /* Unmute Mono out path */
1706         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1707         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1708         { }
1709 };
1710
1711 static struct hda_pcm_stream alc260_pcm_analog_playback = {
1712         .substreams = 1,
1713         .channels_min = 2,
1714         .channels_max = 2,
1715         .nid = 0x2,
1716 };
1717
1718 static struct hda_pcm_stream alc260_pcm_analog_capture = {
1719         .substreams = 1,
1720         .channels_min = 2,
1721         .channels_max = 2,
1722         .nid = 0x4,
1723 };
1724
1725 static int patch_alc260(struct hda_codec *codec)
1726 {
1727         struct alc_spec *spec;
1728
1729         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1730         if (spec == NULL)
1731                 return -ENOMEM;
1732
1733         init_MUTEX(&spec->bind_mutex);
1734         codec->spec = spec;
1735
1736         spec->mixers[spec->num_mixers] = alc260_base_mixer;
1737         spec->num_mixers++;
1738
1739         spec->init_verbs = alc260_init_verbs;
1740         spec->channel_mode = alc260_modes;
1741         spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
1742
1743         spec->stream_name_analog = "ALC260 Analog";
1744         spec->stream_analog_playback = &alc260_pcm_analog_playback;
1745         spec->stream_analog_capture = &alc260_pcm_analog_capture;
1746
1747         spec->multiout.max_channels = spec->channel_mode[0].channels;
1748         spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
1749         spec->multiout.dac_nids = alc260_dac_nids;
1750
1751         spec->input_mux = &alc260_capture_source;
1752         spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
1753         spec->adc_nids = alc260_adc_nids;
1754
1755         codec->patch_ops = alc_patch_ops;
1756
1757         return 0;
1758 }
1759
1760 /*
1761  * ALC882 support
1762  *
1763  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1764  * configuration.  Each pin widget can choose any input DACs and a mixer.
1765  * Each ADC is connected from a mixer of all inputs.  This makes possible
1766  * 6-channel independent captures.
1767  *
1768  * In addition, an independent DAC for the multi-playback (not used in this
1769  * driver yet).
1770  */
1771
1772 static struct alc_channel_mode alc882_ch_modes[1] = {
1773         { 8, NULL }
1774 };
1775
1776 static hda_nid_t alc882_dac_nids[4] = {
1777         /* front, rear, clfe, rear_surr */
1778         0x02, 0x03, 0x04, 0x05
1779 };
1780
1781 static hda_nid_t alc882_adc_nids[3] = {
1782         /* ADC0-2 */
1783         0x07, 0x08, 0x09,
1784 };
1785
1786 /* input MUX */
1787 /* FIXME: should be a matrix-type input source selection */
1788
1789 static struct hda_input_mux alc882_capture_source = {
1790         .num_items = 4,
1791         .items = {
1792                 { "Mic", 0x0 },
1793                 { "Front Mic", 0x1 },
1794                 { "Line", 0x2 },
1795                 { "CD", 0x4 },
1796         },
1797 };
1798
1799 #define alc882_mux_enum_info alc_mux_enum_info
1800 #define alc882_mux_enum_get alc_mux_enum_get
1801
1802 static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
1803 {
1804         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1805         struct alc_spec *spec = codec->spec;
1806         const struct hda_input_mux *imux = spec->input_mux;
1807         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1808         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
1809         hda_nid_t nid = capture_mixers[adc_idx];
1810         unsigned int *cur_val = &spec->cur_mux[adc_idx];
1811         unsigned int i, idx;
1812
1813         idx = ucontrol->value.enumerated.item[0];
1814         if (idx >= imux->num_items)
1815                 idx = imux->num_items - 1;
1816         if (*cur_val == idx && ! codec->in_resume)
1817                 return 0;
1818         for (i = 0; i < imux->num_items; i++) {
1819                 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
1820                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1821                                     v | (imux->items[i].index << 8));
1822         }
1823         *cur_val = idx;
1824         return 1;
1825 }
1826
1827 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
1828  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
1829  */
1830 static snd_kcontrol_new_t alc882_base_mixer[] = {
1831         ALC_BIND_VOL("Front Playback Volume", 0x0c, 2, HDA_OUTPUT),
1832         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1833         ALC_BIND_VOL("Surround Playback Volume", 0x0d, 2, HDA_OUTPUT),
1834         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1835         ALC_BIND_VOL_MONO("Center Playback Volume", 0x0e, 1, 2, HDA_OUTPUT),
1836         ALC_BIND_VOL_MONO("LFE Playback Volume", 0x0e, 2, 2, HDA_OUTPUT),
1837         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
1838         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
1839         ALC_BIND_VOL("Side Playback Volume", 0x0f, 2, HDA_OUTPUT),
1840         HDA_CODEC_MUTE("Side Playback Switch", 0x17, 0x0, HDA_OUTPUT),
1841         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1842         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1843         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1844         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1845         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1846         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1847         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1848         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1849         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1850         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1851         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1852         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1853         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1854         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1855         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1856         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1857         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1858         {
1859                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1860                 /* .name = "Capture Source", */
1861                 .name = "Input Source",
1862                 .count = 3,
1863                 .info = alc882_mux_enum_info,
1864                 .get = alc882_mux_enum_get,
1865                 .put = alc882_mux_enum_put,
1866         },
1867         { } /* end */
1868 };
1869
1870 static struct hda_verb alc882_init_verbs[] = {
1871         /* Front mixer: unmute input/output amp left and right (volume = 0) */
1872         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1873         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1874         /* Rear mixer */
1875         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1876         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1877         /* CLFE mixer */
1878         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1879         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1880         /* Side mixer */
1881         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1882         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1883
1884         /* Front Pin: to output mode */
1885         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1886         /* Front Pin: mute amp left and right (no volume) */
1887         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1888         /* select Front mixer (0x0c, index 0) */
1889         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1890         /* Rear Pin */
1891         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1892         /* Rear Pin: mute amp left and right (no volume) */
1893         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1894         /* select Rear mixer (0x0d, index 1) */
1895         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
1896         /* CLFE Pin */
1897         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1898         /* CLFE Pin: mute amp left and right (no volume) */
1899         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1900         /* select CLFE mixer (0x0e, index 2) */
1901         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1902         /* Side Pin */
1903         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1904         /* Side Pin: mute amp left and right (no volume) */
1905         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1906         /* select Side mixer (0x0f, index 3) */
1907         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1908         /* Headphone Pin */
1909         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1910         /* Headphone Pin: mute amp left and right (no volume) */
1911         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
1912         /* select Front mixer (0x0c, index 0) */
1913         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1914         /* Mic (rear) pin widget for input and vref at 80% */
1915         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1916         /* Front Mic pin widget for input and vref at 80% */
1917         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
1918         /* Line In pin widget for input */
1919         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1920         /* CD pin widget for input */
1921         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1922
1923         /* FIXME: use matrix-type input source selection */
1924         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1925         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1926         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1927         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1928         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1929         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1930         /* Input mixer2 */
1931         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1932         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1933         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1934         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1935         /* Input mixer3 */
1936         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1937         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
1938         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
1939         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
1940         /* ADC1: unmute amp left and right */
1941         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1942         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1943         /* ADC2: unmute amp left and right */
1944         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1945         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1946         /* ADC3: unmute amp left and right */
1947         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
1948         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1949         /* Unmute front loopback */
1950         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1951         /* Unmute rear loopback */
1952         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1953         /* Mute CLFE loopback */
1954         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
1955         /* Unmute side loopback */
1956         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1957
1958         { }
1959 };
1960
1961 static int patch_alc882(struct hda_codec *codec)
1962 {
1963         struct alc_spec *spec;
1964
1965         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1966         if (spec == NULL)
1967                 return -ENOMEM;
1968
1969         init_MUTEX(&spec->bind_mutex);
1970         codec->spec = spec;
1971
1972         spec->mixers[spec->num_mixers] = alc882_base_mixer;
1973         spec->num_mixers++;
1974
1975         spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
1976         spec->dig_in_nid = ALC880_DIGIN_NID;
1977         spec->front_panel = 1;
1978         spec->init_verbs = alc882_init_verbs;
1979         spec->channel_mode = alc882_ch_modes;
1980         spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
1981
1982         spec->stream_name_analog = "ALC882 Analog";
1983         spec->stream_analog_playback = &alc880_pcm_analog_playback;
1984         spec->stream_analog_capture = &alc880_pcm_analog_capture;
1985
1986         spec->stream_name_digital = "ALC882 Digital";
1987         spec->stream_digital_playback = &alc880_pcm_digital_playback;
1988         spec->stream_digital_capture = &alc880_pcm_digital_capture;
1989
1990         spec->multiout.max_channels = spec->channel_mode[0].channels;
1991         spec->multiout.num_dacs = ARRAY_SIZE(alc882_dac_nids);
1992         spec->multiout.dac_nids = alc882_dac_nids;
1993
1994         spec->input_mux = &alc882_capture_source;
1995         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
1996         spec->adc_nids = alc882_adc_nids;
1997
1998         codec->patch_ops = alc_patch_ops;
1999
2000         return 0;
2001 }
2002
2003 /*
2004  * patch entries
2005  */
2006 struct hda_codec_preset snd_hda_preset_realtek[] = {
2007         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
2008         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
2009         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
2010         {} /* terminator */
2011 };