]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Takashi Iwai <tiwai@suse.de> |
2 | Subject: ALSA: hda - IDT/Sigmatel codec updates | |
3 | Patch-mainline: 2.6.28-rc1 | |
4 | References: bnc#409140 | |
5 | ||
6 | A pile of updates for IDT/Sigtmatel codecs. | |
7 | ||
8 | - digital beep support | |
9 | - 92HD83x codecs | |
10 | - HP M4 model support | |
11 | - ECS 202 model support | |
12 | - Multiple SPDIF support | |
13 | - More power-saving | |
14 | ||
15 | Signed-off-by: Takashi Iwai <tiwai@suse.de> | |
16 | ||
17 | --- | |
18 | --- | |
19 | sound/pci/hda/hda_codec.c | 9 | |
20 | sound/pci/hda/hda_local.h | 9 | |
21 | sound/pci/hda/patch_sigmatel.c | 975 ++++++++++++++++++++++++++++++++++++----- | |
22 | 3 files changed, 877 insertions(+), 116 deletions(-) | |
23 | ||
24 | --- a/sound/pci/hda/hda_codec.c | |
25 | +++ b/sound/pci/hda/hda_codec.c | |
26 | @@ -959,15 +959,6 @@ void snd_hda_codec_resume_amp(struct hda | |
27 | } | |
28 | #endif /* SND_HDA_NEEDS_RESUME */ | |
29 | ||
30 | -/* | |
31 | - * AMP control callbacks | |
32 | - */ | |
33 | -/* retrieve parameters from private_value */ | |
34 | -#define get_amp_nid(kc) ((kc)->private_value & 0xffff) | |
35 | -#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) | |
36 | -#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) | |
37 | -#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) | |
38 | - | |
39 | /* volume */ | |
40 | int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, | |
41 | struct snd_ctl_elem_info *uinfo) | |
42 | --- a/sound/pci/hda/hda_local.h | |
43 | +++ b/sound/pci/hda/hda_local.h | |
44 | @@ -421,4 +421,13 @@ int snd_hda_check_amp_list_power(struct | |
45 | hda_nid_t nid); | |
46 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | |
47 | ||
48 | +/* | |
49 | + * AMP control callbacks | |
50 | + */ | |
51 | +/* retrieve parameters from private_value */ | |
52 | +#define get_amp_nid(kc) ((kc)->private_value & 0xffff) | |
53 | +#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) | |
54 | +#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) | |
55 | +#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) | |
56 | + | |
57 | #endif /* __SOUND_HDA_LOCAL_H */ | |
58 | --- a/sound/pci/hda/patch_sigmatel.c | |
59 | +++ b/sound/pci/hda/patch_sigmatel.c | |
60 | @@ -33,10 +33,12 @@ | |
61 | #include "hda_codec.h" | |
62 | #include "hda_local.h" | |
63 | #include "hda_patch.h" | |
64 | +#include "hda_beep.h" | |
65 | ||
66 | #define NUM_CONTROL_ALLOC 32 | |
67 | #define STAC_PWR_EVENT 0x20 | |
68 | #define STAC_HP_EVENT 0x30 | |
69 | +#define STAC_VREF_EVENT 0x40 | |
70 | ||
71 | enum { | |
72 | STAC_REF, | |
73 | @@ -72,9 +74,15 @@ enum { | |
74 | }; | |
75 | ||
76 | enum { | |
77 | + STAC_92HD83XXX_REF, | |
78 | + STAC_92HD83XXX_MODELS | |
79 | +}; | |
80 | + | |
81 | +enum { | |
82 | STAC_92HD71BXX_REF, | |
83 | STAC_DELL_M4_1, | |
84 | STAC_DELL_M4_2, | |
85 | + STAC_HP_M4, | |
86 | STAC_92HD71BXX_MODELS | |
87 | }; | |
88 | ||
89 | @@ -132,6 +140,7 @@ struct sigmatel_spec { | |
90 | unsigned int mic_switch: 1; | |
91 | unsigned int alt_switch: 1; | |
92 | unsigned int hp_detect: 1; | |
93 | + unsigned int spdif_mute: 1; | |
94 | ||
95 | /* gpio lines */ | |
96 | unsigned int eapd_mask; | |
97 | @@ -140,17 +149,22 @@ struct sigmatel_spec { | |
98 | unsigned int gpio_data; | |
99 | unsigned int gpio_mute; | |
100 | ||
101 | + /* stream */ | |
102 | + unsigned int stream_delay; | |
103 | + | |
104 | /* analog loopback */ | |
105 | unsigned char aloopback_mask; | |
106 | unsigned char aloopback_shift; | |
107 | ||
108 | /* power management */ | |
109 | unsigned int num_pwrs; | |
110 | + unsigned int *pwr_mapping; | |
111 | hda_nid_t *pwr_nids; | |
112 | hda_nid_t *dac_list; | |
113 | ||
114 | /* playback */ | |
115 | struct hda_input_mux *mono_mux; | |
116 | + struct hda_input_mux *amp_mux; | |
117 | unsigned int cur_mmux; | |
118 | struct hda_multi_out multiout; | |
119 | hda_nid_t dac_nids[5]; | |
120 | @@ -164,8 +178,14 @@ struct sigmatel_spec { | |
121 | unsigned int num_dmics; | |
122 | hda_nid_t *dmux_nids; | |
123 | unsigned int num_dmuxes; | |
124 | + hda_nid_t *smux_nids; | |
125 | + unsigned int num_smuxes; | |
126 | + const char **spdif_labels; | |
127 | + | |
128 | hda_nid_t dig_in_nid; | |
129 | hda_nid_t mono_nid; | |
130 | + hda_nid_t anabeep_nid; | |
131 | + hda_nid_t digbeep_nid; | |
132 | ||
133 | /* pin widgets */ | |
134 | hda_nid_t *pin_nids; | |
135 | @@ -182,6 +202,12 @@ struct sigmatel_spec { | |
136 | unsigned int cur_dmux[2]; | |
137 | struct hda_input_mux *input_mux; | |
138 | unsigned int cur_mux[3]; | |
139 | + struct hda_input_mux *sinput_mux; | |
140 | + unsigned int cur_smux[2]; | |
141 | + unsigned int cur_amux; | |
142 | + hda_nid_t *amp_nids; | |
143 | + unsigned int num_amps; | |
144 | + unsigned int powerdown_adcs; | |
145 | ||
146 | /* i/o switches */ | |
147 | unsigned int io_switch[2]; | |
148 | @@ -197,6 +223,8 @@ struct sigmatel_spec { | |
149 | struct snd_kcontrol_new *kctl_alloc; | |
150 | struct hda_input_mux private_dimux; | |
151 | struct hda_input_mux private_imux; | |
152 | + struct hda_input_mux private_smux; | |
153 | + struct hda_input_mux private_amp_mux; | |
154 | struct hda_input_mux private_mono_mux; | |
155 | }; | |
156 | ||
157 | @@ -217,10 +245,19 @@ static hda_nid_t stac92hd73xx_pwr_nids[8 | |
158 | 0x0f, 0x10, 0x11 | |
159 | }; | |
160 | ||
161 | +static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { | |
162 | + 0x26, 0, | |
163 | +}; | |
164 | + | |
165 | static hda_nid_t stac92hd73xx_adc_nids[2] = { | |
166 | 0x1a, 0x1b | |
167 | }; | |
168 | ||
169 | +#define DELL_M6_AMP 2 | |
170 | +static hda_nid_t stac92hd73xx_amp_nids[3] = { | |
171 | + 0x0b, 0x0c, 0x0e | |
172 | +}; | |
173 | + | |
174 | #define STAC92HD73XX_NUM_DMICS 2 | |
175 | static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { | |
176 | 0x13, 0x14, 0 | |
177 | @@ -239,6 +276,41 @@ static hda_nid_t stac92hd73xx_dmux_nids[ | |
178 | 0x20, 0x21, | |
179 | }; | |
180 | ||
181 | +static hda_nid_t stac92hd73xx_smux_nids[2] = { | |
182 | + 0x22, 0x23, | |
183 | +}; | |
184 | + | |
185 | +#define STAC92HD83XXX_NUM_DMICS 2 | |
186 | +static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | |
187 | + 0x11, 0x12, 0 | |
188 | +}; | |
189 | + | |
190 | +#define STAC92HD81_DAC_COUNT 2 | |
191 | +#define STAC92HD83_DAC_COUNT 3 | |
192 | +static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = { | |
193 | + 0x13, 0x14, 0x22, | |
194 | +}; | |
195 | + | |
196 | +static hda_nid_t stac92hd83xxx_dmux_nids[2] = { | |
197 | + 0x17, 0x18, | |
198 | +}; | |
199 | + | |
200 | +static hda_nid_t stac92hd83xxx_adc_nids[2] = { | |
201 | + 0x15, 0x16, | |
202 | +}; | |
203 | + | |
204 | +static hda_nid_t stac92hd83xxx_pwr_nids[4] = { | |
205 | + 0xa, 0xb, 0xd, 0xe, | |
206 | +}; | |
207 | + | |
208 | +static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { | |
209 | + 0x1e, 0, | |
210 | +}; | |
211 | + | |
212 | +static unsigned int stac92hd83xxx_pwr_mapping[4] = { | |
213 | + 0x03, 0x0c, 0x10, 0x40, | |
214 | +}; | |
215 | + | |
216 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | |
217 | 0x0a, 0x0d, 0x0f | |
218 | }; | |
219 | @@ -251,8 +323,12 @@ static hda_nid_t stac92hd71bxx_mux_nids[ | |
220 | 0x1a, 0x1b | |
221 | }; | |
222 | ||
223 | -static hda_nid_t stac92hd71bxx_dmux_nids[1] = { | |
224 | - 0x1c, | |
225 | +static hda_nid_t stac92hd71bxx_dmux_nids[2] = { | |
226 | + 0x1c, 0x1d, | |
227 | +}; | |
228 | + | |
229 | +static hda_nid_t stac92hd71bxx_smux_nids[2] = { | |
230 | + 0x24, 0x25, | |
231 | }; | |
232 | ||
233 | static hda_nid_t stac92hd71bxx_dac_nids[1] = { | |
234 | @@ -264,6 +340,10 @@ static hda_nid_t stac92hd71bxx_dmic_nids | |
235 | 0x18, 0x19, 0 | |
236 | }; | |
237 | ||
238 | +static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { | |
239 | + 0x22, 0 | |
240 | +}; | |
241 | + | |
242 | static hda_nid_t stac925x_adc_nids[1] = { | |
243 | 0x03, | |
244 | }; | |
245 | @@ -301,6 +381,10 @@ static hda_nid_t stac927x_mux_nids[3] = | |
246 | 0x15, 0x16, 0x17 | |
247 | }; | |
248 | ||
249 | +static hda_nid_t stac927x_smux_nids[1] = { | |
250 | + 0x21, | |
251 | +}; | |
252 | + | |
253 | static hda_nid_t stac927x_dac_nids[6] = { | |
254 | 0x02, 0x03, 0x04, 0x05, 0x06, 0 | |
255 | }; | |
256 | @@ -314,6 +398,11 @@ static hda_nid_t stac927x_dmic_nids[STAC | |
257 | 0x13, 0x14, 0 | |
258 | }; | |
259 | ||
260 | +static const char *stac927x_spdif_labels[5] = { | |
261 | + "Digital Playback", "ADAT", "Analog Mux 1", | |
262 | + "Analog Mux 2", "Analog Mux 3" | |
263 | +}; | |
264 | + | |
265 | static hda_nid_t stac9205_adc_nids[2] = { | |
266 | 0x12, 0x13 | |
267 | }; | |
268 | @@ -326,6 +415,10 @@ static hda_nid_t stac9205_dmux_nids[1] = | |
269 | 0x1d, | |
270 | }; | |
271 | ||
272 | +static hda_nid_t stac9205_smux_nids[1] = { | |
273 | + 0x21, | |
274 | +}; | |
275 | + | |
276 | #define STAC9205_NUM_DMICS 2 | |
277 | static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { | |
278 | 0x17, 0x18, 0 | |
279 | @@ -349,12 +442,18 @@ static hda_nid_t stac922x_pin_nids[10] = | |
280 | static hda_nid_t stac92hd73xx_pin_nids[13] = { | |
281 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | |
282 | 0x0f, 0x10, 0x11, 0x12, 0x13, | |
283 | - 0x14, 0x1e, 0x22 | |
284 | + 0x14, 0x22, 0x23 | |
285 | }; | |
286 | ||
287 | -static hda_nid_t stac92hd71bxx_pin_nids[10] = { | |
288 | +static hda_nid_t stac92hd83xxx_pin_nids[14] = { | |
289 | + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | |
290 | + 0x0f, 0x10, 0x11, 0x12, 0x13, | |
291 | + 0x1d, 0x1e, 0x1f, 0x20 | |
292 | +}; | |
293 | +static hda_nid_t stac92hd71bxx_pin_nids[11] = { | |
294 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | |
295 | 0x0f, 0x14, 0x18, 0x19, 0x1e, | |
296 | + 0x1f, | |
297 | }; | |
298 | ||
299 | static hda_nid_t stac927x_pin_nids[14] = { | |
300 | @@ -369,6 +468,34 @@ static hda_nid_t stac9205_pin_nids[12] = | |
301 | 0x21, 0x22, | |
302 | }; | |
303 | ||
304 | +#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info | |
305 | + | |
306 | +static int stac92xx_amp_volume_get(struct snd_kcontrol *kcontrol, | |
307 | + struct snd_ctl_elem_value *ucontrol) | |
308 | +{ | |
309 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
310 | + struct sigmatel_spec *spec = codec->spec; | |
311 | + hda_nid_t nid = spec->amp_nids[spec->cur_amux]; | |
312 | + | |
313 | + kcontrol->private_value ^= get_amp_nid(kcontrol); | |
314 | + kcontrol->private_value |= nid; | |
315 | + | |
316 | + return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); | |
317 | +} | |
318 | + | |
319 | +static int stac92xx_amp_volume_put(struct snd_kcontrol *kcontrol, | |
320 | + struct snd_ctl_elem_value *ucontrol) | |
321 | +{ | |
322 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
323 | + struct sigmatel_spec *spec = codec->spec; | |
324 | + hda_nid_t nid = spec->amp_nids[spec->cur_amux]; | |
325 | + | |
326 | + kcontrol->private_value ^= get_amp_nid(kcontrol); | |
327 | + kcontrol->private_value |= nid; | |
328 | + | |
329 | + return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); | |
330 | +} | |
331 | + | |
332 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, | |
333 | struct snd_ctl_elem_info *uinfo) | |
334 | { | |
335 | @@ -399,6 +526,58 @@ static int stac92xx_dmux_enum_put(struct | |
336 | spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); | |
337 | } | |
338 | ||
339 | +static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol, | |
340 | + struct snd_ctl_elem_info *uinfo) | |
341 | +{ | |
342 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
343 | + struct sigmatel_spec *spec = codec->spec; | |
344 | + return snd_hda_input_mux_info(spec->sinput_mux, uinfo); | |
345 | +} | |
346 | + | |
347 | +static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol, | |
348 | + struct snd_ctl_elem_value *ucontrol) | |
349 | +{ | |
350 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
351 | + struct sigmatel_spec *spec = codec->spec; | |
352 | + unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | |
353 | + | |
354 | + ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; | |
355 | + return 0; | |
356 | +} | |
357 | + | |
358 | +static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, | |
359 | + struct snd_ctl_elem_value *ucontrol) | |
360 | +{ | |
361 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
362 | + struct sigmatel_spec *spec = codec->spec; | |
363 | + struct hda_input_mux *smux = &spec->private_smux; | |
364 | + unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | |
365 | + int err, val; | |
366 | + hda_nid_t nid; | |
367 | + | |
368 | + err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, | |
369 | + spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]); | |
370 | + if (err < 0) | |
371 | + return err; | |
372 | + | |
373 | + if (spec->spdif_mute) { | |
374 | + if (smux_idx == 0) | |
375 | + nid = spec->multiout.dig_out_nid; | |
376 | + else | |
377 | + nid = codec->slave_dig_outs[smux_idx - 1]; | |
378 | + if (spec->cur_smux[smux_idx] == smux->num_items - 1) | |
379 | + val = AMP_OUT_MUTE; | |
380 | + if (smux_idx == 0) | |
381 | + nid = spec->multiout.dig_out_nid; | |
382 | + else | |
383 | + nid = codec->slave_dig_outs[smux_idx - 1]; | |
384 | + /* un/mute SPDIF out */ | |
385 | + snd_hda_codec_write_cache(codec, nid, 0, | |
386 | + AC_VERB_SET_AMP_GAIN_MUTE, val); | |
387 | + } | |
388 | + return 0; | |
389 | +} | |
390 | + | |
391 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | |
392 | { | |
393 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
394 | @@ -454,6 +633,41 @@ static int stac92xx_mono_mux_enum_put(st | |
395 | spec->mono_nid, &spec->cur_mmux); | |
396 | } | |
397 | ||
398 | +static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol, | |
399 | + struct snd_ctl_elem_info *uinfo) | |
400 | +{ | |
401 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
402 | + struct sigmatel_spec *spec = codec->spec; | |
403 | + return snd_hda_input_mux_info(spec->amp_mux, uinfo); | |
404 | +} | |
405 | + | |
406 | +static int stac92xx_amp_mux_enum_get(struct snd_kcontrol *kcontrol, | |
407 | + struct snd_ctl_elem_value *ucontrol) | |
408 | +{ | |
409 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
410 | + struct sigmatel_spec *spec = codec->spec; | |
411 | + | |
412 | + ucontrol->value.enumerated.item[0] = spec->cur_amux; | |
413 | + return 0; | |
414 | +} | |
415 | + | |
416 | +static int stac92xx_amp_mux_enum_put(struct snd_kcontrol *kcontrol, | |
417 | + struct snd_ctl_elem_value *ucontrol) | |
418 | +{ | |
419 | + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | |
420 | + struct sigmatel_spec *spec = codec->spec; | |
421 | + struct snd_kcontrol *ctl = | |
422 | + snd_hda_find_mixer_ctl(codec, "Amp Capture Volume"); | |
423 | + if (!ctl) | |
424 | + return -EINVAL; | |
425 | + | |
426 | + snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE | | |
427 | + SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | |
428 | + | |
429 | + return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol, | |
430 | + 0, &spec->cur_amux); | |
431 | +} | |
432 | + | |
433 | #define stac92xx_aloopback_info snd_ctl_boolean_mono_info | |
434 | ||
435 | static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, | |
436 | @@ -565,8 +779,8 @@ static struct hda_verb dell_m6_core_init | |
437 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | |
438 | /* setup audio connections */ | |
439 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | |
440 | - { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | |
441 | - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, | |
442 | + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02}, | |
443 | + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01}, | |
444 | /* setup adcs to point to mixer */ | |
445 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | |
446 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | |
447 | @@ -628,12 +842,25 @@ static struct hda_verb stac92hd73xx_10ch | |
448 | {} | |
449 | }; | |
450 | ||
451 | +static struct hda_verb stac92hd83xxx_core_init[] = { | |
452 | + /* start of config #1 */ | |
453 | + { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3}, | |
454 | + | |
455 | + /* start of config #2 */ | |
456 | + { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, | |
457 | + { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, | |
458 | + { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, | |
459 | + | |
460 | + /* power state controls amps */ | |
461 | + { 0x01, AC_VERB_SET_EAPD, 1 << 2}, | |
462 | + {} | |
463 | +}; | |
464 | + | |
465 | static struct hda_verb stac92hd71bxx_core_init[] = { | |
466 | /* set master volume and direct control */ | |
467 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | |
468 | /* connect headphone jack to dac1 */ | |
469 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | |
470 | - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ | |
471 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ | |
472 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | |
473 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | |
474 | @@ -641,13 +868,12 @@ static struct hda_verb stac92hd71bxx_cor | |
475 | {} | |
476 | }; | |
477 | ||
478 | -#define HD_DISABLE_PORTF 3 | |
479 | +#define HD_DISABLE_PORTF 2 | |
480 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | |
481 | /* start of config #1 */ | |
482 | ||
483 | /* connect port 0f to audio mixer */ | |
484 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | |
485 | - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ | |
486 | /* unmute right and left channels for node 0x0f */ | |
487 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | |
488 | /* start of config #2 */ | |
489 | @@ -656,10 +882,6 @@ static struct hda_verb stac92hd71bxx_ana | |
490 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | |
491 | /* connect headphone jack to dac1 */ | |
492 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | |
493 | - /* connect port 0d to audio mixer */ | |
494 | - { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2}, | |
495 | - /* unmute dac0 input in audio mixer */ | |
496 | - { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, | |
497 | /* unmute right and left channels for nodes 0x0a, 0xd */ | |
498 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | |
499 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | |
500 | @@ -691,12 +913,16 @@ static struct hda_verb d965_core_init[] | |
501 | static struct hda_verb stac927x_core_init[] = { | |
502 | /* set master volume and direct control */ | |
503 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | |
504 | + /* enable analog pc beep path */ | |
505 | + { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, | |
506 | {} | |
507 | }; | |
508 | ||
509 | static struct hda_verb stac9205_core_init[] = { | |
510 | /* set master volume and direct control */ | |
511 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | |
512 | + /* enable analog pc beep path */ | |
513 | + { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, | |
514 | {} | |
515 | }; | |
516 | ||
517 | @@ -710,6 +936,31 @@ static struct hda_verb stac9205_core_ini | |
518 | .put = stac92xx_mono_mux_enum_put, \ | |
519 | } | |
520 | ||
521 | +#define STAC_AMP_MUX \ | |
522 | + { \ | |
523 | + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | |
524 | + .name = "Amp Selector Capture Switch", \ | |
525 | + .count = 1, \ | |
526 | + .info = stac92xx_amp_mux_enum_info, \ | |
527 | + .get = stac92xx_amp_mux_enum_get, \ | |
528 | + .put = stac92xx_amp_mux_enum_put, \ | |
529 | + } | |
530 | + | |
531 | +#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \ | |
532 | + { \ | |
533 | + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | |
534 | + .name = xname, \ | |
535 | + .index = 0, \ | |
536 | + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | |
537 | + SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | |
538 | + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ | |
539 | + .info = stac92xx_amp_volume_info, \ | |
540 | + .get = stac92xx_amp_volume_get, \ | |
541 | + .put = stac92xx_amp_volume_put, \ | |
542 | + .tlv = { .c = snd_hda_mixer_amp_tlv }, \ | |
543 | + .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ | |
544 | + } | |
545 | + | |
546 | #define STAC_INPUT_SOURCE(cnt) \ | |
547 | { \ | |
548 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | |
549 | @@ -737,33 +988,36 @@ static struct snd_kcontrol_new stac9200_ | |
550 | STAC_INPUT_SOURCE(1), | |
551 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | |
552 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | |
553 | - HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT), | |
554 | { } /* end */ | |
555 | }; | |
556 | ||
557 | +#define DELL_M6_MIXER 6 | |
558 | static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | |
559 | - STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | |
560 | - | |
561 | - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | |
562 | - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | |
563 | - | |
564 | - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | |
565 | - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | |
566 | - | |
567 | + /* start of config #1 */ | |
568 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), | |
569 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), | |
570 | ||
571 | - HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), | |
572 | - HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), | |
573 | - | |
574 | HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), | |
575 | HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), | |
576 | ||
577 | + HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), | |
578 | + HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), | |
579 | + | |
580 | + /* start of config #2 */ | |
581 | + HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), | |
582 | + HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), | |
583 | + | |
584 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), | |
585 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), | |
586 | ||
587 | - HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), | |
588 | - HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), | |
589 | + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | |
590 | + | |
591 | + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | |
592 | + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | |
593 | + | |
594 | + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | |
595 | + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | |
596 | + | |
597 | { } /* end */ | |
598 | }; | |
599 | ||
600 | @@ -819,22 +1073,59 @@ static struct snd_kcontrol_new stac92hd7 | |
601 | { } /* end */ | |
602 | }; | |
603 | ||
604 | + | |
605 | +static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | |
606 | + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT), | |
607 | + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT), | |
608 | + | |
609 | + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), | |
610 | + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), | |
611 | + | |
612 | + HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT), | |
613 | + HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT), | |
614 | + | |
615 | + HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT), | |
616 | + HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT), | |
617 | + | |
618 | + HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT), | |
619 | + HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT), | |
620 | + | |
621 | + HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT), | |
622 | + HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT), | |
623 | + | |
624 | + /* | |
625 | + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), | |
626 | + HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), | |
627 | + */ | |
628 | + { } /* end */ | |
629 | +}; | |
630 | + | |
631 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | |
632 | STAC_INPUT_SOURCE(2), | |
633 | + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | |
634 | ||
635 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | |
636 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | |
637 | - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT), | |
638 | ||
639 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | |
640 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | |
641 | - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), | |
642 | - | |
643 | + /* analog pc-beep replaced with digital beep support */ | |
644 | + /* | |
645 | HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), | |
646 | HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), | |
647 | + */ | |
648 | + | |
649 | + HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), | |
650 | + HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), | |
651 | + | |
652 | + HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT), | |
653 | + HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT), | |
654 | ||
655 | - HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), | |
656 | - HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), | |
657 | + HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT), | |
658 | + HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT), | |
659 | + | |
660 | + HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT), | |
661 | + HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT), | |
662 | { } /* end */ | |
663 | }; | |
664 | ||
665 | @@ -844,11 +1135,9 @@ static struct snd_kcontrol_new stac92hd7 | |
666 | ||
667 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | |
668 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | |
669 | - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT), | |
670 | ||
671 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | |
672 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | |
673 | - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), | |
674 | { } /* end */ | |
675 | }; | |
676 | ||
677 | @@ -856,7 +1145,6 @@ static struct snd_kcontrol_new stac925x_ | |
678 | STAC_INPUT_SOURCE(1), | |
679 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | |
680 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | |
681 | - HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), | |
682 | { } /* end */ | |
683 | }; | |
684 | ||
685 | @@ -866,12 +1154,9 @@ static struct snd_kcontrol_new stac9205_ | |
686 | ||
687 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | |
688 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), | |
689 | - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT), | |
690 | ||
691 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), | |
692 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), | |
693 | - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT), | |
694 | - | |
695 | { } /* end */ | |
696 | }; | |
697 | ||
698 | @@ -880,11 +1165,9 @@ static struct snd_kcontrol_new stac922x_ | |
699 | STAC_INPUT_SOURCE(2), | |
700 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | |
701 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | |
702 | - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT), | |
703 | ||
704 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), | |
705 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), | |
706 | - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT), | |
707 | { } /* end */ | |
708 | }; | |
709 | ||
710 | @@ -895,15 +1178,12 @@ static struct snd_kcontrol_new stac927x_ | |
711 | ||
712 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | |
713 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), | |
714 | - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT), | |
715 | ||
716 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), | |
717 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), | |
718 | - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT), | |
719 | ||
720 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), | |
721 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), | |
722 | - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT), | |
723 | { } /* end */ | |
724 | }; | |
725 | ||
726 | @@ -916,6 +1196,15 @@ static struct snd_kcontrol_new stac_dmux | |
727 | .put = stac92xx_dmux_enum_put, | |
728 | }; | |
729 | ||
730 | +static struct snd_kcontrol_new stac_smux_mixer = { | |
731 | + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | |
732 | + .name = "IEC958 Playback Source", | |
733 | + /* count set later */ | |
734 | + .info = stac92xx_smux_enum_info, | |
735 | + .get = stac92xx_smux_enum_get, | |
736 | + .put = stac92xx_smux_enum_put, | |
737 | +}; | |
738 | + | |
739 | static const char *slave_vols[] = { | |
740 | "Front Playback Volume", | |
741 | "Surround Playback Volume", | |
742 | @@ -967,6 +1256,22 @@ static int stac92xx_build_controls(struc | |
743 | if (err < 0) | |
744 | return err; | |
745 | } | |
746 | + if (spec->num_smuxes > 0) { | |
747 | + int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid); | |
748 | + struct hda_input_mux *smux = &spec->private_smux; | |
749 | + /* check for mute support on SPDIF out */ | |
750 | + if (wcaps & AC_WCAP_OUT_AMP) { | |
751 | + smux->items[smux->num_items].label = "Off"; | |
752 | + smux->items[smux->num_items].index = 0; | |
753 | + smux->num_items++; | |
754 | + spec->spdif_mute = 1; | |
755 | + } | |
756 | + stac_smux_mixer.count = spec->num_smuxes; | |
757 | + err = snd_ctl_add(codec->bus->card, | |
758 | + snd_ctl_new1(&stac_smux_mixer, codec)); | |
759 | + if (err < 0) | |
760 | + return err; | |
761 | + } | |
762 | ||
763 | if (spec->multiout.dig_out_nid) { | |
764 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | |
765 | @@ -978,7 +1283,7 @@ static int stac92xx_build_controls(struc | |
766 | return err; | |
767 | spec->multiout.share_spdif = 1; | |
768 | } | |
769 | - if (spec->dig_in_nid) { | |
770 | + if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) { | |
771 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | |
772 | if (err < 0) | |
773 | return err; | |
774 | @@ -1330,40 +1635,65 @@ static struct snd_pci_quirk stac92hd73xx | |
775 | {} /* terminator */ | |
776 | }; | |
777 | ||
778 | -static unsigned int ref92hd71bxx_pin_configs[10] = { | |
779 | +static unsigned int ref92hd83xxx_pin_configs[14] = { | |
780 | + 0x02214030, 0x02211010, 0x02a19020, 0x02170130, | |
781 | + 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, | |
782 | + 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, | |
783 | + 0x01451160, 0x98560170, | |
784 | +}; | |
785 | + | |
786 | +static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | |
787 | + [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | |
788 | +}; | |
789 | + | |
790 | +static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |
791 | + [STAC_92HD83XXX_REF] = "ref", | |
792 | +}; | |
793 | + | |
794 | +static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |
795 | + /* SigmaTel reference board */ | |
796 | + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | |
797 | + "DFI LanParty", STAC_92HD71BXX_REF), | |
798 | +}; | |
799 | + | |
800 | +static unsigned int ref92hd71bxx_pin_configs[11] = { | |
801 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, | |
802 | - 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0, | |
803 | - 0x90a000f0, 0x01452050, | |
804 | + 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, | |
805 | + 0x90a000f0, 0x01452050, 0x01452050, | |
806 | }; | |
807 | ||
808 | -static unsigned int dell_m4_1_pin_configs[10] = { | |
809 | +static unsigned int dell_m4_1_pin_configs[11] = { | |
810 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | |
811 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | |
812 | - 0x40f000f0, 0x4f0000f0, | |
813 | + 0x40f000f0, 0x4f0000f0, 0x4f0000f0, | |
814 | }; | |
815 | ||
816 | -static unsigned int dell_m4_2_pin_configs[10] = { | |
817 | +static unsigned int dell_m4_2_pin_configs[11] = { | |
818 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | |
819 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | |
820 | - 0x40f000f0, 0x044413b0, | |
821 | + 0x40f000f0, 0x044413b0, 0x044413b0, | |
822 | }; | |
823 | ||
824 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | |
825 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, | |
826 | [STAC_DELL_M4_1] = dell_m4_1_pin_configs, | |
827 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, | |
828 | + [STAC_HP_M4] = NULL, | |
829 | }; | |
830 | ||
831 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | |
832 | [STAC_92HD71BXX_REF] = "ref", | |
833 | [STAC_DELL_M4_1] = "dell-m4-1", | |
834 | [STAC_DELL_M4_2] = "dell-m4-2", | |
835 | + [STAC_HP_M4] = "hp-m4", | |
836 | }; | |
837 | ||
838 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |
839 | /* SigmaTel reference board */ | |
840 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | |
841 | "DFI LanParty", STAC_92HD71BXX_REF), | |
842 | + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, | |
843 | + "unknown HP", STAC_HP_M4), | |
844 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | |
845 | "unknown Dell", STAC_DELL_M4_1), | |
846 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | |
847 | @@ -1906,6 +2236,8 @@ static int stac92xx_playback_pcm_open(st | |
848 | struct snd_pcm_substream *substream) | |
849 | { | |
850 | struct sigmatel_spec *spec = codec->spec; | |
851 | + if (spec->stream_delay) | |
852 | + msleep(spec->stream_delay); | |
853 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | |
854 | hinfo); | |
855 | } | |
856 | @@ -1958,7 +2290,6 @@ static int stac92xx_dig_playback_pcm_pre | |
857 | stream_tag, format, substream); | |
858 | } | |
859 | ||
860 | - | |
861 | /* | |
862 | * Analog capture callbacks | |
863 | */ | |
864 | @@ -1969,9 +2300,14 @@ static int stac92xx_capture_pcm_prepare( | |
865 | struct snd_pcm_substream *substream) | |
866 | { | |
867 | struct sigmatel_spec *spec = codec->spec; | |
868 | + hda_nid_t nid = spec->adc_nids[substream->number]; | |
869 | ||
870 | - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], | |
871 | - stream_tag, 0, format); | |
872 | + if (spec->powerdown_adcs) { | |
873 | + msleep(40); | |
874 | + snd_hda_codec_write_cache(codec, nid, 0, | |
875 | + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | |
876 | + } | |
877 | + snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | |
878 | return 0; | |
879 | } | |
880 | ||
881 | @@ -1980,8 +2316,12 @@ static int stac92xx_capture_pcm_cleanup( | |
882 | struct snd_pcm_substream *substream) | |
883 | { | |
884 | struct sigmatel_spec *spec = codec->spec; | |
885 | + hda_nid_t nid = spec->adc_nids[substream->number]; | |
886 | ||
887 | - snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); | |
888 | + snd_hda_codec_cleanup_stream(codec, nid); | |
889 | + if (spec->powerdown_adcs) | |
890 | + snd_hda_codec_write_cache(codec, nid, 0, | |
891 | + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | |
892 | return 0; | |
893 | } | |
894 | ||
895 | @@ -2234,6 +2574,8 @@ enum { | |
896 | STAC_CTL_WIDGET_VOL, | |
897 | STAC_CTL_WIDGET_MUTE, | |
898 | STAC_CTL_WIDGET_MONO_MUX, | |
899 | + STAC_CTL_WIDGET_AMP_MUX, | |
900 | + STAC_CTL_WIDGET_AMP_VOL, | |
901 | STAC_CTL_WIDGET_HP_SWITCH, | |
902 | STAC_CTL_WIDGET_IO_SWITCH, | |
903 | STAC_CTL_WIDGET_CLFE_SWITCH | |
904 | @@ -2243,13 +2585,16 @@ static struct snd_kcontrol_new stac92xx_ | |
905 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | |
906 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | |
907 | STAC_MONO_MUX, | |
908 | + STAC_AMP_MUX, | |
909 | + STAC_AMP_VOL(NULL, 0, 0, 0, 0), | |
910 | STAC_CODEC_HP_SWITCH(NULL), | |
911 | STAC_CODEC_IO_SWITCH(NULL, 0), | |
912 | STAC_CODEC_CLFE_SWITCH(NULL, 0), | |
913 | }; | |
914 | ||
915 | /* add dynamic controls */ | |
916 | -static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val) | |
917 | +static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, | |
918 | + int idx, const char *name, unsigned long val) | |
919 | { | |
920 | struct snd_kcontrol_new *knew; | |
921 | ||
922 | @@ -2269,6 +2614,7 @@ static int stac92xx_add_control(struct s | |
923 | ||
924 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | |
925 | *knew = stac92xx_control_templates[type]; | |
926 | + knew->index = idx; | |
927 | knew->name = kstrdup(name, GFP_KERNEL); | |
928 | if (! knew->name) | |
929 | return -ENOMEM; | |
930 | @@ -2277,6 +2623,14 @@ static int stac92xx_add_control(struct s | |
931 | return 0; | |
932 | } | |
933 | ||
934 | + | |
935 | +/* add dynamic controls */ | |
936 | +static int stac92xx_add_control(struct sigmatel_spec *spec, int type, | |
937 | + const char *name, unsigned long val) | |
938 | +{ | |
939 | + return stac92xx_add_control_idx(spec, type, 0, name, val); | |
940 | +} | |
941 | + | |
942 | /* flag inputs as additional dynamic lineouts */ | |
943 | static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) | |
944 | { | |
945 | @@ -2468,7 +2822,7 @@ static int stac92xx_auto_create_multi_ou | |
946 | static const char *chname[4] = { | |
947 | "Front", "Surround", NULL /*CLFE*/, "Side" | |
948 | }; | |
949 | - hda_nid_t nid; | |
950 | + hda_nid_t nid = 0; | |
951 | int i, err; | |
952 | ||
953 | struct sigmatel_spec *spec = codec->spec; | |
954 | @@ -2508,6 +2862,10 @@ static int stac92xx_auto_create_multi_ou | |
955 | } | |
956 | } | |
957 | ||
958 | + if ((spec->multiout.num_dacs - cfg->line_outs) > 0 && | |
959 | + cfg->hp_outs && !spec->multiout.hp_nid) | |
960 | + spec->multiout.hp_nid = nid; | |
961 | + | |
962 | if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { | |
963 | err = stac92xx_add_control(spec, | |
964 | STAC_CTL_WIDGET_HP_SWITCH, | |
965 | @@ -2620,8 +2978,8 @@ static int stac92xx_auto_create_hp_ctls( | |
966 | } | |
967 | ||
968 | /* labels for mono mux outputs */ | |
969 | -static const char *stac92xx_mono_labels[3] = { | |
970 | - "DAC0", "DAC1", "Mixer" | |
971 | +static const char *stac92xx_mono_labels[4] = { | |
972 | + "DAC0", "DAC1", "Mixer", "DAC2" | |
973 | }; | |
974 | ||
975 | /* create mono mux for mono out on capable codecs */ | |
976 | @@ -2650,6 +3008,116 @@ static int stac92xx_auto_create_mono_out | |
977 | "Mono Mux", spec->mono_nid); | |
978 | } | |
979 | ||
980 | +/* labels for amp mux outputs */ | |
981 | +static const char *stac92xx_amp_labels[3] = { | |
982 | + "Front Microphone", "Microphone", "Line In", | |
983 | +}; | |
984 | + | |
985 | +/* create amp out controls mux on capable codecs */ | |
986 | +static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec) | |
987 | +{ | |
988 | + struct sigmatel_spec *spec = codec->spec; | |
989 | + struct hda_input_mux *amp_mux = &spec->private_amp_mux; | |
990 | + int i, err; | |
991 | + | |
992 | + for (i = 0; i < spec->num_amps; i++) { | |
993 | + amp_mux->items[amp_mux->num_items].label = | |
994 | + stac92xx_amp_labels[i]; | |
995 | + amp_mux->items[amp_mux->num_items].index = i; | |
996 | + amp_mux->num_items++; | |
997 | + } | |
998 | + | |
999 | + if (spec->num_amps > 1) { | |
1000 | + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX, | |
1001 | + "Amp Selector Capture Switch", 0); | |
1002 | + if (err < 0) | |
1003 | + return err; | |
1004 | + } | |
1005 | + return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL, | |
1006 | + "Amp Capture Volume", | |
1007 | + HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT)); | |
1008 | +} | |
1009 | + | |
1010 | + | |
1011 | +/* create PC beep volume controls */ | |
1012 | +static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, | |
1013 | + hda_nid_t nid) | |
1014 | +{ | |
1015 | + struct sigmatel_spec *spec = codec->spec; | |
1016 | + u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); | |
1017 | + int err; | |
1018 | + | |
1019 | + /* check for mute support for the the amp */ | |
1020 | + if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { | |
1021 | + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, | |
1022 | + "PC Beep Playback Switch", | |
1023 | + HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); | |
1024 | + if (err < 0) | |
1025 | + return err; | |
1026 | + } | |
1027 | + | |
1028 | + /* check to see if there is volume support for the amp */ | |
1029 | + if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { | |
1030 | + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, | |
1031 | + "PC Beep Playback Volume", | |
1032 | + HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); | |
1033 | + if (err < 0) | |
1034 | + return err; | |
1035 | + } | |
1036 | + return 0; | |
1037 | +} | |
1038 | + | |
1039 | +static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) | |
1040 | +{ | |
1041 | + struct sigmatel_spec *spec = codec->spec; | |
1042 | + int wcaps, nid, i, err = 0; | |
1043 | + | |
1044 | + for (i = 0; i < spec->num_muxes; i++) { | |
1045 | + nid = spec->mux_nids[i]; | |
1046 | + wcaps = get_wcaps(codec, nid); | |
1047 | + | |
1048 | + if (wcaps & AC_WCAP_OUT_AMP) { | |
1049 | + err = stac92xx_add_control_idx(spec, | |
1050 | + STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", | |
1051 | + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | |
1052 | + if (err < 0) | |
1053 | + return err; | |
1054 | + } | |
1055 | + } | |
1056 | + return 0; | |
1057 | +}; | |
1058 | + | |
1059 | +static const char *stac92xx_spdif_labels[3] = { | |
1060 | + "Digital Playback", "Analog Mux 1", "Analog Mux 2", | |
1061 | +}; | |
1062 | + | |
1063 | +static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) | |
1064 | +{ | |
1065 | + struct sigmatel_spec *spec = codec->spec; | |
1066 | + struct hda_input_mux *spdif_mux = &spec->private_smux; | |
1067 | + const char **labels = spec->spdif_labels; | |
1068 | + int i, num_cons; | |
1069 | + hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | |
1070 | + | |
1071 | + num_cons = snd_hda_get_connections(codec, | |
1072 | + spec->smux_nids[0], | |
1073 | + con_lst, | |
1074 | + HDA_MAX_NUM_INPUTS); | |
1075 | + if (!num_cons) | |
1076 | + return -EINVAL; | |
1077 | + | |
1078 | + if (!labels) | |
1079 | + labels = stac92xx_spdif_labels; | |
1080 | + | |
1081 | + for (i = 0; i < num_cons; i++) { | |
1082 | + spdif_mux->items[spdif_mux->num_items].label = labels[i]; | |
1083 | + spdif_mux->items[spdif_mux->num_items].index = i; | |
1084 | + spdif_mux->num_items++; | |
1085 | + } | |
1086 | + | |
1087 | + return 0; | |
1088 | +} | |
1089 | + | |
1090 | /* labels for dmic mux inputs */ | |
1091 | static const char *stac92xx_dmic_labels[5] = { | |
1092 | "Analog Inputs", "Digital Mic 1", "Digital Mic 2", | |
1093 | @@ -2697,16 +3165,19 @@ static int stac92xx_auto_create_dmic_inp | |
1094 | } | |
1095 | continue; | |
1096 | found: | |
1097 | - wcaps = get_wcaps(codec, nid); | |
1098 | + wcaps = get_wcaps(codec, nid) & | |
1099 | + (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | |
1100 | ||
1101 | - if (wcaps & AC_WCAP_OUT_AMP) { | |
1102 | + if (wcaps) { | |
1103 | sprintf(name, "%s Capture Volume", | |
1104 | stac92xx_dmic_labels[dimux->num_items]); | |
1105 | ||
1106 | err = stac92xx_add_control(spec, | |
1107 | STAC_CTL_WIDGET_VOL, | |
1108 | name, | |
1109 | - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | |
1110 | + HDA_COMPOSE_AMP_VAL(nid, 3, 0, | |
1111 | + (wcaps & AC_WCAP_OUT_AMP) ? | |
1112 | + HDA_OUTPUT : HDA_INPUT)); | |
1113 | if (err < 0) | |
1114 | return err; | |
1115 | } | |
1116 | @@ -2830,8 +3301,8 @@ static int stac92xx_parse_auto_config(st | |
1117 | hp_speaker_swap = 1; | |
1118 | } | |
1119 | if (spec->autocfg.mono_out_pin) { | |
1120 | - int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin) | |
1121 | - & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; | |
1122 | + int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & | |
1123 | + (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | |
1124 | u32 caps = query_amp_caps(codec, | |
1125 | spec->autocfg.mono_out_pin, dir); | |
1126 | hda_nid_t conn_list[1]; | |
1127 | @@ -2853,21 +3324,26 @@ static int stac92xx_parse_auto_config(st | |
1128 | !(wcaps & AC_WCAP_LR_SWAP)) | |
1129 | spec->mono_nid = conn_list[0]; | |
1130 | } | |
1131 | - /* all mono outs have a least a mute/unmute switch */ | |
1132 | - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, | |
1133 | - "Mono Playback Switch", | |
1134 | - HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin, | |
1135 | - 1, 0, dir)); | |
1136 | - if (err < 0) | |
1137 | - return err; | |
1138 | - /* check to see if there is volume support for the amp */ | |
1139 | - if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { | |
1140 | - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, | |
1141 | - "Mono Playback Volume", | |
1142 | - HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin, | |
1143 | - 1, 0, dir)); | |
1144 | + if (dir) { | |
1145 | + hda_nid_t nid = spec->autocfg.mono_out_pin; | |
1146 | + | |
1147 | + /* most mono outs have a least a mute/unmute switch */ | |
1148 | + dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; | |
1149 | + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, | |
1150 | + "Mono Playback Switch", | |
1151 | + HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); | |
1152 | if (err < 0) | |
1153 | return err; | |
1154 | + /* check for volume support for the amp */ | |
1155 | + if ((caps & AC_AMPCAP_NUM_STEPS) | |
1156 | + >> AC_AMPCAP_NUM_STEPS_SHIFT) { | |
1157 | + err = stac92xx_add_control(spec, | |
1158 | + STAC_CTL_WIDGET_VOL, | |
1159 | + "Mono Playback Volume", | |
1160 | + HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); | |
1161 | + if (err < 0) | |
1162 | + return err; | |
1163 | + } | |
1164 | } | |
1165 | ||
1166 | stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin, | |
1167 | @@ -2885,6 +3361,28 @@ static int stac92xx_parse_auto_config(st | |
1168 | if (err < 0) | |
1169 | return err; | |
1170 | ||
1171 | + /* setup analog beep controls */ | |
1172 | + if (spec->anabeep_nid > 0) { | |
1173 | + err = stac92xx_auto_create_beep_ctls(codec, | |
1174 | + spec->anabeep_nid); | |
1175 | + if (err < 0) | |
1176 | + return err; | |
1177 | + } | |
1178 | + | |
1179 | + /* setup digital beep controls and input device */ | |
1180 | +#ifdef CONFIG_SND_HDA_INPUT_BEEP | |
1181 | + if (spec->digbeep_nid > 0) { | |
1182 | + hda_nid_t nid = spec->digbeep_nid; | |
1183 | + | |
1184 | + err = stac92xx_auto_create_beep_ctls(codec, nid); | |
1185 | + if (err < 0) | |
1186 | + return err; | |
1187 | + err = snd_hda_attach_beep_device(codec, nid); | |
1188 | + if (err < 0) | |
1189 | + return err; | |
1190 | + } | |
1191 | +#endif | |
1192 | + | |
1193 | if (hp_speaker_swap == 1) { | |
1194 | /* Restore the hp_outs and line_outs */ | |
1195 | memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, | |
1196 | @@ -2913,11 +3411,25 @@ static int stac92xx_parse_auto_config(st | |
1197 | if (err < 0) | |
1198 | return err; | |
1199 | } | |
1200 | - | |
1201 | - if (spec->num_dmics > 0) | |
1202 | + if (spec->num_amps > 0) { | |
1203 | + err = stac92xx_auto_create_amp_output_ctls(codec); | |
1204 | + if (err < 0) | |
1205 | + return err; | |
1206 | + } | |
1207 | + if (spec->num_dmics > 0 && !spec->dinput_mux) | |
1208 | if ((err = stac92xx_auto_create_dmic_input_ctls(codec, | |
1209 | &spec->autocfg)) < 0) | |
1210 | return err; | |
1211 | + if (spec->num_muxes > 0) { | |
1212 | + err = stac92xx_auto_create_mux_input_ctls(codec); | |
1213 | + if (err < 0) | |
1214 | + return err; | |
1215 | + } | |
1216 | + if (spec->num_smuxes > 0) { | |
1217 | + err = stac92xx_auto_create_spdif_mux_ctls(codec); | |
1218 | + if (err < 0) | |
1219 | + return err; | |
1220 | + } | |
1221 | ||
1222 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | |
1223 | if (spec->multiout.max_channels > 2) | |
1224 | @@ -2925,17 +3437,17 @@ static int stac92xx_parse_auto_config(st | |
1225 | ||
1226 | if (spec->autocfg.dig_out_pin) | |
1227 | spec->multiout.dig_out_nid = dig_out; | |
1228 | - if (spec->autocfg.dig_in_pin) | |
1229 | + if (dig_in && spec->autocfg.dig_in_pin) | |
1230 | spec->dig_in_nid = dig_in; | |
1231 | ||
1232 | if (spec->kctl_alloc) | |
1233 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | |
1234 | ||
1235 | spec->input_mux = &spec->private_imux; | |
1236 | - if (!spec->dinput_mux) | |
1237 | - spec->dinput_mux = &spec->private_dimux; | |
1238 | + spec->dinput_mux = &spec->private_dimux; | |
1239 | + spec->sinput_mux = &spec->private_smux; | |
1240 | spec->mono_mux = &spec->private_mono_mux; | |
1241 | - | |
1242 | + spec->amp_mux = &spec->private_amp_mux; | |
1243 | return 1; | |
1244 | } | |
1245 | ||
1246 | @@ -3115,6 +3627,12 @@ static int stac92xx_init(struct hda_code | |
1247 | ||
1248 | snd_hda_sequence_write(codec, spec->init); | |
1249 | ||
1250 | + /* power down adcs initially */ | |
1251 | + if (spec->powerdown_adcs) | |
1252 | + for (i = 0; i < spec->num_adcs; i++) | |
1253 | + snd_hda_codec_write_cache(codec, | |
1254 | + spec->adc_nids[i], 0, | |
1255 | + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | |
1256 | /* set up pins */ | |
1257 | if (spec->hp_detect) { | |
1258 | /* Enable unsolicited responses on the HP widget */ | |
1259 | @@ -3136,7 +3654,12 @@ static int stac92xx_init(struct hda_code | |
1260 | for (i = 0; i < AUTO_PIN_LAST; i++) { | |
1261 | hda_nid_t nid = cfg->input_pins[i]; | |
1262 | if (nid) { | |
1263 | - unsigned int pinctl = AC_PINCTL_IN_EN; | |
1264 | + unsigned int pinctl = snd_hda_codec_read(codec, nid, | |
1265 | + 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | |
1266 | + /* if PINCTL already set then skip */ | |
1267 | + if (pinctl & AC_PINCAP_IN) | |
1268 | + continue; | |
1269 | + pinctl = AC_PINCTL_IN_EN; | |
1270 | if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) | |
1271 | pinctl |= stac92xx_get_vref(codec, nid); | |
1272 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | |
1273 | @@ -3199,6 +3722,7 @@ static void stac92xx_free(struct hda_cod | |
1274 | kfree(spec->bios_pin_configs); | |
1275 | ||
1276 | kfree(spec); | |
1277 | + snd_hda_detach_beep_device(codec); | |
1278 | } | |
1279 | ||
1280 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | |
1281 | @@ -3320,7 +3844,12 @@ static void stac92xx_pin_sense(struct hd | |
1282 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) | |
1283 | & 0x000000ff; | |
1284 | presence = get_hp_pin_presence(codec, nid); | |
1285 | - idx = 1 << idx; | |
1286 | + | |
1287 | + /* several codecs have two power down bits */ | |
1288 | + if (spec->pwr_mapping) | |
1289 | + idx = spec->pwr_mapping[idx]; | |
1290 | + else | |
1291 | + idx = 1 << idx; | |
1292 | ||
1293 | if (presence) | |
1294 | val &= ~idx; | |
1295 | @@ -3336,13 +3865,22 @@ static void stac92xx_unsol_event(struct | |
1296 | struct sigmatel_spec *spec = codec->spec; | |
1297 | int idx = res >> 26 & 0x0f; | |
1298 | ||
1299 | - switch ((res >> 26) & 0x30) { | |
1300 | + switch ((res >> 26) & 0x70) { | |
1301 | case STAC_HP_EVENT: | |
1302 | stac92xx_hp_detect(codec, res); | |
1303 | /* fallthru */ | |
1304 | case STAC_PWR_EVENT: | |
1305 | if (spec->num_pwrs > 0) | |
1306 | stac92xx_pin_sense(codec, idx); | |
1307 | + break; | |
1308 | + case STAC_VREF_EVENT: { | |
1309 | + int data = snd_hda_codec_read(codec, codec->afg, 0, | |
1310 | + AC_VERB_GET_GPIO_DATA, 0); | |
1311 | + /* toggle VREF state based on GPIOx status */ | |
1312 | + snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, | |
1313 | + !!(data & (1 << idx))); | |
1314 | + break; | |
1315 | + } | |
1316 | } | |
1317 | } | |
1318 | ||
1319 | @@ -3519,9 +4057,9 @@ static struct hda_input_mux stac92hd73xx | |
1320 | .num_items = 4, | |
1321 | .items = { | |
1322 | { "Analog Inputs", 0x0b }, | |
1323 | - { "CD", 0x08 }, | |
1324 | { "Digital Mic 1", 0x09 }, | |
1325 | { "Digital Mic 2", 0x0a }, | |
1326 | + { "CD", 0x08 }, | |
1327 | } | |
1328 | }; | |
1329 | ||
1330 | @@ -3536,6 +4074,7 @@ static int patch_stac92hd73xx(struct hda | |
1331 | return -ENOMEM; | |
1332 | ||
1333 | codec->spec = spec; | |
1334 | + codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; | |
1335 | spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); | |
1336 | spec->pin_nids = stac92hd73xx_pin_nids; | |
1337 | spec->board_config = snd_hda_check_board_config(codec, | |
1338 | @@ -3568,17 +4107,14 @@ again: | |
1339 | ||
1340 | switch (spec->multiout.num_dacs) { | |
1341 | case 0x3: /* 6 Channel */ | |
1342 | - spec->multiout.hp_nid = 0x17; | |
1343 | spec->mixer = stac92hd73xx_6ch_mixer; | |
1344 | spec->init = stac92hd73xx_6ch_core_init; | |
1345 | break; | |
1346 | case 0x4: /* 8 Channel */ | |
1347 | - spec->multiout.hp_nid = 0x18; | |
1348 | spec->mixer = stac92hd73xx_8ch_mixer; | |
1349 | spec->init = stac92hd73xx_8ch_core_init; | |
1350 | break; | |
1351 | case 0x5: /* 10 Channel */ | |
1352 | - spec->multiout.hp_nid = 0x19; | |
1353 | spec->mixer = stac92hd73xx_10ch_mixer; | |
1354 | spec->init = stac92hd73xx_10ch_core_init; | |
1355 | }; | |
1356 | @@ -3587,18 +4123,20 @@ again: | |
1357 | spec->aloopback_mask = 0x01; | |
1358 | spec->aloopback_shift = 8; | |
1359 | ||
1360 | + spec->digbeep_nid = 0x1c; | |
1361 | spec->mux_nids = stac92hd73xx_mux_nids; | |
1362 | spec->adc_nids = stac92hd73xx_adc_nids; | |
1363 | spec->dmic_nids = stac92hd73xx_dmic_nids; | |
1364 | spec->dmux_nids = stac92hd73xx_dmux_nids; | |
1365 | + spec->smux_nids = stac92hd73xx_smux_nids; | |
1366 | + spec->amp_nids = stac92hd73xx_amp_nids; | |
1367 | + spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids); | |
1368 | ||
1369 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); | |
1370 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); | |
1371 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); | |
1372 | - spec->dinput_mux = &stac92hd73xx_dmux; | |
1373 | - /* GPIO0 High = Enable EAPD */ | |
1374 | - spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | |
1375 | - spec->gpio_data = 0x01; | |
1376 | + memcpy(&spec->private_dimux, &stac92hd73xx_dmux, | |
1377 | + sizeof(stac92hd73xx_dmux)); | |
1378 | ||
1379 | switch (spec->board_config) { | |
1380 | case STAC_DELL_EQ: | |
1381 | @@ -3607,11 +4145,16 @@ again: | |
1382 | case STAC_DELL_M6: | |
1383 | if (!spec->init) | |
1384 | spec->init = dell_m6_core_init; | |
1385 | + spec->num_smuxes = 0; | |
1386 | + spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; | |
1387 | + spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; | |
1388 | + spec->num_amps = 1; | |
1389 | switch (codec->subsystem_id) { | |
1390 | case 0x1028025e: /* Analog Mics */ | |
1391 | case 0x1028025f: | |
1392 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | |
1393 | spec->num_dmics = 0; | |
1394 | + spec->private_dimux.num_items = 1; | |
1395 | break; | |
1396 | case 0x10280271: /* Digital Mics */ | |
1397 | case 0x10280272: | |
1398 | @@ -3619,23 +4162,32 @@ again: | |
1399 | case 0x10280255: | |
1400 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | |
1401 | spec->num_dmics = 1; | |
1402 | + spec->private_dimux.num_items = 2; | |
1403 | break; | |
1404 | case 0x10280256: /* Both */ | |
1405 | case 0x10280057: | |
1406 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | |
1407 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | |
1408 | spec->num_dmics = 1; | |
1409 | + spec->private_dimux.num_items = 2; | |
1410 | break; | |
1411 | } | |
1412 | break; | |
1413 | default: | |
1414 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; | |
1415 | + spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); | |
1416 | } | |
1417 | + if (spec->board_config > STAC_92HD73XX_REF) { | |
1418 | + /* GPIO0 High = Enable EAPD */ | |
1419 | + spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | |
1420 | + spec->gpio_data = 0x01; | |
1421 | + } | |
1422 | + spec->dinput_mux = &spec->private_dimux; | |
1423 | ||
1424 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); | |
1425 | spec->pwr_nids = stac92hd73xx_pwr_nids; | |
1426 | ||
1427 | - err = stac92xx_parse_auto_config(codec, 0x22, 0x24); | |
1428 | + err = stac92xx_parse_auto_config(codec, 0x25, 0x27); | |
1429 | ||
1430 | if (!err) { | |
1431 | if (spec->board_config < 0) { | |
1432 | @@ -3657,6 +4209,146 @@ again: | |
1433 | return 0; | |
1434 | } | |
1435 | ||
1436 | +static struct hda_input_mux stac92hd83xxx_dmux = { | |
1437 | + .num_items = 3, | |
1438 | + .items = { | |
1439 | + { "Analog Inputs", 0x03 }, | |
1440 | + { "Digital Mic 1", 0x04 }, | |
1441 | + { "Digital Mic 2", 0x05 }, | |
1442 | + } | |
1443 | +}; | |
1444 | + | |
1445 | +static int patch_stac92hd83xxx(struct hda_codec *codec) | |
1446 | +{ | |
1447 | + struct sigmatel_spec *spec; | |
1448 | + int err; | |
1449 | + | |
1450 | + spec = kzalloc(sizeof(*spec), GFP_KERNEL); | |
1451 | + if (spec == NULL) | |
1452 | + return -ENOMEM; | |
1453 | + | |
1454 | + codec->spec = spec; | |
1455 | + codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | |
1456 | + spec->mono_nid = 0x19; | |
1457 | + spec->digbeep_nid = 0x21; | |
1458 | + spec->dmic_nids = stac92hd83xxx_dmic_nids; | |
1459 | + spec->dmux_nids = stac92hd83xxx_dmux_nids; | |
1460 | + spec->adc_nids = stac92hd83xxx_adc_nids; | |
1461 | + spec->pwr_nids = stac92hd83xxx_pwr_nids; | |
1462 | + spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | |
1463 | + spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | |
1464 | + spec->multiout.dac_nids = stac92hd83xxx_dac_nids; | |
1465 | + | |
1466 | + spec->init = stac92hd83xxx_core_init; | |
1467 | + switch (codec->vendor_id) { | |
1468 | + case 0x111d7605: | |
1469 | + spec->multiout.num_dacs = STAC92HD81_DAC_COUNT; | |
1470 | + break; | |
1471 | + default: | |
1472 | + spec->num_pwrs--; | |
1473 | + spec->init++; /* switch to config #2 */ | |
1474 | + spec->multiout.num_dacs = STAC92HD83_DAC_COUNT; | |
1475 | + } | |
1476 | + | |
1477 | + spec->mixer = stac92hd83xxx_mixer; | |
1478 | + spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | |
1479 | + spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); | |
1480 | + spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | |
1481 | + spec->num_dmics = STAC92HD83XXX_NUM_DMICS; | |
1482 | + spec->dinput_mux = &stac92hd83xxx_dmux; | |
1483 | + spec->pin_nids = stac92hd83xxx_pin_nids; | |
1484 | + spec->board_config = snd_hda_check_board_config(codec, | |
1485 | + STAC_92HD83XXX_MODELS, | |
1486 | + stac92hd83xxx_models, | |
1487 | + stac92hd83xxx_cfg_tbl); | |
1488 | +again: | |
1489 | + if (spec->board_config < 0) { | |
1490 | + snd_printdd(KERN_INFO "hda_codec: Unknown model for" | |
1491 | + " STAC92HD83XXX, using BIOS defaults\n"); | |
1492 | + err = stac92xx_save_bios_config_regs(codec); | |
1493 | + if (err < 0) { | |
1494 | + stac92xx_free(codec); | |
1495 | + return err; | |
1496 | + } | |
1497 | + spec->pin_configs = spec->bios_pin_configs; | |
1498 | + } else { | |
1499 | + spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config]; | |
1500 | + stac92xx_set_config_regs(codec); | |
1501 | + } | |
1502 | + | |
1503 | + err = stac92xx_parse_auto_config(codec, 0x1d, 0); | |
1504 | + if (!err) { | |
1505 | + if (spec->board_config < 0) { | |
1506 | + printk(KERN_WARNING "hda_codec: No auto-config is " | |
1507 | + "available, default to model=ref\n"); | |
1508 | + spec->board_config = STAC_92HD83XXX_REF; | |
1509 | + goto again; | |
1510 | + } | |
1511 | + err = -EINVAL; | |
1512 | + } | |
1513 | + | |
1514 | + if (err < 0) { | |
1515 | + stac92xx_free(codec); | |
1516 | + return err; | |
1517 | + } | |
1518 | + | |
1519 | + codec->patch_ops = stac92xx_patch_ops; | |
1520 | + | |
1521 | + return 0; | |
1522 | +} | |
1523 | + | |
1524 | +#ifdef SND_HDA_NEEDS_RESUME | |
1525 | +static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr) | |
1526 | +{ | |
1527 | + struct sigmatel_spec *spec = codec->spec; | |
1528 | + int i; | |
1529 | + snd_hda_codec_write_cache(codec, codec->afg, 0, | |
1530 | + AC_VERB_SET_POWER_STATE, pwr); | |
1531 | + | |
1532 | + msleep(1); | |
1533 | + for (i = 0; i < spec->num_adcs; i++) { | |
1534 | + snd_hda_codec_write_cache(codec, | |
1535 | + spec->adc_nids[i], 0, | |
1536 | + AC_VERB_SET_POWER_STATE, pwr); | |
1537 | + } | |
1538 | +}; | |
1539 | + | |
1540 | +static int stac92hd71xx_resume(struct hda_codec *codec) | |
1541 | +{ | |
1542 | + stac92hd71xx_set_power_state(codec, AC_PWRST_D0); | |
1543 | + return stac92xx_resume(codec); | |
1544 | +} | |
1545 | + | |
1546 | +static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state) | |
1547 | +{ | |
1548 | + stac92hd71xx_set_power_state(codec, AC_PWRST_D3); | |
1549 | + return 0; | |
1550 | +}; | |
1551 | + | |
1552 | +#endif | |
1553 | + | |
1554 | +static struct hda_codec_ops stac92hd71bxx_patch_ops = { | |
1555 | + .build_controls = stac92xx_build_controls, | |
1556 | + .build_pcms = stac92xx_build_pcms, | |
1557 | + .init = stac92xx_init, | |
1558 | + .free = stac92xx_free, | |
1559 | + .unsol_event = stac92xx_unsol_event, | |
1560 | +#ifdef SND_HDA_NEEDS_RESUME | |
1561 | + .resume = stac92hd71xx_resume, | |
1562 | + .suspend = stac92hd71xx_suspend, | |
1563 | +#endif | |
1564 | +}; | |
1565 | + | |
1566 | +static struct hda_input_mux stac92hd71bxx_dmux = { | |
1567 | + .num_items = 4, | |
1568 | + .items = { | |
1569 | + { "Analog Inputs", 0x00 }, | |
1570 | + { "Mixer", 0x01 }, | |
1571 | + { "Digital Mic 1", 0x02 }, | |
1572 | + { "Digital Mic 2", 0x03 }, | |
1573 | + } | |
1574 | +}; | |
1575 | + | |
1576 | static int patch_stac92hd71bxx(struct hda_codec *codec) | |
1577 | { | |
1578 | struct sigmatel_spec *spec; | |
1579 | @@ -3667,9 +4359,12 @@ static int patch_stac92hd71bxx(struct hd | |
1580 | return -ENOMEM; | |
1581 | ||
1582 | codec->spec = spec; | |
1583 | + codec->patch_ops = stac92xx_patch_ops; | |
1584 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); | |
1585 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | |
1586 | spec->pin_nids = stac92hd71bxx_pin_nids; | |
1587 | + memcpy(&spec->private_dimux, &stac92hd71bxx_dmux, | |
1588 | + sizeof(stac92hd71bxx_dmux)); | |
1589 | spec->board_config = snd_hda_check_board_config(codec, | |
1590 | STAC_92HD71BXX_MODELS, | |
1591 | stac92hd71bxx_models, | |
1592 | @@ -3696,47 +4391,101 @@ again: | |
1593 | case 0x111d76b5: | |
1594 | spec->mixer = stac92hd71bxx_mixer; | |
1595 | spec->init = stac92hd71bxx_core_init; | |
1596 | + codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | |
1597 | break; | |
1598 | case 0x111d7608: /* 5 Port with Analog Mixer */ | |
1599 | + switch (codec->subsystem_id) { | |
1600 | + case 0x103c361a: | |
1601 | + /* Enable VREF power saving on GPIO1 detect */ | |
1602 | + snd_hda_codec_write(codec, codec->afg, 0, | |
1603 | + AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); | |
1604 | + snd_hda_codec_write_cache(codec, codec->afg, 0, | |
1605 | + AC_VERB_SET_UNSOLICITED_ENABLE, | |
1606 | + (AC_USRSP_EN | STAC_VREF_EVENT | 0x01)); | |
1607 | + spec->gpio_mask |= 0x02; | |
1608 | + break; | |
1609 | + } | |
1610 | + if ((codec->revision_id & 0xf) == 0 || | |
1611 | + (codec->revision_id & 0xf) == 1) { | |
1612 | +#ifdef SND_HDA_NEEDS_RESUME | |
1613 | + codec->patch_ops = stac92hd71bxx_patch_ops; | |
1614 | +#endif | |
1615 | + spec->stream_delay = 40; /* 40 milliseconds */ | |
1616 | + } | |
1617 | + | |
1618 | /* no output amps */ | |
1619 | spec->num_pwrs = 0; | |
1620 | spec->mixer = stac92hd71bxx_analog_mixer; | |
1621 | + spec->dinput_mux = &spec->private_dimux; | |
1622 | ||
1623 | /* disable VSW */ | |
1624 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | |
1625 | stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); | |
1626 | break; | |
1627 | case 0x111d7603: /* 6 Port with Analog Mixer */ | |
1628 | + if ((codec->revision_id & 0xf) == 1) { | |
1629 | +#ifdef SND_HDA_NEEDS_RESUME | |
1630 | + codec->patch_ops = stac92hd71bxx_patch_ops; | |
1631 | +#endif | |
1632 | + spec->stream_delay = 40; /* 40 milliseconds */ | |
1633 | + } | |
1634 | + | |
1635 | /* no output amps */ | |
1636 | spec->num_pwrs = 0; | |
1637 | /* fallthru */ | |
1638 | default: | |
1639 | + spec->dinput_mux = &spec->private_dimux; | |
1640 | spec->mixer = stac92hd71bxx_analog_mixer; | |
1641 | spec->init = stac92hd71bxx_analog_core_init; | |
1642 | + codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | |
1643 | } | |
1644 | ||
1645 | - spec->aloopback_mask = 0x20; | |
1646 | + spec->aloopback_mask = 0x50; | |
1647 | spec->aloopback_shift = 0; | |
1648 | ||
1649 | - /* GPIO0 High = EAPD */ | |
1650 | - spec->gpio_mask = 0x01; | |
1651 | - spec->gpio_dir = 0x01; | |
1652 | - spec->gpio_data = 0x01; | |
1653 | + if (spec->board_config > STAC_92HD71BXX_REF) { | |
1654 | + /* GPIO0 = EAPD */ | |
1655 | + spec->gpio_mask = 0x01; | |
1656 | + spec->gpio_dir = 0x01; | |
1657 | + spec->gpio_data = 0x01; | |
1658 | + } | |
1659 | ||
1660 | + spec->powerdown_adcs = 1; | |
1661 | + spec->digbeep_nid = 0x26; | |
1662 | spec->mux_nids = stac92hd71bxx_mux_nids; | |
1663 | spec->adc_nids = stac92hd71bxx_adc_nids; | |
1664 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | |
1665 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | |
1666 | + spec->smux_nids = stac92hd71bxx_smux_nids; | |
1667 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | |
1668 | ||
1669 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | |
1670 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | |
1671 | - spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | |
1672 | - spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | |
1673 | + | |
1674 | + switch (spec->board_config) { | |
1675 | + case STAC_HP_M4: | |
1676 | + spec->num_dmics = 0; | |
1677 | + spec->num_smuxes = 0; | |
1678 | + spec->num_dmuxes = 0; | |
1679 | + | |
1680 | + /* enable internal microphone */ | |
1681 | + stac92xx_set_config_reg(codec, 0x0e, 0x01813040); | |
1682 | + stac92xx_auto_set_pinctl(codec, 0x0e, | |
1683 | + AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); | |
1684 | + break; | |
1685 | + default: | |
1686 | + spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | |
1687 | + spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); | |
1688 | + spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | |
1689 | + }; | |
1690 | ||
1691 | spec->multiout.num_dacs = 1; | |
1692 | spec->multiout.hp_nid = 0x11; | |
1693 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; | |
1694 | + if (spec->dinput_mux) | |
1695 | + spec->private_dimux.num_items += | |
1696 | + spec->num_dmics - | |
1697 | + (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1); | |
1698 | ||
1699 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); | |
1700 | if (!err) { | |
1701 | @@ -3754,8 +4503,6 @@ again: | |
1702 | return err; | |
1703 | } | |
1704 | ||
1705 | - codec->patch_ops = stac92xx_patch_ops; | |
1706 | - | |
1707 | return 0; | |
1708 | }; | |
1709 | ||
1710 | @@ -3897,10 +4644,14 @@ static int patch_stac927x(struct hda_cod | |
1711 | stac92xx_set_config_regs(codec); | |
1712 | } | |
1713 | ||
1714 | + spec->digbeep_nid = 0x23; | |
1715 | spec->adc_nids = stac927x_adc_nids; | |
1716 | spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); | |
1717 | spec->mux_nids = stac927x_mux_nids; | |
1718 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); | |
1719 | + spec->smux_nids = stac927x_smux_nids; | |
1720 | + spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids); | |
1721 | + spec->spdif_labels = stac927x_spdif_labels; | |
1722 | spec->dac_list = stac927x_dac_nids; | |
1723 | spec->multiout.dac_nids = spec->dac_nids; | |
1724 | ||
1725 | @@ -3943,9 +4694,11 @@ static int patch_stac927x(struct hda_cod | |
1726 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); | |
1727 | break; | |
1728 | default: | |
1729 | - /* GPIO0 High = Enable EAPD */ | |
1730 | - spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | |
1731 | - spec->gpio_data = 0x01; | |
1732 | + if (spec->board_config > STAC_D965_REF) { | |
1733 | + /* GPIO0 High = Enable EAPD */ | |
1734 | + spec->eapd_mask = spec->gpio_mask = 0x01; | |
1735 | + spec->gpio_dir = spec->gpio_data = 0x01; | |
1736 | + } | |
1737 | spec->num_dmics = 0; | |
1738 | ||
1739 | spec->init = stac927x_core_init; | |
1740 | @@ -4017,10 +4770,13 @@ static int patch_stac9205(struct hda_cod | |
1741 | stac92xx_set_config_regs(codec); | |
1742 | } | |
1743 | ||
1744 | + spec->digbeep_nid = 0x23; | |
1745 | spec->adc_nids = stac9205_adc_nids; | |
1746 | spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); | |
1747 | spec->mux_nids = stac9205_mux_nids; | |
1748 | spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); | |
1749 | + spec->smux_nids = stac9205_smux_nids; | |
1750 | + spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids); | |
1751 | spec->dmic_nids = stac9205_dmic_nids; | |
1752 | spec->num_dmics = STAC9205_NUM_DMICS; | |
1753 | spec->dmux_nids = stac9205_dmux_nids; | |
1754 | @@ -4056,6 +4812,9 @@ static int patch_stac9205(struct hda_cod | |
1755 | */ | |
1756 | spec->gpio_data = 0x01; | |
1757 | break; | |
1758 | + case STAC_9205_REF: | |
1759 | + /* SPDIF-In enabled */ | |
1760 | + break; | |
1761 | default: | |
1762 | /* GPIO0 High = EAPD */ | |
1763 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | |
1764 | @@ -4375,6 +5134,8 @@ struct hda_codec_preset snd_hda_preset_s | |
1765 | { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, | |
1766 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, | |
1767 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, | |
1768 | + { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, | |
1769 | + { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, | |
1770 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, | |
1771 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | |
1772 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |