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