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