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