diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/alc260_quirks.c | 968 | ||||
-rw-r--r-- | sound/pci/hda/alc_quirks.c | 301 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 21 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 28 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.h | 13 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 66 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 36 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 221 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 29 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 28 |
13 files changed, 238 insertions, 1493 deletions
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 */ | ||
7 | enum { | ||
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 | |||
21 | static const hda_nid_t alc260_dac_nids[1] = { | ||
22 | /* front */ | ||
23 | 0x02, | ||
24 | }; | ||
25 | |||
26 | static const hda_nid_t alc260_adc_nids[1] = { | ||
27 | /* ADC0 */ | ||
28 | 0x04, | ||
29 | }; | ||
30 | |||
31 | static 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 | */ | ||
39 | static 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 | |||
47 | static 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 | */ | ||
63 | static 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 | */ | ||
87 | static 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 */ | ||
110 | static 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 | */ | ||
134 | static 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 | |||
146 | static 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 | |||
156 | static 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 | */ | ||
171 | static 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 | */ | ||
208 | static 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 | */ | ||
229 | static 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 | */ | ||
242 | static 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 | */ | ||
259 | static 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 | */ | ||
276 | static 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 | */ | ||
343 | static 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 | */ | ||
425 | static 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 | */ | ||
513 | static 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 | |||
593 | static 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 | |||
603 | static 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 */ | ||
617 | static 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 | |||
638 | static 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 | |||
645 | static 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 | ||
663 | static const hda_nid_t alc260_test_dac_nids[1] = { | ||
664 | 0x02, | ||
665 | }; | ||
666 | static 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 | */ | ||
673 | static 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 | }; | ||
700 | static 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 | }; | ||
764 | static 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 | */ | ||
850 | static 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 | |||
863 | static 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 | |||
878 | static 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/alc_quirks.c b/sound/pci/hda/alc_quirks.c index a18952ed4311..b344603ac06d 100644 --- a/sound/pci/hda/alc_quirks.c +++ b/sound/pci/hda/alc_quirks.c | |||
@@ -74,307 +74,6 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
74 | return err; | 74 | return err; |
75 | } | 75 | } |
76 | 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 | */ | ||
90 | static const char * const alc_pin_mode_names[] = { | ||
91 | "Mic 50pc bias", "Mic 80pc bias", | ||
92 | "Line in", "Line out", "Headphone out", | ||
93 | }; | ||
94 | static 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 | */ | ||
113 | static 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 | |||
125 | static 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 | |||
141 | static 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 | |||
161 | static 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 | |||
224 | static 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 | } | ||
237 | static 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 | |||
279 | static 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 | } | ||
292 | static 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 | |||
331 | static 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 | |||
345 | static 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 | |||
378 | static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) | 77 | static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) |
379 | { | 78 | { |
380 | struct alc_spec *spec = codec->spec; | 79 | struct alc_spec *spec = codec->spec; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c2c65f63bf06..65c01798d843 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2300,7 +2300,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); | |||
2300 | 2300 | ||
2301 | /* apply the function to all matching slave ctls in the mixer list */ | 2301 | /* apply the function to all matching slave ctls in the mixer list */ |
2302 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, | 2302 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, |
2303 | map_slave_func_t func, void *data) | 2303 | const char *suffix, map_slave_func_t func, void *data) |
2304 | { | 2304 | { |
2305 | struct hda_nid_item *items; | 2305 | struct hda_nid_item *items; |
2306 | const char * const *s; | 2306 | const char * const *s; |
@@ -2313,7 +2313,14 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves, | |||
2313 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) | 2313 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) |
2314 | continue; | 2314 | continue; |
2315 | for (s = slaves; *s; s++) { | 2315 | for (s = slaves; *s; s++) { |
2316 | if (!strcmp(sctl->id.name, *s)) { | 2316 | char tmpname[sizeof(sctl->id.name)]; |
2317 | const char *name = *s; | ||
2318 | if (suffix) { | ||
2319 | snprintf(tmpname, sizeof(tmpname), "%s %s", | ||
2320 | name, suffix); | ||
2321 | name = tmpname; | ||
2322 | } | ||
2323 | if (!strcmp(sctl->id.name, name)) { | ||
2317 | err = func(data, sctl); | 2324 | err = func(data, sctl); |
2318 | if (err) | 2325 | if (err) |
2319 | return err; | 2326 | return err; |
@@ -2335,6 +2342,7 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl) | |||
2335 | * @name: vmaster control name | 2342 | * @name: vmaster control name |
2336 | * @tlv: TLV data (optional) | 2343 | * @tlv: TLV data (optional) |
2337 | * @slaves: slave control names (optional) | 2344 | * @slaves: slave control names (optional) |
2345 | * @suffix: suffix string to each slave name (optional) | ||
2338 | * | 2346 | * |
2339 | * Create a virtual master control with the given name. The TLV data | 2347 | * Create a virtual master control with the given name. The TLV data |
2340 | * must be either NULL or a valid data. | 2348 | * must be either NULL or a valid data. |
@@ -2346,12 +2354,13 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl) | |||
2346 | * This function returns zero if successful or a negative error code. | 2354 | * This function returns zero if successful or a negative error code. |
2347 | */ | 2355 | */ |
2348 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 2356 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
2349 | unsigned int *tlv, const char * const *slaves) | 2357 | unsigned int *tlv, const char * const *slaves, |
2358 | const char *suffix) | ||
2350 | { | 2359 | { |
2351 | struct snd_kcontrol *kctl; | 2360 | struct snd_kcontrol *kctl; |
2352 | int err; | 2361 | int err; |
2353 | 2362 | ||
2354 | err = map_slaves(codec, slaves, check_slave_present, NULL); | 2363 | err = map_slaves(codec, slaves, suffix, check_slave_present, NULL); |
2355 | if (err != 1) { | 2364 | if (err != 1) { |
2356 | snd_printdd("No slave found for %s\n", name); | 2365 | snd_printdd("No slave found for %s\n", name); |
2357 | return 0; | 2366 | return 0; |
@@ -2363,8 +2372,8 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2363 | if (err < 0) | 2372 | if (err < 0) |
2364 | return err; | 2373 | return err; |
2365 | 2374 | ||
2366 | err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, | 2375 | err = map_slaves(codec, slaves, suffix, |
2367 | kctl); | 2376 | (map_slave_func_t)snd_ctl_add_slave, kctl); |
2368 | if (err < 0) | 2377 | if (err < 0) |
2369 | return err; | 2378 | return err; |
2370 | return 0; | 2379 | return 0; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index e9f71dc0d464..654d2e41e25d 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -852,6 +852,7 @@ struct hda_codec { | |||
852 | unsigned int pins_shutup:1; /* pins are shut up */ | 852 | unsigned int pins_shutup:1; /* pins are shut up */ |
853 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 853 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
854 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | 854 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ |
855 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ | ||
855 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 856 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
856 | unsigned int power_on :1; /* current (global) power-state */ | 857 | unsigned int power_on :1; /* current (global) power-state */ |
857 | unsigned int power_transition :1; /* power-state in transition */ | 858 | 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..e354c1616541 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization."); | |||
94 | module_param(single_cmd, bool, 0444); | 94 | module_param(single_cmd, bool, 0444); |
95 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " | 95 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " |
96 | "(for debugging only)."); | 96 | "(for debugging only)."); |
97 | module_param(enable_msi, int, 0444); | 97 | module_param(enable_msi, bint, 0444); |
98 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); | 98 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); |
99 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 99 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
100 | module_param_array(patch, charp, NULL, 0444); | 100 | module_param_array(patch, charp, NULL, 0444); |
@@ -121,8 +121,8 @@ module_param(power_save_controller, bool, 0644); | |||
121 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); | 121 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | static bool align_buffer_size = 1; | 124 | static int align_buffer_size = -1; |
125 | module_param(align_buffer_size, bool, 0644); | 125 | module_param(align_buffer_size, bint, 0644); |
126 | MODULE_PARM_DESC(align_buffer_size, | 126 | MODULE_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}," |
@@ -515,6 +516,7 @@ enum { | |||
515 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | 516 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ |
516 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | 517 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ |
517 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | 518 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ |
519 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | ||
518 | 520 | ||
519 | /* quirks for ATI SB / AMD Hudson */ | 521 | /* quirks for ATI SB / AMD Hudson */ |
520 | #define AZX_DCAPS_PRESET_ATI_SB \ | 522 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -527,7 +529,8 @@ enum { | |||
527 | 529 | ||
528 | /* quirks for Nvidia */ | 530 | /* quirks for Nvidia */ |
529 | #define AZX_DCAPS_PRESET_NVIDIA \ | 531 | #define AZX_DCAPS_PRESET_NVIDIA \ |
530 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI) | 532 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ |
533 | AZX_DCAPS_ALIGN_BUFSIZE) | ||
531 | 534 | ||
532 | static char *driver_short_names[] __devinitdata = { | 535 | static char *driver_short_names[] __devinitdata = { |
533 | [AZX_DRIVER_ICH] = "HDA Intel", | 536 | [AZX_DRIVER_ICH] = "HDA Intel", |
@@ -2774,9 +2777,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2774 | } | 2777 | } |
2775 | 2778 | ||
2776 | /* disable buffer size rounding to 128-byte multiples if supported */ | 2779 | /* disable buffer size rounding to 128-byte multiples if supported */ |
2777 | chip->align_buffer_size = align_buffer_size; | 2780 | if (align_buffer_size >= 0) |
2778 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | 2781 | chip->align_buffer_size = !!align_buffer_size; |
2779 | chip->align_buffer_size = 0; | 2782 | else { |
2783 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | ||
2784 | chip->align_buffer_size = 0; | ||
2785 | else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE) | ||
2786 | chip->align_buffer_size = 1; | ||
2787 | else | ||
2788 | chip->align_buffer_size = 1; | ||
2789 | } | ||
2780 | 2790 | ||
2781 | /* allow 64bit DMA address if supported by H/W */ | 2791 | /* allow 64bit DMA address if supported by H/W */ |
2782 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2792 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
@@ -2992,6 +3002,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2992 | { PCI_DEVICE(0x8086, 0x1e20), | 3002 | { PCI_DEVICE(0x8086, 0x1e20), |
2993 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3003 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
2994 | AZX_DCAPS_BUFSIZE}, | 3004 | AZX_DCAPS_BUFSIZE}, |
3005 | /* Lynx Point */ | ||
3006 | { PCI_DEVICE(0x8086, 0x8c20), | ||
3007 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | ||
3008 | AZX_DCAPS_BUFSIZE}, | ||
2995 | /* SCH */ | 3009 | /* SCH */ |
2996 | { PCI_DEVICE(0x8086, 0x811b), | 3010 | { PCI_DEVICE(0x8086, 0x811b), |
2997 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3011 | .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 | ||
22 | bool 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 | } | ||
36 | EXPORT_SYMBOL_HDA(is_jack_detectable); | ||
37 | |||
22 | /* execute pin sense measurement */ | 38 | /* execute pin sense measurement */ |
23 | static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) | 39 | static 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, | |||
62 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); | 62 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); |
63 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | 63 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); |
64 | 64 | ||
65 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 65 | bool 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 | ||
78 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | 67 | int 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..6094dea82bc3 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -140,7 +140,8 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, | |||
140 | struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | 140 | struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, |
141 | const char *name); | 141 | const char *name); |
142 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 142 | int 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); | ||
144 | int snd_hda_codec_reset(struct hda_codec *codec); | 145 | int snd_hda_codec_reset(struct hda_codec *codec); |
145 | 146 | ||
146 | /* amp value bits */ | 147 | /* amp value bits */ |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 9cb14b42dfff..9771b0702455 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -137,51 +137,17 @@ static int ad198x_init(struct hda_codec *codec) | |||
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | static const char * const ad_slave_vols[] = { | 140 | static const char * const ad_slave_pfxs[] = { |
141 | "Front Playback Volume", | 141 | "Front", "Surround", "Center", "LFE", "Side", |
142 | "Surround Playback Volume", | 142 | "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 | 143 | NULL |
151 | }; | 144 | }; |
152 | 145 | ||
153 | static const char * const ad_slave_sws[] = { | 146 | static const char * const ad1988_6stack_fp_slave_pfxs[] = { |
154 | "Front Playback Switch", | 147 | "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 | 148 | NULL |
164 | }; | 149 | }; |
165 | 150 | ||
166 | static 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 | |||
176 | static 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 | }; | ||
185 | static void ad198x_free_kctls(struct hda_codec *codec); | 151 | static void ad198x_free_kctls(struct hda_codec *codec); |
186 | 152 | ||
187 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 153 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
@@ -260,7 +226,8 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
260 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 226 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
261 | vmaster_tlv, | 227 | vmaster_tlv, |
262 | (spec->slave_vols ? | 228 | (spec->slave_vols ? |
263 | spec->slave_vols : ad_slave_vols)); | 229 | spec->slave_vols : ad_slave_pfxs), |
230 | "Playback Volume"); | ||
264 | if (err < 0) | 231 | if (err < 0) |
265 | return err; | 232 | return err; |
266 | } | 233 | } |
@@ -268,7 +235,8 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
268 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 235 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
269 | NULL, | 236 | NULL, |
270 | (spec->slave_sws ? | 237 | (spec->slave_sws ? |
271 | spec->slave_sws : ad_slave_sws)); | 238 | spec->slave_sws : ad_slave_pfxs), |
239 | "Playback Switch"); | ||
272 | if (err < 0) | 240 | if (err < 0) |
273 | return err; | 241 | return err; |
274 | } | 242 | } |
@@ -3385,8 +3353,8 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3385 | 3353 | ||
3386 | if (spec->autocfg.hp_pins[0]) { | 3354 | if (spec->autocfg.hp_pins[0]) { |
3387 | spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; | 3355 | spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; |
3388 | spec->slave_vols = ad1988_6stack_fp_slave_vols; | 3356 | spec->slave_vols = ad1988_6stack_fp_slave_pfxs; |
3389 | spec->slave_sws = ad1988_6stack_fp_slave_sws; | 3357 | spec->slave_sws = ad1988_6stack_fp_slave_pfxs; |
3390 | spec->alt_dac_nid = ad1988_alt_dac_nid; | 3358 | spec->alt_dac_nid = ad1988_alt_dac_nid; |
3391 | spec->stream_analog_alt_playback = | 3359 | spec->stream_analog_alt_playback = |
3392 | &ad198x_pcm_analog_alt_playback; | 3360 | &ad198x_pcm_analog_alt_playback; |
@@ -3594,16 +3562,8 @@ static const struct hda_amp_list ad1884_loopbacks[] = { | |||
3594 | #endif | 3562 | #endif |
3595 | 3563 | ||
3596 | static const char * const ad1884_slave_vols[] = { | 3564 | static const char * const ad1884_slave_vols[] = { |
3597 | "PCM Playback Volume", | 3565 | "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD", |
3598 | "Mic Playback Volume", | 3566 | "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 | 3567 | NULL |
3608 | }; | 3568 | }; |
3609 | 3569 | ||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index a7a5733aa4d2..266e5a68bafa 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -465,21 +465,8 @@ static const struct snd_kcontrol_new cxt_beep_mixer[] = { | |||
465 | }; | 465 | }; |
466 | #endif | 466 | #endif |
467 | 467 | ||
468 | static const char * const slave_vols[] = { | 468 | static const char * const slave_pfxs[] = { |
469 | "Headphone Playback Volume", | 469 | "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 | |||
477 | static 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 | 470 | NULL |
484 | }; | 471 | }; |
485 | 472 | ||
@@ -519,14 +506,16 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
519 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | 506 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, |
520 | HDA_OUTPUT, vmaster_tlv); | 507 | HDA_OUTPUT, vmaster_tlv); |
521 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 508 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
522 | vmaster_tlv, slave_vols); | 509 | vmaster_tlv, slave_pfxs, |
510 | "Playback Volume"); | ||
523 | if (err < 0) | 511 | if (err < 0) |
524 | return err; | 512 | return err; |
525 | } | 513 | } |
526 | if (spec->vmaster_nid && | 514 | if (spec->vmaster_nid && |
527 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 515 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
528 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 516 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
529 | NULL, slave_sws); | 517 | NULL, slave_pfxs, |
518 | "Playback Switch"); | ||
530 | if (err < 0) | 519 | if (err < 0) |
531 | return err; | 520 | return err; |
532 | } | 521 | } |
@@ -3034,7 +3023,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3034 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), | 3023 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), |
3035 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), | 3024 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), |
3036 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), | 3025 | 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), | 3026 | SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), |
3039 | {} | 3027 | {} |
3040 | }; | 3028 | }; |
@@ -4414,6 +4402,18 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4414 | codec->patch_ops = cx_auto_patch_ops; | 4402 | codec->patch_ops = cx_auto_patch_ops; |
4415 | if (spec->beep_amp) | 4403 | if (spec->beep_amp) |
4416 | snd_hda_attach_beep_device(codec, spec->beep_amp); | 4404 | snd_hda_attach_beep_device(codec, spec->beep_amp); |
4405 | |||
4406 | /* Some laptops with Conexant chips show stalls in S3 resume, | ||
4407 | * which falls into the single-cmd mode. | ||
4408 | * Better to make reset, then. | ||
4409 | */ | ||
4410 | if (!codec->bus->sync_write) { | ||
4411 | snd_printd("hda_codec: " | ||
4412 | "Enable sync_write for stable communication\n"); | ||
4413 | codec->bus->sync_write = 1; | ||
4414 | codec->bus->allow_bus_reset = 1; | ||
4415 | } | ||
4416 | |||
4417 | return 0; | 4417 | return 0; |
4418 | } | 4418 | } |
4419 | 4419 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 389a28a21fa9..0ffccc178957 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1847,36 +1847,10 @@ DEFINE_CAPMIX_NOSRC(3); | |||
1847 | /* | 1847 | /* |
1848 | * slave controls for virtual master | 1848 | * slave controls for virtual master |
1849 | */ | 1849 | */ |
1850 | static const char * const alc_slave_vols[] = { | 1850 | static const char * const alc_slave_pfxs[] = { |
1851 | "Front Playback Volume", | 1851 | "Front", "Surround", "Center", "LFE", "Side", |
1852 | "Surround Playback Volume", | 1852 | "Headphone", "Speaker", "Mono", "Line-Out", |
1853 | "Center Playback Volume", | 1853 | "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 | |||
1866 | static 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, | 1854 | NULL, |
1881 | }; | 1855 | }; |
1882 | 1856 | ||
@@ -1967,14 +1941,16 @@ static int __alc_build_controls(struct hda_codec *codec) | |||
1967 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | 1941 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, |
1968 | HDA_OUTPUT, vmaster_tlv); | 1942 | HDA_OUTPUT, vmaster_tlv); |
1969 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1943 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1970 | vmaster_tlv, alc_slave_vols); | 1944 | vmaster_tlv, alc_slave_pfxs, |
1945 | "Playback Volume"); | ||
1971 | if (err < 0) | 1946 | if (err < 0) |
1972 | return err; | 1947 | return err; |
1973 | } | 1948 | } |
1974 | if (!spec->no_analog && | 1949 | if (!spec->no_analog && |
1975 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 1950 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
1976 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 1951 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
1977 | NULL, alc_slave_sws); | 1952 | NULL, alc_slave_pfxs, |
1953 | "Playback Switch"); | ||
1978 | if (err < 0) | 1954 | if (err < 0) |
1979 | return err; | 1955 | return err; |
1980 | } | 1956 | } |
@@ -4236,34 +4212,111 @@ static const struct hda_amp_list alc260_loopbacks[] = { | |||
4236 | * Pin config fixes | 4212 | * Pin config fixes |
4237 | */ | 4213 | */ |
4238 | enum { | 4214 | enum { |
4239 | PINFIX_HP_DC5750, | 4215 | ALC260_FIXUP_HP_DC5750, |
4216 | ALC260_FIXUP_HP_PIN_0F, | ||
4217 | ALC260_FIXUP_COEF, | ||
4218 | ALC260_FIXUP_GPIO1, | ||
4219 | ALC260_FIXUP_GPIO1_TOGGLE, | ||
4220 | ALC260_FIXUP_REPLACER, | ||
4221 | ALC260_FIXUP_HP_B1900, | ||
4240 | }; | 4222 | }; |
4241 | 4223 | ||
4224 | static void alc260_gpio1_automute(struct hda_codec *codec) | ||
4225 | { | ||
4226 | struct alc_spec *spec = codec->spec; | ||
4227 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
4228 | spec->hp_jack_present); | ||
4229 | } | ||
4230 | |||
4231 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | ||
4232 | const struct alc_fixup *fix, int action) | ||
4233 | { | ||
4234 | struct alc_spec *spec = codec->spec; | ||
4235 | if (action == ALC_FIXUP_ACT_PROBE) { | ||
4236 | /* although the machine has only one output pin, we need to | ||
4237 | * toggle GPIO1 according to the jack state | ||
4238 | */ | ||
4239 | spec->automute_hook = alc260_gpio1_automute; | ||
4240 | spec->detect_hp = 1; | ||
4241 | spec->automute_speaker = 1; | ||
4242 | spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | ||
4243 | snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); | ||
4244 | spec->unsol_event = alc_sku_unsol_event; | ||
4245 | add_verb(codec->spec, alc_gpio1_init_verbs); | ||
4246 | } | ||
4247 | } | ||
4248 | |||
4242 | static const struct alc_fixup alc260_fixups[] = { | 4249 | static const struct alc_fixup alc260_fixups[] = { |
4243 | [PINFIX_HP_DC5750] = { | 4250 | [ALC260_FIXUP_HP_DC5750] = { |
4244 | .type = ALC_FIXUP_PINS, | 4251 | .type = ALC_FIXUP_PINS, |
4245 | .v.pins = (const struct alc_pincfg[]) { | 4252 | .v.pins = (const struct alc_pincfg[]) { |
4246 | { 0x11, 0x90130110 }, /* speaker */ | 4253 | { 0x11, 0x90130110 }, /* speaker */ |
4247 | { } | 4254 | { } |
4248 | } | 4255 | } |
4249 | }, | 4256 | }, |
4257 | [ALC260_FIXUP_HP_PIN_0F] = { | ||
4258 | .type = ALC_FIXUP_PINS, | ||
4259 | .v.pins = (const struct alc_pincfg[]) { | ||
4260 | { 0x0f, 0x01214000 }, /* HP */ | ||
4261 | { } | ||
4262 | } | ||
4263 | }, | ||
4264 | [ALC260_FIXUP_COEF] = { | ||
4265 | .type = ALC_FIXUP_VERBS, | ||
4266 | .v.verbs = (const struct hda_verb[]) { | ||
4267 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4268 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, | ||
4269 | { } | ||
4270 | }, | ||
4271 | .chained = true, | ||
4272 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | ||
4273 | }, | ||
4274 | [ALC260_FIXUP_GPIO1] = { | ||
4275 | .type = ALC_FIXUP_VERBS, | ||
4276 | .v.verbs = alc_gpio1_init_verbs, | ||
4277 | }, | ||
4278 | [ALC260_FIXUP_GPIO1_TOGGLE] = { | ||
4279 | .type = ALC_FIXUP_FUNC, | ||
4280 | .v.func = alc260_fixup_gpio1_toggle, | ||
4281 | .chained = true, | ||
4282 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | ||
4283 | }, | ||
4284 | [ALC260_FIXUP_REPLACER] = { | ||
4285 | .type = ALC_FIXUP_VERBS, | ||
4286 | .v.verbs = (const struct hda_verb[]) { | ||
4287 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4288 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | ||
4289 | { } | ||
4290 | }, | ||
4291 | .chained = true, | ||
4292 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, | ||
4293 | }, | ||
4294 | [ALC260_FIXUP_HP_B1900] = { | ||
4295 | .type = ALC_FIXUP_FUNC, | ||
4296 | .v.func = alc260_fixup_gpio1_toggle, | ||
4297 | .chained = true, | ||
4298 | .chain_id = ALC260_FIXUP_COEF, | ||
4299 | } | ||
4250 | }; | 4300 | }; |
4251 | 4301 | ||
4252 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 4302 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
4253 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), | 4303 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), |
4304 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), | ||
4305 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), | ||
4306 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), | ||
4307 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), | ||
4308 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), | ||
4309 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), | ||
4310 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), | ||
4254 | {} | 4311 | {} |
4255 | }; | 4312 | }; |
4256 | 4313 | ||
4257 | /* | 4314 | /* |
4258 | */ | 4315 | */ |
4259 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4260 | #include "alc260_quirks.c" | ||
4261 | #endif | ||
4262 | |||
4263 | static int patch_alc260(struct hda_codec *codec) | 4316 | static int patch_alc260(struct hda_codec *codec) |
4264 | { | 4317 | { |
4265 | struct alc_spec *spec; | 4318 | struct alc_spec *spec; |
4266 | int err, board_config; | 4319 | int err; |
4267 | 4320 | ||
4268 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4321 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4269 | if (spec == NULL) | 4322 | if (spec == NULL) |
@@ -4273,38 +4326,13 @@ static int patch_alc260(struct hda_codec *codec) | |||
4273 | 4326 | ||
4274 | spec->mixer_nid = 0x07; | 4327 | spec->mixer_nid = 0x07; |
4275 | 4328 | ||
4276 | board_config = alc_board_config(codec, ALC260_MODEL_LAST, | 4329 | alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); |
4277 | alc260_models, alc260_cfg_tbl); | 4330 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
4278 | if (board_config < 0) { | ||
4279 | snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
4280 | codec->chip_name); | ||
4281 | board_config = ALC_MODEL_AUTO; | ||
4282 | } | ||
4283 | |||
4284 | if (board_config == ALC_MODEL_AUTO) { | ||
4285 | alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); | ||
4286 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
4287 | } | ||
4288 | |||
4289 | if (board_config == ALC_MODEL_AUTO) { | ||
4290 | /* automatic parse from the BIOS config */ | ||
4291 | err = alc260_parse_auto_config(codec); | ||
4292 | if (err < 0) | ||
4293 | goto error; | ||
4294 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4295 | else if (!err) { | ||
4296 | printk(KERN_INFO | ||
4297 | "hda_codec: Cannot set up configuration " | ||
4298 | "from BIOS. Using base mode...\n"); | ||
4299 | board_config = ALC260_BASIC; | ||
4300 | } | ||
4301 | #endif | ||
4302 | } | ||
4303 | 4331 | ||
4304 | if (board_config != ALC_MODEL_AUTO) { | 4332 | /* automatic parse from the BIOS config */ |
4305 | setup_preset(codec, &alc260_presets[board_config]); | 4333 | err = alc260_parse_auto_config(codec); |
4306 | spec->vmaster_nid = 0x08; | 4334 | if (err < 0) |
4307 | } | 4335 | goto error; |
4308 | 4336 | ||
4309 | if (!spec->no_analog && !spec->adc_nids) { | 4337 | if (!spec->no_analog && !spec->adc_nids) { |
4310 | alc_auto_fill_adc_caps(codec); | 4338 | alc_auto_fill_adc_caps(codec); |
@@ -4325,10 +4353,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
4325 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4353 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4326 | 4354 | ||
4327 | codec->patch_ops = alc_patch_ops; | 4355 | codec->patch_ops = alc_patch_ops; |
4328 | if (board_config == ALC_MODEL_AUTO) | 4356 | spec->init_hook = alc_auto_init_std; |
4329 | spec->init_hook = alc_auto_init_std; | ||
4330 | else | ||
4331 | codec->patch_ops.build_controls = __alc_build_controls; | ||
4332 | spec->shutup = alc_eapd_shutup; | 4357 | spec->shutup = alc_eapd_shutup; |
4333 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4358 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4334 | if (!spec->loopback.amplist) | 4359 | if (!spec->loopback.amplist) |
@@ -5399,7 +5424,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5399 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), | 5424 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), |
5400 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), | 5425 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
5401 | 5426 | ||
5402 | #if 1 | 5427 | #if 0 |
5403 | /* Below is a quirk table taken from the old code. | 5428 | /* Below is a quirk table taken from the old code. |
5404 | * Basically the device should work as is without the fixup table. | 5429 | * Basically the device should work as is without the fixup table. |
5405 | * If BIOS doesn't give a proper info, enable the corresponding | 5430 | * If BIOS doesn't give a proper info, enable the corresponding |
@@ -5615,8 +5640,10 @@ static const struct hda_amp_list alc861_loopbacks[] = { | |||
5615 | 5640 | ||
5616 | /* Pin config fixes */ | 5641 | /* Pin config fixes */ |
5617 | enum { | 5642 | enum { |
5618 | PINFIX_FSC_AMILO_PI1505, | 5643 | ALC861_FIXUP_FSC_AMILO_PI1505, |
5619 | PINFIX_ASUS_A6RP, | 5644 | ALC861_FIXUP_AMP_VREF_0F, |
5645 | ALC861_FIXUP_NO_JACK_DETECT, | ||
5646 | ALC861_FIXUP_ASUS_A6RP, | ||
5620 | }; | 5647 | }; |
5621 | 5648 | ||
5622 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | 5649 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ |
@@ -5638,8 +5665,16 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | |||
5638 | spec->keep_vref_in_automute = 1; | 5665 | spec->keep_vref_in_automute = 1; |
5639 | } | 5666 | } |
5640 | 5667 | ||
5668 | /* suppress the jack-detection */ | ||
5669 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, | ||
5670 | const struct alc_fixup *fix, int action) | ||
5671 | { | ||
5672 | if (action == ALC_FIXUP_ACT_PRE_PROBE) | ||
5673 | codec->no_jack_detect = 1; | ||
5674 | } | ||
5675 | |||
5641 | static const struct alc_fixup alc861_fixups[] = { | 5676 | static const struct alc_fixup alc861_fixups[] = { |
5642 | [PINFIX_FSC_AMILO_PI1505] = { | 5677 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { |
5643 | .type = ALC_FIXUP_PINS, | 5678 | .type = ALC_FIXUP_PINS, |
5644 | .v.pins = (const struct alc_pincfg[]) { | 5679 | .v.pins = (const struct alc_pincfg[]) { |
5645 | { 0x0b, 0x0221101f }, /* HP */ | 5680 | { 0x0b, 0x0221101f }, /* HP */ |
@@ -5647,17 +5682,29 @@ static const struct alc_fixup alc861_fixups[] = { | |||
5647 | { } | 5682 | { } |
5648 | } | 5683 | } |
5649 | }, | 5684 | }, |
5650 | [PINFIX_ASUS_A6RP] = { | 5685 | [ALC861_FIXUP_AMP_VREF_0F] = { |
5651 | .type = ALC_FIXUP_FUNC, | 5686 | .type = ALC_FIXUP_FUNC, |
5652 | .v.func = alc861_fixup_asus_amp_vref_0f, | 5687 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5653 | }, | 5688 | }, |
5689 | [ALC861_FIXUP_NO_JACK_DETECT] = { | ||
5690 | .type = ALC_FIXUP_FUNC, | ||
5691 | .v.func = alc_fixup_no_jack_detect, | ||
5692 | }, | ||
5693 | [ALC861_FIXUP_ASUS_A6RP] = { | ||
5694 | .type = ALC_FIXUP_FUNC, | ||
5695 | .v.func = alc861_fixup_asus_amp_vref_0f, | ||
5696 | .chained = true, | ||
5697 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, | ||
5698 | } | ||
5654 | }; | 5699 | }; |
5655 | 5700 | ||
5656 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 5701 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5657 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", PINFIX_ASUS_A6RP), | 5702 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), |
5658 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", PINFIX_ASUS_A6RP), | 5703 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), |
5659 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP), | 5704 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), |
5660 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), | 5705 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), |
5706 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), | ||
5707 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), | ||
5661 | {} | 5708 | {} |
5662 | }; | 5709 | }; |
5663 | 5710 | ||
@@ -5905,6 +5952,7 @@ enum { | |||
5905 | ALC662_FIXUP_ASUS_MODE6, | 5952 | ALC662_FIXUP_ASUS_MODE6, |
5906 | ALC662_FIXUP_ASUS_MODE7, | 5953 | ALC662_FIXUP_ASUS_MODE7, |
5907 | ALC662_FIXUP_ASUS_MODE8, | 5954 | ALC662_FIXUP_ASUS_MODE8, |
5955 | ALC662_FIXUP_NO_JACK_DETECT, | ||
5908 | }; | 5956 | }; |
5909 | 5957 | ||
5910 | static const struct alc_fixup alc662_fixups[] = { | 5958 | static const struct alc_fixup alc662_fixups[] = { |
@@ -6050,6 +6098,10 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6050 | .chained = true, | 6098 | .chained = true, |
6051 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 6099 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
6052 | }, | 6100 | }, |
6101 | [ALC662_FIXUP_NO_JACK_DETECT] = { | ||
6102 | .type = ALC_FIXUP_FUNC, | ||
6103 | .v.func = alc_fixup_no_jack_detect, | ||
6104 | }, | ||
6053 | }; | 6105 | }; |
6054 | 6106 | ||
6055 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 6107 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
@@ -6058,6 +6110,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
6058 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 6110 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
6059 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 6111 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
6060 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 6112 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
6113 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | ||
6061 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | 6114 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |
6062 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 6115 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
6063 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 6116 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6345df131a00..4c769405d72a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1060,26 +1060,9 @@ static struct snd_kcontrol_new stac_smux_mixer = { | |||
1060 | .put = stac92xx_smux_enum_put, | 1060 | .put = stac92xx_smux_enum_put, |
1061 | }; | 1061 | }; |
1062 | 1062 | ||
1063 | static const char * const slave_vols[] = { | 1063 | static const char * const slave_pfxs[] = { |
1064 | "Front Playback Volume", | 1064 | "Front", "Surround", "Center", "LFE", "Side", |
1065 | "Surround Playback Volume", | 1065 | "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 | ||
1072 | }; | ||
1073 | |||
1074 | static const char * const slave_sws[] = { | ||
1075 | "Front Playback Switch", | ||
1076 | "Surround Playback Switch", | ||
1077 | "Center Playback Switch", | ||
1078 | "LFE Playback Switch", | ||
1079 | "Side Playback Switch", | ||
1080 | "Headphone Playback Switch", | ||
1081 | "Speaker Playback Switch", | ||
1082 | "IEC958 Playback Switch", | ||
1083 | NULL | 1066 | NULL |
1084 | }; | 1067 | }; |
1085 | 1068 | ||
@@ -1153,13 +1136,15 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1153 | /* minimum value is actually mute */ | 1136 | /* minimum value is actually mute */ |
1154 | vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; | 1137 | vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; |
1155 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1138 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1156 | vmaster_tlv, slave_vols); | 1139 | vmaster_tlv, slave_pfxs, |
1140 | "Playback Volume"); | ||
1157 | if (err < 0) | 1141 | if (err < 0) |
1158 | return err; | 1142 | return err; |
1159 | } | 1143 | } |
1160 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 1144 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
1161 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 1145 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
1162 | NULL, slave_sws); | 1146 | NULL, slave_pfxs, |
1147 | "Playback Switch"); | ||
1163 | if (err < 0) | 1148 | if (err < 0) |
1164 | return err; | 1149 | return err; |
1165 | } | 1150 | } |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index dff9a00ee8fb..c7eb4d7d05c0 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -1445,25 +1445,9 @@ static const struct hda_pcm_stream via_pcm_digital_capture = { | |||
1445 | /* | 1445 | /* |
1446 | * slave controls for virtual master | 1446 | * slave controls for virtual master |
1447 | */ | 1447 | */ |
1448 | static const char * const via_slave_vols[] = { | 1448 | static const char * const via_slave_pfxs[] = { |
1449 | "Front Playback Volume", | 1449 | "Front", "Surround", "Center", "LFE", "Side", |
1450 | "Surround Playback Volume", | 1450 | "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 | |||
1459 | static 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, | 1451 | NULL, |
1468 | }; | 1452 | }; |
1469 | 1453 | ||
@@ -1508,13 +1492,15 @@ static int via_build_controls(struct hda_codec *codec) | |||
1508 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | 1492 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], |
1509 | HDA_OUTPUT, vmaster_tlv); | 1493 | HDA_OUTPUT, vmaster_tlv); |
1510 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1494 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1511 | vmaster_tlv, via_slave_vols); | 1495 | vmaster_tlv, via_slave_pfxs, |
1496 | "Playback Volume"); | ||
1512 | if (err < 0) | 1497 | if (err < 0) |
1513 | return err; | 1498 | return err; |
1514 | } | 1499 | } |
1515 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 1500 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
1516 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 1501 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
1517 | NULL, via_slave_sws); | 1502 | NULL, via_slave_pfxs, |
1503 | "Playback Switch"); | ||
1518 | if (err < 0) | 1504 | if (err < 0) |
1519 | return err; | 1505 | return err; |
1520 | } | 1506 | } |