aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/core/vmaster.c46
-rw-r--r--sound/pci/hda/alc260_quirks.c968
-rw-r--r--sound/pci/hda/alc880_quirks.c1707
-rw-r--r--sound/pci/hda/alc882_quirks.c866
-rw-r--r--sound/pci/hda/alc_quirks.c480
-rw-r--r--sound/pci/hda/hda_codec.c192
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_intel.c52
-rw-r--r--sound/pci/hda/hda_jack.c16
-rw-r--r--sound/pci/hda/hda_jack.h13
-rw-r--r--sound/pci/hda/hda_local.h30
-rw-r--r--sound/pci/hda/patch_analog.c72
-rw-r--r--sound/pci/hda/patch_conexant.c122
-rw-r--r--sound/pci/hda/patch_hdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c1840
-rw-r--r--sound/pci/hda/patch_sigmatel.c203
-rw-r--r--sound/pci/hda/patch_via.c48
17 files changed, 1766 insertions, 4892 deletions
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 130cfe677d60..14a286a7bf2b 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -37,6 +37,8 @@ struct link_master {
37 struct link_ctl_info info; 37 struct link_ctl_info info;
38 int val; /* the master value */ 38 int val; /* the master value */
39 unsigned int tlv[4]; 39 unsigned int tlv[4];
40 void (*hook)(void *private_data, int);
41 void *hook_private_data;
40}; 42};
41 43
42/* 44/*
@@ -126,7 +128,9 @@ static int master_init(struct link_master *master)
126 master->info.count = 1; /* always mono */ 128 master->info.count = 1; /* always mono */
127 /* set full volume as default (= no attenuation) */ 129 /* set full volume as default (= no attenuation) */
128 master->val = master->info.max_val; 130 master->val = master->info.max_val;
129 return 0; 131 if (master->hook)
132 master->hook(master->hook_private_data, master->val);
133 return 1;
130 } 134 }
131 return -ENOENT; 135 return -ENOENT;
132} 136}
@@ -329,6 +333,8 @@ static int master_put(struct snd_kcontrol *kcontrol,
329 slave_put_val(slave, uval); 333 slave_put_val(slave, uval);
330 } 334 }
331 kfree(uval); 335 kfree(uval);
336 if (master->hook && !err)
337 master->hook(master->hook_private_data, master->val);
332 return 1; 338 return 1;
333} 339}
334 340
@@ -408,3 +414,41 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
408 return kctl; 414 return kctl;
409} 415}
410EXPORT_SYMBOL(snd_ctl_make_virtual_master); 416EXPORT_SYMBOL(snd_ctl_make_virtual_master);
417
418/**
419 * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control
420 * @kcontrol: vmaster kctl element
421 * @hook: the hook function
422 *
423 * Adds the given hook to the vmaster control element so that it's called
424 * at each time when the value is changed.
425 */
426int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol,
427 void (*hook)(void *private_data, int),
428 void *private_data)
429{
430 struct link_master *master = snd_kcontrol_chip(kcontrol);
431 master->hook = hook;
432 master->hook_private_data = private_data;
433 return 0;
434}
435EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook);
436
437/**
438 * snd_ctl_sync_vmaster_hook - Sync the vmaster hook
439 * @kcontrol: vmaster kctl element
440 *
441 * Call the hook function to synchronize with the current value of the given
442 * vmaster element. NOP when NULL is passed to @kcontrol or the hook doesn't
443 * exist.
444 */
445void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol)
446{
447 struct link_master *master;
448 if (!kcontrol)
449 return;
450 master = snd_kcontrol_chip(kcontrol);
451 if (master->hook)
452 master->hook(master->hook_private_data, master->val);
453}
454EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook);
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
deleted file mode 100644
index 3b5170b9700f..000000000000
--- a/sound/pci/hda/alc260_quirks.c
+++ /dev/null
@@ -1,968 +0,0 @@
1/*
2 * ALC260 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC260 models */
7enum {
8 ALC260_AUTO,
9 ALC260_BASIC,
10 ALC260_FUJITSU_S702X,
11 ALC260_ACER,
12 ALC260_WILL,
13 ALC260_REPLACER_672V,
14 ALC260_FAVORIT100,
15#ifdef CONFIG_SND_DEBUG
16 ALC260_TEST,
17#endif
18 ALC260_MODEL_LAST /* last tag */
19};
20
21static const hda_nid_t alc260_dac_nids[1] = {
22 /* front */
23 0x02,
24};
25
26static const hda_nid_t alc260_adc_nids[1] = {
27 /* ADC0 */
28 0x04,
29};
30
31static const hda_nid_t alc260_adc_nids_alt[1] = {
32 /* ADC1 */
33 0x05,
34};
35
36/* NIDs used when simultaneous access to both ADCs makes sense. Note that
37 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
38 */
39static const hda_nid_t alc260_dual_adc_nids[2] = {
40 /* ADC0, ADC1 */
41 0x04, 0x05
42};
43
44#define ALC260_DIGOUT_NID 0x03
45#define ALC260_DIGIN_NID 0x06
46
47static const struct hda_input_mux alc260_capture_source = {
48 .num_items = 4,
49 .items = {
50 { "Mic", 0x0 },
51 { "Front Mic", 0x1 },
52 { "Line", 0x2 },
53 { "CD", 0x4 },
54 },
55};
56
57/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
58 * headphone jack and the internal CD lines since these are the only pins at
59 * which audio can appear. For flexibility, also allow the option of
60 * recording the mixer output on the second ADC (ADC0 doesn't have a
61 * connection to the mixer output).
62 */
63static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
64 {
65 .num_items = 3,
66 .items = {
67 { "Mic/Line", 0x0 },
68 { "CD", 0x4 },
69 { "Headphone", 0x2 },
70 },
71 },
72 {
73 .num_items = 4,
74 .items = {
75 { "Mic/Line", 0x0 },
76 { "CD", 0x4 },
77 { "Headphone", 0x2 },
78 { "Mixer", 0x5 },
79 },
80 },
81
82};
83
84/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
85 * the Fujitsu S702x, but jacks are marked differently.
86 */
87static const struct hda_input_mux alc260_acer_capture_sources[2] = {
88 {
89 .num_items = 4,
90 .items = {
91 { "Mic", 0x0 },
92 { "Line", 0x2 },
93 { "CD", 0x4 },
94 { "Headphone", 0x5 },
95 },
96 },
97 {
98 .num_items = 5,
99 .items = {
100 { "Mic", 0x0 },
101 { "Line", 0x2 },
102 { "CD", 0x4 },
103 { "Headphone", 0x6 },
104 { "Mixer", 0x5 },
105 },
106 },
107};
108
109/* Maxdata Favorit 100XS */
110static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
111 {
112 .num_items = 2,
113 .items = {
114 { "Line/Mic", 0x0 },
115 { "CD", 0x4 },
116 },
117 },
118 {
119 .num_items = 3,
120 .items = {
121 { "Line/Mic", 0x0 },
122 { "CD", 0x4 },
123 { "Mixer", 0x5 },
124 },
125 },
126};
127
128/*
129 * This is just place-holder, so there's something for alc_build_pcms to look
130 * at when it calculates the maximum number of channels. ALC260 has no mixer
131 * element which allows changing the channel mode, so the verb list is
132 * never used.
133 */
134static const struct hda_channel_mode alc260_modes[1] = {
135 { 2, NULL },
136};
137
138
139/* Mixer combinations
140 *
141 * basic: base_output + input + pc_beep + capture
142 * fujitsu: fujitsu + capture
143 * acer: acer + capture
144 */
145
146static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
147 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
148 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
149 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
150 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
151 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
152 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
153 { } /* end */
154};
155
156static const struct snd_kcontrol_new alc260_input_mixer[] = {
157 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
158 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
159 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
160 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
162 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
163 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
165 { } /* end */
166};
167
168/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
169 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
170 */
171static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
172 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
173 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
174 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
175 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
176 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
177 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
178 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
179 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
180 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
181 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
182 { } /* end */
183};
184
185/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
186 * versions of the ALC260 don't act on requests to enable mic bias from NID
187 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
188 * datasheet doesn't mention this restriction. At this stage it's not clear
189 * whether this behaviour is intentional or is a hardware bug in chip
190 * revisions available in early 2006. Therefore for now allow the
191 * "Headphone Jack Mode" control to span all choices, but if it turns out
192 * that the lack of mic bias for this NID is intentional we could change the
193 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
194 *
195 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
196 * don't appear to make the mic bias available from the "line" jack, even
197 * though the NID used for this jack (0x14) can supply it. The theory is
198 * that perhaps Acer have included blocking capacitors between the ALC260
199 * and the output jack. If this turns out to be the case for all such
200 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
201 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
202 *
203 * The C20x Tablet series have a mono internal speaker which is controlled
204 * via the chip's Mono sum widget and pin complex, so include the necessary
205 * controls for such models. On models without a "mono speaker" the control
206 * won't do anything.
207 */
208static const struct snd_kcontrol_new alc260_acer_mixer[] = {
209 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
211 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
212 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
213 HDA_OUTPUT),
214 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
215 HDA_INPUT),
216 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
217 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
219 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
220 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
221 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
222 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
223 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
224 { } /* end */
225};
226
227/* Maxdata Favorit 100XS: one output and one input (0x12) jack
228 */
229static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
230 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
231 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
232 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
233 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
234 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
235 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
236 { } /* end */
237};
238
239/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
240 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
241 */
242static const struct snd_kcontrol_new alc260_will_mixer[] = {
243 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
244 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
246 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
247 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
248 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
249 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
250 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
251 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
252 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
253 { } /* end */
254};
255
256/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
257 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
258 */
259static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
260 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
261 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
262 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
263 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
264 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
265 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
266 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
267 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
268 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
269 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
270 { } /* end */
271};
272
273/*
274 * initialization verbs
275 */
276static const struct hda_verb alc260_init_verbs[] = {
277 /* Line In pin widget for input */
278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
279 /* CD pin widget for input */
280 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
281 /* Mic1 (rear panel) pin widget for input and vref at 80% */
282 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
283 /* Mic2 (front panel) pin widget for input and vref at 80% */
284 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
285 /* LINE-2 is used for line-out in rear */
286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
287 /* select line-out */
288 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
289 /* LINE-OUT pin */
290 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
291 /* enable HP */
292 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
293 /* enable Mono */
294 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
295 /* mute capture amp left and right */
296 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
297 /* set connection select to line in (default select for this ADC) */
298 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
299 /* mute capture amp left and right */
300 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
301 /* set connection select to line in (default select for this ADC) */
302 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
303 /* set vol=0 Line-Out mixer amp left and right */
304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
305 /* unmute pin widget amp left and right (no gain on this amp) */
306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
307 /* set vol=0 HP mixer amp left and right */
308 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
309 /* unmute pin widget amp left and right (no gain on this amp) */
310 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
311 /* set vol=0 Mono mixer amp left and right */
312 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
313 /* unmute pin widget amp left and right (no gain on this amp) */
314 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
315 /* unmute LINE-2 out pin */
316 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
317 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
318 * Line In 2 = 0x03
319 */
320 /* mute analog inputs */
321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
322 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
326 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
327 /* mute Front out path */
328 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
329 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
330 /* mute Headphone out path */
331 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
332 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
333 /* mute Mono out path */
334 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
335 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
336 { }
337};
338
339/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
340 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
341 * audio = 0x16, internal speaker = 0x10.
342 */
343static const struct hda_verb alc260_fujitsu_init_verbs[] = {
344 /* Disable all GPIOs */
345 {0x01, AC_VERB_SET_GPIO_MASK, 0},
346 /* Internal speaker is connected to headphone pin */
347 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
348 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
350 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
351 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
352 /* Ensure all other unused pins are disabled and muted. */
353 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
355 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
356 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
357 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
358 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
359 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
361
362 /* Disable digital (SPDIF) pins */
363 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
364 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
365
366 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
367 * when acting as an output.
368 */
369 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
370
371 /* Start with output sum widgets muted and their output gains at min */
372 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
377 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
378 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
379 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
380 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
381
382 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
383 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
384 /* Unmute Line1 pin widget output buffer since it starts as an output.
385 * If the pin mode is changed by the user the pin mode control will
386 * take care of enabling the pin's input/output buffers as needed.
387 * Therefore there's no need to enable the input buffer at this
388 * stage.
389 */
390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
391 /* Unmute input buffer of pin widget used for Line-in (no equiv
392 * mixer ctrl)
393 */
394 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
395
396 /* Mute capture amp left and right */
397 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
398 /* Set ADC connection select to match default mixer setting - line
399 * in (on mic1 pin)
400 */
401 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
402
403 /* Do the same for the second ADC: mute capture input amp and
404 * set ADC connection to line in (on mic1 pin)
405 */
406 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
407 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
408
409 /* Mute all inputs to mixer widget (even unconnected ones) */
410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
414 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
415 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
416 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
418
419 { }
420};
421
422/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
423 * similar laptops (adapted from Fujitsu init verbs).
424 */
425static const struct hda_verb alc260_acer_init_verbs[] = {
426 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
427 * the headphone jack. Turn this on and rely on the standard mute
428 * methods whenever the user wants to turn these outputs off.
429 */
430 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
431 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
432 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
433 /* Internal speaker/Headphone jack is connected to Line-out pin */
434 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
435 /* Internal microphone/Mic jack is connected to Mic1 pin */
436 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
437 /* Line In jack is connected to Line1 pin */
438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
439 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
440 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
441 /* Ensure all other unused pins are disabled and muted. */
442 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
443 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
444 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
445 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
448 /* Disable digital (SPDIF) pins */
449 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
450 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
451
452 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
453 * bus when acting as outputs.
454 */
455 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
456 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
457
458 /* Start with output sum widgets muted and their output gains at min */
459 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
461 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
464 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
465 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
466 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
467 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
468
469 /* Unmute Line-out pin widget amp left and right
470 * (no equiv mixer ctrl)
471 */
472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
473 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
474 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
475 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
476 * inputs. If the pin mode is changed by the user the pin mode control
477 * will take care of enabling the pin's input/output buffers as needed.
478 * Therefore there's no need to enable the input buffer at this
479 * stage.
480 */
481 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
483
484 /* Mute capture amp left and right */
485 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
486 /* Set ADC connection select to match default mixer setting - mic
487 * (on mic1 pin)
488 */
489 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
490
491 /* Do similar with the second ADC: mute capture input amp and
492 * set ADC connection to mic to match ALSA's default state.
493 */
494 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
495 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
496
497 /* Mute all inputs to mixer widget (even unconnected ones) */
498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
506
507 { }
508};
509
510/* Initialisation sequence for Maxdata Favorit 100XS
511 * (adapted from Acer init verbs).
512 */
513static const struct hda_verb alc260_favorit100_init_verbs[] = {
514 /* GPIO 0 enables the output jack.
515 * Turn this on and rely on the standard mute
516 * methods whenever the user wants to turn these outputs off.
517 */
518 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
519 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
520 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
521 /* Line/Mic input jack is connected to Mic1 pin */
522 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
523 /* Ensure all other unused pins are disabled and muted. */
524 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
525 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
526 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
527 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
528 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
529 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
532 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
533 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
534 /* Disable digital (SPDIF) pins */
535 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
536 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
537
538 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
539 * bus when acting as outputs.
540 */
541 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
542 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
543
544 /* Start with output sum widgets muted and their output gains at min */
545 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
547 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
549 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
551 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
552 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
553 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
554
555 /* Unmute Line-out pin widget amp left and right
556 * (no equiv mixer ctrl)
557 */
558 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
559 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
560 * inputs. If the pin mode is changed by the user the pin mode control
561 * will take care of enabling the pin's input/output buffers as needed.
562 * Therefore there's no need to enable the input buffer at this
563 * stage.
564 */
565 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
566
567 /* Mute capture amp left and right */
568 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
569 /* Set ADC connection select to match default mixer setting - mic
570 * (on mic1 pin)
571 */
572 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
573
574 /* Do similar with the second ADC: mute capture input amp and
575 * set ADC connection to mic to match ALSA's default state.
576 */
577 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
578 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
579
580 /* Mute all inputs to mixer widget (even unconnected ones) */
581 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
582 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
583 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
584 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
585 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
588 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
589
590 { }
591};
592
593static const struct hda_verb alc260_will_verbs[] = {
594 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
595 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
596 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
597 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
598 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
599 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
600 {}
601};
602
603static const struct hda_verb alc260_replacer_672v_verbs[] = {
604 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
605 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
606 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
607
608 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
609 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
610 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
611
612 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
613 {}
614};
615
616/* toggle speaker-output according to the hp-jack state */
617static void alc260_replacer_672v_automute(struct hda_codec *codec)
618{
619 unsigned int present;
620
621 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
622 present = snd_hda_jack_detect(codec, 0x0f);
623 if (present) {
624 snd_hda_codec_write_cache(codec, 0x01, 0,
625 AC_VERB_SET_GPIO_DATA, 1);
626 snd_hda_codec_write_cache(codec, 0x0f, 0,
627 AC_VERB_SET_PIN_WIDGET_CONTROL,
628 PIN_HP);
629 } else {
630 snd_hda_codec_write_cache(codec, 0x01, 0,
631 AC_VERB_SET_GPIO_DATA, 0);
632 snd_hda_codec_write_cache(codec, 0x0f, 0,
633 AC_VERB_SET_PIN_WIDGET_CONTROL,
634 PIN_OUT);
635 }
636}
637
638static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
639 unsigned int res)
640{
641 if ((res >> 26) == ALC_HP_EVENT)
642 alc260_replacer_672v_automute(codec);
643}
644
645static const struct hda_verb alc260_hp_dc7600_verbs[] = {
646 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
647 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
648 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
650 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
652 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
653 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
654 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
655 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
656 {}
657};
658
659/* Test configuration for debugging, modelled after the ALC880 test
660 * configuration.
661 */
662#ifdef CONFIG_SND_DEBUG
663static const hda_nid_t alc260_test_dac_nids[1] = {
664 0x02,
665};
666static const hda_nid_t alc260_test_adc_nids[2] = {
667 0x04, 0x05,
668};
669/* For testing the ALC260, each input MUX needs its own definition since
670 * the signal assignments are different. This assumes that the first ADC
671 * is NID 0x04.
672 */
673static const struct hda_input_mux alc260_test_capture_sources[2] = {
674 {
675 .num_items = 7,
676 .items = {
677 { "MIC1 pin", 0x0 },
678 { "MIC2 pin", 0x1 },
679 { "LINE1 pin", 0x2 },
680 { "LINE2 pin", 0x3 },
681 { "CD pin", 0x4 },
682 { "LINE-OUT pin", 0x5 },
683 { "HP-OUT pin", 0x6 },
684 },
685 },
686 {
687 .num_items = 8,
688 .items = {
689 { "MIC1 pin", 0x0 },
690 { "MIC2 pin", 0x1 },
691 { "LINE1 pin", 0x2 },
692 { "LINE2 pin", 0x3 },
693 { "CD pin", 0x4 },
694 { "Mixer", 0x5 },
695 { "LINE-OUT pin", 0x6 },
696 { "HP-OUT pin", 0x7 },
697 },
698 },
699};
700static const struct snd_kcontrol_new alc260_test_mixer[] = {
701 /* Output driver widgets */
702 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
703 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
704 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
705 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
706 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
707 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
708
709 /* Modes for retasking pin widgets
710 * Note: the ALC260 doesn't seem to act on requests to enable mic
711 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
712 * mention this restriction. At this stage it's not clear whether
713 * this behaviour is intentional or is a hardware bug in chip
714 * revisions available at least up until early 2006. Therefore for
715 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
716 * choices, but if it turns out that the lack of mic bias for these
717 * NIDs is intentional we could change their modes from
718 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
719 */
720 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
721 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
722 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
723 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
724 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
725 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
726
727 /* Loopback mixer controls */
728 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
729 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
730 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
731 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
732 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
733 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
734 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
735 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
736 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
737 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
738 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
739 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
740 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
741 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
742
743 /* Controls for GPIO pins, assuming they are configured as outputs */
744 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
745 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
746 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
747 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
748
749 /* Switches to allow the digital IO pins to be enabled. The datasheet
750 * is ambigious as to which NID is which; testing on laptops which
751 * make this output available should provide clarification.
752 */
753 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
754 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
755
756 /* A switch allowing EAPD to be enabled. Some laptops seem to use
757 * this output to turn on an external amplifier.
758 */
759 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
760 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
761
762 { } /* end */
763};
764static const struct hda_verb alc260_test_init_verbs[] = {
765 /* Enable all GPIOs as outputs with an initial value of 0 */
766 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
767 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
768 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
769
770 /* Enable retasking pins as output, initially without power amp */
771 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
772 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
775 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
776 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
777
778 /* Disable digital (SPDIF) pins initially, but users can enable
779 * them via a mixer switch. In the case of SPDIF-out, this initverb
780 * payload also sets the generation to 0, output to be in "consumer"
781 * PCM format, copyright asserted, no pre-emphasis and no validity
782 * control.
783 */
784 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
785 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
786
787 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
788 * OUT1 sum bus when acting as an output.
789 */
790 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
791 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
792 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
793 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
794
795 /* Start with output sum widgets muted and their output gains at min */
796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
797 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
798 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
799 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
800 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
802 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
803 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
804 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
805
806 /* Unmute retasking pin widget output buffers since the default
807 * state appears to be output. As the pin mode is changed by the
808 * user the pin mode control will take care of enabling the pin's
809 * input/output buffers as needed.
810 */
811 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
815 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
816 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
817 /* Also unmute the mono-out pin widget */
818 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
819
820 /* Mute capture amp left and right */
821 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
822 /* Set ADC connection select to match default mixer setting (mic1
823 * pin)
824 */
825 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
826
827 /* Do the same for the second ADC: mute capture input amp and
828 * set ADC connection to mic1 pin
829 */
830 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
831 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
832
833 /* Mute all inputs to mixer widget (even unconnected ones) */
834 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
835 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
836 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
837 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
838 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
839 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
840 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
842
843 { }
844};
845#endif
846
847/*
848 * ALC260 configurations
849 */
850static const char * const alc260_models[ALC260_MODEL_LAST] = {
851 [ALC260_BASIC] = "basic",
852 [ALC260_FUJITSU_S702X] = "fujitsu",
853 [ALC260_ACER] = "acer",
854 [ALC260_WILL] = "will",
855 [ALC260_REPLACER_672V] = "replacer",
856 [ALC260_FAVORIT100] = "favorit100",
857#ifdef CONFIG_SND_DEBUG
858 [ALC260_TEST] = "test",
859#endif
860 [ALC260_AUTO] = "auto",
861};
862
863static const struct snd_pci_quirk alc260_cfg_tbl[] = {
864 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
865 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
866 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
867 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
868 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
869 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
870 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
871 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
872 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
873 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
874 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
875 {}
876};
877
878static const struct alc_config_preset alc260_presets[] = {
879 [ALC260_BASIC] = {
880 .mixers = { alc260_base_output_mixer,
881 alc260_input_mixer },
882 .init_verbs = { alc260_init_verbs },
883 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
884 .dac_nids = alc260_dac_nids,
885 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
886 .adc_nids = alc260_dual_adc_nids,
887 .num_channel_mode = ARRAY_SIZE(alc260_modes),
888 .channel_mode = alc260_modes,
889 .input_mux = &alc260_capture_source,
890 },
891 [ALC260_FUJITSU_S702X] = {
892 .mixers = { alc260_fujitsu_mixer },
893 .init_verbs = { alc260_fujitsu_init_verbs },
894 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
895 .dac_nids = alc260_dac_nids,
896 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
897 .adc_nids = alc260_dual_adc_nids,
898 .num_channel_mode = ARRAY_SIZE(alc260_modes),
899 .channel_mode = alc260_modes,
900 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
901 .input_mux = alc260_fujitsu_capture_sources,
902 },
903 [ALC260_ACER] = {
904 .mixers = { alc260_acer_mixer },
905 .init_verbs = { alc260_acer_init_verbs },
906 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
907 .dac_nids = alc260_dac_nids,
908 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
909 .adc_nids = alc260_dual_adc_nids,
910 .num_channel_mode = ARRAY_SIZE(alc260_modes),
911 .channel_mode = alc260_modes,
912 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
913 .input_mux = alc260_acer_capture_sources,
914 },
915 [ALC260_FAVORIT100] = {
916 .mixers = { alc260_favorit100_mixer },
917 .init_verbs = { alc260_favorit100_init_verbs },
918 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
919 .dac_nids = alc260_dac_nids,
920 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
921 .adc_nids = alc260_dual_adc_nids,
922 .num_channel_mode = ARRAY_SIZE(alc260_modes),
923 .channel_mode = alc260_modes,
924 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
925 .input_mux = alc260_favorit100_capture_sources,
926 },
927 [ALC260_WILL] = {
928 .mixers = { alc260_will_mixer },
929 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
930 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
931 .dac_nids = alc260_dac_nids,
932 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
933 .adc_nids = alc260_adc_nids,
934 .dig_out_nid = ALC260_DIGOUT_NID,
935 .num_channel_mode = ARRAY_SIZE(alc260_modes),
936 .channel_mode = alc260_modes,
937 .input_mux = &alc260_capture_source,
938 },
939 [ALC260_REPLACER_672V] = {
940 .mixers = { alc260_replacer_672v_mixer },
941 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
942 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
943 .dac_nids = alc260_dac_nids,
944 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
945 .adc_nids = alc260_adc_nids,
946 .dig_out_nid = ALC260_DIGOUT_NID,
947 .num_channel_mode = ARRAY_SIZE(alc260_modes),
948 .channel_mode = alc260_modes,
949 .input_mux = &alc260_capture_source,
950 .unsol_event = alc260_replacer_672v_unsol_event,
951 .init_hook = alc260_replacer_672v_automute,
952 },
953#ifdef CONFIG_SND_DEBUG
954 [ALC260_TEST] = {
955 .mixers = { alc260_test_mixer },
956 .init_verbs = { alc260_test_init_verbs },
957 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
958 .dac_nids = alc260_test_dac_nids,
959 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
960 .adc_nids = alc260_test_adc_nids,
961 .num_channel_mode = ARRAY_SIZE(alc260_modes),
962 .channel_mode = alc260_modes,
963 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
964 .input_mux = alc260_test_capture_sources,
965 },
966#endif
967};
968
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
deleted file mode 100644
index 501501ef36a9..000000000000
--- a/sound/pci/hda/alc880_quirks.c
+++ /dev/null
@@ -1,1707 +0,0 @@
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,
13 ALC880_W810,
14 ALC880_Z71V,
15 ALC880_6ST,
16 ALC880_6ST_DIG,
17 ALC880_F1734,
18 ALC880_ASUS,
19 ALC880_ASUS_DIG,
20 ALC880_ASUS_W1V,
21 ALC880_ASUS_DIG2,
22 ALC880_FUJITSU,
23 ALC880_UNIWILL_DIG,
24 ALC880_UNIWILL,
25 ALC880_UNIWILL_P53,
26 ALC880_CLEVO,
27 ALC880_TCL_S700,
28 ALC880_LG,
29#ifdef CONFIG_SND_DEBUG
30 ALC880_TEST,
31#endif
32 ALC880_MODEL_LAST /* last tag */
33};
34
35/*
36 * ALC880 3-stack model
37 *
38 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
39 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
40 * F-Mic = 0x1b, HP = 0x19
41 */
42
43static const hda_nid_t alc880_dac_nids[4] = {
44 /* front, rear, clfe, rear_surr */
45 0x02, 0x05, 0x04, 0x03
46};
47
48static const hda_nid_t alc880_adc_nids[3] = {
49 /* ADC0-2 */
50 0x07, 0x08, 0x09,
51};
52
53/* The datasheet says the node 0x07 is connected from inputs,
54 * but it shows zero connection in the real implementation on some devices.
55 * Note: this is a 915GAV bug, fixed on 915GLV
56 */
57static const hda_nid_t alc880_adc_nids_alt[2] = {
58 /* ADC1-2 */
59 0x08, 0x09,
60};
61
62#define ALC880_DIGOUT_NID 0x06
63#define ALC880_DIGIN_NID 0x0a
64#define ALC880_PIN_CD_NID 0x1c
65
66static const struct hda_input_mux alc880_capture_source = {
67 .num_items = 4,
68 .items = {
69 { "Mic", 0x0 },
70 { "Front Mic", 0x3 },
71 { "Line", 0x2 },
72 { "CD", 0x4 },
73 },
74};
75
76/* channel source setting (2/6 channel selection for 3-stack) */
77/* 2ch mode */
78static const struct hda_verb alc880_threestack_ch2_init[] = {
79 /* set line-in to input, mute it */
80 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
81 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
82 /* set mic-in to input vref 80%, mute it */
83 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
84 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
85 { } /* end */
86};
87
88/* 6ch mode */
89static const struct hda_verb alc880_threestack_ch6_init[] = {
90 /* set line-in to output, unmute it */
91 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
92 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
93 /* set mic-in to output, unmute it */
94 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
95 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
96 { } /* end */
97};
98
99static const struct hda_channel_mode alc880_threestack_modes[2] = {
100 { 2, alc880_threestack_ch2_init },
101 { 6, alc880_threestack_ch6_init },
102};
103
104static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
105 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
106 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
107 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
108 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
109 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
110 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
111 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
112 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
113 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
114 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
115 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
116 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
122 {
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
124 .name = "Channel Mode",
125 .info = alc_ch_mode_info,
126 .get = alc_ch_mode_get,
127 .put = alc_ch_mode_put,
128 },
129 { } /* end */
130};
131
132/*
133 * ALC880 5-stack model
134 *
135 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
136 * Side = 0x02 (0xd)
137 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
138 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
139 */
140
141/* additional mixers to alc880_three_stack_mixer */
142static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
143 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
144 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
145 { } /* end */
146};
147
148/* channel source setting (6/8 channel selection for 5-stack) */
149/* 6ch mode */
150static const struct hda_verb alc880_fivestack_ch6_init[] = {
151 /* set line-in to input, mute it */
152 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
153 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
154 { } /* end */
155};
156
157/* 8ch mode */
158static const struct hda_verb alc880_fivestack_ch8_init[] = {
159 /* set line-in to output, unmute it */
160 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
161 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
162 { } /* end */
163};
164
165static const struct hda_channel_mode alc880_fivestack_modes[2] = {
166 { 6, alc880_fivestack_ch6_init },
167 { 8, alc880_fivestack_ch8_init },
168};
169
170
171/*
172 * ALC880 6-stack model
173 *
174 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
175 * Side = 0x05 (0x0f)
176 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
177 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
178 */
179
180static const hda_nid_t alc880_6st_dac_nids[4] = {
181 /* front, rear, clfe, rear_surr */
182 0x02, 0x03, 0x04, 0x05
183};
184
185static const struct hda_input_mux alc880_6stack_capture_source = {
186 .num_items = 4,
187 .items = {
188 { "Mic", 0x0 },
189 { "Front Mic", 0x1 },
190 { "Line", 0x2 },
191 { "CD", 0x4 },
192 },
193};
194
195/* fixed 8-channels */
196static const struct hda_channel_mode alc880_sixstack_modes[1] = {
197 { 8, NULL },
198};
199
200static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
204 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
205 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
206 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
207 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
208 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
209 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
212 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
213 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
214 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
217 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
218 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
219 {
220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
221 .name = "Channel Mode",
222 .info = alc_ch_mode_info,
223 .get = alc_ch_mode_get,
224 .put = alc_ch_mode_put,
225 },
226 { } /* end */
227};
228
229
230/*
231 * ALC880 W810 model
232 *
233 * W810 has rear IO for:
234 * Front (DAC 02)
235 * Surround (DAC 03)
236 * Center/LFE (DAC 04)
237 * Digital out (06)
238 *
239 * The system also has a pair of internal speakers, and a headphone jack.
240 * These are both connected to Line2 on the codec, hence to DAC 02.
241 *
242 * There is a variable resistor to control the speaker or headphone
243 * volume. This is a hardware-only device without a software API.
244 *
245 * Plugging headphones in will disable the internal speakers. This is
246 * implemented in hardware, not via the driver using jack sense. In
247 * a similar fashion, plugging into the rear socket marked "front" will
248 * disable both the speakers and headphones.
249 *
250 * For input, there's a microphone jack, and an "audio in" jack.
251 * These may not do anything useful with this driver yet, because I
252 * haven't setup any initialization verbs for these yet...
253 */
254
255static const hda_nid_t alc880_w810_dac_nids[3] = {
256 /* front, rear/surround, clfe */
257 0x02, 0x03, 0x04
258};
259
260/* fixed 6 channels */
261static const struct hda_channel_mode alc880_w810_modes[1] = {
262 { 6, NULL }
263};
264
265/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
266static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
270 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
273 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
274 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
276 { } /* end */
277};
278
279
280/*
281 * Z710V model
282 *
283 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
284 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
285 * Line = 0x1a
286 */
287
288static const hda_nid_t alc880_z71v_dac_nids[1] = {
289 0x02
290};
291#define ALC880_Z71V_HP_DAC 0x03
292
293/* fixed 2 channels */
294static const struct hda_channel_mode alc880_2_jack_modes[1] = {
295 { 2, NULL }
296};
297
298static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
300 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
301 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
302 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
303 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
304 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
307 { } /* end */
308};
309
310
311/*
312 * ALC880 F1734 model
313 *
314 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
315 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
316 */
317
318static const hda_nid_t alc880_f1734_dac_nids[1] = {
319 0x03
320};
321#define ALC880_F1734_HP_DAC 0x02
322
323static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
325 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
327 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
328 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
329 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
332 { } /* end */
333};
334
335static const struct hda_input_mux alc880_f1734_capture_source = {
336 .num_items = 2,
337 .items = {
338 { "Mic", 0x1 },
339 { "CD", 0x4 },
340 },
341};
342
343
344/*
345 * ALC880 ASUS model
346 *
347 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
348 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
349 * Mic = 0x18, Line = 0x1a
350 */
351
352#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
353#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
354
355static const struct snd_kcontrol_new alc880_asus_mixer[] = {
356 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
357 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
358 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
359 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
360 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
361 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
362 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
363 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
364 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
365 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
366 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
367 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
369 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
370 {
371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
372 .name = "Channel Mode",
373 .info = alc_ch_mode_info,
374 .get = alc_ch_mode_get,
375 .put = alc_ch_mode_put,
376 },
377 { } /* end */
378};
379
380/*
381 * ALC880 ASUS W1V model
382 *
383 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
384 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
385 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
386 */
387
388/* additional mixers to alc880_asus_mixer */
389static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
390 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
391 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
392 { } /* end */
393};
394
395/* TCL S700 */
396static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
398 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
401 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
404 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
406 { } /* end */
407};
408
409/* Uniwill */
410static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
411 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
412 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
414 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
415 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
417 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
418 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
427 {
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
429 .name = "Channel Mode",
430 .info = alc_ch_mode_info,
431 .get = alc_ch_mode_get,
432 .put = alc_ch_mode_put,
433 },
434 { } /* end */
435};
436
437static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
439 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
440 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
441 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
444 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
445 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
446 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
447 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
448 { } /* end */
449};
450
451static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
452 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
453 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
454 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
458 { } /* end */
459};
460
461/*
462 * initialize the codec volumes, etc
463 */
464
465/*
466 * generic initialization of ADC, input mixers and output mixers
467 */
468static const struct hda_verb alc880_volume_init_verbs[] = {
469 /*
470 * Unmute ADC0-2 and set the default input to mic-in
471 */
472 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
474 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
475 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
476 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
477 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
478
479 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
480 * mixer widget
481 * Note: PASD motherboards uses the Line In 2 as the input for front
482 * panel mic (mic 2)
483 */
484 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
492
493 /*
494 * Set up output mixers (0x0c - 0x0f)
495 */
496 /* set vol=0 to output mixers */
497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
498 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
501 /* set up input amps for analog loopback */
502 /* Amp Indices: DAC = 0, mixer = 1 */
503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
504 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
508 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
511
512 { }
513};
514
515/*
516 * 3-stack pin configuration:
517 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
518 */
519static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
520 /*
521 * preset connection lists of input pins
522 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
523 */
524 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
525 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
526 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
527
528 /*
529 * Set pin mode and muting
530 */
531 /* set front pin widgets 0x14 for output */
532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
534 /* Mic1 (rear panel) pin widget for input and vref at 80% */
535 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
536 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
537 /* Mic2 (as headphone out) for HP output */
538 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
539 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
540 /* Line In pin widget for input */
541 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
542 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
543 /* Line2 (as front mic) pin widget for input and vref at 80% */
544 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
545 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
546 /* CD pin widget for input */
547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
548
549 { }
550};
551
552/*
553 * 5-stack pin configuration:
554 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
555 * line-in/side = 0x1a, f-mic = 0x1b
556 */
557static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
558 /*
559 * preset connection lists of input pins
560 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
561 */
562 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
563 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
564
565 /*
566 * Set pin mode and muting
567 */
568 /* set pin widgets 0x14-0x17 for output */
569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
571 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
572 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
573 /* unmute pins for output (no gain on this amp) */
574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
578
579 /* Mic1 (rear panel) pin widget for input and vref at 80% */
580 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
581 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
582 /* Mic2 (as headphone out) for HP output */
583 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
584 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
585 /* Line In pin widget for input */
586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
587 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
588 /* Line2 (as front mic) pin widget for input and vref at 80% */
589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
590 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
591 /* CD pin widget for input */
592 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
593
594 { }
595};
596
597/*
598 * W810 pin configuration:
599 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
600 */
601static const struct hda_verb alc880_pin_w810_init_verbs[] = {
602 /* hphone/speaker input selector: front DAC */
603 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
604
605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
609 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
610 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611
612 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
613 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
614
615 { }
616};
617
618/*
619 * Z71V pin configuration:
620 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
621 */
622static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
624 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627
628 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
631 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
632
633 { }
634};
635
636/*
637 * 6-stack pin configuration:
638 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
639 * f-mic = 0x19, line = 0x1a, HP = 0x1b
640 */
641static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
642 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
643
644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
648 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
650 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
652
653 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
654 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
655 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
657 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
658 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
661 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
662
663 { }
664};
665
666/*
667 * Uniwill pin configuration:
668 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
669 * line = 0x1a
670 */
671static const struct hda_verb alc880_uniwill_init_verbs[] = {
672 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
673
674 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
675 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
678 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
680 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
681 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
684 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
686 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
688
689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
691 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
692 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
695 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
696 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
697 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
698
699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
700 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
701
702 { }
703};
704
705/*
706* Uniwill P53
707* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
708 */
709static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
710 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
711
712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
713 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
715 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
716 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
717 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
724
725 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
726 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
727 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
728 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
729 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
730 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
731
732 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
733 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
734
735 { }
736};
737
738static const struct hda_verb alc880_beep_init_verbs[] = {
739 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
740 { }
741};
742
743static void alc880_uniwill_setup(struct hda_codec *codec)
744{
745 struct alc_spec *spec = codec->spec;
746
747 spec->autocfg.hp_pins[0] = 0x14;
748 spec->autocfg.speaker_pins[0] = 0x15;
749 spec->autocfg.speaker_pins[0] = 0x16;
750 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
751}
752
753static void alc880_uniwill_init_hook(struct hda_codec *codec)
754{
755 alc_hp_automute(codec);
756 alc88x_simple_mic_automute(codec);
757}
758
759static void alc880_uniwill_unsol_event(struct hda_codec *codec,
760 unsigned int res)
761{
762 /* Looks like the unsol event is incompatible with the standard
763 * definition. 4bit tag is placed at 28 bit!
764 */
765 res >>= 28;
766 switch (res) {
767 case ALC_MIC_EVENT:
768 alc88x_simple_mic_automute(codec);
769 break;
770 default:
771 alc_exec_unsol_event(codec, res);
772 break;
773 }
774}
775
776static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
777{
778 alc_exec_unsol_event(codec, res >> 28);
779}
780
781static void alc880_uniwill_p53_setup(struct hda_codec *codec)
782{
783 struct alc_spec *spec = codec->spec;
784
785 spec->autocfg.hp_pins[0] = 0x14;
786 spec->autocfg.speaker_pins[0] = 0x15;
787 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
788}
789
790static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
791{
792 unsigned int present;
793
794 present = snd_hda_codec_read(codec, 0x21, 0,
795 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
796 present &= HDA_AMP_VOLMASK;
797 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
798 HDA_AMP_VOLMASK, present);
799 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
800 HDA_AMP_VOLMASK, present);
801}
802
803static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
804 unsigned int res)
805{
806 /* Looks like the unsol event is incompatible with the standard
807 * definition. 4bit tag is placed at 28 bit!
808 */
809 res >>= 28;
810 if (res == ALC_DCVOL_EVENT)
811 alc880_uniwill_p53_dcvol_automute(codec);
812 else
813 alc_exec_unsol_event(codec, res);
814}
815
816/*
817 * F1734 pin configuration:
818 * HP = 0x14, speaker-out = 0x15, mic = 0x18
819 */
820static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
821 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
822 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
823 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
824 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
825 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
826
827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
828 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
829 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
831
832 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
834 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
836 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
837 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
838 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
839 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
840 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
841
842 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
843 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
844
845 { }
846};
847
848/*
849 * ASUS pin configuration:
850 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
851 */
852static const struct hda_verb alc880_pin_asus_init_verbs[] = {
853 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
854 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
855 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
856 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
857
858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
860 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
862 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
864 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
866
867 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
868 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
869 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
871 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
873 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
874 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
875 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
876
877 { }
878};
879
880/* Enable GPIO mask and set output */
881#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
882#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
883#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
884
885/* Clevo m520g init */
886static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
887 /* headphone output */
888 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
889 /* line-out */
890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
891 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
892 /* Line-in */
893 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
894 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895 /* CD */
896 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
897 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
898 /* Mic1 (rear panel) */
899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
900 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
901 /* Mic2 (front panel) */
902 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
903 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
904 /* headphone */
905 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
906 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
907 /* change to EAPD mode */
908 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
909 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
910
911 { }
912};
913
914static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
915 /* change to EAPD mode */
916 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
917 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
918
919 /* Headphone output */
920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
921 /* Front output*/
922 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
923 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
924
925 /* Line In pin widget for input */
926 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
927 /* CD pin widget for input */
928 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
929 /* Mic1 (rear panel) pin widget for input and vref at 80% */
930 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
931
932 /* change to EAPD mode */
933 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
934 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
935
936 { }
937};
938
939/*
940 * LG m1 express dual
941 *
942 * Pin assignment:
943 * Rear Line-In/Out (blue): 0x14
944 * Build-in Mic-In: 0x15
945 * Speaker-out: 0x17
946 * HP-Out (green): 0x1b
947 * Mic-In/Out (red): 0x19
948 * SPDIF-Out: 0x1e
949 */
950
951/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
952static const hda_nid_t alc880_lg_dac_nids[3] = {
953 0x05, 0x02, 0x03
954};
955
956/* seems analog CD is not working */
957static const struct hda_input_mux alc880_lg_capture_source = {
958 .num_items = 3,
959 .items = {
960 { "Mic", 0x1 },
961 { "Line", 0x5 },
962 { "Internal Mic", 0x6 },
963 },
964};
965
966/* 2,4,6 channel modes */
967static const struct hda_verb alc880_lg_ch2_init[] = {
968 /* set line-in and mic-in to input */
969 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
970 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
971 { }
972};
973
974static const struct hda_verb alc880_lg_ch4_init[] = {
975 /* set line-in to out and mic-in to input */
976 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
977 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
978 { }
979};
980
981static const struct hda_verb alc880_lg_ch6_init[] = {
982 /* set line-in and mic-in to output */
983 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
984 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
985 { }
986};
987
988static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
989 { 2, alc880_lg_ch2_init },
990 { 4, alc880_lg_ch4_init },
991 { 6, alc880_lg_ch6_init },
992};
993
994static const struct snd_kcontrol_new alc880_lg_mixer[] = {
995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
996 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
997 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
998 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
999 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1000 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1001 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1002 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1003 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1004 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1005 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1006 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1007 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1008 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1009 {
1010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1011 .name = "Channel Mode",
1012 .info = alc_ch_mode_info,
1013 .get = alc_ch_mode_get,
1014 .put = alc_ch_mode_put,
1015 },
1016 { } /* end */
1017};
1018
1019static const struct hda_verb alc880_lg_init_verbs[] = {
1020 /* set capture source to mic-in */
1021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1022 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1023 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1024 /* mute all amp mixer inputs */
1025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1028 /* line-in to input */
1029 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1030 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1031 /* built-in mic */
1032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1034 /* speaker-out */
1035 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1036 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1037 /* mic-in to input */
1038 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1039 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1040 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1041 /* HP-out */
1042 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1043 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1044 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1045 /* jack sense */
1046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1047 { }
1048};
1049
1050/* toggle speaker-output according to the hp-jack state */
1051static void alc880_lg_setup(struct hda_codec *codec)
1052{
1053 struct alc_spec *spec = codec->spec;
1054
1055 spec->autocfg.hp_pins[0] = 0x1b;
1056 spec->autocfg.speaker_pins[0] = 0x17;
1057 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
1058}
1059
1060#ifdef CONFIG_SND_HDA_POWER_SAVE
1061static const struct hda_amp_list alc880_lg_loopbacks[] = {
1062 { 0x0b, HDA_INPUT, 1 },
1063 { 0x0b, HDA_INPUT, 6 },
1064 { 0x0b, HDA_INPUT, 7 },
1065 { } /* end */
1066};
1067#endif
1068
1069/*
1070 * Test configuration for debugging
1071 *
1072 * Almost all inputs/outputs are enabled. I/O pins can be configured via
1073 * enum controls.
1074 */
1075#ifdef CONFIG_SND_DEBUG
1076static const hda_nid_t alc880_test_dac_nids[4] = {
1077 0x02, 0x03, 0x04, 0x05
1078};
1079
1080static const struct hda_input_mux alc880_test_capture_source = {
1081 .num_items = 7,
1082 .items = {
1083 { "In-1", 0x0 },
1084 { "In-2", 0x1 },
1085 { "In-3", 0x2 },
1086 { "In-4", 0x3 },
1087 { "CD", 0x4 },
1088 { "Front", 0x5 },
1089 { "Surround", 0x6 },
1090 },
1091};
1092
1093static const struct hda_channel_mode alc880_test_modes[4] = {
1094 { 2, NULL },
1095 { 4, NULL },
1096 { 6, NULL },
1097 { 8, NULL },
1098};
1099
1100static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
1101 struct snd_ctl_elem_info *uinfo)
1102{
1103 static const char * const texts[] = {
1104 "N/A", "Line Out", "HP Out",
1105 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1106 };
1107 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1108 uinfo->count = 1;
1109 uinfo->value.enumerated.items = 8;
1110 if (uinfo->value.enumerated.item >= 8)
1111 uinfo->value.enumerated.item = 7;
1112 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1113 return 0;
1114}
1115
1116static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
1117 struct snd_ctl_elem_value *ucontrol)
1118{
1119 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1120 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1121 unsigned int pin_ctl, item = 0;
1122
1123 pin_ctl = snd_hda_codec_read(codec, nid, 0,
1124 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1125 if (pin_ctl & AC_PINCTL_OUT_EN) {
1126 if (pin_ctl & AC_PINCTL_HP_EN)
1127 item = 2;
1128 else
1129 item = 1;
1130 } else if (pin_ctl & AC_PINCTL_IN_EN) {
1131 switch (pin_ctl & AC_PINCTL_VREFEN) {
1132 case AC_PINCTL_VREF_HIZ: item = 3; break;
1133 case AC_PINCTL_VREF_50: item = 4; break;
1134 case AC_PINCTL_VREF_GRD: item = 5; break;
1135 case AC_PINCTL_VREF_80: item = 6; break;
1136 case AC_PINCTL_VREF_100: item = 7; break;
1137 }
1138 }
1139 ucontrol->value.enumerated.item[0] = item;
1140 return 0;
1141}
1142
1143static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
1144 struct snd_ctl_elem_value *ucontrol)
1145{
1146 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1147 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1148 static const unsigned int ctls[] = {
1149 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1150 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1151 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1152 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1153 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1154 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1155 };
1156 unsigned int old_ctl, new_ctl;
1157
1158 old_ctl = snd_hda_codec_read(codec, nid, 0,
1159 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1160 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1161 if (old_ctl != new_ctl) {
1162 int val;
1163 snd_hda_codec_write_cache(codec, nid, 0,
1164 AC_VERB_SET_PIN_WIDGET_CONTROL,
1165 new_ctl);
1166 val = ucontrol->value.enumerated.item[0] >= 3 ?
1167 HDA_AMP_MUTE : 0;
1168 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1169 HDA_AMP_MUTE, val);
1170 return 1;
1171 }
1172 return 0;
1173}
1174
1175static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
1176 struct snd_ctl_elem_info *uinfo)
1177{
1178 static const char * const texts[] = {
1179 "Front", "Surround", "CLFE", "Side"
1180 };
1181 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1182 uinfo->count = 1;
1183 uinfo->value.enumerated.items = 4;
1184 if (uinfo->value.enumerated.item >= 4)
1185 uinfo->value.enumerated.item = 3;
1186 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1187 return 0;
1188}
1189
1190static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
1191 struct snd_ctl_elem_value *ucontrol)
1192{
1193 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1194 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1195 unsigned int sel;
1196
1197 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1198 ucontrol->value.enumerated.item[0] = sel & 3;
1199 return 0;
1200}
1201
1202static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
1203 struct snd_ctl_elem_value *ucontrol)
1204{
1205 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1206 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1207 unsigned int sel;
1208
1209 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1210 if (ucontrol->value.enumerated.item[0] != sel) {
1211 sel = ucontrol->value.enumerated.item[0] & 3;
1212 snd_hda_codec_write_cache(codec, nid, 0,
1213 AC_VERB_SET_CONNECT_SEL, sel);
1214 return 1;
1215 }
1216 return 0;
1217}
1218
1219#define PIN_CTL_TEST(xname,nid) { \
1220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1221 .name = xname, \
1222 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1223 .info = alc_test_pin_ctl_info, \
1224 .get = alc_test_pin_ctl_get, \
1225 .put = alc_test_pin_ctl_put, \
1226 .private_value = nid \
1227 }
1228
1229#define PIN_SRC_TEST(xname,nid) { \
1230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1231 .name = xname, \
1232 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1233 .info = alc_test_pin_src_info, \
1234 .get = alc_test_pin_src_get, \
1235 .put = alc_test_pin_src_put, \
1236 .private_value = nid \
1237 }
1238
1239static const struct snd_kcontrol_new alc880_test_mixer[] = {
1240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1241 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1242 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1243 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1246 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1247 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1248 PIN_CTL_TEST("Front Pin Mode", 0x14),
1249 PIN_CTL_TEST("Surround Pin Mode", 0x15),
1250 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1251 PIN_CTL_TEST("Side Pin Mode", 0x17),
1252 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1253 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1254 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1255 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1256 PIN_SRC_TEST("In-1 Pin Source", 0x18),
1257 PIN_SRC_TEST("In-2 Pin Source", 0x19),
1258 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1259 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1260 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1261 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1262 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1263 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1264 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1265 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1266 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1267 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1268 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1269 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1270 {
1271 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1272 .name = "Channel Mode",
1273 .info = alc_ch_mode_info,
1274 .get = alc_ch_mode_get,
1275 .put = alc_ch_mode_put,
1276 },
1277 { } /* end */
1278};
1279
1280static const struct hda_verb alc880_test_init_verbs[] = {
1281 /* Unmute inputs of 0x0c - 0x0f */
1282 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1284 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1285 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1288 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1289 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1290 /* Vol output for 0x0c-0x0f */
1291 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1292 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1294 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1295 /* Set output pins 0x14-0x17 */
1296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1298 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1299 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1300 /* Unmute output pins 0x14-0x17 */
1301 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1304 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1305 /* Set input pins 0x18-0x1c */
1306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1307 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1308 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1310 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1311 /* Mute input pins 0x18-0x1b */
1312 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1313 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1314 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1316 /* ADC set up */
1317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1318 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1320 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1322 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1323 /* Analog input/passthru */
1324 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1325 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1327 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1328 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1329 { }
1330};
1331#endif
1332
1333/*
1334 */
1335
1336static const char * const alc880_models[ALC880_MODEL_LAST] = {
1337 [ALC880_3ST] = "3stack",
1338 [ALC880_TCL_S700] = "tcl",
1339 [ALC880_3ST_DIG] = "3stack-digout",
1340 [ALC880_CLEVO] = "clevo",
1341 [ALC880_5ST] = "5stack",
1342 [ALC880_5ST_DIG] = "5stack-digout",
1343 [ALC880_W810] = "w810",
1344 [ALC880_Z71V] = "z71v",
1345 [ALC880_6ST] = "6stack",
1346 [ALC880_6ST_DIG] = "6stack-digout",
1347 [ALC880_ASUS] = "asus",
1348 [ALC880_ASUS_W1V] = "asus-w1v",
1349 [ALC880_ASUS_DIG] = "asus-dig",
1350 [ALC880_ASUS_DIG2] = "asus-dig2",
1351 [ALC880_UNIWILL_DIG] = "uniwill",
1352 [ALC880_UNIWILL_P53] = "uniwill-p53",
1353 [ALC880_FUJITSU] = "fujitsu",
1354 [ALC880_F1734] = "F1734",
1355 [ALC880_LG] = "lg",
1356#ifdef CONFIG_SND_DEBUG
1357 [ALC880_TEST] = "test",
1358#endif
1359 [ALC880_AUTO] = "auto",
1360};
1361
1362static const struct snd_pci_quirk alc880_cfg_tbl[] = {
1363 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
1364 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
1365 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
1366 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
1367 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
1368 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
1369 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
1370 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
1371 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
1372 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
1373 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
1374 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
1375 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
1376 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
1377 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
1378 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
1379 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
1380 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
1381 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
1382 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
1383 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
1384 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
1385 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
1386 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
1387 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
1388 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
1389 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
1390 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
1391 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
1392 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
1393 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
1394 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
1395 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
1396 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
1397 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
1398 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
1399 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
1400 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
1401 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
1402 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
1403 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
1404 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
1405 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
1406 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
1407 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
1408 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1409 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
1410 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
1411 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
1412 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
1413 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
1414 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
1415 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
1416 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
1417 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
1418 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
1419 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
1420 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
1421 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
1422 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
1423 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
1424 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
1425 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
1426 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
1427 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
1428 /* default Intel */
1429 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
1430 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
1431 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1432 {}
1433};
1434
1435/*
1436 * ALC880 codec presets
1437 */
1438static const struct alc_config_preset alc880_presets[] = {
1439 [ALC880_3ST] = {
1440 .mixers = { alc880_three_stack_mixer },
1441 .init_verbs = { alc880_volume_init_verbs,
1442 alc880_pin_3stack_init_verbs },
1443 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1444 .dac_nids = alc880_dac_nids,
1445 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1446 .channel_mode = alc880_threestack_modes,
1447 .need_dac_fix = 1,
1448 .input_mux = &alc880_capture_source,
1449 },
1450 [ALC880_3ST_DIG] = {
1451 .mixers = { alc880_three_stack_mixer },
1452 .init_verbs = { alc880_volume_init_verbs,
1453 alc880_pin_3stack_init_verbs },
1454 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1455 .dac_nids = alc880_dac_nids,
1456 .dig_out_nid = ALC880_DIGOUT_NID,
1457 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1458 .channel_mode = alc880_threestack_modes,
1459 .need_dac_fix = 1,
1460 .input_mux = &alc880_capture_source,
1461 },
1462 [ALC880_TCL_S700] = {
1463 .mixers = { alc880_tcl_s700_mixer },
1464 .init_verbs = { alc880_volume_init_verbs,
1465 alc880_pin_tcl_S700_init_verbs,
1466 alc880_gpio2_init_verbs },
1467 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1468 .dac_nids = alc880_dac_nids,
1469 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
1470 .num_adc_nids = 1, /* single ADC */
1471 .hp_nid = 0x03,
1472 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1473 .channel_mode = alc880_2_jack_modes,
1474 .input_mux = &alc880_capture_source,
1475 },
1476 [ALC880_5ST] = {
1477 .mixers = { alc880_three_stack_mixer,
1478 alc880_five_stack_mixer},
1479 .init_verbs = { alc880_volume_init_verbs,
1480 alc880_pin_5stack_init_verbs },
1481 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1482 .dac_nids = alc880_dac_nids,
1483 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1484 .channel_mode = alc880_fivestack_modes,
1485 .input_mux = &alc880_capture_source,
1486 },
1487 [ALC880_5ST_DIG] = {
1488 .mixers = { alc880_three_stack_mixer,
1489 alc880_five_stack_mixer },
1490 .init_verbs = { alc880_volume_init_verbs,
1491 alc880_pin_5stack_init_verbs },
1492 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1493 .dac_nids = alc880_dac_nids,
1494 .dig_out_nid = ALC880_DIGOUT_NID,
1495 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1496 .channel_mode = alc880_fivestack_modes,
1497 .input_mux = &alc880_capture_source,
1498 },
1499 [ALC880_6ST] = {
1500 .mixers = { alc880_six_stack_mixer },
1501 .init_verbs = { alc880_volume_init_verbs,
1502 alc880_pin_6stack_init_verbs },
1503 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1504 .dac_nids = alc880_6st_dac_nids,
1505 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1506 .channel_mode = alc880_sixstack_modes,
1507 .input_mux = &alc880_6stack_capture_source,
1508 },
1509 [ALC880_6ST_DIG] = {
1510 .mixers = { alc880_six_stack_mixer },
1511 .init_verbs = { alc880_volume_init_verbs,
1512 alc880_pin_6stack_init_verbs },
1513 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1514 .dac_nids = alc880_6st_dac_nids,
1515 .dig_out_nid = ALC880_DIGOUT_NID,
1516 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1517 .channel_mode = alc880_sixstack_modes,
1518 .input_mux = &alc880_6stack_capture_source,
1519 },
1520 [ALC880_W810] = {
1521 .mixers = { alc880_w810_base_mixer },
1522 .init_verbs = { alc880_volume_init_verbs,
1523 alc880_pin_w810_init_verbs,
1524 alc880_gpio2_init_verbs },
1525 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1526 .dac_nids = alc880_w810_dac_nids,
1527 .dig_out_nid = ALC880_DIGOUT_NID,
1528 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1529 .channel_mode = alc880_w810_modes,
1530 .input_mux = &alc880_capture_source,
1531 },
1532 [ALC880_Z71V] = {
1533 .mixers = { alc880_z71v_mixer },
1534 .init_verbs = { alc880_volume_init_verbs,
1535 alc880_pin_z71v_init_verbs },
1536 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1537 .dac_nids = alc880_z71v_dac_nids,
1538 .dig_out_nid = ALC880_DIGOUT_NID,
1539 .hp_nid = 0x03,
1540 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1541 .channel_mode = alc880_2_jack_modes,
1542 .input_mux = &alc880_capture_source,
1543 },
1544 [ALC880_F1734] = {
1545 .mixers = { alc880_f1734_mixer },
1546 .init_verbs = { alc880_volume_init_verbs,
1547 alc880_pin_f1734_init_verbs },
1548 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
1549 .dac_nids = alc880_f1734_dac_nids,
1550 .hp_nid = 0x02,
1551 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1552 .channel_mode = alc880_2_jack_modes,
1553 .input_mux = &alc880_f1734_capture_source,
1554 .unsol_event = alc880_uniwill_p53_unsol_event,
1555 .setup = alc880_uniwill_p53_setup,
1556 .init_hook = alc_hp_automute,
1557 },
1558 [ALC880_ASUS] = {
1559 .mixers = { alc880_asus_mixer },
1560 .init_verbs = { alc880_volume_init_verbs,
1561 alc880_pin_asus_init_verbs,
1562 alc880_gpio1_init_verbs },
1563 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1564 .dac_nids = alc880_asus_dac_nids,
1565 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1566 .channel_mode = alc880_asus_modes,
1567 .need_dac_fix = 1,
1568 .input_mux = &alc880_capture_source,
1569 },
1570 [ALC880_ASUS_DIG] = {
1571 .mixers = { alc880_asus_mixer },
1572 .init_verbs = { alc880_volume_init_verbs,
1573 alc880_pin_asus_init_verbs,
1574 alc880_gpio1_init_verbs },
1575 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1576 .dac_nids = alc880_asus_dac_nids,
1577 .dig_out_nid = ALC880_DIGOUT_NID,
1578 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1579 .channel_mode = alc880_asus_modes,
1580 .need_dac_fix = 1,
1581 .input_mux = &alc880_capture_source,
1582 },
1583 [ALC880_ASUS_DIG2] = {
1584 .mixers = { alc880_asus_mixer },
1585 .init_verbs = { alc880_volume_init_verbs,
1586 alc880_pin_asus_init_verbs,
1587 alc880_gpio2_init_verbs }, /* use GPIO2 */
1588 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1589 .dac_nids = alc880_asus_dac_nids,
1590 .dig_out_nid = ALC880_DIGOUT_NID,
1591 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1592 .channel_mode = alc880_asus_modes,
1593 .need_dac_fix = 1,
1594 .input_mux = &alc880_capture_source,
1595 },
1596 [ALC880_ASUS_W1V] = {
1597 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
1598 .init_verbs = { alc880_volume_init_verbs,
1599 alc880_pin_asus_init_verbs,
1600 alc880_gpio1_init_verbs },
1601 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1602 .dac_nids = alc880_asus_dac_nids,
1603 .dig_out_nid = ALC880_DIGOUT_NID,
1604 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1605 .channel_mode = alc880_asus_modes,
1606 .need_dac_fix = 1,
1607 .input_mux = &alc880_capture_source,
1608 },
1609 [ALC880_UNIWILL_DIG] = {
1610 .mixers = { alc880_asus_mixer },
1611 .init_verbs = { alc880_volume_init_verbs,
1612 alc880_pin_asus_init_verbs },
1613 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1614 .dac_nids = alc880_asus_dac_nids,
1615 .dig_out_nid = ALC880_DIGOUT_NID,
1616 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1617 .channel_mode = alc880_asus_modes,
1618 .need_dac_fix = 1,
1619 .input_mux = &alc880_capture_source,
1620 },
1621 [ALC880_UNIWILL] = {
1622 .mixers = { alc880_uniwill_mixer },
1623 .init_verbs = { alc880_volume_init_verbs,
1624 alc880_uniwill_init_verbs },
1625 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1626 .dac_nids = alc880_asus_dac_nids,
1627 .dig_out_nid = ALC880_DIGOUT_NID,
1628 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1629 .channel_mode = alc880_threestack_modes,
1630 .need_dac_fix = 1,
1631 .input_mux = &alc880_capture_source,
1632 .unsol_event = alc880_uniwill_unsol_event,
1633 .setup = alc880_uniwill_setup,
1634 .init_hook = alc880_uniwill_init_hook,
1635 },
1636 [ALC880_UNIWILL_P53] = {
1637 .mixers = { alc880_uniwill_p53_mixer },
1638 .init_verbs = { alc880_volume_init_verbs,
1639 alc880_uniwill_p53_init_verbs },
1640 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1641 .dac_nids = alc880_asus_dac_nids,
1642 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1643 .channel_mode = alc880_threestack_modes,
1644 .input_mux = &alc880_capture_source,
1645 .unsol_event = alc880_uniwill_p53_unsol_event,
1646 .setup = alc880_uniwill_p53_setup,
1647 .init_hook = alc_hp_automute,
1648 },
1649 [ALC880_FUJITSU] = {
1650 .mixers = { alc880_fujitsu_mixer },
1651 .init_verbs = { alc880_volume_init_verbs,
1652 alc880_uniwill_p53_init_verbs,
1653 alc880_beep_init_verbs },
1654 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1655 .dac_nids = alc880_dac_nids,
1656 .dig_out_nid = ALC880_DIGOUT_NID,
1657 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1658 .channel_mode = alc880_2_jack_modes,
1659 .input_mux = &alc880_capture_source,
1660 .unsol_event = alc880_uniwill_p53_unsol_event,
1661 .setup = alc880_uniwill_p53_setup,
1662 .init_hook = alc_hp_automute,
1663 },
1664 [ALC880_CLEVO] = {
1665 .mixers = { alc880_three_stack_mixer },
1666 .init_verbs = { alc880_volume_init_verbs,
1667 alc880_pin_clevo_init_verbs },
1668 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1669 .dac_nids = alc880_dac_nids,
1670 .hp_nid = 0x03,
1671 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1672 .channel_mode = alc880_threestack_modes,
1673 .need_dac_fix = 1,
1674 .input_mux = &alc880_capture_source,
1675 },
1676 [ALC880_LG] = {
1677 .mixers = { alc880_lg_mixer },
1678 .init_verbs = { alc880_volume_init_verbs,
1679 alc880_lg_init_verbs },
1680 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
1681 .dac_nids = alc880_lg_dac_nids,
1682 .dig_out_nid = ALC880_DIGOUT_NID,
1683 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
1684 .channel_mode = alc880_lg_ch_modes,
1685 .need_dac_fix = 1,
1686 .input_mux = &alc880_lg_capture_source,
1687 .unsol_event = alc880_unsol_event,
1688 .setup = alc880_lg_setup,
1689 .init_hook = alc_hp_automute,
1690#ifdef CONFIG_SND_HDA_POWER_SAVE
1691 .loopbacks = alc880_lg_loopbacks,
1692#endif
1693 },
1694#ifdef CONFIG_SND_DEBUG
1695 [ALC880_TEST] = {
1696 .mixers = { alc880_test_mixer },
1697 .init_verbs = { alc880_test_init_verbs },
1698 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
1699 .dac_nids = alc880_test_dac_nids,
1700 .dig_out_nid = ALC880_DIGOUT_NID,
1701 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
1702 .channel_mode = alc880_test_modes,
1703 .input_mux = &alc880_test_capture_source,
1704 },
1705#endif
1706};
1707
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
deleted file mode 100644
index bb364a53f546..000000000000
--- a/sound/pci/hda/alc882_quirks.c
+++ /dev/null
@@ -1,866 +0,0 @@
1/*
2 * ALC882/ALC883/ALC888/ALC889 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC882 models */
7enum {
8 ALC882_AUTO,
9 ALC885_MBA21,
10 ALC885_MBP3,
11 ALC885_MB5,
12 ALC885_MACMINI3,
13 ALC885_IMAC91,
14 ALC889A_MB31,
15 ALC882_MODEL_LAST,
16};
17
18#define ALC882_DIGOUT_NID 0x06
19#define ALC882_DIGIN_NID 0x0a
20#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
21#define ALC883_DIGIN_NID ALC882_DIGIN_NID
22#define ALC1200_DIGOUT_NID 0x10
23
24
25static const struct hda_channel_mode alc882_ch_modes[1] = {
26 { 8, NULL }
27};
28
29/* DACs */
30static const hda_nid_t alc882_dac_nids[4] = {
31 /* front, rear, clfe, rear_surr */
32 0x02, 0x03, 0x04, 0x05
33};
34#define alc883_dac_nids alc882_dac_nids
35
36/* ADCs */
37#define alc882_adc_nids alc880_adc_nids
38#define alc882_adc_nids_alt alc880_adc_nids_alt
39#define alc883_adc_nids alc882_adc_nids_alt
40
41static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
42#define alc883_capsrc_nids alc882_capsrc_nids_alt
43
44/* input MUX */
45/* FIXME: should be a matrix-type input source selection */
46
47static const struct hda_input_mux alc882_capture_source = {
48 .num_items = 4,
49 .items = {
50 { "Mic", 0x0 },
51 { "Front Mic", 0x1 },
52 { "Line", 0x2 },
53 { "CD", 0x4 },
54 },
55};
56
57#define alc883_capture_source alc882_capture_source
58
59static const struct hda_input_mux mb5_capture_source = {
60 .num_items = 3,
61 .items = {
62 { "Mic", 0x1 },
63 { "Line", 0x7 },
64 { "CD", 0x4 },
65 },
66};
67
68static const struct hda_input_mux macmini3_capture_source = {
69 .num_items = 2,
70 .items = {
71 { "Line", 0x2 },
72 { "CD", 0x4 },
73 },
74};
75
76static const struct hda_input_mux alc883_3stack_6ch_intel = {
77 .num_items = 4,
78 .items = {
79 { "Mic", 0x1 },
80 { "Front Mic", 0x0 },
81 { "Line", 0x2 },
82 { "CD", 0x4 },
83 },
84};
85
86static const struct hda_input_mux alc889A_mb31_capture_source = {
87 .num_items = 2,
88 .items = {
89 { "Mic", 0x0 },
90 /* Front Mic (0x01) unused */
91 { "Line", 0x2 },
92 /* Line 2 (0x03) unused */
93 /* CD (0x04) unused? */
94 },
95};
96
97static const struct hda_input_mux alc889A_imac91_capture_source = {
98 .num_items = 2,
99 .items = {
100 { "Mic", 0x01 },
101 { "Line", 0x2 }, /* Not sure! */
102 },
103};
104
105/* Macbook Air 2,1 */
106
107static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
108 { 2, NULL },
109};
110
111/*
112 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
113 */
114
115/*
116 * 2ch mode
117 */
118static const struct hda_verb alc885_mbp_ch2_init[] = {
119 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
120 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
121 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
122 { } /* end */
123};
124
125/*
126 * 4ch mode
127 */
128static const struct hda_verb alc885_mbp_ch4_init[] = {
129 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
130 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
131 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
132 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
133 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
134 { } /* end */
135};
136
137static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
138 { 2, alc885_mbp_ch2_init },
139 { 4, alc885_mbp_ch4_init },
140};
141
142/*
143 * 2ch
144 * Speakers/Woofer/HP = Front
145 * LineIn = Input
146 */
147static const struct hda_verb alc885_mb5_ch2_init[] = {
148 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
149 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
150 { } /* end */
151};
152
153/*
154 * 6ch mode
155 * Speakers/HP = Front
156 * Woofer = LFE
157 * LineIn = Surround
158 */
159static const struct hda_verb alc885_mb5_ch6_init[] = {
160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
162 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
163 { } /* end */
164};
165
166static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
167 { 2, alc885_mb5_ch2_init },
168 { 6, alc885_mb5_ch6_init },
169};
170
171#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
172
173/* Macbook Air 2,1 same control for HP and internal Speaker */
174
175static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
176 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
177 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
178 { }
179};
180
181
182static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
183 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
184 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
185 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
186 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
187 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
188 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
189 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
191 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
192 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
194 { } /* end */
195};
196
197static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
199 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
201 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
202 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
203 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
204 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
205 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
206 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
207 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
208 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
209 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
210 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
212 { } /* end */
213};
214
215static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
216 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
217 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
218 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
219 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
220 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
221 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
222 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
223 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
224 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
225 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
226 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
227 { } /* end */
228};
229
230static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
233 { } /* end */
234};
235
236
237static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
238 {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Channel Mode",
241 .info = alc_ch_mode_info,
242 .get = alc_ch_mode_get,
243 .put = alc_ch_mode_put,
244 },
245 { } /* end */
246};
247
248static const struct hda_verb alc882_base_init_verbs[] = {
249 /* Front mixer: unmute input/output amp left and right (volume = 0) */
250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
252 /* Rear mixer */
253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
255 /* CLFE mixer */
256 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
258 /* Side mixer */
259 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
260 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
261
262 /* Front Pin: output 0 (0x0c) */
263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
264 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
265 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
266 /* Rear Pin: output 1 (0x0d) */
267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
268 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
270 /* CLFE Pin: output 2 (0x0e) */
271 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
272 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
273 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
274 /* Side Pin: output 3 (0x0f) */
275 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
276 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
277 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
278 /* Mic (rear) pin: input vref at 80% */
279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
280 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
281 /* Front Mic pin: input vref at 80% */
282 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
283 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
284 /* Line In pin: input */
285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
286 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
287 /* Line-2 In: Headphone output (output 0 - 0x0c) */
288 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
289 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
290 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
291 /* CD pin widget for input */
292 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
293
294 /* FIXME: use matrix-type input source selection */
295 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
296 /* Input mixer2 */
297 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
298 /* Input mixer3 */
299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
300 /* ADC2: mute amp left and right */
301 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
302 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
303 /* ADC3: mute amp left and right */
304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
305 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
306
307 { }
308};
309
310#define alc883_init_verbs alc882_base_init_verbs
311
312/* Macbook 5,1 */
313static const struct hda_verb alc885_mb5_init_verbs[] = {
314 /* DACs */
315 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
316 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
317 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
318 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
319 /* Front mixer */
320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
321 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
323 /* Surround mixer */
324 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
327 /* LFE mixer */
328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
331 /* HP mixer */
332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
333 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
334 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
335 /* Front Pin (0x0c) */
336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
338 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
339 /* LFE Pin (0x0e) */
340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
341 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
342 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
343 /* HP Pin (0x0f) */
344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
346 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
347 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
348 /* Front Mic pin: input vref at 80% */
349 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
350 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
351 /* Line In pin */
352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
353 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
354
355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
358 { }
359};
360
361/* Macmini 3,1 */
362static const struct hda_verb alc885_macmini3_init_verbs[] = {
363 /* DACs */
364 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
365 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
366 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
367 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
368 /* Front mixer */
369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
372 /* Surround mixer */
373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
376 /* LFE mixer */
377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
380 /* HP mixer */
381 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
383 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
384 /* Front Pin (0x0c) */
385 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
386 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
387 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
388 /* LFE Pin (0x0e) */
389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
390 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
391 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
392 /* HP Pin (0x0f) */
393 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
394 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
395 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
396 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
397 /* Line In pin */
398 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
400
401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
405 { }
406};
407
408
409static const struct hda_verb alc885_mba21_init_verbs[] = {
410 /*Internal and HP Speaker Mixer*/
411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
414 /*Internal Speaker Pin (0x0c)*/
415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
417 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
418 /* HP Pin: output 0 (0x0e) */
419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
420 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
421 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
423 /* Line in (is hp when jack connected)*/
424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
425 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
426
427 { }
428 };
429
430
431/* Macbook Pro rev3 */
432static const struct hda_verb alc885_mbp3_init_verbs[] = {
433 /* Front mixer: unmute input/output amp left and right (volume = 0) */
434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
437 /* Rear mixer */
438 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
439 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
441 /* HP mixer */
442 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
445 /* Front Pin: output 0 (0x0c) */
446 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
448 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
449 /* HP Pin: output 0 (0x0e) */
450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
451 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
452 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
453 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
454 /* Mic (rear) pin: input vref at 80% */
455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
457 /* Front Mic pin: input vref at 80% */
458 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
460 /* Line In pin: use output 1 when in LineOut mode */
461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
463 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
464
465 /* FIXME: use matrix-type input source selection */
466 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
467 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
472 /* Input mixer2 */
473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
477 /* Input mixer3 */
478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
482 /* ADC1: mute amp left and right */
483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
484 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
485 /* ADC2: mute amp left and right */
486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
487 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
488 /* ADC3: mute amp left and right */
489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
490 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
491
492 { }
493};
494
495/* iMac 9,1 */
496static const struct hda_verb alc885_imac91_init_verbs[] = {
497 /* Internal Speaker Pin (0x0c) */
498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
500 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
501 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
503 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
504 /* HP Pin: Rear */
505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
507 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
508 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
509 /* Line in Rear */
510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
512 /* Front Mic pin: input vref at 80% */
513 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
514 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
515 /* Rear mixer */
516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
519 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
523 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
528 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
533 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
538 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
540 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
541 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
543 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
544 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
545 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
546 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
547 { }
548};
549
550/* Toggle speaker-output according to the hp-jack state */
551static void alc885_imac24_setup(struct hda_codec *codec)
552{
553 struct alc_spec *spec = codec->spec;
554
555 spec->autocfg.hp_pins[0] = 0x14;
556 spec->autocfg.speaker_pins[0] = 0x18;
557 spec->autocfg.speaker_pins[1] = 0x1a;
558 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
559}
560
561#define alc885_mb5_setup alc885_imac24_setup
562#define alc885_macmini3_setup alc885_imac24_setup
563
564/* Macbook Air 2,1 */
565static void alc885_mba21_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] = 0x18;
571 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
572}
573
574
575
576static void alc885_mbp3_setup(struct hda_codec *codec)
577{
578 struct alc_spec *spec = codec->spec;
579
580 spec->autocfg.hp_pins[0] = 0x15;
581 spec->autocfg.speaker_pins[0] = 0x14;
582 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
583}
584
585static void alc885_imac91_setup(struct hda_codec *codec)
586{
587 struct alc_spec *spec = codec->spec;
588
589 spec->autocfg.hp_pins[0] = 0x14;
590 spec->autocfg.speaker_pins[0] = 0x18;
591 spec->autocfg.speaker_pins[1] = 0x1a;
592 alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP);
593}
594
595/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
596static const struct hda_verb alc889A_mb31_ch2_init[] = {
597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
601 { } /* end */
602};
603
604/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
605static const struct hda_verb alc889A_mb31_ch4_init[] = {
606 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
607 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
608 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
609 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
610 { } /* end */
611};
612
613/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
614static const struct hda_verb alc889A_mb31_ch5_init[] = {
615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
619 { } /* end */
620};
621
622/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
623static const struct hda_verb alc889A_mb31_ch6_init[] = {
624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
625 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
626 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
627 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
628 { } /* end */
629};
630
631static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
632 { 2, alc889A_mb31_ch2_init },
633 { 4, alc889A_mb31_ch4_init },
634 { 5, alc889A_mb31_ch5_init },
635 { 6, alc889A_mb31_ch6_init },
636};
637
638static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
639 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
640 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
641 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
642 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
643 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
644 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
645 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
646 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
648 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
649 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
650 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
651 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
653 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
654 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
655 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
656 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
657 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
658 { } /* end */
659};
660
661static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
662 /* Output mixers */
663 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
664 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
666 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
668 HDA_OUTPUT),
669 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
671 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
672 /* Output switches */
673 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
674 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
675 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
676 /* Boost mixers */
677 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
678 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
679 /* Input mixers */
680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
682 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
683 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
684 { } /* end */
685};
686
687static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
688 {
689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
690 .name = "Channel Mode",
691 .info = alc_ch_mode_info,
692 .get = alc_ch_mode_get,
693 .put = alc_ch_mode_put,
694 },
695 { } /* end */
696};
697
698static const struct hda_verb alc889A_mb31_verbs[] = {
699 /* Init rear pin (used as headphone output) */
700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
701 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
702 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
703 /* Init line pin (used as output in 4ch and 6ch mode) */
704 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
705 /* Init line 2 pin (used as headphone out by default) */
706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
708 { } /* end */
709};
710
711/* Mute speakers according to the headphone jack state */
712static void alc889A_mb31_automute(struct hda_codec *codec)
713{
714 unsigned int present;
715
716 /* Mute only in 2ch or 4ch mode */
717 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
718 == 0x00) {
719 present = snd_hda_jack_detect(codec, 0x15);
720 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
721 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
722 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
723 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
724 }
725}
726
727static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
728{
729 if ((res >> 26) == ALC_HP_EVENT)
730 alc889A_mb31_automute(codec);
731}
732
733static void alc882_unsol_event(struct hda_codec *codec, unsigned int res)
734{
735 alc_exec_unsol_event(codec, res >> 26);
736}
737
738/*
739 * configuration and preset
740 */
741static const char * const alc882_models[ALC882_MODEL_LAST] = {
742 [ALC885_MB5] = "mb5",
743 [ALC885_MACMINI3] = "macmini3",
744 [ALC885_MBA21] = "mba21",
745 [ALC885_MBP3] = "mbp3",
746 [ALC885_IMAC91] = "imac91",
747 [ALC889A_MB31] = "mb31",
748 [ALC882_AUTO] = "auto",
749};
750
751/* codec SSID table for Intel Mac */
752static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
753 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
754 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
755 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
756 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
757 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
758 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
759 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
760 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
761 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
762 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
763 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
764 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
765 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
766 * so apparently no perfect solution yet
767 */
768 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
769 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
770 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
771 {} /* terminator */
772};
773
774static const struct alc_config_preset alc882_presets[] = {
775 [ALC885_MBA21] = {
776 .mixers = { alc885_mba21_mixer },
777 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
778 .num_dacs = 2,
779 .dac_nids = alc882_dac_nids,
780 .channel_mode = alc885_mba21_ch_modes,
781 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
782 .input_mux = &alc882_capture_source,
783 .unsol_event = alc882_unsol_event,
784 .setup = alc885_mba21_setup,
785 .init_hook = alc_hp_automute,
786 },
787 [ALC885_MBP3] = {
788 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
789 .init_verbs = { alc885_mbp3_init_verbs,
790 alc880_gpio1_init_verbs },
791 .num_dacs = 2,
792 .dac_nids = alc882_dac_nids,
793 .hp_nid = 0x04,
794 .channel_mode = alc885_mbp_4ch_modes,
795 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
796 .input_mux = &alc882_capture_source,
797 .dig_out_nid = ALC882_DIGOUT_NID,
798 .dig_in_nid = ALC882_DIGIN_NID,
799 .unsol_event = alc882_unsol_event,
800 .setup = alc885_mbp3_setup,
801 .init_hook = alc_hp_automute,
802 },
803 [ALC885_MB5] = {
804 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
805 .init_verbs = { alc885_mb5_init_verbs,
806 alc880_gpio1_init_verbs },
807 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
808 .dac_nids = alc882_dac_nids,
809 .channel_mode = alc885_mb5_6ch_modes,
810 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
811 .input_mux = &mb5_capture_source,
812 .dig_out_nid = ALC882_DIGOUT_NID,
813 .dig_in_nid = ALC882_DIGIN_NID,
814 .unsol_event = alc882_unsol_event,
815 .setup = alc885_mb5_setup,
816 .init_hook = alc_hp_automute,
817 },
818 [ALC885_MACMINI3] = {
819 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
820 .init_verbs = { alc885_macmini3_init_verbs,
821 alc880_gpio1_init_verbs },
822 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
823 .dac_nids = alc882_dac_nids,
824 .channel_mode = alc885_macmini3_6ch_modes,
825 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
826 .input_mux = &macmini3_capture_source,
827 .dig_out_nid = ALC882_DIGOUT_NID,
828 .dig_in_nid = ALC882_DIGIN_NID,
829 .unsol_event = alc882_unsol_event,
830 .setup = alc885_macmini3_setup,
831 .init_hook = alc_hp_automute,
832 },
833 [ALC885_IMAC91] = {
834 .mixers = {alc885_imac91_mixer},
835 .init_verbs = { alc885_imac91_init_verbs,
836 alc880_gpio1_init_verbs },
837 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
838 .dac_nids = alc882_dac_nids,
839 .channel_mode = alc885_mba21_ch_modes,
840 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
841 .input_mux = &alc889A_imac91_capture_source,
842 .dig_out_nid = ALC882_DIGOUT_NID,
843 .dig_in_nid = ALC882_DIGIN_NID,
844 .unsol_event = alc882_unsol_event,
845 .setup = alc885_imac91_setup,
846 .init_hook = alc_hp_automute,
847 },
848 [ALC889A_MB31] = {
849 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
850 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
851 alc880_gpio1_init_verbs },
852 .adc_nids = alc883_adc_nids,
853 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
854 .capsrc_nids = alc883_capsrc_nids,
855 .dac_nids = alc883_dac_nids,
856 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
857 .channel_mode = alc889A_mb31_6ch_modes,
858 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
859 .input_mux = &alc889A_mb31_capture_source,
860 .dig_out_nid = ALC883_DIGOUT_NID,
861 .unsol_event = alc889A_mb31_unsol_event,
862 .init_hook = alc889A_mb31_automute,
863 },
864};
865
866
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
deleted file mode 100644
index a18952ed4311..000000000000
--- a/sound/pci/hda/alc_quirks.c
+++ /dev/null
@@ -1,480 +0,0 @@
1/*
2 * Common codes for Realtek codec quirks
3 * included by patch_realtek.c
4 */
5
6/*
7 * configuration template - to be copied to the spec instance
8 */
9struct alc_config_preset {
10 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
11 * with spec
12 */
13 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
14 const struct hda_verb *init_verbs[5];
15 unsigned int num_dacs;
16 const hda_nid_t *dac_nids;
17 hda_nid_t dig_out_nid; /* optional */
18 hda_nid_t hp_nid; /* optional */
19 const hda_nid_t *slave_dig_outs;
20 unsigned int num_adc_nids;
21 const hda_nid_t *adc_nids;
22 const hda_nid_t *capsrc_nids;
23 hda_nid_t dig_in_nid;
24 unsigned int num_channel_mode;
25 const struct hda_channel_mode *channel_mode;
26 int need_dac_fix;
27 int const_channel_count;
28 unsigned int num_mux_defs;
29 const struct hda_input_mux *input_mux;
30 void (*unsol_event)(struct hda_codec *, unsigned int);
31 void (*setup)(struct hda_codec *);
32 void (*init_hook)(struct hda_codec *);
33#ifdef CONFIG_SND_HDA_POWER_SAVE
34 const struct hda_amp_list *loopbacks;
35 void (*power_hook)(struct hda_codec *codec);
36#endif
37};
38
39/*
40 * channel mode setting
41 */
42static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
43 struct snd_ctl_elem_info *uinfo)
44{
45 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
46 struct alc_spec *spec = codec->spec;
47 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
48 spec->num_channel_mode);
49}
50
51static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
52 struct snd_ctl_elem_value *ucontrol)
53{
54 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
55 struct alc_spec *spec = codec->spec;
56 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
57 spec->num_channel_mode,
58 spec->ext_channel_count);
59}
60
61static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
62 struct snd_ctl_elem_value *ucontrol)
63{
64 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
65 struct alc_spec *spec = codec->spec;
66 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
67 spec->num_channel_mode,
68 &spec->ext_channel_count);
69 if (err >= 0 && !spec->const_channel_count) {
70 spec->multiout.max_channels = spec->ext_channel_count;
71 if (spec->need_dac_fix)
72 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
73 }
74 return err;
75}
76
77/*
78 * Control the mode of pin widget settings via the mixer. "pc" is used
79 * instead of "%" to avoid consequences of accidentally treating the % as
80 * being part of a format specifier. Maximum allowed length of a value is
81 * 63 characters plus NULL terminator.
82 *
83 * Note: some retasking pin complexes seem to ignore requests for input
84 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
85 * are requested. Therefore order this list so that this behaviour will not
86 * cause problems when mixer clients move through the enum sequentially.
87 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
88 * March 2006.
89 */
90static const char * const alc_pin_mode_names[] = {
91 "Mic 50pc bias", "Mic 80pc bias",
92 "Line in", "Line out", "Headphone out",
93};
94static const unsigned char alc_pin_mode_values[] = {
95 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
96};
97/* The control can present all 5 options, or it can limit the options based
98 * in the pin being assumed to be exclusively an input or an output pin. In
99 * addition, "input" pins may or may not process the mic bias option
100 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
101 * accept requests for bias as of chip versions up to March 2006) and/or
102 * wiring in the computer.
103 */
104#define ALC_PIN_DIR_IN 0x00
105#define ALC_PIN_DIR_OUT 0x01
106#define ALC_PIN_DIR_INOUT 0x02
107#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
108#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
109
110/* Info about the pin modes supported by the different pin direction modes.
111 * For each direction the minimum and maximum values are given.
112 */
113static const signed char alc_pin_mode_dir_info[5][2] = {
114 { 0, 2 }, /* ALC_PIN_DIR_IN */
115 { 3, 4 }, /* ALC_PIN_DIR_OUT */
116 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
117 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
118 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
119};
120#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
121#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
122#define alc_pin_mode_n_items(_dir) \
123 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
124
125static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_info *uinfo)
127{
128 unsigned int item_num = uinfo->value.enumerated.item;
129 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
130
131 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
132 uinfo->count = 1;
133 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
134
135 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
136 item_num = alc_pin_mode_min(dir);
137 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
138 return 0;
139}
140
141static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
142 struct snd_ctl_elem_value *ucontrol)
143{
144 unsigned int i;
145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
146 hda_nid_t nid = kcontrol->private_value & 0xffff;
147 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
148 long *valp = ucontrol->value.integer.value;
149 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
150 AC_VERB_GET_PIN_WIDGET_CONTROL,
151 0x00);
152
153 /* Find enumerated value for current pinctl setting */
154 i = alc_pin_mode_min(dir);
155 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
156 i++;
157 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
158 return 0;
159}
160
161static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 signed int change;
165 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
166 hda_nid_t nid = kcontrol->private_value & 0xffff;
167 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
168 long val = *ucontrol->value.integer.value;
169 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
170 AC_VERB_GET_PIN_WIDGET_CONTROL,
171 0x00);
172
173 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
174 val = alc_pin_mode_min(dir);
175
176 change = pinctl != alc_pin_mode_values[val];
177 if (change) {
178 /* Set pin mode to that requested */
179 snd_hda_codec_write_cache(codec, nid, 0,
180 AC_VERB_SET_PIN_WIDGET_CONTROL,
181 alc_pin_mode_values[val]);
182
183 /* Also enable the retasking pin's input/output as required
184 * for the requested pin mode. Enum values of 2 or less are
185 * input modes.
186 *
187 * Dynamically switching the input/output buffers probably
188 * reduces noise slightly (particularly on input) so we'll
189 * do it. However, having both input and output buffers
190 * enabled simultaneously doesn't seem to be problematic if
191 * this turns out to be necessary in the future.
192 */
193 if (val <= 2) {
194 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
195 HDA_AMP_MUTE, HDA_AMP_MUTE);
196 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
197 HDA_AMP_MUTE, 0);
198 } else {
199 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
200 HDA_AMP_MUTE, HDA_AMP_MUTE);
201 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
202 HDA_AMP_MUTE, 0);
203 }
204 }
205 return change;
206}
207
208#define ALC_PIN_MODE(xname, nid, dir) \
209 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
210 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
211 .info = alc_pin_mode_info, \
212 .get = alc_pin_mode_get, \
213 .put = alc_pin_mode_put, \
214 .private_value = nid | (dir<<16) }
215
216/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
217 * together using a mask with more than one bit set. This control is
218 * currently used only by the ALC260 test model. At this stage they are not
219 * needed for any "production" models.
220 */
221#ifdef CONFIG_SND_DEBUG
222#define alc_gpio_data_info snd_ctl_boolean_mono_info
223
224static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_value *ucontrol)
226{
227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
228 hda_nid_t nid = kcontrol->private_value & 0xffff;
229 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
230 long *valp = ucontrol->value.integer.value;
231 unsigned int val = snd_hda_codec_read(codec, nid, 0,
232 AC_VERB_GET_GPIO_DATA, 0x00);
233
234 *valp = (val & mask) != 0;
235 return 0;
236}
237static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_value *ucontrol)
239{
240 signed int change;
241 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
242 hda_nid_t nid = kcontrol->private_value & 0xffff;
243 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
244 long val = *ucontrol->value.integer.value;
245 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
246 AC_VERB_GET_GPIO_DATA,
247 0x00);
248
249 /* Set/unset the masked GPIO bit(s) as needed */
250 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
251 if (val == 0)
252 gpio_data &= ~mask;
253 else
254 gpio_data |= mask;
255 snd_hda_codec_write_cache(codec, nid, 0,
256 AC_VERB_SET_GPIO_DATA, gpio_data);
257
258 return change;
259}
260#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
261 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
262 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
263 .info = alc_gpio_data_info, \
264 .get = alc_gpio_data_get, \
265 .put = alc_gpio_data_put, \
266 .private_value = nid | (mask<<16) }
267#endif /* CONFIG_SND_DEBUG */
268
269/* A switch control to allow the enabling of the digital IO pins on the
270 * ALC260. This is incredibly simplistic; the intention of this control is
271 * to provide something in the test model allowing digital outputs to be
272 * identified if present. If models are found which can utilise these
273 * outputs a more complete mixer control can be devised for those models if
274 * necessary.
275 */
276#ifdef CONFIG_SND_DEBUG
277#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
278
279static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_value *ucontrol)
281{
282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
283 hda_nid_t nid = kcontrol->private_value & 0xffff;
284 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
285 long *valp = ucontrol->value.integer.value;
286 unsigned int val = snd_hda_codec_read(codec, nid, 0,
287 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
288
289 *valp = (val & mask) != 0;
290 return 0;
291}
292static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
293 struct snd_ctl_elem_value *ucontrol)
294{
295 signed int change;
296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297 hda_nid_t nid = kcontrol->private_value & 0xffff;
298 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
299 long val = *ucontrol->value.integer.value;
300 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
301 AC_VERB_GET_DIGI_CONVERT_1,
302 0x00);
303
304 /* Set/unset the masked control bit(s) as needed */
305 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
306 if (val==0)
307 ctrl_data &= ~mask;
308 else
309 ctrl_data |= mask;
310 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
311 ctrl_data);
312
313 return change;
314}
315#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
316 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
317 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
318 .info = alc_spdif_ctrl_info, \
319 .get = alc_spdif_ctrl_get, \
320 .put = alc_spdif_ctrl_put, \
321 .private_value = nid | (mask<<16) }
322#endif /* CONFIG_SND_DEBUG */
323
324/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
325 * Again, this is only used in the ALC26x test models to help identify when
326 * the EAPD line must be asserted for features to work.
327 */
328#ifdef CONFIG_SND_DEBUG
329#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
330
331static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
332 struct snd_ctl_elem_value *ucontrol)
333{
334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335 hda_nid_t nid = kcontrol->private_value & 0xffff;
336 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
337 long *valp = ucontrol->value.integer.value;
338 unsigned int val = snd_hda_codec_read(codec, nid, 0,
339 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
340
341 *valp = (val & mask) != 0;
342 return 0;
343}
344
345static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol)
347{
348 int change;
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 hda_nid_t nid = kcontrol->private_value & 0xffff;
351 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
352 long val = *ucontrol->value.integer.value;
353 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
354 AC_VERB_GET_EAPD_BTLENABLE,
355 0x00);
356
357 /* Set/unset the masked control bit(s) as needed */
358 change = (!val ? 0 : mask) != (ctrl_data & mask);
359 if (!val)
360 ctrl_data &= ~mask;
361 else
362 ctrl_data |= mask;
363 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
364 ctrl_data);
365
366 return change;
367}
368
369#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
370 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
371 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
372 .info = alc_eapd_ctrl_info, \
373 .get = alc_eapd_ctrl_get, \
374 .put = alc_eapd_ctrl_put, \
375 .private_value = nid | (mask<<16) }
376#endif /* CONFIG_SND_DEBUG */
377
378static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
379{
380 struct alc_spec *spec = codec->spec;
381 struct auto_pin_cfg *cfg = &spec->autocfg;
382
383 if (!cfg->line_outs) {
384 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
385 cfg->line_out_pins[cfg->line_outs])
386 cfg->line_outs++;
387 }
388 if (!cfg->speaker_outs) {
389 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
390 cfg->speaker_pins[cfg->speaker_outs])
391 cfg->speaker_outs++;
392 }
393 if (!cfg->hp_outs) {
394 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
395 cfg->hp_pins[cfg->hp_outs])
396 cfg->hp_outs++;
397 }
398}
399
400/*
401 * set up from the preset table
402 */
403static void setup_preset(struct hda_codec *codec,
404 const struct alc_config_preset *preset)
405{
406 struct alc_spec *spec = codec->spec;
407 int i;
408
409 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
410 add_mixer(spec, preset->mixers[i]);
411 spec->cap_mixer = preset->cap_mixer;
412 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
413 i++)
414 add_verb(spec, preset->init_verbs[i]);
415
416 spec->channel_mode = preset->channel_mode;
417 spec->num_channel_mode = preset->num_channel_mode;
418 spec->need_dac_fix = preset->need_dac_fix;
419 spec->const_channel_count = preset->const_channel_count;
420
421 if (preset->const_channel_count)
422 spec->multiout.max_channels = preset->const_channel_count;
423 else
424 spec->multiout.max_channels = spec->channel_mode[0].channels;
425 spec->ext_channel_count = spec->channel_mode[0].channels;
426
427 spec->multiout.num_dacs = preset->num_dacs;
428 spec->multiout.dac_nids = preset->dac_nids;
429 spec->multiout.dig_out_nid = preset->dig_out_nid;
430 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
431 spec->multiout.hp_nid = preset->hp_nid;
432
433 spec->num_mux_defs = preset->num_mux_defs;
434 if (!spec->num_mux_defs)
435 spec->num_mux_defs = 1;
436 spec->input_mux = preset->input_mux;
437
438 spec->num_adc_nids = preset->num_adc_nids;
439 spec->adc_nids = preset->adc_nids;
440 spec->capsrc_nids = preset->capsrc_nids;
441 spec->dig_in_nid = preset->dig_in_nid;
442
443 spec->unsol_event = preset->unsol_event;
444 spec->init_hook = preset->init_hook;
445#ifdef CONFIG_SND_HDA_POWER_SAVE
446 spec->power_hook = preset->power_hook;
447 spec->loopback.amplist = preset->loopbacks;
448#endif
449
450 if (preset->setup)
451 preset->setup(codec);
452
453 alc_fixup_autocfg_pin_nums(codec);
454}
455
456static void alc_simple_setup_automute(struct alc_spec *spec, int mode)
457{
458 int lo_pin = spec->autocfg.line_out_pins[0];
459
460 if (lo_pin == spec->autocfg.speaker_pins[0] ||
461 lo_pin == spec->autocfg.hp_pins[0])
462 lo_pin = 0;
463 spec->automute_mode = mode;
464 spec->detect_hp = !!spec->autocfg.hp_pins[0];
465 spec->detect_lo = !!lo_pin;
466 spec->automute_lo = spec->automute_lo_possible = !!lo_pin;
467 spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0];
468}
469
470/* auto-toggle front mic */
471static void alc88x_simple_mic_automute(struct hda_codec *codec)
472{
473 unsigned int present;
474 unsigned char bits;
475
476 present = snd_hda_jack_detect(codec, 0x18);
477 bits = present ? HDA_AMP_MUTE : 0;
478 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
479}
480
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 684307372d73..7a8fcc4c15f8 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -19,6 +19,7 @@
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/mm.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
@@ -2304,7 +2305,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
2304 2305
2305/* apply the function to all matching slave ctls in the mixer list */ 2306/* apply the function to all matching slave ctls in the mixer list */
2306static int map_slaves(struct hda_codec *codec, const char * const *slaves, 2307static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2307 map_slave_func_t func, void *data) 2308 const char *suffix, map_slave_func_t func, void *data)
2308{ 2309{
2309 struct hda_nid_item *items; 2310 struct hda_nid_item *items;
2310 const char * const *s; 2311 const char * const *s;
@@ -2317,7 +2318,14 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2317 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) 2318 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
2318 continue; 2319 continue;
2319 for (s = slaves; *s; s++) { 2320 for (s = slaves; *s; s++) {
2320 if (!strcmp(sctl->id.name, *s)) { 2321 char tmpname[sizeof(sctl->id.name)];
2322 const char *name = *s;
2323 if (suffix) {
2324 snprintf(tmpname, sizeof(tmpname), "%s %s",
2325 name, suffix);
2326 name = tmpname;
2327 }
2328 if (!strcmp(sctl->id.name, name)) {
2321 err = func(data, sctl); 2329 err = func(data, sctl);
2322 if (err) 2330 if (err)
2323 return err; 2331 return err;
@@ -2333,12 +2341,65 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2333 return 1; 2341 return 1;
2334} 2342}
2335 2343
2344/* guess the value corresponding to 0dB */
2345static int get_kctl_0dB_offset(struct snd_kcontrol *kctl)
2346{
2347 int _tlv[4];
2348 const int *tlv = NULL;
2349 int val = -1;
2350
2351 if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
2352 /* FIXME: set_fs() hack for obtaining user-space TLV data */
2353 mm_segment_t fs = get_fs();
2354 set_fs(get_ds());
2355 if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv))
2356 tlv = _tlv;
2357 set_fs(fs);
2358 } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
2359 tlv = kctl->tlv.p;
2360 if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE)
2361 val = -tlv[2] / tlv[3];
2362 return val;
2363}
2364
2365/* call kctl->put with the given value(s) */
2366static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
2367{
2368 struct snd_ctl_elem_value *ucontrol;
2369 ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
2370 if (!ucontrol)
2371 return -ENOMEM;
2372 ucontrol->value.integer.value[0] = val;
2373 ucontrol->value.integer.value[1] = val;
2374 kctl->put(kctl, ucontrol);
2375 kfree(ucontrol);
2376 return 0;
2377}
2378
2379/* initialize the slave volume with 0dB */
2380static int init_slave_0dB(void *data, struct snd_kcontrol *slave)
2381{
2382 int offset = get_kctl_0dB_offset(slave);
2383 if (offset > 0)
2384 put_kctl_with_value(slave, offset);
2385 return 0;
2386}
2387
2388/* unmute the slave */
2389static int init_slave_unmute(void *data, struct snd_kcontrol *slave)
2390{
2391 return put_kctl_with_value(slave, 1);
2392}
2393
2336/** 2394/**
2337 * snd_hda_add_vmaster - create a virtual master control and add slaves 2395 * snd_hda_add_vmaster - create a virtual master control and add slaves
2338 * @codec: HD-audio codec 2396 * @codec: HD-audio codec
2339 * @name: vmaster control name 2397 * @name: vmaster control name
2340 * @tlv: TLV data (optional) 2398 * @tlv: TLV data (optional)
2341 * @slaves: slave control names (optional) 2399 * @slaves: slave control names (optional)
2400 * @suffix: suffix string to each slave name (optional)
2401 * @init_slave_vol: initialize slaves to unmute/0dB
2402 * @ctl_ret: store the vmaster kcontrol in return
2342 * 2403 *
2343 * Create a virtual master control with the given name. The TLV data 2404 * Create a virtual master control with the given name. The TLV data
2344 * must be either NULL or a valid data. 2405 * must be either NULL or a valid data.
@@ -2349,13 +2410,18 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2349 * 2410 *
2350 * This function returns zero if successful or a negative error code. 2411 * This function returns zero if successful or a negative error code.
2351 */ 2412 */
2352int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 2413int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2353 unsigned int *tlv, const char * const *slaves) 2414 unsigned int *tlv, const char * const *slaves,
2415 const char *suffix, bool init_slave_vol,
2416 struct snd_kcontrol **ctl_ret)
2354{ 2417{
2355 struct snd_kcontrol *kctl; 2418 struct snd_kcontrol *kctl;
2356 int err; 2419 int err;
2357 2420
2358 err = map_slaves(codec, slaves, check_slave_present, NULL); 2421 if (ctl_ret)
2422 *ctl_ret = NULL;
2423
2424 err = map_slaves(codec, slaves, suffix, check_slave_present, NULL);
2359 if (err != 1) { 2425 if (err != 1) {
2360 snd_printdd("No slave found for %s\n", name); 2426 snd_printdd("No slave found for %s\n", name);
2361 return 0; 2427 return 0;
@@ -2367,13 +2433,119 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2367 if (err < 0) 2433 if (err < 0)
2368 return err; 2434 return err;
2369 2435
2370 err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, 2436 err = map_slaves(codec, slaves, suffix,
2371 kctl); 2437 (map_slave_func_t)snd_ctl_add_slave, kctl);
2372 if (err < 0) 2438 if (err < 0)
2373 return err; 2439 return err;
2440
2441 /* init with master mute & zero volume */
2442 put_kctl_with_value(kctl, 0);
2443 if (init_slave_vol)
2444 map_slaves(codec, slaves, suffix,
2445 tlv ? init_slave_0dB : init_slave_unmute, kctl);
2446
2447 if (ctl_ret)
2448 *ctl_ret = kctl;
2374 return 0; 2449 return 0;
2375} 2450}
2376EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); 2451EXPORT_SYMBOL_HDA(__snd_hda_add_vmaster);
2452
2453/*
2454 * mute-LED control using vmaster
2455 */
2456static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
2457 struct snd_ctl_elem_info *uinfo)
2458{
2459 static const char * const texts[] = {
2460 "Off", "On", "Follow Master"
2461 };
2462 unsigned int index;
2463
2464 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2465 uinfo->count = 1;
2466 uinfo->value.enumerated.items = 3;
2467 index = uinfo->value.enumerated.item;
2468 if (index >= 3)
2469 index = 2;
2470 strcpy(uinfo->value.enumerated.name, texts[index]);
2471 return 0;
2472}
2473
2474static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
2475 struct snd_ctl_elem_value *ucontrol)
2476{
2477 struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2478 ucontrol->value.enumerated.item[0] = hook->mute_mode;
2479 return 0;
2480}
2481
2482static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
2483 struct snd_ctl_elem_value *ucontrol)
2484{
2485 struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2486 unsigned int old_mode = hook->mute_mode;
2487
2488 hook->mute_mode = ucontrol->value.enumerated.item[0];
2489 if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
2490 hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2491 if (old_mode == hook->mute_mode)
2492 return 0;
2493 snd_hda_sync_vmaster_hook(hook);
2494 return 1;
2495}
2496
2497static struct snd_kcontrol_new vmaster_mute_mode = {
2498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2499 .name = "Mute-LED Mode",
2500 .info = vmaster_mute_mode_info,
2501 .get = vmaster_mute_mode_get,
2502 .put = vmaster_mute_mode_put,
2503};
2504
2505/*
2506 * Add a mute-LED hook with the given vmaster switch kctl
2507 * "Mute-LED Mode" control is automatically created and associated with
2508 * the given hook.
2509 */
2510int snd_hda_add_vmaster_hook(struct hda_codec *codec,
2511 struct hda_vmaster_mute_hook *hook,
2512 bool expose_enum_ctl)
2513{
2514 struct snd_kcontrol *kctl;
2515
2516 if (!hook->hook || !hook->sw_kctl)
2517 return 0;
2518 snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec);
2519 hook->codec = codec;
2520 hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2521 if (!expose_enum_ctl)
2522 return 0;
2523 kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
2524 if (!kctl)
2525 return -ENOMEM;
2526 return snd_hda_ctl_add(codec, 0, kctl);
2527}
2528EXPORT_SYMBOL_HDA(snd_hda_add_vmaster_hook);
2529
2530/*
2531 * Call the hook with the current value for synchronization
2532 * Should be called in init callback
2533 */
2534void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook)
2535{
2536 if (!hook->hook || !hook->codec)
2537 return;
2538 switch (hook->mute_mode) {
2539 case HDA_VMUTE_FOLLOW_MASTER:
2540 snd_ctl_sync_vmaster_hook(hook->sw_kctl);
2541 break;
2542 default:
2543 hook->hook(hook->codec, hook->mute_mode);
2544 break;
2545 }
2546}
2547EXPORT_SYMBOL_HDA(snd_hda_sync_vmaster_hook);
2548
2377 2549
2378/** 2550/**
2379 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch 2551 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
@@ -5272,6 +5444,10 @@ int snd_hda_suspend(struct hda_bus *bus)
5272 list_for_each_entry(codec, &bus->codec_list, list) { 5444 list_for_each_entry(codec, &bus->codec_list, list) {
5273 if (hda_codec_is_power_on(codec)) 5445 if (hda_codec_is_power_on(codec))
5274 hda_call_codec_suspend(codec); 5446 hda_call_codec_suspend(codec);
5447 else /* forcibly change the power to D3 even if not used */
5448 hda_set_power_state(codec,
5449 codec->afg ? codec->afg : codec->mfg,
5450 AC_PWRST_D3);
5275 if (codec->patch_ops.post_suspend) 5451 if (codec->patch_ops.post_suspend)
5276 codec->patch_ops.post_suspend(codec); 5452 codec->patch_ops.post_suspend(codec);
5277 } 5453 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index f0f1943a4b2c..9a9f372e1be4 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -855,6 +855,7 @@ struct hda_codec {
855 unsigned int pins_shutup:1; /* pins are shut up */ 855 unsigned int pins_shutup:1; /* pins are shut up */
856 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ 856 unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
857 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ 857 unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
858 unsigned int no_jack_detect:1; /* Machine has no jack-detection */
858#ifdef CONFIG_SND_HDA_POWER_SAVE 859#ifdef CONFIG_SND_HDA_POWER_SAVE
859 unsigned int power_on :1; /* current (global) power-state */ 860 unsigned int power_on :1; /* current (global) power-state */
860 unsigned int power_transition :1; /* power-state in transition */ 861 unsigned int power_transition :1; /* power-state in transition */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 95dfb6874941..c19e71a94e1b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -84,7 +84,7 @@ module_param_array(model, charp, NULL, 0444);
84MODULE_PARM_DESC(model, "Use the given board model."); 84MODULE_PARM_DESC(model, "Use the given board model.");
85module_param_array(position_fix, int, NULL, 0444); 85module_param_array(position_fix, int, NULL, 0444);
86MODULE_PARM_DESC(position_fix, "DMA pointer read method." 86MODULE_PARM_DESC(position_fix, "DMA pointer read method."
87 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO)."); 87 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
88module_param_array(bdl_pos_adj, int, NULL, 0644); 88module_param_array(bdl_pos_adj, int, NULL, 0644);
89MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 89MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
90module_param_array(probe_mask, int, NULL, 0444); 90module_param_array(probe_mask, int, NULL, 0444);
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
94module_param(single_cmd, bool, 0444); 94module_param(single_cmd, bool, 0444);
95MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 95MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
96 "(for debugging only)."); 96 "(for debugging only).");
97module_param(enable_msi, int, 0444); 97module_param(enable_msi, bint, 0444);
98MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 98MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
99#ifdef CONFIG_SND_HDA_PATCH_LOADER 99#ifdef CONFIG_SND_HDA_PATCH_LOADER
100module_param_array(patch, charp, NULL, 0444); 100module_param_array(patch, charp, NULL, 0444);
@@ -121,8 +121,8 @@ module_param(power_save_controller, bool, 0644);
121MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); 121MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
122#endif 122#endif
123 123
124static bool align_buffer_size = 1; 124static int align_buffer_size = -1;
125module_param(align_buffer_size, bool, 0644); 125module_param(align_buffer_size, bint, 0644);
126MODULE_PARM_DESC(align_buffer_size, 126MODULE_PARM_DESC(align_buffer_size,
127 "Force buffer and period sizes to be multiple of 128 bytes."); 127 "Force buffer and period sizes to be multiple of 128 bytes.");
128 128
@@ -148,6 +148,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
148 "{Intel, PCH}," 148 "{Intel, PCH},"
149 "{Intel, CPT}," 149 "{Intel, CPT},"
150 "{Intel, PPT}," 150 "{Intel, PPT},"
151 "{Intel, LPT},"
151 "{Intel, PBG}," 152 "{Intel, PBG},"
152 "{Intel, SCH}," 153 "{Intel, SCH},"
153 "{ATI, SB450}," 154 "{ATI, SB450},"
@@ -329,6 +330,7 @@ enum {
329 POS_FIX_LPIB, 330 POS_FIX_LPIB,
330 POS_FIX_POSBUF, 331 POS_FIX_POSBUF,
331 POS_FIX_VIACOMBO, 332 POS_FIX_VIACOMBO,
333 POS_FIX_COMBO,
332}; 334};
333 335
334/* Defines for ATI HD Audio support in SB450 south bridge */ 336/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -515,6 +517,7 @@ enum {
515#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 517#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
516#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ 518#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
517#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ 519#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
520#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
518 521
519/* quirks for ATI SB / AMD Hudson */ 522/* quirks for ATI SB / AMD Hudson */
520#define AZX_DCAPS_PRESET_ATI_SB \ 523#define AZX_DCAPS_PRESET_ATI_SB \
@@ -527,7 +530,8 @@ enum {
527 530
528/* quirks for Nvidia */ 531/* quirks for Nvidia */
529#define AZX_DCAPS_PRESET_NVIDIA \ 532#define AZX_DCAPS_PRESET_NVIDIA \
530 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI) 533 (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\
534 AZX_DCAPS_ALIGN_BUFSIZE)
531 535
532static char *driver_short_names[] __devinitdata = { 536static char *driver_short_names[] __devinitdata = {
533 [AZX_DRIVER_ICH] = "HDA Intel", 537 [AZX_DRIVER_ICH] = "HDA Intel",
@@ -2347,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus)
2347 * power management 2351 * power management
2348 */ 2352 */
2349 2353
2350static int snd_hda_codecs_inuse(struct hda_bus *bus)
2351{
2352 struct hda_codec *codec;
2353
2354 list_for_each_entry(codec, &bus->codec_list, list) {
2355 if (snd_hda_codec_needs_resume(codec))
2356 return 1;
2357 }
2358 return 0;
2359}
2360
2361static int azx_suspend(struct pci_dev *pci, pm_message_t state) 2354static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2362{ 2355{
2363 struct snd_card *card = pci_get_drvdata(pci); 2356 struct snd_card *card = pci_get_drvdata(pci);
@@ -2404,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci)
2404 return -EIO; 2397 return -EIO;
2405 azx_init_pci(chip); 2398 azx_init_pci(chip);
2406 2399
2407 if (snd_hda_codecs_inuse(chip->bus)) 2400 azx_init_chip(chip, 1);
2408 azx_init_chip(chip, 1);
2409 2401
2410 snd_hda_resume(chip->bus); 2402 snd_hda_resume(chip->bus);
2411 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2403 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
@@ -2517,6 +2509,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2517 case POS_FIX_LPIB: 2509 case POS_FIX_LPIB:
2518 case POS_FIX_POSBUF: 2510 case POS_FIX_POSBUF:
2519 case POS_FIX_VIACOMBO: 2511 case POS_FIX_VIACOMBO:
2512 case POS_FIX_COMBO:
2520 return fix; 2513 return fix;
2521 } 2514 }
2522 2515
@@ -2696,6 +2689,12 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2696 2689
2697 chip->position_fix[0] = chip->position_fix[1] = 2690 chip->position_fix[0] = chip->position_fix[1] =
2698 check_position_fix(chip, position_fix[dev]); 2691 check_position_fix(chip, position_fix[dev]);
2692 /* combo mode uses LPIB for playback */
2693 if (chip->position_fix[0] == POS_FIX_COMBO) {
2694 chip->position_fix[0] = POS_FIX_LPIB;
2695 chip->position_fix[1] = POS_FIX_AUTO;
2696 }
2697
2699 check_probe_mask(chip, dev); 2698 check_probe_mask(chip, dev);
2700 2699
2701 chip->single_cmd = single_cmd; 2700 chip->single_cmd = single_cmd;
@@ -2774,9 +2773,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2774 } 2773 }
2775 2774
2776 /* disable buffer size rounding to 128-byte multiples if supported */ 2775 /* disable buffer size rounding to 128-byte multiples if supported */
2777 chip->align_buffer_size = align_buffer_size; 2776 if (align_buffer_size >= 0)
2778 if (chip->driver_caps & AZX_DCAPS_BUFSIZE) 2777 chip->align_buffer_size = !!align_buffer_size;
2779 chip->align_buffer_size = 0; 2778 else {
2779 if (chip->driver_caps & AZX_DCAPS_BUFSIZE)
2780 chip->align_buffer_size = 0;
2781 else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE)
2782 chip->align_buffer_size = 1;
2783 else
2784 chip->align_buffer_size = 1;
2785 }
2780 2786
2781 /* allow 64bit DMA address if supported by H/W */ 2787 /* allow 64bit DMA address if supported by H/W */
2782 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 2788 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
@@ -2992,6 +2998,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2992 { PCI_DEVICE(0x8086, 0x1e20), 2998 { PCI_DEVICE(0x8086, 0x1e20),
2993 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 2999 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
2994 AZX_DCAPS_BUFSIZE}, 3000 AZX_DCAPS_BUFSIZE},
3001 /* Lynx Point */
3002 { PCI_DEVICE(0x8086, 0x8c20),
3003 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3004 AZX_DCAPS_BUFSIZE},
2995 /* SCH */ 3005 /* SCH */
2996 { PCI_DEVICE(0x8086, 0x811b), 3006 { PCI_DEVICE(0x8086, 0x811b),
2997 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3007 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 9d819c4b4923..d68948499fbc 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -19,6 +19,22 @@
19#include "hda_local.h" 19#include "hda_local.h"
20#include "hda_jack.h" 20#include "hda_jack.h"
21 21
22bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
23{
24 if (codec->no_jack_detect)
25 return false;
26 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
27 return false;
28 if (!codec->ignore_misc_bit &&
29 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
30 AC_DEFCFG_MISC_NO_PRESENCE))
31 return false;
32 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
33 return false;
34 return true;
35}
36EXPORT_SYMBOL_HDA(is_jack_detectable);
37
22/* execute pin sense measurement */ 38/* execute pin sense measurement */
23static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) 39static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
24{ 40{
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index f8f97c71c9c1..c66655cf413a 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -62,18 +62,7 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
62u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 62u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
63int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 63int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
64 64
65static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) 65bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
66{
67 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
68 return false;
69 if (!codec->ignore_misc_bit &&
70 (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
71 AC_DEFCFG_MISC_NO_PRESENCE))
72 return false;
73 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
74 return false;
75 return true;
76}
77 66
78int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 67int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
79 const char *name, int idx); 68 const char *name, int idx);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index aca8d3193b95..0ec9248165bc 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -139,10 +139,36 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
139 unsigned int *tlv); 139 unsigned int *tlv);
140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, 140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
141 const char *name); 141 const char *name);
142int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 142int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
143 unsigned int *tlv, const char * const *slaves); 143 unsigned int *tlv, const char * const *slaves,
144 const char *suffix, bool init_slave_vol,
145 struct snd_kcontrol **ctl_ret);
146#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
147 __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
144int snd_hda_codec_reset(struct hda_codec *codec); 148int snd_hda_codec_reset(struct hda_codec *codec);
145 149
150enum {
151 HDA_VMUTE_OFF,
152 HDA_VMUTE_ON,
153 HDA_VMUTE_FOLLOW_MASTER,
154};
155
156struct hda_vmaster_mute_hook {
157 /* below two fields must be filled by the caller of
158 * snd_hda_add_vmaster_hook() beforehand
159 */
160 struct snd_kcontrol *sw_kctl;
161 void (*hook)(void *, int);
162 /* below are initialized automatically */
163 unsigned int mute_mode; /* HDA_VMUTE_XXX */
164 struct hda_codec *codec;
165};
166
167int snd_hda_add_vmaster_hook(struct hda_codec *codec,
168 struct hda_vmaster_mute_hook *hook,
169 bool expose_enum_ctl);
170void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
171
146/* amp value bits */ 172/* amp value bits */
147#define HDA_AMP_MUTE 0x80 173#define HDA_AMP_MUTE 0x80
148#define HDA_AMP_UNMUTE 0x00 174#define HDA_AMP_UNMUTE 0x00
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 9cb14b42dfff..7143393927da 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -82,6 +82,7 @@ struct ad198x_spec {
82 unsigned int inv_jack_detect: 1;/* inverted jack-detection */ 82 unsigned int inv_jack_detect: 1;/* inverted jack-detection */
83 unsigned int inv_eapd: 1; /* inverted EAPD implementation */ 83 unsigned int inv_eapd: 1; /* inverted EAPD implementation */
84 unsigned int analog_beep: 1; /* analog beep input present */ 84 unsigned int analog_beep: 1; /* analog beep input present */
85 unsigned int avoid_init_slave_vol:1;
85 86
86#ifdef CONFIG_SND_HDA_POWER_SAVE 87#ifdef CONFIG_SND_HDA_POWER_SAVE
87 struct hda_loopback_check loopback; 88 struct hda_loopback_check loopback;
@@ -137,51 +138,17 @@ static int ad198x_init(struct hda_codec *codec)
137 return 0; 138 return 0;
138} 139}
139 140
140static const char * const ad_slave_vols[] = { 141static const char * const ad_slave_pfxs[] = {
141 "Front Playback Volume", 142 "Front", "Surround", "Center", "LFE", "Side",
142 "Surround Playback Volume", 143 "Headphone", "Mono", "Speaker", "IEC958",
143 "Center Playback Volume",
144 "LFE Playback Volume",
145 "Side Playback Volume",
146 "Headphone Playback Volume",
147 "Mono Playback Volume",
148 "Speaker Playback Volume",
149 "IEC958 Playback Volume",
150 NULL 144 NULL
151}; 145};
152 146
153static const char * const ad_slave_sws[] = { 147static const char * const ad1988_6stack_fp_slave_pfxs[] = {
154 "Front Playback Switch", 148 "Front", "Surround", "Center", "LFE", "Side", "IEC958",
155 "Surround Playback Switch",
156 "Center Playback Switch",
157 "LFE Playback Switch",
158 "Side Playback Switch",
159 "Headphone Playback Switch",
160 "Mono Playback Switch",
161 "Speaker Playback Switch",
162 "IEC958 Playback Switch",
163 NULL 149 NULL
164}; 150};
165 151
166static const char * const ad1988_6stack_fp_slave_vols[] = {
167 "Front Playback Volume",
168 "Surround Playback Volume",
169 "Center Playback Volume",
170 "LFE Playback Volume",
171 "Side Playback Volume",
172 "IEC958 Playback Volume",
173 NULL
174};
175
176static const char * const ad1988_6stack_fp_slave_sws[] = {
177 "Front Playback Switch",
178 "Surround Playback Switch",
179 "Center Playback Switch",
180 "LFE Playback Switch",
181 "Side Playback Switch",
182 "IEC958 Playback Switch",
183 NULL
184};
185static void ad198x_free_kctls(struct hda_codec *codec); 152static void ad198x_free_kctls(struct hda_codec *codec);
186 153
187#ifdef CONFIG_SND_HDA_INPUT_BEEP 154#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -257,10 +224,12 @@ static int ad198x_build_controls(struct hda_codec *codec)
257 unsigned int vmaster_tlv[4]; 224 unsigned int vmaster_tlv[4];
258 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 225 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
259 HDA_OUTPUT, vmaster_tlv); 226 HDA_OUTPUT, vmaster_tlv);
260 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 227 err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
261 vmaster_tlv, 228 vmaster_tlv,
262 (spec->slave_vols ? 229 (spec->slave_vols ?
263 spec->slave_vols : ad_slave_vols)); 230 spec->slave_vols : ad_slave_pfxs),
231 "Playback Volume",
232 !spec->avoid_init_slave_vol, NULL);
264 if (err < 0) 233 if (err < 0)
265 return err; 234 return err;
266 } 235 }
@@ -268,7 +237,8 @@ static int ad198x_build_controls(struct hda_codec *codec)
268 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 237 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
269 NULL, 238 NULL,
270 (spec->slave_sws ? 239 (spec->slave_sws ?
271 spec->slave_sws : ad_slave_sws)); 240 spec->slave_sws : ad_slave_pfxs),
241 "Playback Switch");
272 if (err < 0) 242 if (err < 0)
273 return err; 243 return err;
274 } 244 }
@@ -3385,8 +3355,8 @@ static int patch_ad1988(struct hda_codec *codec)
3385 3355
3386 if (spec->autocfg.hp_pins[0]) { 3356 if (spec->autocfg.hp_pins[0]) {
3387 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; 3357 spec->mixers[spec->num_mixers++] = ad1988_hp_mixers;
3388 spec->slave_vols = ad1988_6stack_fp_slave_vols; 3358 spec->slave_vols = ad1988_6stack_fp_slave_pfxs;
3389 spec->slave_sws = ad1988_6stack_fp_slave_sws; 3359 spec->slave_sws = ad1988_6stack_fp_slave_pfxs;
3390 spec->alt_dac_nid = ad1988_alt_dac_nid; 3360 spec->alt_dac_nid = ad1988_alt_dac_nid;
3391 spec->stream_analog_alt_playback = 3361 spec->stream_analog_alt_playback =
3392 &ad198x_pcm_analog_alt_playback; 3362 &ad198x_pcm_analog_alt_playback;
@@ -3594,16 +3564,8 @@ static const struct hda_amp_list ad1884_loopbacks[] = {
3594#endif 3564#endif
3595 3565
3596static const char * const ad1884_slave_vols[] = { 3566static const char * const ad1884_slave_vols[] = {
3597 "PCM Playback Volume", 3567 "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3598 "Mic Playback Volume", 3568 "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
3599 "Mono Playback Volume",
3600 "Front Mic Playback Volume",
3601 "Mic Playback Volume",
3602 "CD Playback Volume",
3603 "Internal Mic Playback Volume",
3604 "Docking Mic Playback Volume",
3605 /* "Beep Playback Volume", */
3606 "IEC958 Playback Volume",
3607 NULL 3569 NULL
3608}; 3570};
3609 3571
@@ -3644,6 +3606,8 @@ static int patch_ad1884(struct hda_codec *codec)
3644 spec->vmaster_nid = 0x04; 3606 spec->vmaster_nid = 0x04;
3645 /* we need to cover all playback volumes */ 3607 /* we need to cover all playback volumes */
3646 spec->slave_vols = ad1884_slave_vols; 3608 spec->slave_vols = ad1884_slave_vols;
3609 /* slaves may contain input volumes, so we can't raise to 0dB blindly */
3610 spec->avoid_init_slave_vol = 1;
3647 3611
3648 codec->patch_ops = ad198x_patch_ops; 3612 codec->patch_ops = ad198x_patch_ops;
3649 3613
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index d29d6d377904..e6eafb18c8f5 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -70,6 +70,8 @@ struct conexant_spec {
70 const struct snd_kcontrol_new *mixers[5]; 70 const struct snd_kcontrol_new *mixers[5];
71 int num_mixers; 71 int num_mixers;
72 hda_nid_t vmaster_nid; 72 hda_nid_t vmaster_nid;
73 struct hda_vmaster_mute_hook vmaster_mute;
74 bool vmaster_mute_led;
73 75
74 const struct hda_verb *init_verbs[5]; /* initialization verbs 76 const struct hda_verb *init_verbs[5]; /* initialization verbs
75 * don't forget NULL 77 * don't forget NULL
@@ -465,21 +467,8 @@ static const struct snd_kcontrol_new cxt_beep_mixer[] = {
465}; 467};
466#endif 468#endif
467 469
468static const char * const slave_vols[] = { 470static const char * const slave_pfxs[] = {
469 "Headphone Playback Volume", 471 "Headphone", "Speaker", "Front", "Surround", "CLFE",
470 "Speaker Playback Volume",
471 "Front Playback Volume",
472 "Surround Playback Volume",
473 "CLFE Playback Volume",
474 NULL
475};
476
477static const char * const slave_sws[] = {
478 "Headphone Playback Switch",
479 "Speaker Playback Switch",
480 "Front Playback Switch",
481 "Surround Playback Switch",
482 "CLFE Playback Switch",
483 NULL 472 NULL
484}; 473};
485 474
@@ -519,14 +508,17 @@ static int conexant_build_controls(struct hda_codec *codec)
519 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 508 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
520 HDA_OUTPUT, vmaster_tlv); 509 HDA_OUTPUT, vmaster_tlv);
521 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 510 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
522 vmaster_tlv, slave_vols); 511 vmaster_tlv, slave_pfxs,
512 "Playback Volume");
523 if (err < 0) 513 if (err < 0)
524 return err; 514 return err;
525 } 515 }
526 if (spec->vmaster_nid && 516 if (spec->vmaster_nid &&
527 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 517 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
528 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 518 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
529 NULL, slave_sws); 519 NULL, slave_pfxs,
520 "Playback Switch", true,
521 &spec->vmaster_mute.sw_kctl);
530 if (err < 0) 522 if (err < 0)
531 return err; 523 return err;
532 } 524 }
@@ -3034,7 +3026,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3034 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), 3026 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
3035 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), 3027 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3036 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), 3028 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3037 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3038 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), 3029 SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3039 {} 3030 {}
3040}; 3031};
@@ -3943,6 +3934,63 @@ static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3943 snd_hda_jack_detect_enable(codec, pins[i], action); 3934 snd_hda_jack_detect_enable(codec, pins[i], action);
3944} 3935}
3945 3936
3937static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3938{
3939 int i;
3940 for (i = 0; i < nums; i++)
3941 if (list[i] == nid)
3942 return true;
3943 return false;
3944}
3945
3946/* is the given NID found in any of autocfg items? */
3947static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid)
3948{
3949 int i;
3950
3951 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3952 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3953 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) ||
3954 found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs))
3955 return true;
3956 for (i = 0; i < cfg->num_inputs; i++)
3957 if (cfg->inputs[i].pin == nid)
3958 return true;
3959 if (cfg->dig_in_pin == nid)
3960 return true;
3961 return false;
3962}
3963
3964/* clear unsol-event tags on unused pins; Conexant codecs seem to leave
3965 * invalid unsol tags by some reason
3966 */
3967static void clear_unsol_on_unused_pins(struct hda_codec *codec)
3968{
3969 struct conexant_spec *spec = codec->spec;
3970 struct auto_pin_cfg *cfg = &spec->autocfg;
3971 int i;
3972
3973 for (i = 0; i < codec->init_pins.used; i++) {
3974 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
3975 if (!found_in_autocfg(cfg, pin->nid))
3976 snd_hda_codec_write(codec, pin->nid, 0,
3977 AC_VERB_SET_UNSOLICITED_ENABLE, 0);
3978 }
3979}
3980
3981/* turn on/off EAPD according to Master switch */
3982static void cx_auto_vmaster_hook(void *private_data, int enabled)
3983{
3984 struct hda_codec *codec = private_data;
3985 struct conexant_spec *spec = codec->spec;
3986
3987 if (enabled && spec->pin_eapd_ctrls) {
3988 cx_auto_update_speakers(codec);
3989 return;
3990 }
3991 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled);
3992}
3993
3946static void cx_auto_init_output(struct hda_codec *codec) 3994static void cx_auto_init_output(struct hda_codec *codec)
3947{ 3995{
3948 struct conexant_spec *spec = codec->spec; 3996 struct conexant_spec *spec = codec->spec;
@@ -3983,6 +4031,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
3983 /* turn on all EAPDs if no individual EAPD control is available */ 4031 /* turn on all EAPDs if no individual EAPD control is available */
3984 if (!spec->pin_eapd_ctrls) 4032 if (!spec->pin_eapd_ctrls)
3985 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 4033 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4034 clear_unsol_on_unused_pins(codec);
3986} 4035}
3987 4036
3988static void cx_auto_init_input(struct hda_codec *codec) 4037static void cx_auto_init_input(struct hda_codec *codec)
@@ -4046,11 +4095,13 @@ static void cx_auto_init_digital(struct hda_codec *codec)
4046 4095
4047static int cx_auto_init(struct hda_codec *codec) 4096static int cx_auto_init(struct hda_codec *codec)
4048{ 4097{
4098 struct conexant_spec *spec = codec->spec;
4049 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ 4099 /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
4050 cx_auto_init_output(codec); 4100 cx_auto_init_output(codec);
4051 cx_auto_init_input(codec); 4101 cx_auto_init_input(codec);
4052 cx_auto_init_digital(codec); 4102 cx_auto_init_digital(codec);
4053 snd_hda_jack_report_sync(codec); 4103 snd_hda_jack_report_sync(codec);
4104 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
4054 return 0; 4105 return 0;
4055} 4106}
4056 4107
@@ -4296,6 +4347,13 @@ static int cx_auto_build_controls(struct hda_codec *codec)
4296 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 4347 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
4297 if (err < 0) 4348 if (err < 0)
4298 return err; 4349 return err;
4350 if (spec->vmaster_mute.sw_kctl) {
4351 spec->vmaster_mute.hook = cx_auto_vmaster_hook;
4352 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
4353 spec->vmaster_mute_led);
4354 if (err < 0)
4355 return err;
4356 }
4299 return 0; 4357 return 0;
4300} 4358}
4301 4359
@@ -4320,7 +4378,6 @@ static int cx_auto_search_adcs(struct hda_codec *codec)
4320 return 0; 4378 return 0;
4321} 4379}
4322 4380
4323
4324static const struct hda_codec_ops cx_auto_patch_ops = { 4381static const struct hda_codec_ops cx_auto_patch_ops = {
4325 .build_controls = cx_auto_build_controls, 4382 .build_controls = cx_auto_build_controls,
4326 .build_pcms = conexant_build_pcms, 4383 .build_pcms = conexant_build_pcms,
@@ -4368,6 +4425,7 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
4368 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 4425 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
4369 { 0x17, 0x21a11000 }, /* dock-mic */ 4426 { 0x17, 0x21a11000 }, /* dock-mic */
4370 { 0x19, 0x2121103f }, /* dock-HP */ 4427 { 0x19, 0x2121103f }, /* dock-HP */
4428 { 0x1c, 0x21440100 }, /* dock SPDIF out */
4371 {} 4429 {}
4372}; 4430};
4373 4431
@@ -4421,6 +4479,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
4421 4479
4422 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); 4480 apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
4423 4481
4482 /* Show mute-led control only on HP laptops
4483 * This is a sort of white-list: on HP laptops, EAPD corresponds
4484 * only to the mute-LED without actualy amp function. Meanwhile,
4485 * others may use EAPD really as an amp switch, so it might be
4486 * not good to expose it blindly.
4487 */
4488 switch (codec->subsystem_id >> 16) {
4489 case 0x103c:
4490 spec->vmaster_mute_led = 1;
4491 break;
4492 }
4493
4424 err = cx_auto_search_adcs(codec); 4494 err = cx_auto_search_adcs(codec);
4425 if (err < 0) 4495 if (err < 0)
4426 return err; 4496 return err;
@@ -4434,6 +4504,18 @@ static int patch_conexant_auto(struct hda_codec *codec)
4434 codec->patch_ops = cx_auto_patch_ops; 4504 codec->patch_ops = cx_auto_patch_ops;
4435 if (spec->beep_amp) 4505 if (spec->beep_amp)
4436 snd_hda_attach_beep_device(codec, spec->beep_amp); 4506 snd_hda_attach_beep_device(codec, spec->beep_amp);
4507
4508 /* Some laptops with Conexant chips show stalls in S3 resume,
4509 * which falls into the single-cmd mode.
4510 * Better to make reset, then.
4511 */
4512 if (!codec->bus->sync_write) {
4513 snd_printd("hda_codec: "
4514 "Enable sync_write for stable communication\n");
4515 codec->bus->sync_write = 1;
4516 codec->bus->allow_bus_reset = 1;
4517 }
4518
4437 return 0; 4519 return 0;
4438} 4520}
4439 4521
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 1168ebd3fb5c..540cd13f7f15 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1912,6 +1912,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1912{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1912{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1913{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, 1913{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1914{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, 1914{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, 1916{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1916{} /* terminator */ 1917{} /* terminator */
1917}; 1918};
@@ -1958,6 +1959,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803");
1958MODULE_ALIAS("snd-hda-codec-id:80862804"); 1959MODULE_ALIAS("snd-hda-codec-id:80862804");
1959MODULE_ALIAS("snd-hda-codec-id:80862805"); 1960MODULE_ALIAS("snd-hda-codec-id:80862805");
1960MODULE_ALIAS("snd-hda-codec-id:80862806"); 1961MODULE_ALIAS("snd-hda-codec-id:80862806");
1962MODULE_ALIAS("snd-hda-codec-id:80862880");
1961MODULE_ALIAS("snd-hda-codec-id:808629fb"); 1963MODULE_ALIAS("snd-hda-codec-id:808629fb");
1962 1964
1963MODULE_LICENSE("GPL"); 1965MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 22c73b78ac6f..8ea2fd654327 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -198,8 +198,11 @@ struct alc_spec {
198 198
199 /* for virtual master */ 199 /* for virtual master */
200 hda_nid_t vmaster_nid; 200 hda_nid_t vmaster_nid;
201 struct hda_vmaster_mute_hook vmaster_mute;
201#ifdef CONFIG_SND_HDA_POWER_SAVE 202#ifdef CONFIG_SND_HDA_POWER_SAVE
202 struct hda_loopback_check loopback; 203 struct hda_loopback_check loopback;
204 int num_loopbacks;
205 struct hda_amp_list loopback_list[8];
203#endif 206#endif
204 207
205 /* for PLL fix */ 208 /* for PLL fix */
@@ -220,8 +223,6 @@ struct alc_spec {
220 struct snd_array bind_ctls; 223 struct snd_array bind_ctls;
221}; 224};
222 225
223#define ALC_MODEL_AUTO 0 /* common for all chips */
224
225static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, 226static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
226 int dir, unsigned int bits) 227 int dir, unsigned int bits)
227{ 228{
@@ -300,6 +301,9 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
300 int i, type, num_conns; 301 int i, type, num_conns;
301 hda_nid_t nid; 302 hda_nid_t nid;
302 303
304 if (!spec->input_mux)
305 return 0;
306
303 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 307 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
304 imux = &spec->input_mux[mux_idx]; 308 imux = &spec->input_mux[mux_idx];
305 if (!imux->num_items && mux_idx > 0) 309 if (!imux->num_items && mux_idx > 0)
@@ -651,15 +655,51 @@ static void alc_exec_unsol_event(struct hda_codec *codec, int action)
651 snd_hda_jack_report_sync(codec); 655 snd_hda_jack_report_sync(codec);
652} 656}
653 657
658/* update the master volume per volume-knob's unsol event */
659static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
660{
661 unsigned int val;
662 struct snd_kcontrol *kctl;
663 struct snd_ctl_elem_value *uctl;
664
665 kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
666 if (!kctl)
667 return;
668 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
669 if (!uctl)
670 return;
671 val = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
673 val &= HDA_AMP_VOLMASK;
674 uctl->value.integer.value[0] = val;
675 uctl->value.integer.value[1] = val;
676 kctl->put(kctl, uctl);
677 kfree(uctl);
678}
679
654/* unsolicited event for HP jack sensing */ 680/* unsolicited event for HP jack sensing */
655static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 681static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
656{ 682{
683 int action;
684
657 if (codec->vendor_id == 0x10ec0880) 685 if (codec->vendor_id == 0x10ec0880)
658 res >>= 28; 686 res >>= 28;
659 else 687 else
660 res >>= 26; 688 res >>= 26;
661 res = snd_hda_jack_get_action(codec, res); 689 action = snd_hda_jack_get_action(codec, res);
662 alc_exec_unsol_event(codec, res); 690 if (action == ALC_DCVOL_EVENT) {
691 /* Execute the dc-vol event here as it requires the NID
692 * but we don't pass NID to alc_exec_unsol_event().
693 * Once when we convert all static quirks to the auto-parser,
694 * this can be integerated into there.
695 */
696 struct hda_jack_tbl *jack;
697 jack = snd_hda_jack_tbl_get_from_tag(codec, res);
698 if (jack)
699 alc_update_knob_master(codec, jack->nid);
700 return;
701 }
702 alc_exec_unsol_event(codec, action);
663} 703}
664 704
665/* call init functions of standard auto-mute helpers */ 705/* call init functions of standard auto-mute helpers */
@@ -1033,45 +1073,6 @@ static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
1033 return true; 1073 return true;
1034} 1074}
1035 1075
1036/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1037static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
1038{
1039 struct alc_spec *spec = codec->spec;
1040 struct hda_input_mux *imux;
1041 static char * const texts[3] = {
1042 "Mic", "Internal Mic", "Dock Mic"
1043 };
1044 int i;
1045
1046 if (!spec->auto_mic)
1047 return false;
1048 imux = &spec->private_imux[0];
1049 if (spec->input_mux == imux)
1050 return true;
1051 spec->imux_pins[0] = spec->ext_mic_pin;
1052 spec->imux_pins[1] = spec->int_mic_pin;
1053 spec->imux_pins[2] = spec->dock_mic_pin;
1054 for (i = 0; i < 3; i++) {
1055 strcpy(imux->items[i].label, texts[i]);
1056 if (spec->imux_pins[i]) {
1057 hda_nid_t pin = spec->imux_pins[i];
1058 int c;
1059 for (c = 0; c < spec->num_adc_nids; c++) {
1060 hda_nid_t cap = get_capsrc(spec, c);
1061 int idx = get_connection_index(codec, cap, pin);
1062 if (idx >= 0) {
1063 imux->items[i].index = idx;
1064 break;
1065 }
1066 }
1067 imux->num_items = i + 1;
1068 }
1069 }
1070 spec->num_mux_defs = 1;
1071 spec->input_mux = imux;
1072 return true;
1073}
1074
1075/* check whether all auto-mic pins are valid; setup indices if OK */ 1076/* check whether all auto-mic pins are valid; setup indices if OK */
1076static bool alc_auto_mic_check_imux(struct hda_codec *codec) 1077static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1077{ 1078{
@@ -1441,6 +1442,7 @@ enum {
1441 ALC_FIXUP_ACT_PRE_PROBE, 1442 ALC_FIXUP_ACT_PRE_PROBE,
1442 ALC_FIXUP_ACT_PROBE, 1443 ALC_FIXUP_ACT_PROBE,
1443 ALC_FIXUP_ACT_INIT, 1444 ALC_FIXUP_ACT_INIT,
1445 ALC_FIXUP_ACT_BUILD,
1444}; 1446};
1445 1447
1446static void alc_apply_fixup(struct hda_codec *codec, int action) 1448static void alc_apply_fixup(struct hda_codec *codec, int action)
@@ -1520,6 +1522,13 @@ static void alc_pick_fixup(struct hda_codec *codec,
1520 int id = -1; 1522 int id = -1;
1521 const char *name = NULL; 1523 const char *name = NULL;
1522 1524
1525 /* when model=nofixup is given, don't pick up any fixups */
1526 if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
1527 spec->fixup_list = NULL;
1528 spec->fixup_id = -1;
1529 return;
1530 }
1531
1523 if (codec->modelname && models) { 1532 if (codec->modelname && models) {
1524 while (models->name) { 1533 while (models->name) {
1525 if (!strcmp(codec->modelname, models->name)) { 1534 if (!strcmp(codec->modelname, models->name)) {
@@ -1847,36 +1856,10 @@ DEFINE_CAPMIX_NOSRC(3);
1847/* 1856/*
1848 * slave controls for virtual master 1857 * slave controls for virtual master
1849 */ 1858 */
1850static const char * const alc_slave_vols[] = { 1859static const char * const alc_slave_pfxs[] = {
1851 "Front Playback Volume", 1860 "Front", "Surround", "Center", "LFE", "Side",
1852 "Surround Playback Volume", 1861 "Headphone", "Speaker", "Mono", "Line Out",
1853 "Center Playback Volume", 1862 "CLFE", "Bass Speaker", "PCM",
1854 "LFE Playback Volume",
1855 "Side Playback Volume",
1856 "Headphone Playback Volume",
1857 "Speaker Playback Volume",
1858 "Mono Playback Volume",
1859 "Line Out Playback Volume",
1860 "CLFE Playback Volume",
1861 "Bass Speaker Playback Volume",
1862 "PCM Playback Volume",
1863 NULL,
1864};
1865
1866static const char * const alc_slave_sws[] = {
1867 "Front Playback Switch",
1868 "Surround Playback Switch",
1869 "Center Playback Switch",
1870 "LFE Playback Switch",
1871 "Side Playback Switch",
1872 "Headphone Playback Switch",
1873 "Speaker Playback Switch",
1874 "Mono Playback Switch",
1875 "IEC958 Playback Switch",
1876 "Line Out Playback Switch",
1877 "CLFE Playback Switch",
1878 "Bass Speaker Playback Switch",
1879 "PCM Playback Switch",
1880 NULL, 1863 NULL,
1881}; 1864};
1882 1865
@@ -1967,14 +1950,17 @@ static int __alc_build_controls(struct hda_codec *codec)
1967 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 1950 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1968 HDA_OUTPUT, vmaster_tlv); 1951 HDA_OUTPUT, vmaster_tlv);
1969 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1952 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1970 vmaster_tlv, alc_slave_vols); 1953 vmaster_tlv, alc_slave_pfxs,
1954 "Playback Volume");
1971 if (err < 0) 1955 if (err < 0)
1972 return err; 1956 return err;
1973 } 1957 }
1974 if (!spec->no_analog && 1958 if (!spec->no_analog &&
1975 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1959 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1976 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1960 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1977 NULL, alc_slave_sws); 1961 NULL, alc_slave_pfxs,
1962 "Playback Switch",
1963 true, &spec->vmaster_mute.sw_kctl);
1978 if (err < 0) 1964 if (err < 0)
1979 return err; 1965 return err;
1980 } 1966 }
@@ -2059,7 +2045,11 @@ static int alc_build_controls(struct hda_codec *codec)
2059 int err = __alc_build_controls(codec); 2045 int err = __alc_build_controls(codec);
2060 if (err < 0) 2046 if (err < 0)
2061 return err; 2047 return err;
2062 return snd_hda_jack_add_kctls(codec, &spec->autocfg); 2048 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
2049 if (err < 0)
2050 return err;
2051 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
2052 return 0;
2063} 2053}
2064 2054
2065 2055
@@ -2068,15 +2058,15 @@ static int alc_build_controls(struct hda_codec *codec)
2068 */ 2058 */
2069 2059
2070static void alc_init_special_input_src(struct hda_codec *codec); 2060static void alc_init_special_input_src(struct hda_codec *codec);
2071static int alc269_fill_coef(struct hda_codec *codec); 2061static void alc_auto_init_std(struct hda_codec *codec);
2072 2062
2073static int alc_init(struct hda_codec *codec) 2063static int alc_init(struct hda_codec *codec)
2074{ 2064{
2075 struct alc_spec *spec = codec->spec; 2065 struct alc_spec *spec = codec->spec;
2076 unsigned int i; 2066 unsigned int i;
2077 2067
2078 if (codec->vendor_id == 0x10ec0269) 2068 if (spec->init_hook)
2079 alc269_fill_coef(codec); 2069 spec->init_hook(codec);
2080 2070
2081 alc_fix_pll(codec); 2071 alc_fix_pll(codec);
2082 alc_auto_init_amp(codec, spec->init_amp); 2072 alc_auto_init_amp(codec, spec->init_amp);
@@ -2084,9 +2074,7 @@ static int alc_init(struct hda_codec *codec)
2084 for (i = 0; i < spec->num_init_verbs; i++) 2074 for (i = 0; i < spec->num_init_verbs; i++)
2085 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2075 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2086 alc_init_special_input_src(codec); 2076 alc_init_special_input_src(codec);
2087 2077 alc_auto_init_std(codec);
2088 if (spec->init_hook)
2089 spec->init_hook(codec);
2090 2078
2091 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); 2079 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
2092 2080
@@ -2675,6 +2663,25 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
2675 return channel_name[ch]; 2663 return channel_name[ch];
2676} 2664}
2677 2665
2666#ifdef CONFIG_SND_HDA_POWER_SAVE
2667/* add the powersave loopback-list entry */
2668static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
2669{
2670 struct hda_amp_list *list;
2671
2672 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2673 return;
2674 list = spec->loopback_list + spec->num_loopbacks;
2675 list->nid = mix;
2676 list->dir = HDA_INPUT;
2677 list->idx = idx;
2678 spec->num_loopbacks++;
2679 spec->loopback.amplist = spec->loopback_list;
2680}
2681#else
2682#define add_loopback_list(spec, mix, idx) /* NOP */
2683#endif
2684
2678/* create input playback/capture controls for the given pin */ 2685/* create input playback/capture controls for the given pin */
2679static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, 2686static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
2680 const char *ctlname, int ctlidx, 2687 const char *ctlname, int ctlidx,
@@ -2690,6 +2697,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
2690 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); 2697 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
2691 if (err < 0) 2698 if (err < 0)
2692 return err; 2699 return err;
2700 add_loopback_list(spec, mix_nid, idx);
2693 return 0; 2701 return 0;
2694} 2702}
2695 2703
@@ -2954,10 +2962,27 @@ static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2954 return 0; 2962 return 0;
2955} 2963}
2956 2964
2965static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
2966{
2967 struct alc_spec *spec = codec->spec;
2968 int i;
2969 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2970 ARRAY_SIZE(spec->private_dac_nids)) ||
2971 found_in_nid_list(nid, spec->multiout.hp_out_nid,
2972 ARRAY_SIZE(spec->multiout.hp_out_nid)) ||
2973 found_in_nid_list(nid, spec->multiout.extra_out_nid,
2974 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2975 return true;
2976 for (i = 0; i < spec->multi_ios; i++) {
2977 if (spec->multi_io[i].dac == nid)
2978 return true;
2979 }
2980 return false;
2981}
2982
2957/* look for an empty DAC slot */ 2983/* look for an empty DAC slot */
2958static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 2984static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2959{ 2985{
2960 struct alc_spec *spec = codec->spec;
2961 hda_nid_t srcs[5]; 2986 hda_nid_t srcs[5];
2962 int i, num; 2987 int i, num;
2963 2988
@@ -2967,16 +2992,8 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2967 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); 2992 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
2968 if (!nid) 2993 if (!nid)
2969 continue; 2994 continue;
2970 if (found_in_nid_list(nid, spec->multiout.dac_nids, 2995 if (!alc_is_dac_already_used(codec, nid))
2971 ARRAY_SIZE(spec->private_dac_nids))) 2996 return nid;
2972 continue;
2973 if (found_in_nid_list(nid, spec->multiout.hp_out_nid,
2974 ARRAY_SIZE(spec->multiout.hp_out_nid)))
2975 continue;
2976 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2977 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2978 continue;
2979 return nid;
2980 } 2997 }
2981 return 0; 2998 return 0;
2982} 2999}
@@ -2988,6 +3005,8 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
2988 hda_nid_t srcs[5]; 3005 hda_nid_t srcs[5];
2989 int i, num; 3006 int i, num;
2990 3007
3008 if (!pin || !dac)
3009 return false;
2991 pin = alc_go_down_to_selector(codec, pin); 3010 pin = alc_go_down_to_selector(codec, pin);
2992 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); 3011 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
2993 for (i = 0; i < num; i++) { 3012 for (i = 0; i < num; i++) {
@@ -3000,83 +3019,260 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec,
3000 3019
3001static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) 3020static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
3002{ 3021{
3022 struct alc_spec *spec = codec->spec;
3003 hda_nid_t sel = alc_go_down_to_selector(codec, pin); 3023 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
3004 if (snd_hda_get_conn_list(codec, sel, NULL) == 1) 3024 hda_nid_t nid, nid_found, srcs[5];
3025 int i, num = snd_hda_get_connections(codec, sel, srcs,
3026 ARRAY_SIZE(srcs));
3027 if (num == 1)
3005 return alc_auto_look_for_dac(codec, pin); 3028 return alc_auto_look_for_dac(codec, pin);
3006 return 0; 3029 nid_found = 0;
3030 for (i = 0; i < num; i++) {
3031 if (srcs[i] == spec->mixer_nid)
3032 continue;
3033 nid = alc_auto_mix_to_dac(codec, srcs[i]);
3034 if (nid && !alc_is_dac_already_used(codec, nid)) {
3035 if (nid_found)
3036 return 0;
3037 nid_found = nid;
3038 }
3039 }
3040 return nid_found;
3007} 3041}
3008 3042
3009/* return 0 if no possible DAC is found, 1 if one or more found */ 3043/* mark up volume and mute control NIDs: used during badness parsing and
3010static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, 3044 * at creating actual controls
3011 const hda_nid_t *pins, hda_nid_t *dacs) 3045 */
3046static inline unsigned int get_ctl_pos(unsigned int data)
3012{ 3047{
3013 int i; 3048 hda_nid_t nid = get_amp_nid_(data);
3049 unsigned int dir;
3050 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3051 return 0;
3052 dir = get_amp_direction_(data);
3053 return (nid << 1) | dir;
3054}
3014 3055
3015 if (num_outs && !dacs[0]) { 3056#define is_ctl_used(bits, data) \
3016 dacs[0] = alc_auto_look_for_dac(codec, pins[0]); 3057 test_bit(get_ctl_pos(data), bits)
3017 if (!dacs[0]) 3058#define mark_ctl_usage(bits, data) \
3018 return 0; 3059 set_bit(get_ctl_pos(data), bits)
3019 }
3020 3060
3021 for (i = 1; i < num_outs; i++) 3061static void clear_vol_marks(struct hda_codec *codec)
3022 dacs[i] = get_dac_if_single(codec, pins[i]); 3062{
3023 for (i = 1; i < num_outs; i++) { 3063 struct alc_spec *spec = codec->spec;
3064 memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls));
3065 memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls));
3066}
3067
3068/* badness definition */
3069enum {
3070 /* No primary DAC is found for the main output */
3071 BAD_NO_PRIMARY_DAC = 0x10000,
3072 /* No DAC is found for the extra output */
3073 BAD_NO_DAC = 0x4000,
3074 /* No possible multi-ios */
3075 BAD_MULTI_IO = 0x103,
3076 /* No individual DAC for extra output */
3077 BAD_NO_EXTRA_DAC = 0x102,
3078 /* No individual DAC for extra surrounds */
3079 BAD_NO_EXTRA_SURR_DAC = 0x101,
3080 /* Primary DAC shared with main surrounds */
3081 BAD_SHARED_SURROUND = 0x100,
3082 /* Primary DAC shared with main CLFE */
3083 BAD_SHARED_CLFE = 0x10,
3084 /* Primary DAC shared with extra surrounds */
3085 BAD_SHARED_EXTRA_SURROUND = 0x10,
3086 /* Volume widget is shared */
3087 BAD_SHARED_VOL = 0x10,
3088};
3089
3090static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
3091 hda_nid_t pin, hda_nid_t dac);
3092static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
3093 hda_nid_t pin, hda_nid_t dac);
3094
3095static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin,
3096 hda_nid_t dac)
3097{
3098 struct alc_spec *spec = codec->spec;
3099 hda_nid_t nid;
3100 unsigned int val;
3101 int badness = 0;
3102
3103 nid = alc_look_for_out_vol_nid(codec, pin, dac);
3104 if (nid) {
3105 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3106 if (is_ctl_used(spec->vol_ctls, nid))
3107 badness += BAD_SHARED_VOL;
3108 else
3109 mark_ctl_usage(spec->vol_ctls, val);
3110 } else
3111 badness += BAD_SHARED_VOL;
3112 nid = alc_look_for_out_mute_nid(codec, pin, dac);
3113 if (nid) {
3114 unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
3115 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT)
3116 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3117 else
3118 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
3119 if (is_ctl_used(spec->sw_ctls, val))
3120 badness += BAD_SHARED_VOL;
3121 else
3122 mark_ctl_usage(spec->sw_ctls, val);
3123 } else
3124 badness += BAD_SHARED_VOL;
3125 return badness;
3126}
3127
3128struct badness_table {
3129 int no_primary_dac; /* no primary DAC */
3130 int no_dac; /* no secondary DACs */
3131 int shared_primary; /* primary DAC is shared with main output */
3132 int shared_surr; /* secondary DAC shared with main or primary */
3133 int shared_clfe; /* third DAC shared with main or primary */
3134 int shared_surr_main; /* secondary DAC sahred with main/DAC0 */
3135};
3136
3137static struct badness_table main_out_badness = {
3138 .no_primary_dac = BAD_NO_PRIMARY_DAC,
3139 .no_dac = BAD_NO_DAC,
3140 .shared_primary = BAD_NO_PRIMARY_DAC,
3141 .shared_surr = BAD_SHARED_SURROUND,
3142 .shared_clfe = BAD_SHARED_CLFE,
3143 .shared_surr_main = BAD_SHARED_SURROUND,
3144};
3145
3146static struct badness_table extra_out_badness = {
3147 .no_primary_dac = BAD_NO_DAC,
3148 .no_dac = BAD_NO_DAC,
3149 .shared_primary = BAD_NO_EXTRA_DAC,
3150 .shared_surr = BAD_SHARED_EXTRA_SURROUND,
3151 .shared_clfe = BAD_SHARED_EXTRA_SURROUND,
3152 .shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
3153};
3154
3155/* try to assign DACs to pins and return the resultant badness */
3156static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs,
3157 const hda_nid_t *pins, hda_nid_t *dacs,
3158 const struct badness_table *bad)
3159{
3160 struct alc_spec *spec = codec->spec;
3161 struct auto_pin_cfg *cfg = &spec->autocfg;
3162 int i, j;
3163 int badness = 0;
3164 hda_nid_t dac;
3165
3166 if (!num_outs)
3167 return 0;
3168
3169 for (i = 0; i < num_outs; i++) {
3170 hda_nid_t pin = pins[i];
3024 if (!dacs[i]) 3171 if (!dacs[i])
3025 dacs[i] = alc_auto_look_for_dac(codec, pins[i]); 3172 dacs[i] = alc_auto_look_for_dac(codec, pin);
3173 if (!dacs[i] && !i) {
3174 for (j = 1; j < num_outs; j++) {
3175 if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) {
3176 dacs[0] = dacs[j];
3177 dacs[j] = 0;
3178 break;
3179 }
3180 }
3181 }
3182 dac = dacs[i];
3183 if (!dac) {
3184 if (alc_auto_is_dac_reachable(codec, pin, dacs[0]))
3185 dac = dacs[0];
3186 else if (cfg->line_outs > i &&
3187 alc_auto_is_dac_reachable(codec, pin,
3188 spec->private_dac_nids[i]))
3189 dac = spec->private_dac_nids[i];
3190 if (dac) {
3191 if (!i)
3192 badness += bad->shared_primary;
3193 else if (i == 1)
3194 badness += bad->shared_surr;
3195 else
3196 badness += bad->shared_clfe;
3197 } else if (alc_auto_is_dac_reachable(codec, pin,
3198 spec->private_dac_nids[0])) {
3199 dac = spec->private_dac_nids[0];
3200 badness += bad->shared_surr_main;
3201 } else if (!i)
3202 badness += bad->no_primary_dac;
3203 else
3204 badness += bad->no_dac;
3205 }
3206 if (dac)
3207 badness += eval_shared_vol_badness(codec, pin, dac);
3026 } 3208 }
3027 return 1; 3209
3210 return badness;
3028} 3211}
3029 3212
3030static int alc_auto_fill_multi_ios(struct hda_codec *codec, 3213static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3031 unsigned int location, int offset); 3214 hda_nid_t reference_pin,
3032static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, 3215 bool hardwired, int offset);
3033 hda_nid_t pin, hda_nid_t dac); 3216
3217static bool alc_map_singles(struct hda_codec *codec, int outs,
3218 const hda_nid_t *pins, hda_nid_t *dacs)
3219{
3220 int i;
3221 bool found = false;
3222 for (i = 0; i < outs; i++) {
3223 if (dacs[i])
3224 continue;
3225 dacs[i] = get_dac_if_single(codec, pins[i]);
3226 if (dacs[i])
3227 found = true;
3228 }
3229 return found;
3230}
3034 3231
3035/* fill in the dac_nids table from the parsed pin configuration */ 3232/* fill in the dac_nids table from the parsed pin configuration */
3036static int alc_auto_fill_dac_nids(struct hda_codec *codec) 3233static int fill_and_eval_dacs(struct hda_codec *codec,
3234 bool fill_hardwired,
3235 bool fill_mio_first)
3037{ 3236{
3038 struct alc_spec *spec = codec->spec; 3237 struct alc_spec *spec = codec->spec;
3039 struct auto_pin_cfg *cfg = &spec->autocfg; 3238 struct auto_pin_cfg *cfg = &spec->autocfg;
3040 unsigned int location, defcfg; 3239 int i, err, badness;
3041 int num_pins;
3042 bool redone = false;
3043 int i;
3044 3240
3045 again:
3046 /* set num_dacs once to full for alc_auto_look_for_dac() */ 3241 /* set num_dacs once to full for alc_auto_look_for_dac() */
3047 spec->multiout.num_dacs = cfg->line_outs; 3242 spec->multiout.num_dacs = cfg->line_outs;
3048 spec->multiout.hp_out_nid[0] = 0;
3049 spec->multiout.extra_out_nid[0] = 0;
3050 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3051 spec->multiout.dac_nids = spec->private_dac_nids; 3243 spec->multiout.dac_nids = spec->private_dac_nids;
3244 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
3245 memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
3246 memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
3052 spec->multi_ios = 0; 3247 spec->multi_ios = 0;
3248 clear_vol_marks(codec);
3249 badness = 0;
3053 3250
3054 /* fill hard-wired DACs first */ 3251 /* fill hard-wired DACs first */
3055 if (!redone) { 3252 if (fill_hardwired) {
3056 for (i = 0; i < cfg->line_outs; i++) 3253 bool mapped;
3057 spec->private_dac_nids[i] = 3254 do {
3058 get_dac_if_single(codec, cfg->line_out_pins[i]); 3255 mapped = alc_map_singles(codec, cfg->line_outs,
3059 if (cfg->hp_outs) 3256 cfg->line_out_pins,
3060 spec->multiout.hp_out_nid[0] = 3257 spec->private_dac_nids);
3061 get_dac_if_single(codec, cfg->hp_pins[0]); 3258 mapped |= alc_map_singles(codec, cfg->hp_outs,
3062 if (cfg->speaker_outs) 3259 cfg->hp_pins,
3063 spec->multiout.extra_out_nid[0] = 3260 spec->multiout.hp_out_nid);
3064 get_dac_if_single(codec, cfg->speaker_pins[0]); 3261 mapped |= alc_map_singles(codec, cfg->speaker_outs,
3262 cfg->speaker_pins,
3263 spec->multiout.extra_out_nid);
3264 if (fill_mio_first && cfg->line_outs == 1 &&
3265 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3266 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0);
3267 if (!err)
3268 mapped = true;
3269 }
3270 } while (mapped);
3065 } 3271 }
3066 3272
3067 for (i = 0; i < cfg->line_outs; i++) { 3273 badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins,
3068 hda_nid_t pin = cfg->line_out_pins[i]; 3274 spec->private_dac_nids,
3069 if (spec->private_dac_nids[i]) 3275 &main_out_badness);
3070 continue;
3071 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
3072 if (!spec->private_dac_nids[i] && !redone) {
3073 /* if we can't find primary DACs, re-probe without
3074 * checking the hard-wired DACs
3075 */
3076 redone = true;
3077 goto again;
3078 }
3079 }
3080 3276
3081 /* re-count num_dacs and squash invalid entries */ 3277 /* re-count num_dacs and squash invalid entries */
3082 spec->multiout.num_dacs = 0; 3278 spec->multiout.num_dacs = 0;
@@ -3091,30 +3287,144 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3091 } 3287 }
3092 } 3288 }
3093 3289
3094 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 3290 if (fill_mio_first &&
3291 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3095 /* try to fill multi-io first */ 3292 /* try to fill multi-io first */
3096 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); 3293 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3097 location = get_defcfg_location(defcfg); 3294 if (err < 0)
3098 3295 return err;
3099 num_pins = alc_auto_fill_multi_ios(codec, location, 0); 3296 /* we don't count badness at this stage yet */
3100 if (num_pins > 0) {
3101 spec->multi_ios = num_pins;
3102 spec->ext_channel_count = 2;
3103 spec->multiout.num_dacs = num_pins + 1;
3104 }
3105 } 3297 }
3106 3298
3107 if (cfg->line_out_type != AUTO_PIN_HP_OUT) 3299 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
3108 alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, 3300 err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins,
3109 spec->multiout.hp_out_nid); 3301 spec->multiout.hp_out_nid,
3302 &extra_out_badness);
3303 if (err < 0)
3304 return err;
3305 badness += err;
3306 }
3110 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 3307 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3111 int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, 3308 err = alc_auto_fill_dacs(codec, cfg->speaker_outs,
3112 cfg->speaker_pins, 3309 cfg->speaker_pins,
3113 spec->multiout.extra_out_nid); 3310 spec->multiout.extra_out_nid,
3114 /* if no speaker volume is assigned, try again as the primary 3311 &extra_out_badness);
3115 * output 3312 if (err < 0)
3116 */ 3313 return err;
3117 if (!err && cfg->speaker_outs > 0 && 3314 badness += err;
3315 }
3316 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
3317 err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0);
3318 if (err < 0)
3319 return err;
3320 badness += err;
3321 }
3322 if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3323 /* try multi-ios with HP + inputs */
3324 int offset = 0;
3325 if (cfg->line_outs >= 3)
3326 offset = 1;
3327 err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false,
3328 offset);
3329 if (err < 0)
3330 return err;
3331 badness += err;
3332 }
3333
3334 if (spec->multi_ios == 2) {
3335 for (i = 0; i < 2; i++)
3336 spec->private_dac_nids[spec->multiout.num_dacs++] =
3337 spec->multi_io[i].dac;
3338 spec->ext_channel_count = 2;
3339 } else if (spec->multi_ios) {
3340 spec->multi_ios = 0;
3341 badness += BAD_MULTI_IO;
3342 }
3343
3344 return badness;
3345}
3346
3347#define DEBUG_BADNESS
3348
3349#ifdef DEBUG_BADNESS
3350#define debug_badness snd_printdd
3351#else
3352#define debug_badness(...)
3353#endif
3354
3355static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg)
3356{
3357 debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3358 cfg->line_out_pins[0], cfg->line_out_pins[1],
3359 cfg->line_out_pins[2], cfg->line_out_pins[2],
3360 spec->multiout.dac_nids[0],
3361 spec->multiout.dac_nids[1],
3362 spec->multiout.dac_nids[2],
3363 spec->multiout.dac_nids[3]);
3364 if (spec->multi_ios > 0)
3365 debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
3366 spec->multi_ios,
3367 spec->multi_io[0].pin, spec->multi_io[1].pin,
3368 spec->multi_io[0].dac, spec->multi_io[1].dac);
3369 debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3370 cfg->hp_pins[0], cfg->hp_pins[1],
3371 cfg->hp_pins[2], cfg->hp_pins[2],
3372 spec->multiout.hp_out_nid[0],
3373 spec->multiout.hp_out_nid[1],
3374 spec->multiout.hp_out_nid[2],
3375 spec->multiout.hp_out_nid[3]);
3376 debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
3377 cfg->speaker_pins[0], cfg->speaker_pins[1],
3378 cfg->speaker_pins[2], cfg->speaker_pins[3],
3379 spec->multiout.extra_out_nid[0],
3380 spec->multiout.extra_out_nid[1],
3381 spec->multiout.extra_out_nid[2],
3382 spec->multiout.extra_out_nid[3]);
3383}
3384
3385static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3386{
3387 struct alc_spec *spec = codec->spec;
3388 struct auto_pin_cfg *cfg = &spec->autocfg;
3389 struct auto_pin_cfg *best_cfg;
3390 int best_badness = INT_MAX;
3391 int badness;
3392 bool fill_hardwired = true, fill_mio_first = true;
3393 bool best_wired = true, best_mio = true;
3394 bool hp_spk_swapped = false;
3395
3396 best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
3397 if (!best_cfg)
3398 return -ENOMEM;
3399 *best_cfg = *cfg;
3400
3401 for (;;) {
3402 badness = fill_and_eval_dacs(codec, fill_hardwired,
3403 fill_mio_first);
3404 if (badness < 0)
3405 return badness;
3406 debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
3407 cfg->line_out_type, fill_hardwired, fill_mio_first,
3408 badness);
3409 debug_show_configs(spec, cfg);
3410 if (badness < best_badness) {
3411 best_badness = badness;
3412 *best_cfg = *cfg;
3413 best_wired = fill_hardwired;
3414 best_mio = fill_mio_first;
3415 }
3416 if (!badness)
3417 break;
3418 fill_mio_first = !fill_mio_first;
3419 if (!fill_mio_first)
3420 continue;
3421 fill_hardwired = !fill_hardwired;
3422 if (!fill_hardwired)
3423 continue;
3424 if (hp_spk_swapped)
3425 break;
3426 hp_spk_swapped = true;
3427 if (cfg->speaker_outs > 0 &&
3118 cfg->line_out_type == AUTO_PIN_HP_OUT) { 3428 cfg->line_out_type == AUTO_PIN_HP_OUT) {
3119 cfg->hp_outs = cfg->line_outs; 3429 cfg->hp_outs = cfg->line_outs;
3120 memcpy(cfg->hp_pins, cfg->line_out_pins, 3430 memcpy(cfg->hp_pins, cfg->line_out_pins,
@@ -3125,48 +3435,45 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
3125 cfg->speaker_outs = 0; 3435 cfg->speaker_outs = 0;
3126 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); 3436 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
3127 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; 3437 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
3128 redone = false; 3438 fill_hardwired = true;
3129 goto again; 3439 continue;
3130 } 3440 }
3441 if (cfg->hp_outs > 0 &&
3442 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
3443 cfg->speaker_outs = cfg->line_outs;
3444 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3445 sizeof(cfg->speaker_pins));
3446 cfg->line_outs = cfg->hp_outs;
3447 memcpy(cfg->line_out_pins, cfg->hp_pins,
3448 sizeof(cfg->hp_pins));
3449 cfg->hp_outs = 0;
3450 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3451 cfg->line_out_type = AUTO_PIN_HP_OUT;
3452 fill_hardwired = true;
3453 continue;
3454 }
3455 break;
3131 } 3456 }
3132 3457
3133 if (!spec->multi_ios && 3458 if (badness) {
3134 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && 3459 *cfg = *best_cfg;
3135 cfg->hp_outs) { 3460 fill_and_eval_dacs(codec, best_wired, best_mio);
3136 /* try multi-ios with HP + inputs */
3137 defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]);
3138 location = get_defcfg_location(defcfg);
3139
3140 num_pins = alc_auto_fill_multi_ios(codec, location, 1);
3141 if (num_pins > 0) {
3142 spec->multi_ios = num_pins;
3143 spec->ext_channel_count = 2;
3144 spec->multiout.num_dacs = num_pins + 1;
3145 }
3146 } 3461 }
3462 debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
3463 cfg->line_out_type, best_wired, best_mio);
3464 debug_show_configs(spec, cfg);
3147 3465
3148 if (cfg->line_out_pins[0]) 3466 if (cfg->line_out_pins[0])
3149 spec->vmaster_nid = 3467 spec->vmaster_nid =
3150 alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], 3468 alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0],
3151 spec->multiout.dac_nids[0]); 3469 spec->multiout.dac_nids[0]);
3152 return 0;
3153}
3154 3470
3155static inline unsigned int get_ctl_pos(unsigned int data) 3471 /* clear the bitmap flags for creating controls */
3156{ 3472 clear_vol_marks(codec);
3157 hda_nid_t nid = get_amp_nid_(data); 3473 kfree(best_cfg);
3158 unsigned int dir; 3474 return 0;
3159 if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
3160 return 0;
3161 dir = get_amp_direction_(data);
3162 return (nid << 1) | dir;
3163} 3475}
3164 3476
3165#define is_ctl_used(bits, data) \
3166 test_bit(get_ctl_pos(data), bits)
3167#define mark_ctl_usage(bits, data) \
3168 set_bit(get_ctl_pos(data), bits)
3169
3170static int alc_auto_add_vol_ctl(struct hda_codec *codec, 3477static int alc_auto_add_vol_ctl(struct hda_codec *codec,
3171 const char *pfx, int cidx, 3478 const char *pfx, int cidx,
3172 hda_nid_t nid, unsigned int chs) 3479 hda_nid_t nid, unsigned int chs)
@@ -3278,14 +3585,17 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
3278 dac = spec->multiout.dac_nids[i]; 3585 dac = spec->multiout.dac_nids[i];
3279 if (!dac) 3586 if (!dac)
3280 continue; 3587 continue;
3281 if (i >= cfg->line_outs) 3588 if (i >= cfg->line_outs) {
3282 pin = spec->multi_io[i - 1].pin; 3589 pin = spec->multi_io[i - 1].pin;
3283 else 3590 index = 0;
3591 name = channel_name[i];
3592 } else {
3284 pin = cfg->line_out_pins[i]; 3593 pin = cfg->line_out_pins[i];
3594 name = alc_get_line_out_pfx(spec, i, true, &index);
3595 }
3285 3596
3286 sw = alc_look_for_out_mute_nid(codec, pin, dac); 3597 sw = alc_look_for_out_mute_nid(codec, pin, dac);
3287 vol = alc_look_for_out_vol_nid(codec, pin, dac); 3598 vol = alc_look_for_out_vol_nid(codec, pin, dac);
3288 name = alc_get_line_out_pfx(spec, i, true, &index);
3289 if (!name || !strcmp(name, "CLFE")) { 3599 if (!name || !strcmp(name, "CLFE")) {
3290 /* Center/LFE */ 3600 /* Center/LFE */
3291 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); 3601 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
@@ -3382,41 +3692,31 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
3382 return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); 3692 return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0);
3383 } 3693 }
3384 3694
3385 if (dacs[num_pins - 1]) {
3386 /* OK, we have a multi-output system with individual volumes */
3387 for (i = 0; i < num_pins; i++) {
3388 if (num_pins >= 3) {
3389 snprintf(name, sizeof(name), "%s %s",
3390 pfx, channel_name[i]);
3391 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3392 name, 0);
3393 } else {
3394 err = alc_auto_create_extra_out(codec, pins[i], dacs[i],
3395 pfx, i);
3396 }
3397 if (err < 0)
3398 return err;
3399 }
3400 return 0;
3401 }
3402
3403 /* Let's create a bind-controls */
3404 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw);
3405 if (!ctl)
3406 return -ENOMEM;
3407 n = 0;
3408 for (i = 0; i < num_pins; i++) { 3695 for (i = 0; i < num_pins; i++) {
3409 if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP) 3696 hda_nid_t dac;
3410 ctl->values[n++] = 3697 if (dacs[num_pins - 1])
3411 HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT); 3698 dac = dacs[i]; /* with individual volumes */
3412 } 3699 else
3413 if (n) { 3700 dac = 0;
3414 snprintf(name, sizeof(name), "%s Playback Switch", pfx); 3701 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) {
3415 err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl); 3702 err = alc_auto_create_extra_out(codec, pins[i], dac,
3703 "Bass Speaker", 0);
3704 } else if (num_pins >= 3) {
3705 snprintf(name, sizeof(name), "%s %s",
3706 pfx, channel_name[i]);
3707 err = alc_auto_create_extra_out(codec, pins[i], dac,
3708 name, 0);
3709 } else {
3710 err = alc_auto_create_extra_out(codec, pins[i], dac,
3711 pfx, i);
3712 }
3416 if (err < 0) 3713 if (err < 0)
3417 return err; 3714 return err;
3418 } 3715 }
3716 if (dacs[num_pins - 1])
3717 return 0;
3419 3718
3719 /* Let's create a bind-controls for volumes */
3420 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); 3720 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
3421 if (!ctl) 3721 if (!ctl)
3422 return -ENOMEM; 3722 return -ENOMEM;
@@ -3552,58 +3852,111 @@ static void alc_auto_init_extra_out(struct hda_codec *codec)
3552 } 3852 }
3553} 3853}
3554 3854
3855/* check whether the given pin can be a multi-io pin */
3856static bool can_be_multiio_pin(struct hda_codec *codec,
3857 unsigned int location, hda_nid_t nid)
3858{
3859 unsigned int defcfg, caps;
3860
3861 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3862 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3863 return false;
3864 if (location && get_defcfg_location(defcfg) != location)
3865 return false;
3866 caps = snd_hda_query_pin_caps(codec, nid);
3867 if (!(caps & AC_PINCAP_OUT))
3868 return false;
3869 return true;
3870}
3871
3555/* 3872/*
3556 * multi-io helper 3873 * multi-io helper
3874 *
3875 * When hardwired is set, try to fill ony hardwired pins, and returns
3876 * zero if any pins are filled, non-zero if nothing found.
3877 * When hardwired is off, try to fill possible input pins, and returns
3878 * the badness value.
3557 */ 3879 */
3558static int alc_auto_fill_multi_ios(struct hda_codec *codec, 3880static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3559 unsigned int location, 3881 hda_nid_t reference_pin,
3560 int offset) 3882 bool hardwired, int offset)
3561{ 3883{
3562 struct alc_spec *spec = codec->spec; 3884 struct alc_spec *spec = codec->spec;
3563 struct auto_pin_cfg *cfg = &spec->autocfg; 3885 struct auto_pin_cfg *cfg = &spec->autocfg;
3564 hda_nid_t prime_dac = spec->private_dac_nids[0]; 3886 int type, i, j, dacs, num_pins, old_pins;
3565 int type, i, dacs, num_pins = 0; 3887 unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
3888 unsigned int location = get_defcfg_location(defcfg);
3889 int badness = 0;
3890
3891 old_pins = spec->multi_ios;
3892 if (old_pins >= 2)
3893 goto end_fill;
3894
3895 num_pins = 0;
3896 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3897 for (i = 0; i < cfg->num_inputs; i++) {
3898 if (cfg->inputs[i].type != type)
3899 continue;
3900 if (can_be_multiio_pin(codec, location,
3901 cfg->inputs[i].pin))
3902 num_pins++;
3903 }
3904 }
3905 if (num_pins < 2)
3906 goto end_fill;
3566 3907
3567 dacs = spec->multiout.num_dacs; 3908 dacs = spec->multiout.num_dacs;
3568 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { 3909 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3569 for (i = 0; i < cfg->num_inputs; i++) { 3910 for (i = 0; i < cfg->num_inputs; i++) {
3570 hda_nid_t nid = cfg->inputs[i].pin; 3911 hda_nid_t nid = cfg->inputs[i].pin;
3571 hda_nid_t dac = 0; 3912 hda_nid_t dac = 0;
3572 unsigned int defcfg, caps; 3913
3573 if (cfg->inputs[i].type != type) 3914 if (cfg->inputs[i].type != type)
3574 continue; 3915 continue;
3575 defcfg = snd_hda_codec_get_pincfg(codec, nid); 3916 if (!can_be_multiio_pin(codec, location, nid))
3576 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3577 continue;
3578 if (location && get_defcfg_location(defcfg) != location)
3579 continue; 3917 continue;
3580 caps = snd_hda_query_pin_caps(codec, nid); 3918 for (j = 0; j < spec->multi_ios; j++) {
3581 if (!(caps & AC_PINCAP_OUT)) 3919 if (nid == spec->multi_io[j].pin)
3920 break;
3921 }
3922 if (j < spec->multi_ios)
3582 continue; 3923 continue;
3583 if (offset && offset + num_pins < dacs) { 3924
3584 dac = spec->private_dac_nids[offset + num_pins]; 3925 if (offset && offset + spec->multi_ios < dacs) {
3926 dac = spec->private_dac_nids[offset + spec->multi_ios];
3585 if (!alc_auto_is_dac_reachable(codec, nid, dac)) 3927 if (!alc_auto_is_dac_reachable(codec, nid, dac))
3586 dac = 0; 3928 dac = 0;
3587 } 3929 }
3588 if (!dac) 3930 if (hardwired)
3931 dac = get_dac_if_single(codec, nid);
3932 else if (!dac)
3589 dac = alc_auto_look_for_dac(codec, nid); 3933 dac = alc_auto_look_for_dac(codec, nid);
3590 if (!dac) 3934 if (!dac) {
3935 badness++;
3591 continue; 3936 continue;
3592 spec->multi_io[num_pins].pin = nid; 3937 }
3593 spec->multi_io[num_pins].dac = dac; 3938 spec->multi_io[spec->multi_ios].pin = nid;
3594 num_pins++; 3939 spec->multi_io[spec->multi_ios].dac = dac;
3595 spec->private_dac_nids[spec->multiout.num_dacs++] = dac; 3940 spec->multi_ios++;
3941 if (spec->multi_ios >= 2)
3942 break;
3596 } 3943 }
3597 } 3944 }
3598 spec->multiout.num_dacs = dacs; 3945 end_fill:
3599 if (num_pins < 2) { 3946 if (badness)
3600 /* clear up again */ 3947 badness = BAD_MULTI_IO;
3601 memset(spec->private_dac_nids + dacs, 0, 3948 if (old_pins == spec->multi_ios) {
3602 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs)); 3949 if (hardwired)
3603 spec->private_dac_nids[0] = prime_dac; 3950 return 1; /* nothing found */
3604 return 0; 3951 else
3952 return badness; /* no badness if nothing found */
3953 }
3954 if (!hardwired && spec->multi_ios < 2) {
3955 spec->multi_ios = old_pins;
3956 return badness;
3605 } 3957 }
3606 return num_pins; 3958
3959 return 0;
3607} 3960}
3608 3961
3609static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, 3962static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
@@ -3958,6 +4311,7 @@ static const struct snd_pci_quirk beep_white_list[] = {
3958 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), 4311 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
3959 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), 4312 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
3960 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), 4313 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
4314 SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
3961 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), 4315 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
3962 {} 4316 {}
3963}; 4317};
@@ -4057,6 +4411,9 @@ static int alc_parse_auto_config(struct hda_codec *codec,
4057 if (spec->kctls.list) 4411 if (spec->kctls.list)
4058 add_mixer(spec, spec->kctls.list); 4412 add_mixer(spec, spec->kctls.list);
4059 4413
4414 if (!spec->no_analog && !spec->cap_mixer)
4415 set_capture_mixer(codec);
4416
4060 return 1; 4417 return 1;
4061} 4418}
4062 4419
@@ -4067,26 +4424,47 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4067 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); 4424 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
4068} 4425}
4069 4426
4070#ifdef CONFIG_SND_HDA_POWER_SAVE
4071static const struct hda_amp_list alc880_loopbacks[] = {
4072 { 0x0b, HDA_INPUT, 0 },
4073 { 0x0b, HDA_INPUT, 1 },
4074 { 0x0b, HDA_INPUT, 2 },
4075 { 0x0b, HDA_INPUT, 3 },
4076 { 0x0b, HDA_INPUT, 4 },
4077 { } /* end */
4078};
4079#endif
4080
4081/* 4427/*
4082 * ALC880 fix-ups 4428 * ALC880 fix-ups
4083 */ 4429 */
4084enum { 4430enum {
4431 ALC880_FIXUP_GPIO1,
4085 ALC880_FIXUP_GPIO2, 4432 ALC880_FIXUP_GPIO2,
4086 ALC880_FIXUP_MEDION_RIM, 4433 ALC880_FIXUP_MEDION_RIM,
4434 ALC880_FIXUP_LG,
4435 ALC880_FIXUP_W810,
4436 ALC880_FIXUP_EAPD_COEF,
4437 ALC880_FIXUP_TCL_S700,
4438 ALC880_FIXUP_VOL_KNOB,
4439 ALC880_FIXUP_FUJITSU,
4440 ALC880_FIXUP_F1734,
4441 ALC880_FIXUP_UNIWILL,
4442 ALC880_FIXUP_UNIWILL_DIG,
4443 ALC880_FIXUP_Z71V,
4444 ALC880_FIXUP_3ST_BASE,
4445 ALC880_FIXUP_3ST,
4446 ALC880_FIXUP_3ST_DIG,
4447 ALC880_FIXUP_5ST_BASE,
4448 ALC880_FIXUP_5ST,
4449 ALC880_FIXUP_5ST_DIG,
4450 ALC880_FIXUP_6ST_BASE,
4451 ALC880_FIXUP_6ST,
4452 ALC880_FIXUP_6ST_DIG,
4087}; 4453};
4088 4454
4455/* enable the volume-knob widget support on NID 0x21 */
4456static void alc880_fixup_vol_knob(struct hda_codec *codec,
4457 const struct alc_fixup *fix, int action)
4458{
4459 if (action == ALC_FIXUP_ACT_PROBE)
4460 snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
4461}
4462
4089static const struct alc_fixup alc880_fixups[] = { 4463static const struct alc_fixup alc880_fixups[] = {
4464 [ALC880_FIXUP_GPIO1] = {
4465 .type = ALC_FIXUP_VERBS,
4466 .v.verbs = alc_gpio1_init_verbs,
4467 },
4090 [ALC880_FIXUP_GPIO2] = { 4468 [ALC880_FIXUP_GPIO2] = {
4091 .type = ALC_FIXUP_VERBS, 4469 .type = ALC_FIXUP_VERBS,
4092 .v.verbs = alc_gpio2_init_verbs, 4470 .v.verbs = alc_gpio2_init_verbs,
@@ -4101,40 +4479,323 @@ static const struct alc_fixup alc880_fixups[] = {
4101 .chained = true, 4479 .chained = true,
4102 .chain_id = ALC880_FIXUP_GPIO2, 4480 .chain_id = ALC880_FIXUP_GPIO2,
4103 }, 4481 },
4482 [ALC880_FIXUP_LG] = {
4483 .type = ALC_FIXUP_PINS,
4484 .v.pins = (const struct alc_pincfg[]) {
4485 /* disable bogus unused pins */
4486 { 0x16, 0x411111f0 },
4487 { 0x18, 0x411111f0 },
4488 { 0x1a, 0x411111f0 },
4489 { }
4490 }
4491 },
4492 [ALC880_FIXUP_W810] = {
4493 .type = ALC_FIXUP_PINS,
4494 .v.pins = (const struct alc_pincfg[]) {
4495 /* disable bogus unused pins */
4496 { 0x17, 0x411111f0 },
4497 { }
4498 },
4499 .chained = true,
4500 .chain_id = ALC880_FIXUP_GPIO2,
4501 },
4502 [ALC880_FIXUP_EAPD_COEF] = {
4503 .type = ALC_FIXUP_VERBS,
4504 .v.verbs = (const struct hda_verb[]) {
4505 /* change to EAPD mode */
4506 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4507 { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
4508 {}
4509 },
4510 },
4511 [ALC880_FIXUP_TCL_S700] = {
4512 .type = ALC_FIXUP_VERBS,
4513 .v.verbs = (const struct hda_verb[]) {
4514 /* change to EAPD mode */
4515 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4516 { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
4517 {}
4518 },
4519 .chained = true,
4520 .chain_id = ALC880_FIXUP_GPIO2,
4521 },
4522 [ALC880_FIXUP_VOL_KNOB] = {
4523 .type = ALC_FIXUP_FUNC,
4524 .v.func = alc880_fixup_vol_knob,
4525 },
4526 [ALC880_FIXUP_FUJITSU] = {
4527 /* override all pins as BIOS on old Amilo is broken */
4528 .type = ALC_FIXUP_PINS,
4529 .v.pins = (const struct alc_pincfg[]) {
4530 { 0x14, 0x0121411f }, /* HP */
4531 { 0x15, 0x99030120 }, /* speaker */
4532 { 0x16, 0x99030130 }, /* bass speaker */
4533 { 0x17, 0x411111f0 }, /* N/A */
4534 { 0x18, 0x411111f0 }, /* N/A */
4535 { 0x19, 0x01a19950 }, /* mic-in */
4536 { 0x1a, 0x411111f0 }, /* N/A */
4537 { 0x1b, 0x411111f0 }, /* N/A */
4538 { 0x1c, 0x411111f0 }, /* N/A */
4539 { 0x1d, 0x411111f0 }, /* N/A */
4540 { 0x1e, 0x01454140 }, /* SPDIF out */
4541 { }
4542 },
4543 .chained = true,
4544 .chain_id = ALC880_FIXUP_VOL_KNOB,
4545 },
4546 [ALC880_FIXUP_F1734] = {
4547 /* almost compatible with FUJITSU, but no bass and SPDIF */
4548 .type = ALC_FIXUP_PINS,
4549 .v.pins = (const struct alc_pincfg[]) {
4550 { 0x14, 0x0121411f }, /* HP */
4551 { 0x15, 0x99030120 }, /* speaker */
4552 { 0x16, 0x411111f0 }, /* N/A */
4553 { 0x17, 0x411111f0 }, /* N/A */
4554 { 0x18, 0x411111f0 }, /* N/A */
4555 { 0x19, 0x01a19950 }, /* mic-in */
4556 { 0x1a, 0x411111f0 }, /* N/A */
4557 { 0x1b, 0x411111f0 }, /* N/A */
4558 { 0x1c, 0x411111f0 }, /* N/A */
4559 { 0x1d, 0x411111f0 }, /* N/A */
4560 { 0x1e, 0x411111f0 }, /* N/A */
4561 { }
4562 },
4563 .chained = true,
4564 .chain_id = ALC880_FIXUP_VOL_KNOB,
4565 },
4566 [ALC880_FIXUP_UNIWILL] = {
4567 /* need to fix HP and speaker pins to be parsed correctly */
4568 .type = ALC_FIXUP_PINS,
4569 .v.pins = (const struct alc_pincfg[]) {
4570 { 0x14, 0x0121411f }, /* HP */
4571 { 0x15, 0x99030120 }, /* speaker */
4572 { 0x16, 0x99030130 }, /* bass speaker */
4573 { }
4574 },
4575 },
4576 [ALC880_FIXUP_UNIWILL_DIG] = {
4577 .type = ALC_FIXUP_PINS,
4578 .v.pins = (const struct alc_pincfg[]) {
4579 /* disable bogus unused pins */
4580 { 0x17, 0x411111f0 },
4581 { 0x19, 0x411111f0 },
4582 { 0x1b, 0x411111f0 },
4583 { 0x1f, 0x411111f0 },
4584 { }
4585 }
4586 },
4587 [ALC880_FIXUP_Z71V] = {
4588 .type = ALC_FIXUP_PINS,
4589 .v.pins = (const struct alc_pincfg[]) {
4590 /* set up the whole pins as BIOS is utterly broken */
4591 { 0x14, 0x99030120 }, /* speaker */
4592 { 0x15, 0x0121411f }, /* HP */
4593 { 0x16, 0x411111f0 }, /* N/A */
4594 { 0x17, 0x411111f0 }, /* N/A */
4595 { 0x18, 0x01a19950 }, /* mic-in */
4596 { 0x19, 0x411111f0 }, /* N/A */
4597 { 0x1a, 0x01813031 }, /* line-in */
4598 { 0x1b, 0x411111f0 }, /* N/A */
4599 { 0x1c, 0x411111f0 }, /* N/A */
4600 { 0x1d, 0x411111f0 }, /* N/A */
4601 { 0x1e, 0x0144111e }, /* SPDIF */
4602 { }
4603 }
4604 },
4605 [ALC880_FIXUP_3ST_BASE] = {
4606 .type = ALC_FIXUP_PINS,
4607 .v.pins = (const struct alc_pincfg[]) {
4608 { 0x14, 0x01014010 }, /* line-out */
4609 { 0x15, 0x411111f0 }, /* N/A */
4610 { 0x16, 0x411111f0 }, /* N/A */
4611 { 0x17, 0x411111f0 }, /* N/A */
4612 { 0x18, 0x01a19c30 }, /* mic-in */
4613 { 0x19, 0x0121411f }, /* HP */
4614 { 0x1a, 0x01813031 }, /* line-in */
4615 { 0x1b, 0x02a19c40 }, /* front-mic */
4616 { 0x1c, 0x411111f0 }, /* N/A */
4617 { 0x1d, 0x411111f0 }, /* N/A */
4618 /* 0x1e is filled in below */
4619 { 0x1f, 0x411111f0 }, /* N/A */
4620 { }
4621 }
4622 },
4623 [ALC880_FIXUP_3ST] = {
4624 .type = ALC_FIXUP_PINS,
4625 .v.pins = (const struct alc_pincfg[]) {
4626 { 0x1e, 0x411111f0 }, /* N/A */
4627 { }
4628 },
4629 .chained = true,
4630 .chain_id = ALC880_FIXUP_3ST_BASE,
4631 },
4632 [ALC880_FIXUP_3ST_DIG] = {
4633 .type = ALC_FIXUP_PINS,
4634 .v.pins = (const struct alc_pincfg[]) {
4635 { 0x1e, 0x0144111e }, /* SPDIF */
4636 { }
4637 },
4638 .chained = true,
4639 .chain_id = ALC880_FIXUP_3ST_BASE,
4640 },
4641 [ALC880_FIXUP_5ST_BASE] = {
4642 .type = ALC_FIXUP_PINS,
4643 .v.pins = (const struct alc_pincfg[]) {
4644 { 0x14, 0x01014010 }, /* front */
4645 { 0x15, 0x411111f0 }, /* N/A */
4646 { 0x16, 0x01011411 }, /* CLFE */
4647 { 0x17, 0x01016412 }, /* surr */
4648 { 0x18, 0x01a19c30 }, /* mic-in */
4649 { 0x19, 0x0121411f }, /* HP */
4650 { 0x1a, 0x01813031 }, /* line-in */
4651 { 0x1b, 0x02a19c40 }, /* front-mic */
4652 { 0x1c, 0x411111f0 }, /* N/A */
4653 { 0x1d, 0x411111f0 }, /* N/A */
4654 /* 0x1e is filled in below */
4655 { 0x1f, 0x411111f0 }, /* N/A */
4656 { }
4657 }
4658 },
4659 [ALC880_FIXUP_5ST] = {
4660 .type = ALC_FIXUP_PINS,
4661 .v.pins = (const struct alc_pincfg[]) {
4662 { 0x1e, 0x411111f0 }, /* N/A */
4663 { }
4664 },
4665 .chained = true,
4666 .chain_id = ALC880_FIXUP_5ST_BASE,
4667 },
4668 [ALC880_FIXUP_5ST_DIG] = {
4669 .type = ALC_FIXUP_PINS,
4670 .v.pins = (const struct alc_pincfg[]) {
4671 { 0x1e, 0x0144111e }, /* SPDIF */
4672 { }
4673 },
4674 .chained = true,
4675 .chain_id = ALC880_FIXUP_5ST_BASE,
4676 },
4677 [ALC880_FIXUP_6ST_BASE] = {
4678 .type = ALC_FIXUP_PINS,
4679 .v.pins = (const struct alc_pincfg[]) {
4680 { 0x14, 0x01014010 }, /* front */
4681 { 0x15, 0x01016412 }, /* surr */
4682 { 0x16, 0x01011411 }, /* CLFE */
4683 { 0x17, 0x01012414 }, /* side */
4684 { 0x18, 0x01a19c30 }, /* mic-in */
4685 { 0x19, 0x02a19c40 }, /* front-mic */
4686 { 0x1a, 0x01813031 }, /* line-in */
4687 { 0x1b, 0x0121411f }, /* HP */
4688 { 0x1c, 0x411111f0 }, /* N/A */
4689 { 0x1d, 0x411111f0 }, /* N/A */
4690 /* 0x1e is filled in below */
4691 { 0x1f, 0x411111f0 }, /* N/A */
4692 { }
4693 }
4694 },
4695 [ALC880_FIXUP_6ST] = {
4696 .type = ALC_FIXUP_PINS,
4697 .v.pins = (const struct alc_pincfg[]) {
4698 { 0x1e, 0x411111f0 }, /* N/A */
4699 { }
4700 },
4701 .chained = true,
4702 .chain_id = ALC880_FIXUP_6ST_BASE,
4703 },
4704 [ALC880_FIXUP_6ST_DIG] = {
4705 .type = ALC_FIXUP_PINS,
4706 .v.pins = (const struct alc_pincfg[]) {
4707 { 0x1e, 0x0144111e }, /* SPDIF */
4708 { }
4709 },
4710 .chained = true,
4711 .chain_id = ALC880_FIXUP_6ST_BASE,
4712 },
4104}; 4713};
4105 4714
4106static const struct snd_pci_quirk alc880_fixup_tbl[] = { 4715static const struct snd_pci_quirk alc880_fixup_tbl[] = {
4716 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
4717 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
4718 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
4719 SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
4720 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
4721 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
4722 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
4723 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
4724 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
4725 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
4107 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), 4726 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
4727 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734),
4728 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
4729 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
4730 SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
4731 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
4732 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
4733 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
4734 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
4735
4736 /* Below is the copied entries from alc880_quirks.c.
4737 * It's not quite sure whether BIOS sets the correct pin-config table
4738 * on these machines, thus they are kept to be compatible with
4739 * the old static quirks. Once when it's confirmed to work without
4740 * these overrides, it'd be better to remove.
4741 */
4742 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
4743 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
4744 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
4745 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
4746 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
4747 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
4748 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
4749 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
4750 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
4751 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
4752 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
4753 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
4754 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
4755 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
4756 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
4757 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
4758 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
4759 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
4760 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
4761 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
4762 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
4763 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
4764 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
4765 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4766 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4767 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4768 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4769 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4770 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4771 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
4772 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4773 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4774 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
4775 /* default Intel */
4776 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
4777 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
4778 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
4108 {} 4779 {}
4109}; 4780};
4110 4781
4782static const struct alc_model_fixup alc880_fixup_models[] = {
4783 {.id = ALC880_FIXUP_3ST, .name = "3stack"},
4784 {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
4785 {.id = ALC880_FIXUP_5ST, .name = "5stack"},
4786 {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
4787 {.id = ALC880_FIXUP_6ST, .name = "6stack"},
4788 {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
4789 {}
4790};
4111 4791
4112/*
4113 * board setups
4114 */
4115#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4116#define alc_board_config \
4117 snd_hda_check_board_config
4118#define alc_board_codec_sid_config \
4119 snd_hda_check_board_codec_sid_config
4120#include "alc_quirks.c"
4121#else
4122#define alc_board_config(codec, nums, models, tbl) -1
4123#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
4124#define setup_preset(codec, x) /* NOP */
4125#endif
4126 4792
4127/* 4793/*
4128 * OK, here we have finally the patch for ALC880 4794 * OK, here we have finally the patch for ALC880
4129 */ 4795 */
4130#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4131#include "alc880_quirks.c"
4132#endif
4133
4134static int patch_alc880(struct hda_codec *codec) 4796static int patch_alc880(struct hda_codec *codec)
4135{ 4797{
4136 struct alc_spec *spec; 4798 struct alc_spec *spec;
4137 int board_config;
4138 int err; 4799 int err;
4139 4800
4140 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4801 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -4146,47 +4807,14 @@ static int patch_alc880(struct hda_codec *codec)
4146 spec->mixer_nid = 0x0b; 4807 spec->mixer_nid = 0x0b;
4147 spec->need_dac_fix = 1; 4808 spec->need_dac_fix = 1;
4148 4809
4149 board_config = alc_board_config(codec, ALC880_MODEL_LAST, 4810 alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
4150 alc880_models, alc880_cfg_tbl); 4811 alc880_fixups);
4151 if (board_config < 0) { 4812 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4152 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4153 codec->chip_name);
4154 board_config = ALC_MODEL_AUTO;
4155 }
4156
4157 if (board_config == ALC_MODEL_AUTO) {
4158 alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups);
4159 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4160 }
4161
4162 if (board_config == ALC_MODEL_AUTO) {
4163 /* automatic parse from the BIOS config */
4164 err = alc880_parse_auto_config(codec);
4165 if (err < 0)
4166 goto error;
4167#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4168 else if (!err) {
4169 printk(KERN_INFO
4170 "hda_codec: Cannot set up configuration "
4171 "from BIOS. Using 3-stack mode...\n");
4172 board_config = ALC880_3ST;
4173 }
4174#endif
4175 }
4176
4177 if (board_config != ALC_MODEL_AUTO) {
4178 spec->vmaster_nid = 0x0c;
4179 setup_preset(codec, &alc880_presets[board_config]);
4180 }
4181
4182 if (!spec->no_analog && !spec->adc_nids) {
4183 alc_auto_fill_adc_caps(codec);
4184 alc_rebuild_imux_for_auto_mic(codec);
4185 alc_remove_invalid_adc_nids(codec);
4186 }
4187 4813
4188 if (!spec->no_analog && !spec->cap_mixer) 4814 /* automatic parse from the BIOS config */
4189 set_capture_mixer(codec); 4815 err = alc880_parse_auto_config(codec);
4816 if (err < 0)
4817 goto error;
4190 4818
4191 if (!spec->no_analog) { 4819 if (!spec->no_analog) {
4192 err = snd_hda_attach_beep_device(codec, 0x1); 4820 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4195,17 +4823,9 @@ static int patch_alc880(struct hda_codec *codec)
4195 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4823 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4196 } 4824 }
4197 4825
4198 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4199
4200 codec->patch_ops = alc_patch_ops; 4826 codec->patch_ops = alc_patch_ops;
4201 if (board_config == ALC_MODEL_AUTO) 4827
4202 spec->init_hook = alc_auto_init_std; 4828 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4203 else
4204 codec->patch_ops.build_controls = __alc_build_controls;
4205#ifdef CONFIG_SND_HDA_POWER_SAVE
4206 if (!spec->loopback.amplist)
4207 spec->loopback.amplist = alc880_loopbacks;
4208#endif
4209 4829
4210 return 0; 4830 return 0;
4211 4831
@@ -4225,49 +4845,115 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
4225 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); 4845 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
4226} 4846}
4227 4847
4228#ifdef CONFIG_SND_HDA_POWER_SAVE
4229static const struct hda_amp_list alc260_loopbacks[] = {
4230 { 0x07, HDA_INPUT, 0 },
4231 { 0x07, HDA_INPUT, 1 },
4232 { 0x07, HDA_INPUT, 2 },
4233 { 0x07, HDA_INPUT, 3 },
4234 { 0x07, HDA_INPUT, 4 },
4235 { } /* end */
4236};
4237#endif
4238
4239/* 4848/*
4240 * Pin config fixes 4849 * Pin config fixes
4241 */ 4850 */
4242enum { 4851enum {
4243 PINFIX_HP_DC5750, 4852 ALC260_FIXUP_HP_DC5750,
4853 ALC260_FIXUP_HP_PIN_0F,
4854 ALC260_FIXUP_COEF,
4855 ALC260_FIXUP_GPIO1,
4856 ALC260_FIXUP_GPIO1_TOGGLE,
4857 ALC260_FIXUP_REPLACER,
4858 ALC260_FIXUP_HP_B1900,
4244}; 4859};
4245 4860
4861static void alc260_gpio1_automute(struct hda_codec *codec)
4862{
4863 struct alc_spec *spec = codec->spec;
4864 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4865 spec->hp_jack_present);
4866}
4867
4868static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4869 const struct alc_fixup *fix, int action)
4870{
4871 struct alc_spec *spec = codec->spec;
4872 if (action == ALC_FIXUP_ACT_PROBE) {
4873 /* although the machine has only one output pin, we need to
4874 * toggle GPIO1 according to the jack state
4875 */
4876 spec->automute_hook = alc260_gpio1_automute;
4877 spec->detect_hp = 1;
4878 spec->automute_speaker = 1;
4879 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4880 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4881 spec->unsol_event = alc_sku_unsol_event;
4882 add_verb(codec->spec, alc_gpio1_init_verbs);
4883 }
4884}
4885
4246static const struct alc_fixup alc260_fixups[] = { 4886static const struct alc_fixup alc260_fixups[] = {
4247 [PINFIX_HP_DC5750] = { 4887 [ALC260_FIXUP_HP_DC5750] = {
4248 .type = ALC_FIXUP_PINS, 4888 .type = ALC_FIXUP_PINS,
4249 .v.pins = (const struct alc_pincfg[]) { 4889 .v.pins = (const struct alc_pincfg[]) {
4250 { 0x11, 0x90130110 }, /* speaker */ 4890 { 0x11, 0x90130110 }, /* speaker */
4251 { } 4891 { }
4252 } 4892 }
4253 }, 4893 },
4894 [ALC260_FIXUP_HP_PIN_0F] = {
4895 .type = ALC_FIXUP_PINS,
4896 .v.pins = (const struct alc_pincfg[]) {
4897 { 0x0f, 0x01214000 }, /* HP */
4898 { }
4899 }
4900 },
4901 [ALC260_FIXUP_COEF] = {
4902 .type = ALC_FIXUP_VERBS,
4903 .v.verbs = (const struct hda_verb[]) {
4904 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4905 { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 },
4906 { }
4907 },
4908 .chained = true,
4909 .chain_id = ALC260_FIXUP_HP_PIN_0F,
4910 },
4911 [ALC260_FIXUP_GPIO1] = {
4912 .type = ALC_FIXUP_VERBS,
4913 .v.verbs = alc_gpio1_init_verbs,
4914 },
4915 [ALC260_FIXUP_GPIO1_TOGGLE] = {
4916 .type = ALC_FIXUP_FUNC,
4917 .v.func = alc260_fixup_gpio1_toggle,
4918 .chained = true,
4919 .chain_id = ALC260_FIXUP_HP_PIN_0F,
4920 },
4921 [ALC260_FIXUP_REPLACER] = {
4922 .type = ALC_FIXUP_VERBS,
4923 .v.verbs = (const struct hda_verb[]) {
4924 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4925 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
4926 { }
4927 },
4928 .chained = true,
4929 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
4930 },
4931 [ALC260_FIXUP_HP_B1900] = {
4932 .type = ALC_FIXUP_FUNC,
4933 .v.func = alc260_fixup_gpio1_toggle,
4934 .chained = true,
4935 .chain_id = ALC260_FIXUP_COEF,
4936 }
4254}; 4937};
4255 4938
4256static const struct snd_pci_quirk alc260_fixup_tbl[] = { 4939static const struct snd_pci_quirk alc260_fixup_tbl[] = {
4257 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), 4940 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
4941 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
4942 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
4943 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
4944 SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
4945 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
4946 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
4947 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
4258 {} 4948 {}
4259}; 4949};
4260 4950
4261/* 4951/*
4262 */ 4952 */
4263#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4264#include "alc260_quirks.c"
4265#endif
4266
4267static int patch_alc260(struct hda_codec *codec) 4953static int patch_alc260(struct hda_codec *codec)
4268{ 4954{
4269 struct alc_spec *spec; 4955 struct alc_spec *spec;
4270 int err, board_config; 4956 int err;
4271 4957
4272 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4958 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4273 if (spec == NULL) 4959 if (spec == NULL)
@@ -4277,47 +4963,13 @@ static int patch_alc260(struct hda_codec *codec)
4277 4963
4278 spec->mixer_nid = 0x07; 4964 spec->mixer_nid = 0x07;
4279 4965
4280 board_config = alc_board_config(codec, ALC260_MODEL_LAST, 4966 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
4281 alc260_models, alc260_cfg_tbl); 4967 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4282 if (board_config < 0) {
4283 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4284 codec->chip_name);
4285 board_config = ALC_MODEL_AUTO;
4286 }
4287
4288 if (board_config == ALC_MODEL_AUTO) {
4289 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
4290 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4291 }
4292
4293 if (board_config == ALC_MODEL_AUTO) {
4294 /* automatic parse from the BIOS config */
4295 err = alc260_parse_auto_config(codec);
4296 if (err < 0)
4297 goto error;
4298#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4299 else if (!err) {
4300 printk(KERN_INFO
4301 "hda_codec: Cannot set up configuration "
4302 "from BIOS. Using base mode...\n");
4303 board_config = ALC260_BASIC;
4304 }
4305#endif
4306 }
4307
4308 if (board_config != ALC_MODEL_AUTO) {
4309 setup_preset(codec, &alc260_presets[board_config]);
4310 spec->vmaster_nid = 0x08;
4311 }
4312
4313 if (!spec->no_analog && !spec->adc_nids) {
4314 alc_auto_fill_adc_caps(codec);
4315 alc_rebuild_imux_for_auto_mic(codec);
4316 alc_remove_invalid_adc_nids(codec);
4317 }
4318 4968
4319 if (!spec->no_analog && !spec->cap_mixer) 4969 /* automatic parse from the BIOS config */
4320 set_capture_mixer(codec); 4970 err = alc260_parse_auto_config(codec);
4971 if (err < 0)
4972 goto error;
4321 4973
4322 if (!spec->no_analog) { 4974 if (!spec->no_analog) {
4323 err = snd_hda_attach_beep_device(codec, 0x1); 4975 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4326,18 +4978,10 @@ static int patch_alc260(struct hda_codec *codec)
4326 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 4978 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
4327 } 4979 }
4328 4980
4329 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4330
4331 codec->patch_ops = alc_patch_ops; 4981 codec->patch_ops = alc_patch_ops;
4332 if (board_config == ALC_MODEL_AUTO)
4333 spec->init_hook = alc_auto_init_std;
4334 else
4335 codec->patch_ops.build_controls = __alc_build_controls;
4336 spec->shutup = alc_eapd_shutup; 4982 spec->shutup = alc_eapd_shutup;
4337#ifdef CONFIG_SND_HDA_POWER_SAVE 4983
4338 if (!spec->loopback.amplist) 4984 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4339 spec->loopback.amplist = alc260_loopbacks;
4340#endif
4341 4985
4342 return 0; 4986 return 0;
4343 4987
@@ -4358,9 +5002,6 @@ static int patch_alc260(struct hda_codec *codec)
4358 * In addition, an independent DAC for the multi-playback (not used in this 5002 * In addition, an independent DAC for the multi-playback (not used in this
4359 * driver yet). 5003 * driver yet).
4360 */ 5004 */
4361#ifdef CONFIG_SND_HDA_POWER_SAVE
4362#define alc882_loopbacks alc880_loopbacks
4363#endif
4364 5005
4365/* 5006/*
4366 * Pin config fixes 5007 * Pin config fixes
@@ -4377,6 +5018,8 @@ enum {
4377 ALC882_FIXUP_EAPD, 5018 ALC882_FIXUP_EAPD,
4378 ALC883_FIXUP_EAPD, 5019 ALC883_FIXUP_EAPD,
4379 ALC883_FIXUP_ACER_EAPD, 5020 ALC883_FIXUP_ACER_EAPD,
5021 ALC882_FIXUP_GPIO1,
5022 ALC882_FIXUP_GPIO2,
4380 ALC882_FIXUP_GPIO3, 5023 ALC882_FIXUP_GPIO3,
4381 ALC889_FIXUP_COEF, 5024 ALC889_FIXUP_COEF,
4382 ALC882_FIXUP_ASUS_W2JC, 5025 ALC882_FIXUP_ASUS_W2JC,
@@ -4385,6 +5028,8 @@ enum {
4385 ALC882_FIXUP_ASPIRE_8930G_VERBS, 5028 ALC882_FIXUP_ASPIRE_8930G_VERBS,
4386 ALC885_FIXUP_MACPRO_GPIO, 5029 ALC885_FIXUP_MACPRO_GPIO,
4387 ALC889_FIXUP_DAC_ROUTE, 5030 ALC889_FIXUP_DAC_ROUTE,
5031 ALC889_FIXUP_MBP_VREF,
5032 ALC889_FIXUP_IMAC91_VREF,
4388}; 5033};
4389 5034
4390static void alc889_fixup_coef(struct hda_codec *codec, 5035static void alc889_fixup_coef(struct hda_codec *codec,
@@ -4463,6 +5108,51 @@ static void alc889_fixup_dac_route(struct hda_codec *codec,
4463 } 5108 }
4464} 5109}
4465 5110
5111/* Set VREF on HP pin */
5112static void alc889_fixup_mbp_vref(struct hda_codec *codec,
5113 const struct alc_fixup *fix, int action)
5114{
5115 struct alc_spec *spec = codec->spec;
5116 static hda_nid_t nids[2] = { 0x14, 0x15 };
5117 int i;
5118
5119 if (action != ALC_FIXUP_ACT_INIT)
5120 return;
5121 for (i = 0; i < ARRAY_SIZE(nids); i++) {
5122 unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
5123 if (get_defcfg_device(val) != AC_JACK_HP_OUT)
5124 continue;
5125 val = snd_hda_codec_read(codec, nids[i], 0,
5126 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5127 val |= AC_PINCTL_VREF_80;
5128 snd_hda_codec_write(codec, nids[i], 0,
5129 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5130 spec->keep_vref_in_automute = 1;
5131 break;
5132 }
5133}
5134
5135/* Set VREF on speaker pins on imac91 */
5136static void alc889_fixup_imac91_vref(struct hda_codec *codec,
5137 const struct alc_fixup *fix, int action)
5138{
5139 struct alc_spec *spec = codec->spec;
5140 static hda_nid_t nids[2] = { 0x18, 0x1a };
5141 int i;
5142
5143 if (action != ALC_FIXUP_ACT_INIT)
5144 return;
5145 for (i = 0; i < ARRAY_SIZE(nids); i++) {
5146 unsigned int val;
5147 val = snd_hda_codec_read(codec, nids[i], 0,
5148 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
5149 val |= AC_PINCTL_VREF_50;
5150 snd_hda_codec_write(codec, nids[i], 0,
5151 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
5152 }
5153 spec->keep_vref_in_automute = 1;
5154}
5155
4466static const struct alc_fixup alc882_fixups[] = { 5156static const struct alc_fixup alc882_fixups[] = {
4467 [ALC882_FIXUP_ABIT_AW9D_MAX] = { 5157 [ALC882_FIXUP_ABIT_AW9D_MAX] = {
4468 .type = ALC_FIXUP_PINS, 5158 .type = ALC_FIXUP_PINS,
@@ -4548,6 +5238,14 @@ static const struct alc_fixup alc882_fixups[] = {
4548 { } 5238 { }
4549 } 5239 }
4550 }, 5240 },
5241 [ALC882_FIXUP_GPIO1] = {
5242 .type = ALC_FIXUP_VERBS,
5243 .v.verbs = alc_gpio1_init_verbs,
5244 },
5245 [ALC882_FIXUP_GPIO2] = {
5246 .type = ALC_FIXUP_VERBS,
5247 .v.verbs = alc_gpio2_init_verbs,
5248 },
4551 [ALC882_FIXUP_GPIO3] = { 5249 [ALC882_FIXUP_GPIO3] = {
4552 .type = ALC_FIXUP_VERBS, 5250 .type = ALC_FIXUP_VERBS,
4553 .v.verbs = alc_gpio3_init_verbs, 5251 .v.verbs = alc_gpio3_init_verbs,
@@ -4621,6 +5319,18 @@ static const struct alc_fixup alc882_fixups[] = {
4621 .type = ALC_FIXUP_FUNC, 5319 .type = ALC_FIXUP_FUNC,
4622 .v.func = alc889_fixup_dac_route, 5320 .v.func = alc889_fixup_dac_route,
4623 }, 5321 },
5322 [ALC889_FIXUP_MBP_VREF] = {
5323 .type = ALC_FIXUP_FUNC,
5324 .v.func = alc889_fixup_mbp_vref,
5325 .chained = true,
5326 .chain_id = ALC882_FIXUP_GPIO1,
5327 },
5328 [ALC889_FIXUP_IMAC91_VREF] = {
5329 .type = ALC_FIXUP_FUNC,
5330 .v.func = alc889_fixup_imac91_vref,
5331 .chained = true,
5332 .chain_id = ALC882_FIXUP_GPIO1,
5333 },
4624}; 5334};
4625 5335
4626static const struct snd_pci_quirk alc882_fixup_tbl[] = { 5336static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -4654,11 +5364,26 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
4654 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), 5364 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
4655 5365
4656 /* All Apple entries are in codec SSIDs */ 5366 /* All Apple entries are in codec SSIDs */
5367 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
5368 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
5369 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
4657 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), 5370 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO),
4658 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), 5371 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
4659 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), 5372 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
5373 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
5374 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
4660 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), 5375 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
5376 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF),
5377 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF),
5378 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
5379 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
4661 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), 5380 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
5381 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
5382 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
5383 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
5384 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
5385 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
5386 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF),
4662 5387
4663 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), 5388 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
4664 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), 5389 SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
@@ -4684,14 +5409,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
4684 5409
4685/* 5410/*
4686 */ 5411 */
4687#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4688#include "alc882_quirks.c"
4689#endif
4690
4691static int patch_alc882(struct hda_codec *codec) 5412static int patch_alc882(struct hda_codec *codec)
4692{ 5413{
4693 struct alc_spec *spec; 5414 struct alc_spec *spec;
4694 int err, board_config; 5415 int err;
4695 5416
4696 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5417 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4697 if (spec == NULL) 5418 if (spec == NULL)
@@ -4715,45 +5436,15 @@ static int patch_alc882(struct hda_codec *codec)
4715 if (err < 0) 5436 if (err < 0)
4716 goto error; 5437 goto error;
4717 5438
4718 board_config = alc_board_config(codec, ALC882_MODEL_LAST, 5439 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
4719 alc882_models, NULL); 5440 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4720 if (board_config < 0)
4721 board_config = alc_board_codec_sid_config(codec,
4722 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
4723
4724 if (board_config < 0) {
4725 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4726 codec->chip_name);
4727 board_config = ALC_MODEL_AUTO;
4728 }
4729
4730 if (board_config == ALC_MODEL_AUTO) {
4731 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
4732 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
4733 }
4734 5441
4735 alc_auto_parse_customize_define(codec); 5442 alc_auto_parse_customize_define(codec);
4736 5443
4737 if (board_config == ALC_MODEL_AUTO) { 5444 /* automatic parse from the BIOS config */
4738 /* automatic parse from the BIOS config */ 5445 err = alc882_parse_auto_config(codec);
4739 err = alc882_parse_auto_config(codec); 5446 if (err < 0)
4740 if (err < 0) 5447 goto error;
4741 goto error;
4742 }
4743
4744 if (board_config != ALC_MODEL_AUTO) {
4745 setup_preset(codec, &alc882_presets[board_config]);
4746 spec->vmaster_nid = 0x0c;
4747 }
4748
4749 if (!spec->no_analog && !spec->adc_nids) {
4750 alc_auto_fill_adc_caps(codec);
4751 alc_rebuild_imux_for_auto_mic(codec);
4752 alc_remove_invalid_adc_nids(codec);
4753 }
4754
4755 if (!spec->no_analog && !spec->cap_mixer)
4756 set_capture_mixer(codec);
4757 5448
4758 if (!spec->no_analog && has_cdefine_beep(codec)) { 5449 if (!spec->no_analog && has_cdefine_beep(codec)) {
4759 err = snd_hda_attach_beep_device(codec, 0x1); 5450 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -4762,18 +5453,9 @@ static int patch_alc882(struct hda_codec *codec)
4762 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5453 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4763 } 5454 }
4764 5455
4765 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4766
4767 codec->patch_ops = alc_patch_ops; 5456 codec->patch_ops = alc_patch_ops;
4768 if (board_config == ALC_MODEL_AUTO)
4769 spec->init_hook = alc_auto_init_std;
4770 else
4771 codec->patch_ops.build_controls = __alc_build_controls;
4772 5457
4773#ifdef CONFIG_SND_HDA_POWER_SAVE 5458 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4774 if (!spec->loopback.amplist)
4775 spec->loopback.amplist = alc882_loopbacks;
4776#endif
4777 5459
4778 return 0; 5460 return 0;
4779 5461
@@ -4869,10 +5551,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4869}; 5551};
4870 5552
4871 5553
4872#ifdef CONFIG_SND_HDA_POWER_SAVE
4873#define alc262_loopbacks alc880_loopbacks
4874#endif
4875
4876/* 5554/*
4877 */ 5555 */
4878static int patch_alc262(struct hda_codec *codec) 5556static int patch_alc262(struct hda_codec *codec)
@@ -4912,15 +5590,6 @@ static int patch_alc262(struct hda_codec *codec)
4912 if (err < 0) 5590 if (err < 0)
4913 goto error; 5591 goto error;
4914 5592
4915 if (!spec->no_analog && !spec->adc_nids) {
4916 alc_auto_fill_adc_caps(codec);
4917 alc_rebuild_imux_for_auto_mic(codec);
4918 alc_remove_invalid_adc_nids(codec);
4919 }
4920
4921 if (!spec->no_analog && !spec->cap_mixer)
4922 set_capture_mixer(codec);
4923
4924 if (!spec->no_analog && has_cdefine_beep(codec)) { 5593 if (!spec->no_analog && has_cdefine_beep(codec)) {
4925 err = snd_hda_attach_beep_device(codec, 0x1); 5594 err = snd_hda_attach_beep_device(codec, 0x1);
4926 if (err < 0) 5595 if (err < 0)
@@ -4928,16 +5597,10 @@ static int patch_alc262(struct hda_codec *codec)
4928 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5597 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4929 } 5598 }
4930 5599
4931 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4932
4933 codec->patch_ops = alc_patch_ops; 5600 codec->patch_ops = alc_patch_ops;
4934 spec->init_hook = alc_auto_init_std;
4935 spec->shutup = alc_eapd_shutup; 5601 spec->shutup = alc_eapd_shutup;
4936 5602
4937#ifdef CONFIG_SND_HDA_POWER_SAVE 5603 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
4938 if (!spec->loopback.amplist)
4939 spec->loopback.amplist = alc262_loopbacks;
4940#endif
4941 5604
4942 return 0; 5605 return 0;
4943 5606
@@ -5031,17 +5694,7 @@ static int patch_alc268(struct hda_codec *codec)
5031 (0 << AC_AMPCAP_MUTE_SHIFT)); 5694 (0 << AC_AMPCAP_MUTE_SHIFT));
5032 } 5695 }
5033 5696
5034 if (!spec->no_analog && !spec->adc_nids) {
5035 alc_auto_fill_adc_caps(codec);
5036 alc_rebuild_imux_for_auto_mic(codec);
5037 alc_remove_invalid_adc_nids(codec);
5038 }
5039
5040 if (!spec->no_analog && !spec->cap_mixer)
5041 set_capture_mixer(codec);
5042
5043 codec->patch_ops = alc_patch_ops; 5697 codec->patch_ops = alc_patch_ops;
5044 spec->init_hook = alc_auto_init_std;
5045 spec->shutup = alc_eapd_shutup; 5698 spec->shutup = alc_eapd_shutup;
5046 5699
5047 return 0; 5700 return 0;
@@ -5054,10 +5707,6 @@ static int patch_alc268(struct hda_codec *codec)
5054/* 5707/*
5055 * ALC269 5708 * ALC269
5056 */ 5709 */
5057#ifdef CONFIG_SND_HDA_POWER_SAVE
5058#define alc269_loopbacks alc880_loopbacks
5059#endif
5060
5061static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 5710static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
5062 .substreams = 1, 5711 .substreams = 1,
5063 .channels_min = 2, 5712 .channels_min = 2,
@@ -5079,35 +5728,6 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
5079 /* NID is set in alc_build_pcms */ 5728 /* NID is set in alc_build_pcms */
5080}; 5729};
5081 5730
5082#ifdef CONFIG_SND_HDA_POWER_SAVE
5083static int alc269_mic2_for_mute_led(struct hda_codec *codec)
5084{
5085 switch (codec->subsystem_id) {
5086 case 0x103c1586:
5087 return 1;
5088 }
5089 return 0;
5090}
5091
5092static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
5093{
5094 /* update mute-LED according to the speaker mute state */
5095 if (nid == 0x01 || nid == 0x14) {
5096 int pinval;
5097 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
5098 HDA_AMP_MUTE)
5099 pinval = 0x24;
5100 else
5101 pinval = 0x20;
5102 /* mic2 vref pin is used for mute LED control */
5103 snd_hda_codec_update_cache(codec, 0x19, 0,
5104 AC_VERB_SET_PIN_WIDGET_CONTROL,
5105 pinval);
5106 }
5107 return alc_check_power_status(codec, nid);
5108}
5109#endif /* CONFIG_SND_HDA_POWER_SAVE */
5110
5111/* different alc269-variants */ 5731/* different alc269-variants */
5112enum { 5732enum {
5113 ALC269_TYPE_ALC269VA, 5733 ALC269_TYPE_ALC269VA,
@@ -5258,6 +5878,31 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec,
5258 spec->automute_hook = alc269_quanta_automute; 5878 spec->automute_hook = alc269_quanta_automute;
5259} 5879}
5260 5880
5881/* update mute-LED according to the speaker mute state via mic2 VREF pin */
5882static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
5883{
5884 struct hda_codec *codec = private_data;
5885 unsigned int pinval = enabled ? 0x20 : 0x24;
5886 snd_hda_codec_update_cache(codec, 0x19, 0,
5887 AC_VERB_SET_PIN_WIDGET_CONTROL,
5888 pinval);
5889}
5890
5891static void alc269_fixup_mic2_mute(struct hda_codec *codec,
5892 const struct alc_fixup *fix, int action)
5893{
5894 struct alc_spec *spec = codec->spec;
5895 switch (action) {
5896 case ALC_FIXUP_ACT_BUILD:
5897 spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook;
5898 snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
5899 /* fallthru */
5900 case ALC_FIXUP_ACT_INIT:
5901 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
5902 break;
5903 }
5904}
5905
5261enum { 5906enum {
5262 ALC269_FIXUP_SONY_VAIO, 5907 ALC269_FIXUP_SONY_VAIO,
5263 ALC275_FIXUP_SONY_VAIO_GPIO2, 5908 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -5275,6 +5920,7 @@ enum {
5275 ALC269_FIXUP_DMIC, 5920 ALC269_FIXUP_DMIC,
5276 ALC269VB_FIXUP_AMIC, 5921 ALC269VB_FIXUP_AMIC,
5277 ALC269VB_FIXUP_DMIC, 5922 ALC269VB_FIXUP_DMIC,
5923 ALC269_FIXUP_MIC2_MUTE_LED,
5278}; 5924};
5279 5925
5280static const struct alc_fixup alc269_fixups[] = { 5926static const struct alc_fixup alc269_fixups[] = {
@@ -5395,9 +6041,14 @@ static const struct alc_fixup alc269_fixups[] = {
5395 { } 6041 { }
5396 }, 6042 },
5397 }, 6043 },
6044 [ALC269_FIXUP_MIC2_MUTE_LED] = {
6045 .type = ALC_FIXUP_FUNC,
6046 .v.func = alc269_fixup_mic2_mute,
6047 },
5398}; 6048};
5399 6049
5400static const struct snd_pci_quirk alc269_fixup_tbl[] = { 6050static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6051 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
5401 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 6052 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5402 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 6053 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5403 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 6054 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
@@ -5420,7 +6071,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5420 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), 6071 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
5421 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 6072 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5422 6073
5423#if 1 6074#if 0
5424 /* Below is a quirk table taken from the old code. 6075 /* Below is a quirk table taken from the old code.
5425 * Basically the device should work as is without the fixup table. 6076 * Basically the device should work as is without the fixup table.
5426 * If BIOS doesn't give a proper info, enable the corresponding 6077 * If BIOS doesn't give a proper info, enable the corresponding
@@ -5478,13 +6129,13 @@ static const struct alc_model_fixup alc269_fixup_models[] = {
5478}; 6129};
5479 6130
5480 6131
5481static int alc269_fill_coef(struct hda_codec *codec) 6132static void alc269_fill_coef(struct hda_codec *codec)
5482{ 6133{
5483 struct alc_spec *spec = codec->spec; 6134 struct alc_spec *spec = codec->spec;
5484 int val; 6135 int val;
5485 6136
5486 if (spec->codec_variant != ALC269_TYPE_ALC269VB) 6137 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
5487 return 0; 6138 return;
5488 6139
5489 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { 6140 if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
5490 alc_write_coef_idx(codec, 0xf, 0x960b); 6141 alc_write_coef_idx(codec, 0xf, 0x960b);
@@ -5520,8 +6171,6 @@ static int alc269_fill_coef(struct hda_codec *codec)
5520 6171
5521 val = alc_read_coef_idx(codec, 0x4); /* HP */ 6172 val = alc_read_coef_idx(codec, 0x4); /* HP */
5522 alc_write_coef_idx(codec, 0x4, val | (1<<11)); 6173 alc_write_coef_idx(codec, 0x4, val | (1<<11));
5523
5524 return 0;
5525} 6174}
5526 6175
5527/* 6176/*
@@ -5565,6 +6214,7 @@ static int patch_alc269(struct hda_codec *codec)
5565 } 6214 }
5566 if (err < 0) 6215 if (err < 0)
5567 goto error; 6216 goto error;
6217 spec->init_hook = alc269_fill_coef;
5568 alc269_fill_coef(codec); 6218 alc269_fill_coef(codec);
5569 } 6219 }
5570 6220
@@ -5577,15 +6227,6 @@ static int patch_alc269(struct hda_codec *codec)
5577 if (err < 0) 6227 if (err < 0)
5578 goto error; 6228 goto error;
5579 6229
5580 if (!spec->no_analog && !spec->adc_nids) {
5581 alc_auto_fill_adc_caps(codec);
5582 alc_rebuild_imux_for_auto_mic(codec);
5583 alc_remove_invalid_adc_nids(codec);
5584 }
5585
5586 if (!spec->no_analog && !spec->cap_mixer)
5587 set_capture_mixer(codec);
5588
5589 if (!spec->no_analog && has_cdefine_beep(codec)) { 6230 if (!spec->no_analog && has_cdefine_beep(codec)) {
5590 err = snd_hda_attach_beep_device(codec, 0x1); 6231 err = snd_hda_attach_beep_device(codec, 0x1);
5591 if (err < 0) 6232 if (err < 0)
@@ -5593,21 +6234,13 @@ static int patch_alc269(struct hda_codec *codec)
5593 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 6234 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
5594 } 6235 }
5595 6236
5596 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5597
5598 codec->patch_ops = alc_patch_ops; 6237 codec->patch_ops = alc_patch_ops;
5599#ifdef CONFIG_PM 6238#ifdef CONFIG_PM
5600 codec->patch_ops.resume = alc269_resume; 6239 codec->patch_ops.resume = alc269_resume;
5601#endif 6240#endif
5602 spec->init_hook = alc_auto_init_std;
5603 spec->shutup = alc269_shutup; 6241 spec->shutup = alc269_shutup;
5604 6242
5605#ifdef CONFIG_SND_HDA_POWER_SAVE 6243 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5606 if (!spec->loopback.amplist)
5607 spec->loopback.amplist = alc269_loopbacks;
5608 if (alc269_mic2_for_mute_led(codec))
5609 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
5610#endif
5611 6244
5612 return 0; 6245 return 0;
5613 6246
@@ -5627,21 +6260,12 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
5627 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); 6260 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
5628} 6261}
5629 6262
5630#ifdef CONFIG_SND_HDA_POWER_SAVE
5631static const struct hda_amp_list alc861_loopbacks[] = {
5632 { 0x15, HDA_INPUT, 0 },
5633 { 0x15, HDA_INPUT, 1 },
5634 { 0x15, HDA_INPUT, 2 },
5635 { 0x15, HDA_INPUT, 3 },
5636 { } /* end */
5637};
5638#endif
5639
5640
5641/* Pin config fixes */ 6263/* Pin config fixes */
5642enum { 6264enum {
5643 PINFIX_FSC_AMILO_PI1505, 6265 ALC861_FIXUP_FSC_AMILO_PI1505,
5644 PINFIX_ASUS_A6RP, 6266 ALC861_FIXUP_AMP_VREF_0F,
6267 ALC861_FIXUP_NO_JACK_DETECT,
6268 ALC861_FIXUP_ASUS_A6RP,
5645}; 6269};
5646 6270
5647/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ 6271/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
@@ -5663,8 +6287,16 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
5663 spec->keep_vref_in_automute = 1; 6287 spec->keep_vref_in_automute = 1;
5664} 6288}
5665 6289
6290/* suppress the jack-detection */
6291static void alc_fixup_no_jack_detect(struct hda_codec *codec,
6292 const struct alc_fixup *fix, int action)
6293{
6294 if (action == ALC_FIXUP_ACT_PRE_PROBE)
6295 codec->no_jack_detect = 1;
6296}
6297
5666static const struct alc_fixup alc861_fixups[] = { 6298static const struct alc_fixup alc861_fixups[] = {
5667 [PINFIX_FSC_AMILO_PI1505] = { 6299 [ALC861_FIXUP_FSC_AMILO_PI1505] = {
5668 .type = ALC_FIXUP_PINS, 6300 .type = ALC_FIXUP_PINS,
5669 .v.pins = (const struct alc_pincfg[]) { 6301 .v.pins = (const struct alc_pincfg[]) {
5670 { 0x0b, 0x0221101f }, /* HP */ 6302 { 0x0b, 0x0221101f }, /* HP */
@@ -5672,17 +6304,29 @@ static const struct alc_fixup alc861_fixups[] = {
5672 { } 6304 { }
5673 } 6305 }
5674 }, 6306 },
5675 [PINFIX_ASUS_A6RP] = { 6307 [ALC861_FIXUP_AMP_VREF_0F] = {
5676 .type = ALC_FIXUP_FUNC, 6308 .type = ALC_FIXUP_FUNC,
5677 .v.func = alc861_fixup_asus_amp_vref_0f, 6309 .v.func = alc861_fixup_asus_amp_vref_0f,
5678 }, 6310 },
6311 [ALC861_FIXUP_NO_JACK_DETECT] = {
6312 .type = ALC_FIXUP_FUNC,
6313 .v.func = alc_fixup_no_jack_detect,
6314 },
6315 [ALC861_FIXUP_ASUS_A6RP] = {
6316 .type = ALC_FIXUP_FUNC,
6317 .v.func = alc861_fixup_asus_amp_vref_0f,
6318 .chained = true,
6319 .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
6320 }
5679}; 6321};
5680 6322
5681static const struct snd_pci_quirk alc861_fixup_tbl[] = { 6323static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5682 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), 6324 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
5683 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP), 6325 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
5684 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), 6326 SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
5685 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 6327 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
6328 SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
6329 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
5686 {} 6330 {}
5687}; 6331};
5688 6332
@@ -5709,15 +6353,6 @@ static int patch_alc861(struct hda_codec *codec)
5709 if (err < 0) 6353 if (err < 0)
5710 goto error; 6354 goto error;
5711 6355
5712 if (!spec->no_analog && !spec->adc_nids) {
5713 alc_auto_fill_adc_caps(codec);
5714 alc_rebuild_imux_for_auto_mic(codec);
5715 alc_remove_invalid_adc_nids(codec);
5716 }
5717
5718 if (!spec->no_analog && !spec->cap_mixer)
5719 set_capture_mixer(codec);
5720
5721 if (!spec->no_analog) { 6356 if (!spec->no_analog) {
5722 err = snd_hda_attach_beep_device(codec, 0x23); 6357 err = snd_hda_attach_beep_device(codec, 0x23);
5723 if (err < 0) 6358 if (err < 0)
@@ -5725,16 +6360,13 @@ static int patch_alc861(struct hda_codec *codec)
5725 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 6360 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
5726 } 6361 }
5727 6362
5728 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5729
5730 codec->patch_ops = alc_patch_ops; 6363 codec->patch_ops = alc_patch_ops;
5731 spec->init_hook = alc_auto_init_std;
5732#ifdef CONFIG_SND_HDA_POWER_SAVE 6364#ifdef CONFIG_SND_HDA_POWER_SAVE
5733 spec->power_hook = alc_power_eapd; 6365 spec->power_hook = alc_power_eapd;
5734 if (!spec->loopback.amplist)
5735 spec->loopback.amplist = alc861_loopbacks;
5736#endif 6366#endif
5737 6367
6368 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6369
5738 return 0; 6370 return 0;
5739 6371
5740 error: 6372 error:
@@ -5749,10 +6381,6 @@ static int patch_alc861(struct hda_codec *codec)
5749 * 6381 *
5750 * In addition, an independent DAC 6382 * In addition, an independent DAC
5751 */ 6383 */
5752#ifdef CONFIG_SND_HDA_POWER_SAVE
5753#define alc861vd_loopbacks alc880_loopbacks
5754#endif
5755
5756static int alc861vd_parse_auto_config(struct hda_codec *codec) 6384static int alc861vd_parse_auto_config(struct hda_codec *codec)
5757{ 6385{
5758 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 6386 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
@@ -5833,15 +6461,6 @@ static int patch_alc861vd(struct hda_codec *codec)
5833 add_verb(spec, alc660vd_eapd_verbs); 6461 add_verb(spec, alc660vd_eapd_verbs);
5834 } 6462 }
5835 6463
5836 if (!spec->no_analog && !spec->adc_nids) {
5837 alc_auto_fill_adc_caps(codec);
5838 alc_rebuild_imux_for_auto_mic(codec);
5839 alc_remove_invalid_adc_nids(codec);
5840 }
5841
5842 if (!spec->no_analog && !spec->cap_mixer)
5843 set_capture_mixer(codec);
5844
5845 if (!spec->no_analog) { 6464 if (!spec->no_analog) {
5846 err = snd_hda_attach_beep_device(codec, 0x23); 6465 err = snd_hda_attach_beep_device(codec, 0x23);
5847 if (err < 0) 6466 if (err < 0)
@@ -5849,16 +6468,11 @@ static int patch_alc861vd(struct hda_codec *codec)
5849 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 6468 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5850 } 6469 }
5851 6470
5852 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5853
5854 codec->patch_ops = alc_patch_ops; 6471 codec->patch_ops = alc_patch_ops;
5855 6472
5856 spec->init_hook = alc_auto_init_std;
5857 spec->shutup = alc_eapd_shutup; 6473 spec->shutup = alc_eapd_shutup;
5858#ifdef CONFIG_SND_HDA_POWER_SAVE 6474
5859 if (!spec->loopback.amplist) 6475 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5860 spec->loopback.amplist = alc861vd_loopbacks;
5861#endif
5862 6476
5863 return 0; 6477 return 0;
5864 6478
@@ -5878,9 +6492,6 @@ static int patch_alc861vd(struct hda_codec *codec)
5878 * In addition, an independent DAC for the multi-playback (not used in this 6492 * In addition, an independent DAC for the multi-playback (not used in this
5879 * driver yet). 6493 * driver yet).
5880 */ 6494 */
5881#ifdef CONFIG_SND_HDA_POWER_SAVE
5882#define alc662_loopbacks alc880_loopbacks
5883#endif
5884 6495
5885/* 6496/*
5886 * BIOS auto configuration 6497 * BIOS auto configuration
@@ -5930,6 +6541,7 @@ enum {
5930 ALC662_FIXUP_ASUS_MODE6, 6541 ALC662_FIXUP_ASUS_MODE6,
5931 ALC662_FIXUP_ASUS_MODE7, 6542 ALC662_FIXUP_ASUS_MODE7,
5932 ALC662_FIXUP_ASUS_MODE8, 6543 ALC662_FIXUP_ASUS_MODE8,
6544 ALC662_FIXUP_NO_JACK_DETECT,
5933}; 6545};
5934 6546
5935static const struct alc_fixup alc662_fixups[] = { 6547static const struct alc_fixup alc662_fixups[] = {
@@ -6075,6 +6687,10 @@ static const struct alc_fixup alc662_fixups[] = {
6075 .chained = true, 6687 .chained = true,
6076 .chain_id = ALC662_FIXUP_SKU_IGNORE 6688 .chain_id = ALC662_FIXUP_SKU_IGNORE
6077 }, 6689 },
6690 [ALC662_FIXUP_NO_JACK_DETECT] = {
6691 .type = ALC_FIXUP_FUNC,
6692 .v.func = alc_fixup_no_jack_detect,
6693 },
6078}; 6694};
6079 6695
6080static const struct snd_pci_quirk alc662_fixup_tbl[] = { 6696static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -6083,6 +6699,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6083 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 6699 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6084 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 6700 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6085 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6701 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6702 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
6086 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), 6703 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
6087 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 6704 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
6088 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 6705 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
@@ -6204,15 +6821,6 @@ static int patch_alc662(struct hda_codec *codec)
6204 if (err < 0) 6821 if (err < 0)
6205 goto error; 6822 goto error;
6206 6823
6207 if (!spec->no_analog && !spec->adc_nids) {
6208 alc_auto_fill_adc_caps(codec);
6209 alc_rebuild_imux_for_auto_mic(codec);
6210 alc_remove_invalid_adc_nids(codec);
6211 }
6212
6213 if (!spec->no_analog && !spec->cap_mixer)
6214 set_capture_mixer(codec);
6215
6216 if (!spec->no_analog && has_cdefine_beep(codec)) { 6824 if (!spec->no_analog && has_cdefine_beep(codec)) {
6217 err = snd_hda_attach_beep_device(codec, 0x1); 6825 err = snd_hda_attach_beep_device(codec, 0x1);
6218 if (err < 0) 6826 if (err < 0)
@@ -6232,16 +6840,10 @@ static int patch_alc662(struct hda_codec *codec)
6232 } 6840 }
6233 } 6841 }
6234 6842
6235 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6236
6237 codec->patch_ops = alc_patch_ops; 6843 codec->patch_ops = alc_patch_ops;
6238 spec->init_hook = alc_auto_init_std;
6239 spec->shutup = alc_eapd_shutup; 6844 spec->shutup = alc_eapd_shutup;
6240 6845
6241#ifdef CONFIG_SND_HDA_POWER_SAVE 6846 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
6242 if (!spec->loopback.amplist)
6243 spec->loopback.amplist = alc662_loopbacks;
6244#endif
6245 6847
6246 return 0; 6848 return 0;
6247 6849
@@ -6281,11 +6883,7 @@ static int patch_alc680(struct hda_codec *codec)
6281 return err; 6883 return err;
6282 } 6884 }
6283 6885
6284 if (!spec->no_analog && !spec->cap_mixer)
6285 set_capture_mixer(codec);
6286
6287 codec->patch_ops = alc_patch_ops; 6886 codec->patch_ops = alc_patch_ops;
6288 spec->init_hook = alc_auto_init_std;
6289 6887
6290 return 0; 6888 return 0;
6291} 6889}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 9dbb5735d778..33a9946b492c 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -99,6 +99,7 @@ enum {
99 STAC_DELL_VOSTRO_3500, 99 STAC_DELL_VOSTRO_3500,
100 STAC_92HD83XXX_HP_cNB11_INTQUAD, 100 STAC_92HD83XXX_HP_cNB11_INTQUAD,
101 STAC_HP_DV7_4000, 101 STAC_HP_DV7_4000,
102 STAC_HP_ZEPHYR,
102 STAC_92HD83XXX_MODELS 103 STAC_92HD83XXX_MODELS
103}; 104};
104 105
@@ -309,6 +310,8 @@ struct sigmatel_spec {
309 unsigned long auto_capvols[MAX_ADCS_NUM]; 310 unsigned long auto_capvols[MAX_ADCS_NUM];
310 unsigned auto_dmic_cnt; 311 unsigned auto_dmic_cnt;
311 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; 312 hda_nid_t auto_dmic_nids[MAX_DMICS_NUM];
313
314 struct hda_vmaster_mute_hook vmaster_mute;
312}; 315};
313 316
314static const hda_nid_t stac9200_adc_nids[1] = { 317static const hda_nid_t stac9200_adc_nids[1] = {
@@ -662,7 +665,6 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
662 return 0; 665 return 0;
663} 666}
664 667
665#ifdef CONFIG_SND_HDA_POWER_SAVE
666static int stac_vrefout_set(struct hda_codec *codec, 668static int stac_vrefout_set(struct hda_codec *codec,
667 hda_nid_t nid, unsigned int new_vref) 669 hda_nid_t nid, unsigned int new_vref)
668{ 670{
@@ -686,7 +688,6 @@ static int stac_vrefout_set(struct hda_codec *codec,
686 688
687 return 1; 689 return 1;
688} 690}
689#endif
690 691
691static unsigned int stac92xx_vref_set(struct hda_codec *codec, 692static unsigned int stac92xx_vref_set(struct hda_codec *codec,
692 hda_nid_t nid, unsigned int new_vref) 693 hda_nid_t nid, unsigned int new_vref)
@@ -894,6 +895,13 @@ static const struct hda_verb stac92hd83xxx_core_init[] = {
894 {} 895 {}
895}; 896};
896 897
898static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = {
899 { 0x22, 0x785, 0x43 },
900 { 0x22, 0x782, 0xe0 },
901 { 0x22, 0x795, 0x00 },
902 {}
903};
904
897static const struct hda_verb stac92hd71bxx_core_init[] = { 905static const struct hda_verb stac92hd71bxx_core_init[] = {
898 /* set master volume and direct control */ 906 /* set master volume and direct control */
899 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 907 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -999,8 +1007,8 @@ static const struct hda_verb stac9205_core_init[] = {
999 } 1007 }
1000 1008
1001static const struct snd_kcontrol_new stac9200_mixer[] = { 1009static const struct snd_kcontrol_new stac9200_mixer[] = {
1002 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), 1010 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT),
1003 HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), 1011 HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT),
1004 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), 1012 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT),
1005 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), 1013 HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT),
1006 { } /* end */ 1014 { } /* end */
@@ -1027,8 +1035,8 @@ static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1027}; 1035};
1028 1036
1029static const struct snd_kcontrol_new stac925x_mixer[] = { 1037static const struct snd_kcontrol_new stac925x_mixer[] = {
1030 HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), 1038 HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT),
1031 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 1039 HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT),
1032 { } /* end */ 1040 { } /* end */
1033}; 1041};
1034 1042
@@ -1060,34 +1068,25 @@ static struct snd_kcontrol_new stac_smux_mixer = {
1060 .put = stac92xx_smux_enum_put, 1068 .put = stac92xx_smux_enum_put,
1061}; 1069};
1062 1070
1063static const char * const slave_vols[] = { 1071static const char * const slave_pfxs[] = {
1064 "Front Playback Volume", 1072 "Front", "Surround", "Center", "LFE", "Side",
1065 "Surround Playback Volume", 1073 "Headphone", "Speaker", "IEC958",
1066 "Center Playback Volume",
1067 "LFE Playback Volume",
1068 "Side Playback Volume",
1069 "Headphone Playback Volume",
1070 "Speaker Playback Volume",
1071 NULL 1074 NULL
1072}; 1075};
1073 1076
1074static const char * const slave_sws[] = { 1077static void stac92xx_update_led_status(struct hda_codec *codec, int enabled);
1075 "Front Playback Switch", 1078
1076 "Surround Playback Switch", 1079static void stac92xx_vmaster_hook(void *private_data, int val)
1077 "Center Playback Switch", 1080{
1078 "LFE Playback Switch", 1081 stac92xx_update_led_status(private_data, val);
1079 "Side Playback Switch", 1082}
1080 "Headphone Playback Switch",
1081 "Speaker Playback Switch",
1082 "IEC958 Playback Switch",
1083 NULL
1084};
1085 1083
1086static void stac92xx_free_kctls(struct hda_codec *codec); 1084static void stac92xx_free_kctls(struct hda_codec *codec);
1087 1085
1088static int stac92xx_build_controls(struct hda_codec *codec) 1086static int stac92xx_build_controls(struct hda_codec *codec)
1089{ 1087{
1090 struct sigmatel_spec *spec = codec->spec; 1088 struct sigmatel_spec *spec = codec->spec;
1089 unsigned int vmaster_tlv[4];
1091 int err; 1090 int err;
1092 int i; 1091 int i;
1093 1092
@@ -1144,22 +1143,28 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1144 } 1143 }
1145 1144
1146 /* if we have no master control, let's create it */ 1145 /* if we have no master control, let's create it */
1147 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 1146 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1148 unsigned int vmaster_tlv[4]; 1147 HDA_OUTPUT, vmaster_tlv);
1149 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], 1148 /* correct volume offset */
1150 HDA_OUTPUT, vmaster_tlv); 1149 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
1151 /* correct volume offset */ 1150 /* minimum value is actually mute */
1152 vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; 1151 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1153 /* minimum value is actually mute */ 1152 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1154 vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; 1153 vmaster_tlv, slave_pfxs,
1155 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1154 "Playback Volume");
1156 vmaster_tlv, slave_vols); 1155 if (err < 0)
1157 if (err < 0) 1156 return err;
1158 return err; 1157
1159 } 1158 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
1160 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1159 NULL, slave_pfxs,
1161 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1160 "Playback Switch", true,
1162 NULL, slave_sws); 1161 &spec->vmaster_mute.sw_kctl);
1162 if (err < 0)
1163 return err;
1164
1165 if (spec->gpio_led) {
1166 spec->vmaster_mute.hook = stac92xx_vmaster_hook;
1167 err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true);
1163 if (err < 0) 1168 if (err < 0)
1164 return err; 1169 return err;
1165 } 1170 }
@@ -1636,6 +1641,12 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = {
1636 0x40f000f0, 0x40f000f0, 1641 0x40f000f0, 0x40f000f0,
1637}; 1642};
1638 1643
1644static const unsigned int hp_zephyr_pin_configs[10] = {
1645 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310,
1646 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130,
1647 0, 0,
1648};
1649
1639static const unsigned int hp_cNB11_intquad_pin_configs[10] = { 1650static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
1640 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110, 1651 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
1641 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130, 1652 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
@@ -1649,6 +1660,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1649 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, 1660 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
1650 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, 1661 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1651 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1662 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1663 [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs,
1652}; 1664};
1653 1665
1654static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { 1666static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
@@ -1659,6 +1671,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1659 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", 1671 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
1660 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", 1672 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1661 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1673 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1674 [STAC_HP_ZEPHYR] = "hp-zephyr",
1662}; 1675};
1663 1676
1664static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1677static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1711,6 +1724,14 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1711 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 1724 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1712 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593, 1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
1713 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), 1726 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
1728 "HP", STAC_HP_ZEPHYR),
1729 {} /* terminator */
1730};
1731
1732static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = {
1733 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561,
1734 "HP", STAC_HP_ZEPHYR),
1714 {} /* terminator */ 1735 {} /* terminator */
1715}; 1736};
1716 1737
@@ -4410,8 +4431,7 @@ static int stac92xx_init(struct hda_codec *codec)
4410 snd_hda_jack_report_sync(codec); 4431 snd_hda_jack_report_sync(codec);
4411 4432
4412 /* sync mute LED */ 4433 /* sync mute LED */
4413 if (spec->gpio_led) 4434 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
4414 hda_call_check_power_status(codec, 0x01);
4415 if (spec->dac_list) 4435 if (spec->dac_list)
4416 stac92xx_power_down(codec); 4436 stac92xx_power_down(codec);
4417 return 0; 4437 return 0;
@@ -4989,7 +5009,6 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4989 return 0; 5009 return 0;
4990} 5010}
4991 5011
4992#ifdef CONFIG_SND_HDA_POWER_SAVE
4993static int stac92xx_pre_resume(struct hda_codec *codec) 5012static int stac92xx_pre_resume(struct hda_codec *codec)
4994{ 5013{
4995 struct sigmatel_spec *spec = codec->spec; 5014 struct sigmatel_spec *spec = codec->spec;
@@ -5024,82 +5043,40 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5024 afg_power_state); 5043 afg_power_state);
5025 snd_hda_codec_set_power_to_all(codec, fg, power_state, true); 5044 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
5026} 5045}
5046#else
5047#define stac92xx_suspend NULL
5048#define stac92xx_resume NULL
5049#define stac92xx_pre_resume NULL
5050#define stac92xx_set_power_state NULL
5051#endif /* CONFIG_PM */
5027 5052
5028/* 5053/* update mute-LED accoring to the master switch */
5029 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed 5054static void stac92xx_update_led_status(struct hda_codec *codec, int enabled)
5030 * as mute LED state is updated in check_power_status hook
5031 */
5032static int stac92xx_update_led_status(struct hda_codec *codec)
5033{ 5055{
5034 struct sigmatel_spec *spec = codec->spec; 5056 struct sigmatel_spec *spec = codec->spec;
5035 int i, num_ext_dacs, muted = 1; 5057 int muted = !enabled;
5036 unsigned int muted_lvl, notmtd_lvl;
5037 hda_nid_t nid;
5038 5058
5039 if (!spec->gpio_led) 5059 if (!spec->gpio_led)
5040 return 0; 5060 return;
5061
5062 /* LED state is inverted on these systems */
5063 if (spec->gpio_led_polarity)
5064 muted = !muted;
5041 5065
5042 for (i = 0; i < spec->multiout.num_dacs; i++) {
5043 nid = spec->multiout.dac_nids[i];
5044 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5045 HDA_AMP_MUTE)) {
5046 muted = 0; /* something heard */
5047 break;
5048 }
5049 }
5050 if (muted && spec->multiout.hp_nid)
5051 if (!(snd_hda_codec_amp_read(codec,
5052 spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
5053 HDA_AMP_MUTE)) {
5054 muted = 0; /* HP is not muted */
5055 }
5056 num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
5057 for (i = 0; muted && i < num_ext_dacs; i++) {
5058 nid = spec->multiout.extra_out_nid[i];
5059 if (nid == 0)
5060 break;
5061 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5062 HDA_AMP_MUTE)) {
5063 muted = 0; /* extra output is not muted */
5064 }
5065 }
5066 /*polarity defines *not* muted state level*/ 5066 /*polarity defines *not* muted state level*/
5067 if (!spec->vref_mute_led_nid) { 5067 if (!spec->vref_mute_led_nid) {
5068 if (muted) 5068 if (muted)
5069 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5069 spec->gpio_data &= ~spec->gpio_led; /* orange */
5070 else 5070 else
5071 spec->gpio_data |= spec->gpio_led; /* white */ 5071 spec->gpio_data |= spec->gpio_led; /* white */
5072
5073 if (!spec->gpio_led_polarity) {
5074 /* LED state is inverted on these systems */
5075 spec->gpio_data ^= spec->gpio_led;
5076 }
5077 stac_gpio_set(codec, spec->gpio_mask, 5072 stac_gpio_set(codec, spec->gpio_mask,
5078 spec->gpio_dir, spec->gpio_data); 5073 spec->gpio_dir, spec->gpio_data);
5079 } else { 5074 } else {
5080 notmtd_lvl = spec->gpio_led_polarity ? 5075 spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
5081 AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD;
5082 muted_lvl = spec->gpio_led_polarity ?
5083 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_50;
5084 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5085 stac_vrefout_set(codec, spec->vref_mute_led_nid, 5076 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5086 spec->vref_led); 5077 spec->vref_led);
5087 } 5078 }
5088 return 0;
5089}
5090
5091/*
5092 * use power check for controlling mute led of HP notebooks
5093 */
5094static int stac92xx_check_power_status(struct hda_codec *codec,
5095 hda_nid_t nid)
5096{
5097 stac92xx_update_led_status(codec);
5098
5099 return 0;
5100} 5079}
5101#endif /* CONFIG_SND_HDA_POWER_SAVE */
5102#endif /* CONFIG_PM */
5103 5080
5104static const struct hda_codec_ops stac92xx_patch_ops = { 5081static const struct hda_codec_ops stac92xx_patch_ops = {
5105 .build_controls = stac92xx_build_controls, 5082 .build_controls = stac92xx_build_controls,
@@ -5580,6 +5557,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5580 STAC_92HD83XXX_MODELS, 5557 STAC_92HD83XXX_MODELS,
5581 stac92hd83xxx_models, 5558 stac92hd83xxx_models,
5582 stac92hd83xxx_cfg_tbl); 5559 stac92hd83xxx_cfg_tbl);
5560 /* check codec subsystem id if not found */
5561 if (spec->board_config < 0)
5562 spec->board_config =
5563 snd_hda_check_board_codec_sid_config(codec,
5564 STAC_92HD83XXX_MODELS, stac92hd83xxx_models,
5565 stac92hd83xxx_codec_id_cfg_tbl);
5583again: 5566again:
5584 if (spec->board_config < 0) 5567 if (spec->board_config < 0)
5585 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5568 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
@@ -5590,12 +5573,17 @@ again:
5590 5573
5591 codec->patch_ops = stac92xx_patch_ops; 5574 codec->patch_ops = stac92xx_patch_ops;
5592 5575
5576 switch (spec->board_config) {
5577 case STAC_HP_ZEPHYR:
5578 spec->init = stac92hd83xxx_hp_zephyr_init;
5579 break;
5580 }
5581
5593 if (find_mute_led_cfg(codec, -1/*no default cfg*/)) 5582 if (find_mute_led_cfg(codec, -1/*no default cfg*/))
5594 snd_printd("mute LED gpio %d polarity %d\n", 5583 snd_printd("mute LED gpio %d polarity %d\n",
5595 spec->gpio_led, 5584 spec->gpio_led,
5596 spec->gpio_led_polarity); 5585 spec->gpio_led_polarity);
5597 5586
5598#ifdef CONFIG_SND_HDA_POWER_SAVE
5599 if (spec->gpio_led) { 5587 if (spec->gpio_led) {
5600 if (!spec->vref_mute_led_nid) { 5588 if (!spec->vref_mute_led_nid) {
5601 spec->gpio_mask |= spec->gpio_led; 5589 spec->gpio_mask |= spec->gpio_led;
@@ -5605,11 +5593,10 @@ again:
5605 codec->patch_ops.set_power_state = 5593 codec->patch_ops.set_power_state =
5606 stac92xx_set_power_state; 5594 stac92xx_set_power_state;
5607 } 5595 }
5596#ifdef CONFIG_PM
5608 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5597 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5609 codec->patch_ops.check_power_status = 5598#endif
5610 stac92xx_check_power_status;
5611 } 5599 }
5612#endif
5613 5600
5614 err = stac92xx_parse_auto_config(codec); 5601 err = stac92xx_parse_auto_config(codec);
5615 if (!err) { 5602 if (!err) {
@@ -5906,7 +5893,6 @@ again:
5906 spec->gpio_led, 5893 spec->gpio_led,
5907 spec->gpio_led_polarity); 5894 spec->gpio_led_polarity);
5908 5895
5909#ifdef CONFIG_SND_HDA_POWER_SAVE
5910 if (spec->gpio_led) { 5896 if (spec->gpio_led) {
5911 if (!spec->vref_mute_led_nid) { 5897 if (!spec->vref_mute_led_nid) {
5912 spec->gpio_mask |= spec->gpio_led; 5898 spec->gpio_mask |= spec->gpio_led;
@@ -5916,11 +5902,10 @@ again:
5916 codec->patch_ops.set_power_state = 5902 codec->patch_ops.set_power_state =
5917 stac92xx_set_power_state; 5903 stac92xx_set_power_state;
5918 } 5904 }
5905#ifdef CONFIG_PM
5919 codec->patch_ops.pre_resume = stac92xx_pre_resume; 5906 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5920 codec->patch_ops.check_power_status = 5907#endif
5921 stac92xx_check_power_status;
5922 } 5908 }
5923#endif
5924 5909
5925 spec->multiout.dac_nids = spec->dac_nids; 5910 spec->multiout.dac_nids = spec->dac_nids;
5926 5911
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index dff9a00ee8fb..06214fdc9486 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -550,7 +550,10 @@ static void via_auto_init_output(struct hda_codec *codec,
550 pin = path->path[path->depth - 1]; 550 pin = path->path[path->depth - 1];
551 551
552 init_output_pin(codec, pin, pin_type); 552 init_output_pin(codec, pin, pin_type);
553 caps = query_amp_caps(codec, pin, HDA_OUTPUT); 553 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
554 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
555 else
556 caps = 0;
554 if (caps & AC_AMPCAP_MUTE) { 557 if (caps & AC_AMPCAP_MUTE) {
555 unsigned int val; 558 unsigned int val;
556 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; 559 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
@@ -645,6 +648,10 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
645 648
646 /* init ADCs */ 649 /* init ADCs */
647 for (i = 0; i < spec->num_adc_nids; i++) { 650 for (i = 0; i < spec->num_adc_nids; i++) {
651 hda_nid_t nid = spec->adc_nids[i];
652 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP) ||
653 !(query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE))
654 continue;
648 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 655 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
649 AC_VERB_SET_AMP_GAIN_MUTE, 656 AC_VERB_SET_AMP_GAIN_MUTE,
650 AMP_IN_UNMUTE(0)); 657 AMP_IN_UNMUTE(0));
@@ -1445,25 +1452,9 @@ static const struct hda_pcm_stream via_pcm_digital_capture = {
1445/* 1452/*
1446 * slave controls for virtual master 1453 * slave controls for virtual master
1447 */ 1454 */
1448static const char * const via_slave_vols[] = { 1455static const char * const via_slave_pfxs[] = {
1449 "Front Playback Volume", 1456 "Front", "Surround", "Center", "LFE", "Side",
1450 "Surround Playback Volume", 1457 "Headphone", "Speaker",
1451 "Center Playback Volume",
1452 "LFE Playback Volume",
1453 "Side Playback Volume",
1454 "Headphone Playback Volume",
1455 "Speaker Playback Volume",
1456 NULL,
1457};
1458
1459static const char * const via_slave_sws[] = {
1460 "Front Playback Switch",
1461 "Surround Playback Switch",
1462 "Center Playback Switch",
1463 "LFE Playback Switch",
1464 "Side Playback Switch",
1465 "Headphone Playback Switch",
1466 "Speaker Playback Switch",
1467 NULL, 1458 NULL,
1468}; 1459};
1469 1460
@@ -1508,13 +1499,15 @@ static int via_build_controls(struct hda_codec *codec)
1508 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], 1499 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1509 HDA_OUTPUT, vmaster_tlv); 1500 HDA_OUTPUT, vmaster_tlv);
1510 err = snd_hda_add_vmaster(codec, "Master Playback Volume", 1501 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1511 vmaster_tlv, via_slave_vols); 1502 vmaster_tlv, via_slave_pfxs,
1503 "Playback Volume");
1512 if (err < 0) 1504 if (err < 0)
1513 return err; 1505 return err;
1514 } 1506 }
1515 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 1507 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1516 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 1508 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1517 NULL, via_slave_sws); 1509 NULL, via_slave_pfxs,
1510 "Playback Switch");
1518 if (err < 0) 1511 if (err < 0)
1519 return err; 1512 return err;
1520 } 1513 }
@@ -1522,6 +1515,8 @@ static int via_build_controls(struct hda_codec *codec)
1522 /* assign Capture Source enums to NID */ 1515 /* assign Capture Source enums to NID */
1523 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1516 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1524 for (i = 0; kctl && i < kctl->count; i++) { 1517 for (i = 0; kctl && i < kctl->count; i++) {
1518 if (!spec->mux_nids[i])
1519 continue;
1525 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); 1520 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1526 if (err < 0) 1521 if (err < 0)
1527 return err; 1522 return err;
@@ -2488,6 +2483,8 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
2488{ 2483{
2489 struct via_spec *spec = codec->spec; 2484 struct via_spec *spec = codec->spec;
2490 const struct auto_pin_cfg *cfg = &spec->autocfg; 2485 const struct auto_pin_cfg *cfg = &spec->autocfg;
2486 const char *prev_label = NULL;
2487 int type_idx = 0;
2491 int i, err; 2488 int i, err;
2492 2489
2493 for (i = 0; i < cfg->num_inputs; i++) { 2490 for (i = 0; i < cfg->num_inputs; i++) {
@@ -2502,8 +2499,13 @@ static int create_mic_boost_ctls(struct hda_codec *codec)
2502 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS)) 2499 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2503 continue; 2500 continue;
2504 label = hda_get_autocfg_input_label(codec, cfg, i); 2501 label = hda_get_autocfg_input_label(codec, cfg, i);
2502 if (prev_label && !strcmp(label, prev_label))
2503 type_idx++;
2504 else
2505 type_idx = 0;
2506 prev_label = label;
2505 snprintf(name, sizeof(name), "%s Boost Volume", label); 2507 snprintf(name, sizeof(name), "%s Boost Volume", label);
2506 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 2508 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
2507 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT)); 2509 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2508 if (err < 0) 2510 if (err < 0)
2509 return err; 2511 return err;