]> git.karo-electronics.de Git - mv-sheeva.git/blob - sound/pci/hda/alc880_quirks.c
c8af01b7f8538a00dcfb9237fa0999ea9d2abc1a
[mv-sheeva.git] / sound / pci / hda / alc880_quirks.c
1 /*
2  * ALC880 quirk models
3  * included by patch_realtek.c
4  */
5
6 /* ALC880 board config type */
7 enum {
8         ALC880_AUTO,
9         ALC880_3ST,
10         ALC880_3ST_DIG,
11         ALC880_5ST,
12         ALC880_5ST_DIG,
13         ALC880_6ST,
14         ALC880_6ST_DIG,
15         ALC880_ASUS,
16         ALC880_ASUS_DIG,
17         ALC880_ASUS_DIG2,
18 #ifdef CONFIG_SND_DEBUG
19         ALC880_TEST,
20 #endif
21         ALC880_MODEL_LAST /* last tag */
22 };
23
24 /*
25  * ALC880 3-stack model
26  *
27  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
28  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
29  *                 F-Mic = 0x1b, HP = 0x19
30  */
31
32 static const hda_nid_t alc880_dac_nids[4] = {
33         /* front, rear, clfe, rear_surr */
34         0x02, 0x05, 0x04, 0x03
35 };
36
37 static const hda_nid_t alc880_adc_nids[3] = {
38         /* ADC0-2 */
39         0x07, 0x08, 0x09,
40 };
41
42 /* The datasheet says the node 0x07 is connected from inputs,
43  * but it shows zero connection in the real implementation on some devices.
44  * Note: this is a 915GAV bug, fixed on 915GLV
45  */
46 static const hda_nid_t alc880_adc_nids_alt[2] = {
47         /* ADC1-2 */
48         0x08, 0x09,
49 };
50
51 #define ALC880_DIGOUT_NID       0x06
52 #define ALC880_DIGIN_NID        0x0a
53 #define ALC880_PIN_CD_NID       0x1c
54
55 static const struct hda_input_mux alc880_capture_source = {
56         .num_items = 4,
57         .items = {
58                 { "Mic", 0x0 },
59                 { "Front Mic", 0x3 },
60                 { "Line", 0x2 },
61                 { "CD", 0x4 },
62         },
63 };
64
65 /* channel source setting (2/6 channel selection for 3-stack) */
66 /* 2ch mode */
67 static const struct hda_verb alc880_threestack_ch2_init[] = {
68         /* set line-in to input, mute it */
69         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
70         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
71         /* set mic-in to input vref 80%, mute it */
72         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
73         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
74         { } /* end */
75 };
76
77 /* 6ch mode */
78 static const struct hda_verb alc880_threestack_ch6_init[] = {
79         /* set line-in to output, unmute it */
80         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
81         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
82         /* set mic-in to output, unmute it */
83         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
84         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
85         { } /* end */
86 };
87
88 static const struct hda_channel_mode alc880_threestack_modes[2] = {
89         { 2, alc880_threestack_ch2_init },
90         { 6, alc880_threestack_ch6_init },
91 };
92
93 static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
94         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
95         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
96         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
97         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
98         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
99         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
100         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
101         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
102         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
103         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
104         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
105         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
106         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
107         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
108         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
109         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
110         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
111         {
112                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
113                 .name = "Channel Mode",
114                 .info = alc_ch_mode_info,
115                 .get = alc_ch_mode_get,
116                 .put = alc_ch_mode_put,
117         },
118         { } /* end */
119 };
120
121 /*
122  * ALC880 5-stack model
123  *
124  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
125  *      Side = 0x02 (0xd)
126  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
127  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
128  */
129
130 /* additional mixers to alc880_three_stack_mixer */
131 static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
132         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
133         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
134         { } /* end */
135 };
136
137 /* channel source setting (6/8 channel selection for 5-stack) */
138 /* 6ch mode */
139 static const struct hda_verb alc880_fivestack_ch6_init[] = {
140         /* set line-in to input, mute it */
141         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
142         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
143         { } /* end */
144 };
145
146 /* 8ch mode */
147 static const struct hda_verb alc880_fivestack_ch8_init[] = {
148         /* set line-in to output, unmute it */
149         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
150         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
151         { } /* end */
152 };
153
154 static const struct hda_channel_mode alc880_fivestack_modes[2] = {
155         { 6, alc880_fivestack_ch6_init },
156         { 8, alc880_fivestack_ch8_init },
157 };
158
159
160 /*
161  * ALC880 6-stack model
162  *
163  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
164  *      Side = 0x05 (0x0f)
165  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
166  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
167  */
168
169 static const hda_nid_t alc880_6st_dac_nids[4] = {
170         /* front, rear, clfe, rear_surr */
171         0x02, 0x03, 0x04, 0x05
172 };
173
174 static const struct hda_input_mux alc880_6stack_capture_source = {
175         .num_items = 4,
176         .items = {
177                 { "Mic", 0x0 },
178                 { "Front Mic", 0x1 },
179                 { "Line", 0x2 },
180                 { "CD", 0x4 },
181         },
182 };
183
184 /* fixed 8-channels */
185 static const struct hda_channel_mode alc880_sixstack_modes[1] = {
186         { 8, NULL },
187 };
188
189 static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
190         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
191         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
192         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
193         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
194         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
195         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
196         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
197         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
198         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
199         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
200         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
201         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
202         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
203         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
204         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
205         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
206         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
207         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
208         {
209                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
210                 .name = "Channel Mode",
211                 .info = alc_ch_mode_info,
212                 .get = alc_ch_mode_get,
213                 .put = alc_ch_mode_put,
214         },
215         { } /* end */
216 };
217
218
219 static const hda_nid_t alc880_w810_dac_nids[3] = {
220         /* front, rear/surround, clfe */
221         0x02, 0x03, 0x04
222 };
223
224 /* fixed 2 channels */
225 static const struct hda_channel_mode alc880_2_jack_modes[1] = {
226         { 2, NULL }
227 };
228
229 /*
230  * ALC880 ASUS model
231  *
232  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
233  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
234  *  Mic = 0x18, Line = 0x1a
235  */
236
237 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
238 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
239
240 static const struct snd_kcontrol_new alc880_asus_mixer[] = {
241         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
242         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
243         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
244         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
245         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
246         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
247         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
248         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
249         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
250         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
251         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
252         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
253         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
254         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
255         {
256                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
257                 .name = "Channel Mode",
258                 .info = alc_ch_mode_info,
259                 .get = alc_ch_mode_get,
260                 .put = alc_ch_mode_put,
261         },
262         { } /* end */
263 };
264
265 /*
266  * initialize the codec volumes, etc
267  */
268
269 /*
270  * generic initialization of ADC, input mixers and output mixers
271  */
272 static const struct hda_verb alc880_volume_init_verbs[] = {
273         /*
274          * Unmute ADC0-2 and set the default input to mic-in
275          */
276         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
277         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
278         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
279         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
280         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
281         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
282
283         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
284          * mixer widget
285          * Note: PASD motherboards uses the Line In 2 as the input for front
286          * panel mic (mic 2)
287          */
288         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
289         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
290         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
291         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
292         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
293         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
294         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
295         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
296
297         /*
298          * Set up output mixers (0x0c - 0x0f)
299          */
300         /* set vol=0 to output mixers */
301         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
302         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
303         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
304         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
305         /* set up input amps for analog loopback */
306         /* Amp Indices: DAC = 0, mixer = 1 */
307         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
308         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
309         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
310         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
311         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
312         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
313         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
314         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
315
316         { }
317 };
318
319 /*
320  * 3-stack pin configuration:
321  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
322  */
323 static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
324         /*
325          * preset connection lists of input pins
326          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
327          */
328         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
329         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
330         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
331
332         /*
333          * Set pin mode and muting
334          */
335         /* set front pin widgets 0x14 for output */
336         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
337         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
338         /* Mic1 (rear panel) pin widget for input and vref at 80% */
339         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
340         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
341         /* Mic2 (as headphone out) for HP output */
342         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
343         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
344         /* Line In pin widget for input */
345         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
346         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
347         /* Line2 (as front mic) pin widget for input and vref at 80% */
348         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
349         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
350         /* CD pin widget for input */
351         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
352
353         { }
354 };
355
356 /*
357  * 5-stack pin configuration:
358  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
359  * line-in/side = 0x1a, f-mic = 0x1b
360  */
361 static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
362         /*
363          * preset connection lists of input pins
364          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
365          */
366         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
367         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
368
369         /*
370          * Set pin mode and muting
371          */
372         /* set pin widgets 0x14-0x17 for output */
373         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
374         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
375         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
376         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
377         /* unmute pins for output (no gain on this amp) */
378         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
379         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
380         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
381         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
382
383         /* Mic1 (rear panel) pin widget for input and vref at 80% */
384         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
385         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
386         /* Mic2 (as headphone out) for HP output */
387         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
388         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
389         /* Line In pin widget for input */
390         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
391         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
392         /* Line2 (as front mic) pin widget for input and vref at 80% */
393         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
394         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
395         /* CD pin widget for input */
396         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
397
398         { }
399 };
400
401 /*
402  * 6-stack pin configuration:
403  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
404  * f-mic = 0x19, line = 0x1a, HP = 0x1b
405  */
406 static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
407         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
408
409         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
410         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
411         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
412         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
413         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
414         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
415         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
416         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
417
418         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
419         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
420         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
421         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
422         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
423         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
424         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
425         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
426         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
427
428         { }
429 };
430
431 static const struct hda_verb alc880_beep_init_verbs[] = {
432         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
433         { }
434 };
435
436 /*
437  * ASUS pin configuration:
438  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
439  */
440 static const struct hda_verb alc880_pin_asus_init_verbs[] = {
441         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
442         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
443         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
444         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
445
446         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
447         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
448         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
449         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
450         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
451         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
452         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
453         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
454
455         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
456         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
457         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
458         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
459         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
460         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
461         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
462         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
463         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
464
465         { }
466 };
467
468 /* Enable GPIO mask and set output */
469 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
470 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
471 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
472
473 /*
474  * Test configuration for debugging
475  *
476  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
477  * enum controls.
478  */
479 #ifdef CONFIG_SND_DEBUG
480 static const hda_nid_t alc880_test_dac_nids[4] = {
481         0x02, 0x03, 0x04, 0x05
482 };
483
484 static const struct hda_input_mux alc880_test_capture_source = {
485         .num_items = 7,
486         .items = {
487                 { "In-1", 0x0 },
488                 { "In-2", 0x1 },
489                 { "In-3", 0x2 },
490                 { "In-4", 0x3 },
491                 { "CD", 0x4 },
492                 { "Front", 0x5 },
493                 { "Surround", 0x6 },
494         },
495 };
496
497 static const struct hda_channel_mode alc880_test_modes[4] = {
498         { 2, NULL },
499         { 4, NULL },
500         { 6, NULL },
501         { 8, NULL },
502 };
503
504 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
505                                  struct snd_ctl_elem_info *uinfo)
506 {
507         static const char * const texts[] = {
508                 "N/A", "Line Out", "HP Out",
509                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
510         };
511         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
512         uinfo->count = 1;
513         uinfo->value.enumerated.items = 8;
514         if (uinfo->value.enumerated.item >= 8)
515                 uinfo->value.enumerated.item = 7;
516         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
517         return 0;
518 }
519
520 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
521                                 struct snd_ctl_elem_value *ucontrol)
522 {
523         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
524         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
525         unsigned int pin_ctl, item = 0;
526
527         pin_ctl = snd_hda_codec_read(codec, nid, 0,
528                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
529         if (pin_ctl & AC_PINCTL_OUT_EN) {
530                 if (pin_ctl & AC_PINCTL_HP_EN)
531                         item = 2;
532                 else
533                         item = 1;
534         } else if (pin_ctl & AC_PINCTL_IN_EN) {
535                 switch (pin_ctl & AC_PINCTL_VREFEN) {
536                 case AC_PINCTL_VREF_HIZ: item = 3; break;
537                 case AC_PINCTL_VREF_50:  item = 4; break;
538                 case AC_PINCTL_VREF_GRD: item = 5; break;
539                 case AC_PINCTL_VREF_80:  item = 6; break;
540                 case AC_PINCTL_VREF_100: item = 7; break;
541                 }
542         }
543         ucontrol->value.enumerated.item[0] = item;
544         return 0;
545 }
546
547 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
548                                 struct snd_ctl_elem_value *ucontrol)
549 {
550         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
551         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
552         static const unsigned int ctls[] = {
553                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
554                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
555                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
556                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
557                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
558                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
559         };
560         unsigned int old_ctl, new_ctl;
561
562         old_ctl = snd_hda_codec_read(codec, nid, 0,
563                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
564         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
565         if (old_ctl != new_ctl) {
566                 int val;
567                 snd_hda_codec_write_cache(codec, nid, 0,
568                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
569                                           new_ctl);
570                 val = ucontrol->value.enumerated.item[0] >= 3 ?
571                         HDA_AMP_MUTE : 0;
572                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
573                                          HDA_AMP_MUTE, val);
574                 return 1;
575         }
576         return 0;
577 }
578
579 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
580                                  struct snd_ctl_elem_info *uinfo)
581 {
582         static const char * const texts[] = {
583                 "Front", "Surround", "CLFE", "Side"
584         };
585         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
586         uinfo->count = 1;
587         uinfo->value.enumerated.items = 4;
588         if (uinfo->value.enumerated.item >= 4)
589                 uinfo->value.enumerated.item = 3;
590         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
591         return 0;
592 }
593
594 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
595                                 struct snd_ctl_elem_value *ucontrol)
596 {
597         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
598         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
599         unsigned int sel;
600
601         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
602         ucontrol->value.enumerated.item[0] = sel & 3;
603         return 0;
604 }
605
606 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
607                                 struct snd_ctl_elem_value *ucontrol)
608 {
609         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
610         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
611         unsigned int sel;
612
613         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
614         if (ucontrol->value.enumerated.item[0] != sel) {
615                 sel = ucontrol->value.enumerated.item[0] & 3;
616                 snd_hda_codec_write_cache(codec, nid, 0,
617                                           AC_VERB_SET_CONNECT_SEL, sel);
618                 return 1;
619         }
620         return 0;
621 }
622
623 #define PIN_CTL_TEST(xname,nid) {                       \
624                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
625                         .name = xname,                 \
626                         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
627                         .info = alc_test_pin_ctl_info, \
628                         .get = alc_test_pin_ctl_get,   \
629                         .put = alc_test_pin_ctl_put,   \
630                         .private_value = nid           \
631                         }
632
633 #define PIN_SRC_TEST(xname,nid) {                       \
634                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
635                         .name = xname,                 \
636                         .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
637                         .info = alc_test_pin_src_info, \
638                         .get = alc_test_pin_src_get,   \
639                         .put = alc_test_pin_src_put,   \
640                         .private_value = nid           \
641                         }
642
643 static const struct snd_kcontrol_new alc880_test_mixer[] = {
644         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
645         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
646         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
647         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
648         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
649         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
650         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
651         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
652         PIN_CTL_TEST("Front Pin Mode", 0x14),
653         PIN_CTL_TEST("Surround Pin Mode", 0x15),
654         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
655         PIN_CTL_TEST("Side Pin Mode", 0x17),
656         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
657         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
658         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
659         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
660         PIN_SRC_TEST("In-1 Pin Source", 0x18),
661         PIN_SRC_TEST("In-2 Pin Source", 0x19),
662         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
663         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
664         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
665         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
666         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
667         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
668         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
669         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
670         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
671         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
672         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
673         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
674         {
675                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
676                 .name = "Channel Mode",
677                 .info = alc_ch_mode_info,
678                 .get = alc_ch_mode_get,
679                 .put = alc_ch_mode_put,
680         },
681         { } /* end */
682 };
683
684 static const struct hda_verb alc880_test_init_verbs[] = {
685         /* Unmute inputs of 0x0c - 0x0f */
686         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
687         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
688         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
689         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
690         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
691         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
692         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
693         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
694         /* Vol output for 0x0c-0x0f */
695         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
696         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
697         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
698         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
699         /* Set output pins 0x14-0x17 */
700         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
701         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
702         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
703         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
704         /* Unmute output pins 0x14-0x17 */
705         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
706         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
707         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
708         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
709         /* Set input pins 0x18-0x1c */
710         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
711         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
712         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
713         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
714         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
715         /* Mute input pins 0x18-0x1b */
716         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
717         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
718         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
719         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
720         /* ADC set up */
721         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
722         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
723         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
724         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
725         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
726         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
727         /* Analog input/passthru */
728         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
729         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
730         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
731         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
732         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
733         { }
734 };
735 #endif
736
737 /*
738  */
739
740 static const char * const alc880_models[ALC880_MODEL_LAST] = {
741         [ALC880_3ST]            = "3stack",
742         [ALC880_3ST_DIG]        = "3stack-digout",
743         [ALC880_5ST]            = "5stack",
744         [ALC880_5ST_DIG]        = "5stack-digout",
745         [ALC880_6ST]            = "6stack",
746         [ALC880_6ST_DIG]        = "6stack-digout",
747         [ALC880_ASUS]           = "asus",
748         [ALC880_ASUS_DIG]       = "asus-dig",
749         [ALC880_ASUS_DIG2]      = "asus-dig2",
750 #ifdef CONFIG_SND_DEBUG
751         [ALC880_TEST]           = "test",
752 #endif
753         [ALC880_AUTO]           = "auto",
754 };
755
756 static const struct snd_pci_quirk alc880_cfg_tbl[] = {
757         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
758         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
759         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
760         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
761         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
762         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
763         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
764         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
765         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
766         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
767         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
768         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
769         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
770         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
771         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
772         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
773         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
774         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
775         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
776         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
777         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
778         SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
779         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
780         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
781         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
782         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
783         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
784         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
785         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
786         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
787         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
788         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
789         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
790         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
791         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
792         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
793         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
794         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
795         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
796         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
797         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
798         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
799         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
800         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
801         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
802         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
803         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
804         /* default Intel */
805         SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
806         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
807         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
808         {}
809 };
810
811 /*
812  * ALC880 codec presets
813  */
814 static const struct alc_config_preset alc880_presets[] = {
815         [ALC880_3ST] = {
816                 .mixers = { alc880_three_stack_mixer },
817                 .init_verbs = { alc880_volume_init_verbs,
818                                 alc880_pin_3stack_init_verbs },
819                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
820                 .dac_nids = alc880_dac_nids,
821                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
822                 .channel_mode = alc880_threestack_modes,
823                 .need_dac_fix = 1,
824                 .input_mux = &alc880_capture_source,
825         },
826         [ALC880_3ST_DIG] = {
827                 .mixers = { alc880_three_stack_mixer },
828                 .init_verbs = { alc880_volume_init_verbs,
829                                 alc880_pin_3stack_init_verbs },
830                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
831                 .dac_nids = alc880_dac_nids,
832                 .dig_out_nid = ALC880_DIGOUT_NID,
833                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
834                 .channel_mode = alc880_threestack_modes,
835                 .need_dac_fix = 1,
836                 .input_mux = &alc880_capture_source,
837         },
838         [ALC880_5ST] = {
839                 .mixers = { alc880_three_stack_mixer,
840                             alc880_five_stack_mixer},
841                 .init_verbs = { alc880_volume_init_verbs,
842                                 alc880_pin_5stack_init_verbs },
843                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
844                 .dac_nids = alc880_dac_nids,
845                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
846                 .channel_mode = alc880_fivestack_modes,
847                 .input_mux = &alc880_capture_source,
848         },
849         [ALC880_5ST_DIG] = {
850                 .mixers = { alc880_three_stack_mixer,
851                             alc880_five_stack_mixer },
852                 .init_verbs = { alc880_volume_init_verbs,
853                                 alc880_pin_5stack_init_verbs },
854                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
855                 .dac_nids = alc880_dac_nids,
856                 .dig_out_nid = ALC880_DIGOUT_NID,
857                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
858                 .channel_mode = alc880_fivestack_modes,
859                 .input_mux = &alc880_capture_source,
860         },
861         [ALC880_6ST] = {
862                 .mixers = { alc880_six_stack_mixer },
863                 .init_verbs = { alc880_volume_init_verbs,
864                                 alc880_pin_6stack_init_verbs },
865                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
866                 .dac_nids = alc880_6st_dac_nids,
867                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
868                 .channel_mode = alc880_sixstack_modes,
869                 .input_mux = &alc880_6stack_capture_source,
870         },
871         [ALC880_6ST_DIG] = {
872                 .mixers = { alc880_six_stack_mixer },
873                 .init_verbs = { alc880_volume_init_verbs,
874                                 alc880_pin_6stack_init_verbs },
875                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
876                 .dac_nids = alc880_6st_dac_nids,
877                 .dig_out_nid = ALC880_DIGOUT_NID,
878                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
879                 .channel_mode = alc880_sixstack_modes,
880                 .input_mux = &alc880_6stack_capture_source,
881         },
882         [ALC880_ASUS] = {
883                 .mixers = { alc880_asus_mixer },
884                 .init_verbs = { alc880_volume_init_verbs,
885                                 alc880_pin_asus_init_verbs,
886                                 alc880_gpio1_init_verbs },
887                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
888                 .dac_nids = alc880_asus_dac_nids,
889                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
890                 .channel_mode = alc880_asus_modes,
891                 .need_dac_fix = 1,
892                 .input_mux = &alc880_capture_source,
893         },
894         [ALC880_ASUS_DIG] = {
895                 .mixers = { alc880_asus_mixer },
896                 .init_verbs = { alc880_volume_init_verbs,
897                                 alc880_pin_asus_init_verbs,
898                                 alc880_gpio1_init_verbs },
899                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
900                 .dac_nids = alc880_asus_dac_nids,
901                 .dig_out_nid = ALC880_DIGOUT_NID,
902                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
903                 .channel_mode = alc880_asus_modes,
904                 .need_dac_fix = 1,
905                 .input_mux = &alc880_capture_source,
906         },
907         [ALC880_ASUS_DIG2] = {
908                 .mixers = { alc880_asus_mixer },
909                 .init_verbs = { alc880_volume_init_verbs,
910                                 alc880_pin_asus_init_verbs,
911                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
912                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
913                 .dac_nids = alc880_asus_dac_nids,
914                 .dig_out_nid = ALC880_DIGOUT_NID,
915                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
916                 .channel_mode = alc880_asus_modes,
917                 .need_dac_fix = 1,
918                 .input_mux = &alc880_capture_source,
919         },
920 #ifdef CONFIG_SND_DEBUG
921         [ALC880_TEST] = {
922                 .mixers = { alc880_test_mixer },
923                 .init_verbs = { alc880_test_init_verbs },
924                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
925                 .dac_nids = alc880_test_dac_nids,
926                 .dig_out_nid = ALC880_DIGOUT_NID,
927                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
928                 .channel_mode = alc880_test_modes,
929                 .input_mux = &alc880_test_capture_source,
930         },
931 #endif
932 };
933