diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 1008 |
1 files changed, 902 insertions, 106 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ad994fcab725..c59065513118 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -33,10 +33,12 @@ | |||
33 | #include "hda_codec.h" | 33 | #include "hda_codec.h" |
34 | #include "hda_local.h" | 34 | #include "hda_local.h" |
35 | #include "hda_patch.h" | 35 | #include "hda_patch.h" |
36 | #include "hda_beep.h" | ||
36 | 37 | ||
37 | #define NUM_CONTROL_ALLOC 32 | 38 | #define NUM_CONTROL_ALLOC 32 |
38 | #define STAC_PWR_EVENT 0x20 | 39 | #define STAC_PWR_EVENT 0x20 |
39 | #define STAC_HP_EVENT 0x30 | 40 | #define STAC_HP_EVENT 0x30 |
41 | #define STAC_VREF_EVENT 0x40 | ||
40 | 42 | ||
41 | enum { | 43 | enum { |
42 | STAC_REF, | 44 | STAC_REF, |
@@ -71,9 +73,15 @@ enum { | |||
71 | }; | 73 | }; |
72 | 74 | ||
73 | enum { | 75 | enum { |
76 | STAC_92HD83XXX_REF, | ||
77 | STAC_92HD83XXX_MODELS | ||
78 | }; | ||
79 | |||
80 | enum { | ||
74 | STAC_92HD71BXX_REF, | 81 | STAC_92HD71BXX_REF, |
75 | STAC_DELL_M4_1, | 82 | STAC_DELL_M4_1, |
76 | STAC_DELL_M4_2, | 83 | STAC_DELL_M4_2, |
84 | STAC_HP_M4, | ||
77 | STAC_92HD71BXX_MODELS | 85 | STAC_92HD71BXX_MODELS |
78 | }; | 86 | }; |
79 | 87 | ||
@@ -104,6 +112,7 @@ enum { | |||
104 | STAC_MACBOOK_PRO_V2, | 112 | STAC_MACBOOK_PRO_V2, |
105 | STAC_IMAC_INTEL, | 113 | STAC_IMAC_INTEL, |
106 | STAC_IMAC_INTEL_20, | 114 | STAC_IMAC_INTEL_20, |
115 | STAC_ECS_202, | ||
107 | STAC_922X_DELL_D81, | 116 | STAC_922X_DELL_D81, |
108 | STAC_922X_DELL_D82, | 117 | STAC_922X_DELL_D82, |
109 | STAC_922X_DELL_M81, | 118 | STAC_922X_DELL_M81, |
@@ -130,6 +139,7 @@ struct sigmatel_spec { | |||
130 | unsigned int mic_switch: 1; | 139 | unsigned int mic_switch: 1; |
131 | unsigned int alt_switch: 1; | 140 | unsigned int alt_switch: 1; |
132 | unsigned int hp_detect: 1; | 141 | unsigned int hp_detect: 1; |
142 | unsigned int spdif_mute: 1; | ||
133 | 143 | ||
134 | /* gpio lines */ | 144 | /* gpio lines */ |
135 | unsigned int eapd_mask; | 145 | unsigned int eapd_mask; |
@@ -138,17 +148,22 @@ struct sigmatel_spec { | |||
138 | unsigned int gpio_data; | 148 | unsigned int gpio_data; |
139 | unsigned int gpio_mute; | 149 | unsigned int gpio_mute; |
140 | 150 | ||
151 | /* stream */ | ||
152 | unsigned int stream_delay; | ||
153 | |||
141 | /* analog loopback */ | 154 | /* analog loopback */ |
142 | unsigned char aloopback_mask; | 155 | unsigned char aloopback_mask; |
143 | unsigned char aloopback_shift; | 156 | unsigned char aloopback_shift; |
144 | 157 | ||
145 | /* power management */ | 158 | /* power management */ |
146 | unsigned int num_pwrs; | 159 | unsigned int num_pwrs; |
160 | unsigned int *pwr_mapping; | ||
147 | hda_nid_t *pwr_nids; | 161 | hda_nid_t *pwr_nids; |
148 | hda_nid_t *dac_list; | 162 | hda_nid_t *dac_list; |
149 | 163 | ||
150 | /* playback */ | 164 | /* playback */ |
151 | struct hda_input_mux *mono_mux; | 165 | struct hda_input_mux *mono_mux; |
166 | struct hda_input_mux *amp_mux; | ||
152 | unsigned int cur_mmux; | 167 | unsigned int cur_mmux; |
153 | struct hda_multi_out multiout; | 168 | struct hda_multi_out multiout; |
154 | hda_nid_t dac_nids[5]; | 169 | hda_nid_t dac_nids[5]; |
@@ -162,8 +177,14 @@ struct sigmatel_spec { | |||
162 | unsigned int num_dmics; | 177 | unsigned int num_dmics; |
163 | hda_nid_t *dmux_nids; | 178 | hda_nid_t *dmux_nids; |
164 | unsigned int num_dmuxes; | 179 | unsigned int num_dmuxes; |
180 | hda_nid_t *smux_nids; | ||
181 | unsigned int num_smuxes; | ||
182 | const char **spdif_labels; | ||
183 | |||
165 | hda_nid_t dig_in_nid; | 184 | hda_nid_t dig_in_nid; |
166 | hda_nid_t mono_nid; | 185 | hda_nid_t mono_nid; |
186 | hda_nid_t anabeep_nid; | ||
187 | hda_nid_t digbeep_nid; | ||
167 | 188 | ||
168 | /* pin widgets */ | 189 | /* pin widgets */ |
169 | hda_nid_t *pin_nids; | 190 | hda_nid_t *pin_nids; |
@@ -180,6 +201,12 @@ struct sigmatel_spec { | |||
180 | unsigned int cur_dmux[2]; | 201 | unsigned int cur_dmux[2]; |
181 | struct hda_input_mux *input_mux; | 202 | struct hda_input_mux *input_mux; |
182 | unsigned int cur_mux[3]; | 203 | unsigned int cur_mux[3]; |
204 | struct hda_input_mux *sinput_mux; | ||
205 | unsigned int cur_smux[2]; | ||
206 | unsigned int cur_amux; | ||
207 | hda_nid_t *amp_nids; | ||
208 | unsigned int num_amps; | ||
209 | unsigned int powerdown_adcs; | ||
183 | 210 | ||
184 | /* i/o switches */ | 211 | /* i/o switches */ |
185 | unsigned int io_switch[2]; | 212 | unsigned int io_switch[2]; |
@@ -195,6 +222,8 @@ struct sigmatel_spec { | |||
195 | struct snd_kcontrol_new *kctl_alloc; | 222 | struct snd_kcontrol_new *kctl_alloc; |
196 | struct hda_input_mux private_dimux; | 223 | struct hda_input_mux private_dimux; |
197 | struct hda_input_mux private_imux; | 224 | struct hda_input_mux private_imux; |
225 | struct hda_input_mux private_smux; | ||
226 | struct hda_input_mux private_amp_mux; | ||
198 | struct hda_input_mux private_mono_mux; | 227 | struct hda_input_mux private_mono_mux; |
199 | }; | 228 | }; |
200 | 229 | ||
@@ -215,10 +244,19 @@ static hda_nid_t stac92hd73xx_pwr_nids[8] = { | |||
215 | 0x0f, 0x10, 0x11 | 244 | 0x0f, 0x10, 0x11 |
216 | }; | 245 | }; |
217 | 246 | ||
247 | static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { | ||
248 | 0x26, 0, | ||
249 | }; | ||
250 | |||
218 | static hda_nid_t stac92hd73xx_adc_nids[2] = { | 251 | static hda_nid_t stac92hd73xx_adc_nids[2] = { |
219 | 0x1a, 0x1b | 252 | 0x1a, 0x1b |
220 | }; | 253 | }; |
221 | 254 | ||
255 | #define DELL_M6_AMP 2 | ||
256 | static hda_nid_t stac92hd73xx_amp_nids[3] = { | ||
257 | 0x0b, 0x0c, 0x0e | ||
258 | }; | ||
259 | |||
222 | #define STAC92HD73XX_NUM_DMICS 2 | 260 | #define STAC92HD73XX_NUM_DMICS 2 |
223 | static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { | 261 | static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { |
224 | 0x13, 0x14, 0 | 262 | 0x13, 0x14, 0 |
@@ -237,6 +275,41 @@ static hda_nid_t stac92hd73xx_dmux_nids[2] = { | |||
237 | 0x20, 0x21, | 275 | 0x20, 0x21, |
238 | }; | 276 | }; |
239 | 277 | ||
278 | static hda_nid_t stac92hd73xx_smux_nids[2] = { | ||
279 | 0x22, 0x23, | ||
280 | }; | ||
281 | |||
282 | #define STAC92HD83XXX_NUM_DMICS 2 | ||
283 | static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | ||
284 | 0x11, 0x12, 0 | ||
285 | }; | ||
286 | |||
287 | #define STAC92HD81_DAC_COUNT 2 | ||
288 | #define STAC92HD83_DAC_COUNT 3 | ||
289 | static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = { | ||
290 | 0x13, 0x14, 0x22, | ||
291 | }; | ||
292 | |||
293 | static hda_nid_t stac92hd83xxx_dmux_nids[2] = { | ||
294 | 0x17, 0x18, | ||
295 | }; | ||
296 | |||
297 | static hda_nid_t stac92hd83xxx_adc_nids[2] = { | ||
298 | 0x15, 0x16, | ||
299 | }; | ||
300 | |||
301 | static hda_nid_t stac92hd83xxx_pwr_nids[4] = { | ||
302 | 0xa, 0xb, 0xd, 0xe, | ||
303 | }; | ||
304 | |||
305 | static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { | ||
306 | 0x1e, 0, | ||
307 | }; | ||
308 | |||
309 | static unsigned int stac92hd83xxx_pwr_mapping[4] = { | ||
310 | 0x03, 0x0c, 0x10, 0x40, | ||
311 | }; | ||
312 | |||
240 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 313 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
241 | 0x0a, 0x0d, 0x0f | 314 | 0x0a, 0x0d, 0x0f |
242 | }; | 315 | }; |
@@ -249,8 +322,12 @@ static hda_nid_t stac92hd71bxx_mux_nids[2] = { | |||
249 | 0x1a, 0x1b | 322 | 0x1a, 0x1b |
250 | }; | 323 | }; |
251 | 324 | ||
252 | static hda_nid_t stac92hd71bxx_dmux_nids[1] = { | 325 | static hda_nid_t stac92hd71bxx_dmux_nids[2] = { |
253 | 0x1c, | 326 | 0x1c, 0x1d, |
327 | }; | ||
328 | |||
329 | static hda_nid_t stac92hd71bxx_smux_nids[2] = { | ||
330 | 0x24, 0x25, | ||
254 | }; | 331 | }; |
255 | 332 | ||
256 | static hda_nid_t stac92hd71bxx_dac_nids[1] = { | 333 | static hda_nid_t stac92hd71bxx_dac_nids[1] = { |
@@ -262,6 +339,10 @@ static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { | |||
262 | 0x18, 0x19, 0 | 339 | 0x18, 0x19, 0 |
263 | }; | 340 | }; |
264 | 341 | ||
342 | static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { | ||
343 | 0x22, 0 | ||
344 | }; | ||
345 | |||
265 | static hda_nid_t stac925x_adc_nids[1] = { | 346 | static hda_nid_t stac925x_adc_nids[1] = { |
266 | 0x03, | 347 | 0x03, |
267 | }; | 348 | }; |
@@ -299,6 +380,10 @@ static hda_nid_t stac927x_mux_nids[3] = { | |||
299 | 0x15, 0x16, 0x17 | 380 | 0x15, 0x16, 0x17 |
300 | }; | 381 | }; |
301 | 382 | ||
383 | static hda_nid_t stac927x_smux_nids[1] = { | ||
384 | 0x21, | ||
385 | }; | ||
386 | |||
302 | static hda_nid_t stac927x_dac_nids[6] = { | 387 | static hda_nid_t stac927x_dac_nids[6] = { |
303 | 0x02, 0x03, 0x04, 0x05, 0x06, 0 | 388 | 0x02, 0x03, 0x04, 0x05, 0x06, 0 |
304 | }; | 389 | }; |
@@ -312,6 +397,11 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { | |||
312 | 0x13, 0x14, 0 | 397 | 0x13, 0x14, 0 |
313 | }; | 398 | }; |
314 | 399 | ||
400 | static const char *stac927x_spdif_labels[5] = { | ||
401 | "Digital Playback", "ADAT", "Analog Mux 1", | ||
402 | "Analog Mux 2", "Analog Mux 3" | ||
403 | }; | ||
404 | |||
315 | static hda_nid_t stac9205_adc_nids[2] = { | 405 | static hda_nid_t stac9205_adc_nids[2] = { |
316 | 0x12, 0x13 | 406 | 0x12, 0x13 |
317 | }; | 407 | }; |
@@ -324,6 +414,10 @@ static hda_nid_t stac9205_dmux_nids[1] = { | |||
324 | 0x1d, | 414 | 0x1d, |
325 | }; | 415 | }; |
326 | 416 | ||
417 | static hda_nid_t stac9205_smux_nids[1] = { | ||
418 | 0x21, | ||
419 | }; | ||
420 | |||
327 | #define STAC9205_NUM_DMICS 2 | 421 | #define STAC9205_NUM_DMICS 2 |
328 | static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { | 422 | static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { |
329 | 0x17, 0x18, 0 | 423 | 0x17, 0x18, 0 |
@@ -347,12 +441,18 @@ static hda_nid_t stac922x_pin_nids[10] = { | |||
347 | static hda_nid_t stac92hd73xx_pin_nids[13] = { | 441 | static hda_nid_t stac92hd73xx_pin_nids[13] = { |
348 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 442 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
349 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 443 | 0x0f, 0x10, 0x11, 0x12, 0x13, |
350 | 0x14, 0x1e, 0x22 | 444 | 0x14, 0x22, 0x23 |
351 | }; | 445 | }; |
352 | 446 | ||
353 | static hda_nid_t stac92hd71bxx_pin_nids[10] = { | 447 | static hda_nid_t stac92hd83xxx_pin_nids[14] = { |
448 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | ||
449 | 0x0f, 0x10, 0x11, 0x12, 0x13, | ||
450 | 0x1d, 0x1e, 0x1f, 0x20 | ||
451 | }; | ||
452 | static hda_nid_t stac92hd71bxx_pin_nids[11] = { | ||
354 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 453 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
355 | 0x0f, 0x14, 0x18, 0x19, 0x1e, | 454 | 0x0f, 0x14, 0x18, 0x19, 0x1e, |
455 | 0x1f, | ||
356 | }; | 456 | }; |
357 | 457 | ||
358 | static hda_nid_t stac927x_pin_nids[14] = { | 458 | static hda_nid_t stac927x_pin_nids[14] = { |
@@ -367,6 +467,34 @@ static hda_nid_t stac9205_pin_nids[12] = { | |||
367 | 0x21, 0x22, | 467 | 0x21, 0x22, |
368 | }; | 468 | }; |
369 | 469 | ||
470 | #define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info | ||
471 | |||
472 | static int stac92xx_amp_volume_get(struct snd_kcontrol *kcontrol, | ||
473 | struct snd_ctl_elem_value *ucontrol) | ||
474 | { | ||
475 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
476 | struct sigmatel_spec *spec = codec->spec; | ||
477 | hda_nid_t nid = spec->amp_nids[spec->cur_amux]; | ||
478 | |||
479 | kcontrol->private_value ^= get_amp_nid(kcontrol); | ||
480 | kcontrol->private_value |= nid; | ||
481 | |||
482 | return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); | ||
483 | } | ||
484 | |||
485 | static int stac92xx_amp_volume_put(struct snd_kcontrol *kcontrol, | ||
486 | struct snd_ctl_elem_value *ucontrol) | ||
487 | { | ||
488 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
489 | struct sigmatel_spec *spec = codec->spec; | ||
490 | hda_nid_t nid = spec->amp_nids[spec->cur_amux]; | ||
491 | |||
492 | kcontrol->private_value ^= get_amp_nid(kcontrol); | ||
493 | kcontrol->private_value |= nid; | ||
494 | |||
495 | return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); | ||
496 | } | ||
497 | |||
370 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, | 498 | static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, |
371 | struct snd_ctl_elem_info *uinfo) | 499 | struct snd_ctl_elem_info *uinfo) |
372 | { | 500 | { |
@@ -397,6 +525,58 @@ static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol, | |||
397 | spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); | 525 | spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); |
398 | } | 526 | } |
399 | 527 | ||
528 | static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol, | ||
529 | struct snd_ctl_elem_info *uinfo) | ||
530 | { | ||
531 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
532 | struct sigmatel_spec *spec = codec->spec; | ||
533 | return snd_hda_input_mux_info(spec->sinput_mux, uinfo); | ||
534 | } | ||
535 | |||
536 | static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol, | ||
537 | struct snd_ctl_elem_value *ucontrol) | ||
538 | { | ||
539 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
540 | struct sigmatel_spec *spec = codec->spec; | ||
541 | unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
542 | |||
543 | ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; | ||
544 | return 0; | ||
545 | } | ||
546 | |||
547 | static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, | ||
548 | struct snd_ctl_elem_value *ucontrol) | ||
549 | { | ||
550 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
551 | struct sigmatel_spec *spec = codec->spec; | ||
552 | struct hda_input_mux *smux = &spec->private_smux; | ||
553 | unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
554 | int err, val; | ||
555 | hda_nid_t nid; | ||
556 | |||
557 | err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, | ||
558 | spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]); | ||
559 | if (err < 0) | ||
560 | return err; | ||
561 | |||
562 | if (spec->spdif_mute) { | ||
563 | if (smux_idx == 0) | ||
564 | nid = spec->multiout.dig_out_nid; | ||
565 | else | ||
566 | nid = codec->slave_dig_outs[smux_idx - 1]; | ||
567 | if (spec->cur_smux[smux_idx] == smux->num_items - 1) | ||
568 | val = AMP_OUT_MUTE; | ||
569 | if (smux_idx == 0) | ||
570 | nid = spec->multiout.dig_out_nid; | ||
571 | else | ||
572 | nid = codec->slave_dig_outs[smux_idx - 1]; | ||
573 | /* un/mute SPDIF out */ | ||
574 | snd_hda_codec_write_cache(codec, nid, 0, | ||
575 | AC_VERB_SET_AMP_GAIN_MUTE, val); | ||
576 | } | ||
577 | return 0; | ||
578 | } | ||
579 | |||
400 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 580 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
401 | { | 581 | { |
402 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 582 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
@@ -452,6 +632,41 @@ static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
452 | spec->mono_nid, &spec->cur_mmux); | 632 | spec->mono_nid, &spec->cur_mmux); |
453 | } | 633 | } |
454 | 634 | ||
635 | static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
636 | struct snd_ctl_elem_info *uinfo) | ||
637 | { | ||
638 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
639 | struct sigmatel_spec *spec = codec->spec; | ||
640 | return snd_hda_input_mux_info(spec->amp_mux, uinfo); | ||
641 | } | ||
642 | |||
643 | static int stac92xx_amp_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
644 | struct snd_ctl_elem_value *ucontrol) | ||
645 | { | ||
646 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
647 | struct sigmatel_spec *spec = codec->spec; | ||
648 | |||
649 | ucontrol->value.enumerated.item[0] = spec->cur_amux; | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static int stac92xx_amp_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
654 | struct snd_ctl_elem_value *ucontrol) | ||
655 | { | ||
656 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
657 | struct sigmatel_spec *spec = codec->spec; | ||
658 | struct snd_kcontrol *ctl = | ||
659 | snd_hda_find_mixer_ctl(codec, "Amp Capture Volume"); | ||
660 | if (!ctl) | ||
661 | return -EINVAL; | ||
662 | |||
663 | snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE | | ||
664 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
665 | |||
666 | return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol, | ||
667 | 0, &spec->cur_amux); | ||
668 | } | ||
669 | |||
455 | #define stac92xx_aloopback_info snd_ctl_boolean_mono_info | 670 | #define stac92xx_aloopback_info snd_ctl_boolean_mono_info |
456 | 671 | ||
457 | static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, | 672 | static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, |
@@ -546,8 +761,8 @@ static struct hda_verb dell_eq_core_init[] = { | |||
546 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, | 761 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, |
547 | /* setup audio connections */ | 762 | /* setup audio connections */ |
548 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | 763 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, |
549 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | 764 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02}, |
550 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, | 765 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01}, |
551 | /* setup adcs to point to mixer */ | 766 | /* setup adcs to point to mixer */ |
552 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 767 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
553 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 768 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
@@ -628,25 +843,36 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { | |||
628 | {} | 843 | {} |
629 | }; | 844 | }; |
630 | 845 | ||
846 | static struct hda_verb stac92hd83xxx_core_init[] = { | ||
847 | /* start of config #1 */ | ||
848 | { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3}, | ||
849 | |||
850 | /* start of config #2 */ | ||
851 | { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
852 | { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
853 | { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
854 | |||
855 | /* power state controls amps */ | ||
856 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, | ||
857 | }; | ||
858 | |||
631 | static struct hda_verb stac92hd71bxx_core_init[] = { | 859 | static struct hda_verb stac92hd71bxx_core_init[] = { |
632 | /* set master volume and direct control */ | 860 | /* set master volume and direct control */ |
633 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 861 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
634 | /* connect headphone jack to dac1 */ | 862 | /* connect headphone jack to dac1 */ |
635 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | 863 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, |
636 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ | ||
637 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ | 864 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ |
638 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 865 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
639 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 866 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
640 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 867 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
641 | }; | 868 | }; |
642 | 869 | ||
643 | #define HD_DISABLE_PORTF 3 | 870 | #define HD_DISABLE_PORTF 2 |
644 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | 871 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { |
645 | /* start of config #1 */ | 872 | /* start of config #1 */ |
646 | 873 | ||
647 | /* connect port 0f to audio mixer */ | 874 | /* connect port 0f to audio mixer */ |
648 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | 875 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, |
649 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Speaker */ | ||
650 | /* unmute right and left channels for node 0x0f */ | 876 | /* unmute right and left channels for node 0x0f */ |
651 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 877 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
652 | /* start of config #2 */ | 878 | /* start of config #2 */ |
@@ -655,10 +881,6 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = { | |||
655 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 881 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
656 | /* connect headphone jack to dac1 */ | 882 | /* connect headphone jack to dac1 */ |
657 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | 883 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, |
658 | /* connect port 0d to audio mixer */ | ||
659 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x2}, | ||
660 | /* unmute dac0 input in audio mixer */ | ||
661 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, | ||
662 | /* unmute right and left channels for nodes 0x0a, 0xd */ | 884 | /* unmute right and left channels for nodes 0x0a, 0xd */ |
663 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 885 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
664 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 886 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -690,12 +912,16 @@ static struct hda_verb d965_core_init[] = { | |||
690 | static struct hda_verb stac927x_core_init[] = { | 912 | static struct hda_verb stac927x_core_init[] = { |
691 | /* set master volume and direct control */ | 913 | /* set master volume and direct control */ |
692 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 914 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
915 | /* enable analog pc beep path */ | ||
916 | { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, | ||
693 | {} | 917 | {} |
694 | }; | 918 | }; |
695 | 919 | ||
696 | static struct hda_verb stac9205_core_init[] = { | 920 | static struct hda_verb stac9205_core_init[] = { |
697 | /* set master volume and direct control */ | 921 | /* set master volume and direct control */ |
698 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 922 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
923 | /* enable analog pc beep path */ | ||
924 | { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, | ||
699 | {} | 925 | {} |
700 | }; | 926 | }; |
701 | 927 | ||
@@ -709,6 +935,31 @@ static struct hda_verb stac9205_core_init[] = { | |||
709 | .put = stac92xx_mono_mux_enum_put, \ | 935 | .put = stac92xx_mono_mux_enum_put, \ |
710 | } | 936 | } |
711 | 937 | ||
938 | #define STAC_AMP_MUX \ | ||
939 | { \ | ||
940 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
941 | .name = "Amp Selector Capture Switch", \ | ||
942 | .count = 1, \ | ||
943 | .info = stac92xx_amp_mux_enum_info, \ | ||
944 | .get = stac92xx_amp_mux_enum_get, \ | ||
945 | .put = stac92xx_amp_mux_enum_put, \ | ||
946 | } | ||
947 | |||
948 | #define STAC_AMP_VOL(xname, nid, chs, idx, dir) \ | ||
949 | { \ | ||
950 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
951 | .name = xname, \ | ||
952 | .index = 0, \ | ||
953 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | ||
954 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | ||
955 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ | ||
956 | .info = stac92xx_amp_volume_info, \ | ||
957 | .get = stac92xx_amp_volume_get, \ | ||
958 | .put = stac92xx_amp_volume_put, \ | ||
959 | .tlv = { .c = snd_hda_mixer_amp_tlv }, \ | ||
960 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ | ||
961 | } | ||
962 | |||
712 | #define STAC_INPUT_SOURCE(cnt) \ | 963 | #define STAC_INPUT_SOURCE(cnt) \ |
713 | { \ | 964 | { \ |
714 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 965 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
@@ -736,33 +987,36 @@ static struct snd_kcontrol_new stac9200_mixer[] = { | |||
736 | STAC_INPUT_SOURCE(1), | 987 | STAC_INPUT_SOURCE(1), |
737 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 988 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
738 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 989 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
739 | HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT), | ||
740 | { } /* end */ | 990 | { } /* end */ |
741 | }; | 991 | }; |
742 | 992 | ||
993 | #define DELL_M6_MIXER 6 | ||
743 | static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | 994 | static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { |
744 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | 995 | /* start of config #1 */ |
745 | |||
746 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
747 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
748 | |||
749 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
750 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
751 | |||
752 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), | 996 | HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), |
753 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), | 997 | HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), |
754 | 998 | ||
755 | HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), | ||
756 | HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), | ||
757 | |||
758 | HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), | 999 | HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), |
759 | HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), | 1000 | HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), |
760 | 1001 | ||
1002 | HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), | ||
1003 | HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), | ||
1004 | |||
1005 | /* start of config #2 */ | ||
1006 | HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), | ||
1007 | HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), | ||
1008 | |||
761 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), | 1009 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), |
762 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), | 1010 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), |
763 | 1011 | ||
764 | HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), | 1012 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), |
765 | HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), | 1013 | |
1014 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1015 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | ||
1016 | |||
1017 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1018 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), | ||
1019 | |||
766 | { } /* end */ | 1020 | { } /* end */ |
767 | }; | 1021 | }; |
768 | 1022 | ||
@@ -818,22 +1072,59 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | |||
818 | { } /* end */ | 1072 | { } /* end */ |
819 | }; | 1073 | }; |
820 | 1074 | ||
1075 | |||
1076 | static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | ||
1077 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT), | ||
1078 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT), | ||
1079 | |||
1080 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), | ||
1081 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), | ||
1082 | |||
1083 | HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT), | ||
1084 | HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT), | ||
1085 | |||
1086 | HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT), | ||
1087 | HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT), | ||
1088 | |||
1089 | HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT), | ||
1090 | HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT), | ||
1091 | |||
1092 | HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT), | ||
1093 | HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT), | ||
1094 | |||
1095 | /* | ||
1096 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), | ||
1097 | HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), | ||
1098 | */ | ||
1099 | { } /* end */ | ||
1100 | }; | ||
1101 | |||
821 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 1102 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { |
822 | STAC_INPUT_SOURCE(2), | 1103 | STAC_INPUT_SOURCE(2), |
1104 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | ||
823 | 1105 | ||
824 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1106 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
825 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1107 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
826 | HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT), | ||
827 | 1108 | ||
828 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | 1109 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), |
829 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | 1110 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), |
830 | HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), | 1111 | /* analog pc-beep replaced with digital beep support */ |
831 | 1112 | /* | |
832 | HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), | 1113 | HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), |
833 | HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), | 1114 | HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), |
1115 | */ | ||
1116 | |||
1117 | HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), | ||
1118 | HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), | ||
1119 | |||
1120 | HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT), | ||
1121 | HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT), | ||
834 | 1122 | ||
835 | HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), | 1123 | HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT), |
836 | HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), | 1124 | HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT), |
1125 | |||
1126 | HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT), | ||
1127 | HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT), | ||
837 | { } /* end */ | 1128 | { } /* end */ |
838 | }; | 1129 | }; |
839 | 1130 | ||
@@ -843,11 +1134,9 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | |||
843 | 1134 | ||
844 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1135 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
845 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1136 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
846 | HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT), | ||
847 | 1137 | ||
848 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), | 1138 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), |
849 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), | 1139 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), |
850 | HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), | ||
851 | { } /* end */ | 1140 | { } /* end */ |
852 | }; | 1141 | }; |
853 | 1142 | ||
@@ -855,7 +1144,6 @@ static struct snd_kcontrol_new stac925x_mixer[] = { | |||
855 | STAC_INPUT_SOURCE(1), | 1144 | STAC_INPUT_SOURCE(1), |
856 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | 1145 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), |
857 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | 1146 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), |
858 | HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), | ||
859 | { } /* end */ | 1147 | { } /* end */ |
860 | }; | 1148 | }; |
861 | 1149 | ||
@@ -865,12 +1153,9 @@ static struct snd_kcontrol_new stac9205_mixer[] = { | |||
865 | 1153 | ||
866 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | 1154 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), |
867 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), | 1155 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), |
868 | HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT), | ||
869 | 1156 | ||
870 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), | 1157 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), |
871 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), | 1158 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), |
872 | HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT), | ||
873 | |||
874 | { } /* end */ | 1159 | { } /* end */ |
875 | }; | 1160 | }; |
876 | 1161 | ||
@@ -879,11 +1164,9 @@ static struct snd_kcontrol_new stac922x_mixer[] = { | |||
879 | STAC_INPUT_SOURCE(2), | 1164 | STAC_INPUT_SOURCE(2), |
880 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | 1165 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), |
881 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | 1166 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), |
882 | HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT), | ||
883 | 1167 | ||
884 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), | 1168 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), |
885 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), | 1169 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), |
886 | HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT), | ||
887 | { } /* end */ | 1170 | { } /* end */ |
888 | }; | 1171 | }; |
889 | 1172 | ||
@@ -894,15 +1177,12 @@ static struct snd_kcontrol_new stac927x_mixer[] = { | |||
894 | 1177 | ||
895 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | 1178 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), |
896 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), | 1179 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), |
897 | HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT), | ||
898 | 1180 | ||
899 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), | 1181 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), |
900 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), | 1182 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), |
901 | HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT), | ||
902 | 1183 | ||
903 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), | 1184 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), |
904 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), | 1185 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), |
905 | HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT), | ||
906 | { } /* end */ | 1186 | { } /* end */ |
907 | }; | 1187 | }; |
908 | 1188 | ||
@@ -915,6 +1195,15 @@ static struct snd_kcontrol_new stac_dmux_mixer = { | |||
915 | .put = stac92xx_dmux_enum_put, | 1195 | .put = stac92xx_dmux_enum_put, |
916 | }; | 1196 | }; |
917 | 1197 | ||
1198 | static struct snd_kcontrol_new stac_smux_mixer = { | ||
1199 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1200 | .name = "IEC958 Playback Source", | ||
1201 | /* count set later */ | ||
1202 | .info = stac92xx_smux_enum_info, | ||
1203 | .get = stac92xx_smux_enum_get, | ||
1204 | .put = stac92xx_smux_enum_put, | ||
1205 | }; | ||
1206 | |||
918 | static const char *slave_vols[] = { | 1207 | static const char *slave_vols[] = { |
919 | "Front Playback Volume", | 1208 | "Front Playback Volume", |
920 | "Surround Playback Volume", | 1209 | "Surround Playback Volume", |
@@ -966,6 +1255,22 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
966 | if (err < 0) | 1255 | if (err < 0) |
967 | return err; | 1256 | return err; |
968 | } | 1257 | } |
1258 | if (spec->num_smuxes > 0) { | ||
1259 | int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid); | ||
1260 | struct hda_input_mux *smux = &spec->private_smux; | ||
1261 | /* check for mute support on SPDIF out */ | ||
1262 | if (wcaps & AC_WCAP_OUT_AMP) { | ||
1263 | smux->items[smux->num_items].label = "Off"; | ||
1264 | smux->items[smux->num_items].index = 0; | ||
1265 | smux->num_items++; | ||
1266 | spec->spdif_mute = 1; | ||
1267 | } | ||
1268 | stac_smux_mixer.count = spec->num_smuxes; | ||
1269 | err = snd_ctl_add(codec->bus->card, | ||
1270 | snd_ctl_new1(&stac_smux_mixer, codec)); | ||
1271 | if (err < 0) | ||
1272 | return err; | ||
1273 | } | ||
969 | 1274 | ||
970 | if (spec->multiout.dig_out_nid) { | 1275 | if (spec->multiout.dig_out_nid) { |
971 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | 1276 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); |
@@ -977,7 +1282,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
977 | return err; | 1282 | return err; |
978 | spec->multiout.share_spdif = 1; | 1283 | spec->multiout.share_spdif = 1; |
979 | } | 1284 | } |
980 | if (spec->dig_in_nid) { | 1285 | if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) { |
981 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | 1286 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); |
982 | if (err < 0) | 1287 | if (err < 0) |
983 | return err; | 1288 | return err; |
@@ -1325,40 +1630,65 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1325 | {} /* terminator */ | 1630 | {} /* terminator */ |
1326 | }; | 1631 | }; |
1327 | 1632 | ||
1328 | static unsigned int ref92hd71bxx_pin_configs[10] = { | 1633 | static unsigned int ref92hd83xxx_pin_configs[14] = { |
1634 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, | ||
1635 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, | ||
1636 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, | ||
1637 | 0x01451160, 0x98560170, | ||
1638 | }; | ||
1639 | |||
1640 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | ||
1641 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | ||
1642 | }; | ||
1643 | |||
1644 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | ||
1645 | [STAC_92HD83XXX_REF] = "ref", | ||
1646 | }; | ||
1647 | |||
1648 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | ||
1649 | /* SigmaTel reference board */ | ||
1650 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | ||
1651 | "DFI LanParty", STAC_92HD71BXX_REF), | ||
1652 | }; | ||
1653 | |||
1654 | static unsigned int ref92hd71bxx_pin_configs[11] = { | ||
1329 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, | 1655 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, |
1330 | 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0, | 1656 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, |
1331 | 0x90a000f0, 0x01452050, | 1657 | 0x90a000f0, 0x01452050, 0x01452050, |
1332 | }; | 1658 | }; |
1333 | 1659 | ||
1334 | static unsigned int dell_m4_1_pin_configs[10] = { | 1660 | static unsigned int dell_m4_1_pin_configs[11] = { |
1335 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | 1661 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, |
1336 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | 1662 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, |
1337 | 0x40f000f0, 0x4f0000f0, | 1663 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, |
1338 | }; | 1664 | }; |
1339 | 1665 | ||
1340 | static unsigned int dell_m4_2_pin_configs[10] = { | 1666 | static unsigned int dell_m4_2_pin_configs[11] = { |
1341 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1667 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1342 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | 1668 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, |
1343 | 0x40f000f0, 0x044413b0, | 1669 | 0x40f000f0, 0x044413b0, 0x044413b0, |
1344 | }; | 1670 | }; |
1345 | 1671 | ||
1346 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | 1672 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { |
1347 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, | 1673 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, |
1348 | [STAC_DELL_M4_1] = dell_m4_1_pin_configs, | 1674 | [STAC_DELL_M4_1] = dell_m4_1_pin_configs, |
1349 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, | 1675 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, |
1676 | [STAC_HP_M4] = NULL, | ||
1350 | }; | 1677 | }; |
1351 | 1678 | ||
1352 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1679 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { |
1353 | [STAC_92HD71BXX_REF] = "ref", | 1680 | [STAC_92HD71BXX_REF] = "ref", |
1354 | [STAC_DELL_M4_1] = "dell-m4-1", | 1681 | [STAC_DELL_M4_1] = "dell-m4-1", |
1355 | [STAC_DELL_M4_2] = "dell-m4-2", | 1682 | [STAC_DELL_M4_2] = "dell-m4-2", |
1683 | [STAC_HP_M4] = "hp-m4", | ||
1356 | }; | 1684 | }; |
1357 | 1685 | ||
1358 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 1686 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { |
1359 | /* SigmaTel reference board */ | 1687 | /* SigmaTel reference board */ |
1360 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1688 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1361 | "DFI LanParty", STAC_92HD71BXX_REF), | 1689 | "DFI LanParty", STAC_92HD71BXX_REF), |
1690 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, | ||
1691 | "unknown HP", STAC_HP_M4), | ||
1362 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | 1692 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, |
1363 | "unknown Dell", STAC_DELL_M4_1), | 1693 | "unknown Dell", STAC_DELL_M4_1), |
1364 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | 1694 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, |
@@ -1477,6 +1807,11 @@ static unsigned int intel_mac_v5_pin_configs[10] = { | |||
1477 | 0x400000fc, 0x400000fb, | 1807 | 0x400000fc, 0x400000fb, |
1478 | }; | 1808 | }; |
1479 | 1809 | ||
1810 | static unsigned int ecs202_pin_configs[10] = { | ||
1811 | 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, | ||
1812 | 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, | ||
1813 | 0x9037012e, 0x40e000f2, | ||
1814 | }; | ||
1480 | 1815 | ||
1481 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | 1816 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { |
1482 | [STAC_D945_REF] = ref922x_pin_configs, | 1817 | [STAC_D945_REF] = ref922x_pin_configs, |
@@ -1495,6 +1830,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | |||
1495 | [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, | 1830 | [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, |
1496 | [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, | 1831 | [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, |
1497 | [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, | 1832 | [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, |
1833 | [STAC_ECS_202] = ecs202_pin_configs, | ||
1498 | [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, | 1834 | [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, |
1499 | [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, | 1835 | [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, |
1500 | [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, | 1836 | [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, |
@@ -1518,6 +1854,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = { | |||
1518 | [STAC_MACBOOK_PRO_V2] = "macbook-pro", | 1854 | [STAC_MACBOOK_PRO_V2] = "macbook-pro", |
1519 | [STAC_IMAC_INTEL] = "imac-intel", | 1855 | [STAC_IMAC_INTEL] = "imac-intel", |
1520 | [STAC_IMAC_INTEL_20] = "imac-intel-20", | 1856 | [STAC_IMAC_INTEL_20] = "imac-intel-20", |
1857 | [STAC_ECS_202] = "ecs202", | ||
1521 | [STAC_922X_DELL_D81] = "dell-d81", | 1858 | [STAC_922X_DELL_D81] = "dell-d81", |
1522 | [STAC_922X_DELL_D82] = "dell-d82", | 1859 | [STAC_922X_DELL_D82] = "dell-d82", |
1523 | [STAC_922X_DELL_M81] = "dell-m81", | 1860 | [STAC_922X_DELL_M81] = "dell-m81", |
@@ -1604,6 +1941,33 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
1604 | "unknown Dell", STAC_922X_DELL_D81), | 1941 | "unknown Dell", STAC_922X_DELL_D81), |
1605 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, | 1942 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, |
1606 | "Dell XPS M1210", STAC_922X_DELL_M82), | 1943 | "Dell XPS M1210", STAC_922X_DELL_M82), |
1944 | /* ECS/PC Chips boards */ | ||
1945 | SND_PCI_QUIRK(0x1019, 0x2144, | ||
1946 | "ECS/PC chips", STAC_ECS_202), | ||
1947 | SND_PCI_QUIRK(0x1019, 0x2608, | ||
1948 | "ECS/PC chips", STAC_ECS_202), | ||
1949 | SND_PCI_QUIRK(0x1019, 0x2633, | ||
1950 | "ECS/PC chips P17G/1333", STAC_ECS_202), | ||
1951 | SND_PCI_QUIRK(0x1019, 0x2811, | ||
1952 | "ECS/PC chips", STAC_ECS_202), | ||
1953 | SND_PCI_QUIRK(0x1019, 0x2812, | ||
1954 | "ECS/PC chips", STAC_ECS_202), | ||
1955 | SND_PCI_QUIRK(0x1019, 0x2813, | ||
1956 | "ECS/PC chips", STAC_ECS_202), | ||
1957 | SND_PCI_QUIRK(0x1019, 0x2814, | ||
1958 | "ECS/PC chips", STAC_ECS_202), | ||
1959 | SND_PCI_QUIRK(0x1019, 0x2815, | ||
1960 | "ECS/PC chips", STAC_ECS_202), | ||
1961 | SND_PCI_QUIRK(0x1019, 0x2816, | ||
1962 | "ECS/PC chips", STAC_ECS_202), | ||
1963 | SND_PCI_QUIRK(0x1019, 0x2817, | ||
1964 | "ECS/PC chips", STAC_ECS_202), | ||
1965 | SND_PCI_QUIRK(0x1019, 0x2818, | ||
1966 | "ECS/PC chips", STAC_ECS_202), | ||
1967 | SND_PCI_QUIRK(0x1019, 0x2819, | ||
1968 | "ECS/PC chips", STAC_ECS_202), | ||
1969 | SND_PCI_QUIRK(0x1019, 0x2820, | ||
1970 | "ECS/PC chips", STAC_ECS_202), | ||
1607 | {} /* terminator */ | 1971 | {} /* terminator */ |
1608 | }; | 1972 | }; |
1609 | 1973 | ||
@@ -1683,8 +2047,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
1683 | /* Dell 3 stack systems with verb table in BIOS */ | 2047 | /* Dell 3 stack systems with verb table in BIOS */ |
1684 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), | 2048 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), |
1685 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), | 2049 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), |
1686 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS), | ||
1687 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), | 2050 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), |
2051 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST), | ||
1688 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), | 2052 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), |
1689 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), | 2053 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), |
1690 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), | 2054 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), |
@@ -1867,6 +2231,8 @@ static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
1867 | struct snd_pcm_substream *substream) | 2231 | struct snd_pcm_substream *substream) |
1868 | { | 2232 | { |
1869 | struct sigmatel_spec *spec = codec->spec; | 2233 | struct sigmatel_spec *spec = codec->spec; |
2234 | if (spec->stream_delay) | ||
2235 | msleep(spec->stream_delay); | ||
1870 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | 2236 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, |
1871 | hinfo); | 2237 | hinfo); |
1872 | } | 2238 | } |
@@ -1930,9 +2296,14 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1930 | struct snd_pcm_substream *substream) | 2296 | struct snd_pcm_substream *substream) |
1931 | { | 2297 | { |
1932 | struct sigmatel_spec *spec = codec->spec; | 2298 | struct sigmatel_spec *spec = codec->spec; |
2299 | hda_nid_t nid = spec->adc_nids[substream->number]; | ||
1933 | 2300 | ||
1934 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], | 2301 | if (spec->powerdown_adcs) { |
1935 | stream_tag, 0, format); | 2302 | msleep(40); |
2303 | snd_hda_codec_write_cache(codec, nid, 0, | ||
2304 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
2305 | } | ||
2306 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | ||
1936 | return 0; | 2307 | return 0; |
1937 | } | 2308 | } |
1938 | 2309 | ||
@@ -1941,8 +2312,12 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1941 | struct snd_pcm_substream *substream) | 2312 | struct snd_pcm_substream *substream) |
1942 | { | 2313 | { |
1943 | struct sigmatel_spec *spec = codec->spec; | 2314 | struct sigmatel_spec *spec = codec->spec; |
2315 | hda_nid_t nid = spec->adc_nids[substream->number]; | ||
1944 | 2316 | ||
1945 | snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); | 2317 | snd_hda_codec_cleanup_stream(codec, nid); |
2318 | if (spec->powerdown_adcs) | ||
2319 | snd_hda_codec_write_cache(codec, nid, 0, | ||
2320 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
1946 | return 0; | 2321 | return 0; |
1947 | } | 2322 | } |
1948 | 2323 | ||
@@ -2193,6 +2568,8 @@ enum { | |||
2193 | STAC_CTL_WIDGET_VOL, | 2568 | STAC_CTL_WIDGET_VOL, |
2194 | STAC_CTL_WIDGET_MUTE, | 2569 | STAC_CTL_WIDGET_MUTE, |
2195 | STAC_CTL_WIDGET_MONO_MUX, | 2570 | STAC_CTL_WIDGET_MONO_MUX, |
2571 | STAC_CTL_WIDGET_AMP_MUX, | ||
2572 | STAC_CTL_WIDGET_AMP_VOL, | ||
2196 | STAC_CTL_WIDGET_HP_SWITCH, | 2573 | STAC_CTL_WIDGET_HP_SWITCH, |
2197 | STAC_CTL_WIDGET_IO_SWITCH, | 2574 | STAC_CTL_WIDGET_IO_SWITCH, |
2198 | STAC_CTL_WIDGET_CLFE_SWITCH | 2575 | STAC_CTL_WIDGET_CLFE_SWITCH |
@@ -2202,13 +2579,16 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2202 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 2579 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
2203 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 2580 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
2204 | STAC_MONO_MUX, | 2581 | STAC_MONO_MUX, |
2582 | STAC_AMP_MUX, | ||
2583 | STAC_AMP_VOL(NULL, 0, 0, 0, 0), | ||
2205 | STAC_CODEC_HP_SWITCH(NULL), | 2584 | STAC_CODEC_HP_SWITCH(NULL), |
2206 | STAC_CODEC_IO_SWITCH(NULL, 0), | 2585 | STAC_CODEC_IO_SWITCH(NULL, 0), |
2207 | STAC_CODEC_CLFE_SWITCH(NULL, 0), | 2586 | STAC_CODEC_CLFE_SWITCH(NULL, 0), |
2208 | }; | 2587 | }; |
2209 | 2588 | ||
2210 | /* add dynamic controls */ | 2589 | /* add dynamic controls */ |
2211 | static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val) | 2590 | static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, |
2591 | int idx, const char *name, unsigned long val) | ||
2212 | { | 2592 | { |
2213 | struct snd_kcontrol_new *knew; | 2593 | struct snd_kcontrol_new *knew; |
2214 | 2594 | ||
@@ -2228,6 +2608,7 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char | |||
2228 | 2608 | ||
2229 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | 2609 | knew = &spec->kctl_alloc[spec->num_kctl_used]; |
2230 | *knew = stac92xx_control_templates[type]; | 2610 | *knew = stac92xx_control_templates[type]; |
2611 | knew->index = idx; | ||
2231 | knew->name = kstrdup(name, GFP_KERNEL); | 2612 | knew->name = kstrdup(name, GFP_KERNEL); |
2232 | if (! knew->name) | 2613 | if (! knew->name) |
2233 | return -ENOMEM; | 2614 | return -ENOMEM; |
@@ -2236,6 +2617,14 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char | |||
2236 | return 0; | 2617 | return 0; |
2237 | } | 2618 | } |
2238 | 2619 | ||
2620 | |||
2621 | /* add dynamic controls */ | ||
2622 | static int stac92xx_add_control(struct sigmatel_spec *spec, int type, | ||
2623 | const char *name, unsigned long val) | ||
2624 | { | ||
2625 | return stac92xx_add_control_idx(spec, type, 0, name, val); | ||
2626 | } | ||
2627 | |||
2239 | /* flag inputs as additional dynamic lineouts */ | 2628 | /* flag inputs as additional dynamic lineouts */ |
2240 | static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) | 2629 | static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) |
2241 | { | 2630 | { |
@@ -2467,6 +2856,10 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2467 | } | 2856 | } |
2468 | } | 2857 | } |
2469 | 2858 | ||
2859 | if ((spec->multiout.num_dacs - cfg->line_outs) > 0 && | ||
2860 | cfg->hp_outs && !spec->multiout.hp_nid) | ||
2861 | spec->multiout.hp_nid = nid; | ||
2862 | |||
2470 | if (cfg->hp_outs > 1) { | 2863 | if (cfg->hp_outs > 1) { |
2471 | err = stac92xx_add_control(spec, | 2864 | err = stac92xx_add_control(spec, |
2472 | STAC_CTL_WIDGET_HP_SWITCH, | 2865 | STAC_CTL_WIDGET_HP_SWITCH, |
@@ -2579,8 +2972,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
2579 | } | 2972 | } |
2580 | 2973 | ||
2581 | /* labels for mono mux outputs */ | 2974 | /* labels for mono mux outputs */ |
2582 | static const char *stac92xx_mono_labels[3] = { | 2975 | static const char *stac92xx_mono_labels[4] = { |
2583 | "DAC0", "DAC1", "Mixer" | 2976 | "DAC0", "DAC1", "Mixer", "DAC2" |
2584 | }; | 2977 | }; |
2585 | 2978 | ||
2586 | /* create mono mux for mono out on capable codecs */ | 2979 | /* create mono mux for mono out on capable codecs */ |
@@ -2609,6 +3002,116 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) | |||
2609 | "Mono Mux", spec->mono_nid); | 3002 | "Mono Mux", spec->mono_nid); |
2610 | } | 3003 | } |
2611 | 3004 | ||
3005 | /* labels for amp mux outputs */ | ||
3006 | static const char *stac92xx_amp_labels[3] = { | ||
3007 | "Front Microphone", "Microphone", "Line In", | ||
3008 | }; | ||
3009 | |||
3010 | /* create amp out controls mux on capable codecs */ | ||
3011 | static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec) | ||
3012 | { | ||
3013 | struct sigmatel_spec *spec = codec->spec; | ||
3014 | struct hda_input_mux *amp_mux = &spec->private_amp_mux; | ||
3015 | int i, err; | ||
3016 | |||
3017 | for (i = 0; i < spec->num_amps; i++) { | ||
3018 | amp_mux->items[amp_mux->num_items].label = | ||
3019 | stac92xx_amp_labels[i]; | ||
3020 | amp_mux->items[amp_mux->num_items].index = i; | ||
3021 | amp_mux->num_items++; | ||
3022 | } | ||
3023 | |||
3024 | if (spec->num_amps > 1) { | ||
3025 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX, | ||
3026 | "Amp Selector Capture Switch", 0); | ||
3027 | if (err < 0) | ||
3028 | return err; | ||
3029 | } | ||
3030 | return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL, | ||
3031 | "Amp Capture Volume", | ||
3032 | HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT)); | ||
3033 | } | ||
3034 | |||
3035 | |||
3036 | /* create PC beep volume controls */ | ||
3037 | static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, | ||
3038 | hda_nid_t nid) | ||
3039 | { | ||
3040 | struct sigmatel_spec *spec = codec->spec; | ||
3041 | u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); | ||
3042 | int err; | ||
3043 | |||
3044 | /* check for mute support for the the amp */ | ||
3045 | if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { | ||
3046 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, | ||
3047 | "PC Beep Playback Switch", | ||
3048 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); | ||
3049 | if (err < 0) | ||
3050 | return err; | ||
3051 | } | ||
3052 | |||
3053 | /* check to see if there is volume support for the amp */ | ||
3054 | if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { | ||
3055 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, | ||
3056 | "PC Beep Playback Volume", | ||
3057 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); | ||
3058 | if (err < 0) | ||
3059 | return err; | ||
3060 | } | ||
3061 | return 0; | ||
3062 | } | ||
3063 | |||
3064 | static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) | ||
3065 | { | ||
3066 | struct sigmatel_spec *spec = codec->spec; | ||
3067 | int wcaps, nid, i, err = 0; | ||
3068 | |||
3069 | for (i = 0; i < spec->num_muxes; i++) { | ||
3070 | nid = spec->mux_nids[i]; | ||
3071 | wcaps = get_wcaps(codec, nid); | ||
3072 | |||
3073 | if (wcaps & AC_WCAP_OUT_AMP) { | ||
3074 | err = stac92xx_add_control_idx(spec, | ||
3075 | STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", | ||
3076 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
3077 | if (err < 0) | ||
3078 | return err; | ||
3079 | } | ||
3080 | } | ||
3081 | return 0; | ||
3082 | }; | ||
3083 | |||
3084 | static const char *stac92xx_spdif_labels[3] = { | ||
3085 | "Digital Playback", "Analog Mux 1", "Analog Mux 2", | ||
3086 | }; | ||
3087 | |||
3088 | static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) | ||
3089 | { | ||
3090 | struct sigmatel_spec *spec = codec->spec; | ||
3091 | struct hda_input_mux *spdif_mux = &spec->private_smux; | ||
3092 | const char **labels = spec->spdif_labels; | ||
3093 | int i, num_cons; | ||
3094 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | ||
3095 | |||
3096 | num_cons = snd_hda_get_connections(codec, | ||
3097 | spec->smux_nids[0], | ||
3098 | con_lst, | ||
3099 | HDA_MAX_NUM_INPUTS); | ||
3100 | if (!num_cons) | ||
3101 | return -EINVAL; | ||
3102 | |||
3103 | if (!labels) | ||
3104 | labels = stac92xx_spdif_labels; | ||
3105 | |||
3106 | for (i = 0; i < num_cons; i++) { | ||
3107 | spdif_mux->items[spdif_mux->num_items].label = labels[i]; | ||
3108 | spdif_mux->items[spdif_mux->num_items].index = i; | ||
3109 | spdif_mux->num_items++; | ||
3110 | } | ||
3111 | |||
3112 | return 0; | ||
3113 | } | ||
3114 | |||
2612 | /* labels for dmic mux inputs */ | 3115 | /* labels for dmic mux inputs */ |
2613 | static const char *stac92xx_dmic_labels[5] = { | 3116 | static const char *stac92xx_dmic_labels[5] = { |
2614 | "Analog Inputs", "Digital Mic 1", "Digital Mic 2", | 3117 | "Analog Inputs", "Digital Mic 1", "Digital Mic 2", |
@@ -2656,16 +3159,19 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
2656 | } | 3159 | } |
2657 | continue; | 3160 | continue; |
2658 | found: | 3161 | found: |
2659 | wcaps = get_wcaps(codec, nid); | 3162 | wcaps = get_wcaps(codec, nid) & |
3163 | (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); | ||
2660 | 3164 | ||
2661 | if (wcaps & AC_WCAP_OUT_AMP) { | 3165 | if (wcaps) { |
2662 | sprintf(name, "%s Capture Volume", | 3166 | sprintf(name, "%s Capture Volume", |
2663 | stac92xx_dmic_labels[dimux->num_items]); | 3167 | stac92xx_dmic_labels[dimux->num_items]); |
2664 | 3168 | ||
2665 | err = stac92xx_add_control(spec, | 3169 | err = stac92xx_add_control(spec, |
2666 | STAC_CTL_WIDGET_VOL, | 3170 | STAC_CTL_WIDGET_VOL, |
2667 | name, | 3171 | name, |
2668 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | 3172 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, |
3173 | (wcaps & AC_WCAP_OUT_AMP) ? | ||
3174 | HDA_OUTPUT : HDA_INPUT)); | ||
2669 | if (err < 0) | 3175 | if (err < 0) |
2670 | return err; | 3176 | return err; |
2671 | } | 3177 | } |
@@ -2789,8 +3295,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
2789 | hp_speaker_swap = 1; | 3295 | hp_speaker_swap = 1; |
2790 | } | 3296 | } |
2791 | if (spec->autocfg.mono_out_pin) { | 3297 | if (spec->autocfg.mono_out_pin) { |
2792 | int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin) | 3298 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & |
2793 | & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; | 3299 | (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); |
2794 | u32 caps = query_amp_caps(codec, | 3300 | u32 caps = query_amp_caps(codec, |
2795 | spec->autocfg.mono_out_pin, dir); | 3301 | spec->autocfg.mono_out_pin, dir); |
2796 | hda_nid_t conn_list[1]; | 3302 | hda_nid_t conn_list[1]; |
@@ -2812,21 +3318,26 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
2812 | !(wcaps & AC_WCAP_LR_SWAP)) | 3318 | !(wcaps & AC_WCAP_LR_SWAP)) |
2813 | spec->mono_nid = conn_list[0]; | 3319 | spec->mono_nid = conn_list[0]; |
2814 | } | 3320 | } |
2815 | /* all mono outs have a least a mute/unmute switch */ | 3321 | if (dir) { |
2816 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, | 3322 | hda_nid_t nid = spec->autocfg.mono_out_pin; |
2817 | "Mono Playback Switch", | 3323 | |
2818 | HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin, | 3324 | /* most mono outs have a least a mute/unmute switch */ |
2819 | 1, 0, dir)); | 3325 | dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; |
2820 | if (err < 0) | 3326 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, |
2821 | return err; | 3327 | "Mono Playback Switch", |
2822 | /* check to see if there is volume support for the amp */ | 3328 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); |
2823 | if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { | ||
2824 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, | ||
2825 | "Mono Playback Volume", | ||
2826 | HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin, | ||
2827 | 1, 0, dir)); | ||
2828 | if (err < 0) | 3329 | if (err < 0) |
2829 | return err; | 3330 | return err; |
3331 | /* check for volume support for the amp */ | ||
3332 | if ((caps & AC_AMPCAP_NUM_STEPS) | ||
3333 | >> AC_AMPCAP_NUM_STEPS_SHIFT) { | ||
3334 | err = stac92xx_add_control(spec, | ||
3335 | STAC_CTL_WIDGET_VOL, | ||
3336 | "Mono Playback Volume", | ||
3337 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); | ||
3338 | if (err < 0) | ||
3339 | return err; | ||
3340 | } | ||
2830 | } | 3341 | } |
2831 | 3342 | ||
2832 | stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin, | 3343 | stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin, |
@@ -2844,6 +3355,28 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
2844 | if (err < 0) | 3355 | if (err < 0) |
2845 | return err; | 3356 | return err; |
2846 | 3357 | ||
3358 | /* setup analog beep controls */ | ||
3359 | if (spec->anabeep_nid > 0) { | ||
3360 | err = stac92xx_auto_create_beep_ctls(codec, | ||
3361 | spec->anabeep_nid); | ||
3362 | if (err < 0) | ||
3363 | return err; | ||
3364 | } | ||
3365 | |||
3366 | /* setup digital beep controls and input device */ | ||
3367 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
3368 | if (spec->digbeep_nid > 0) { | ||
3369 | hda_nid_t nid = spec->digbeep_nid; | ||
3370 | |||
3371 | err = stac92xx_auto_create_beep_ctls(codec, nid); | ||
3372 | if (err < 0) | ||
3373 | return err; | ||
3374 | err = snd_hda_attach_beep_device(codec, nid); | ||
3375 | if (err < 0) | ||
3376 | return err; | ||
3377 | } | ||
3378 | #endif | ||
3379 | |||
2847 | if (hp_speaker_swap == 1) { | 3380 | if (hp_speaker_swap == 1) { |
2848 | /* Restore the hp_outs and line_outs */ | 3381 | /* Restore the hp_outs and line_outs */ |
2849 | memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, | 3382 | memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, |
@@ -2872,11 +3405,25 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
2872 | if (err < 0) | 3405 | if (err < 0) |
2873 | return err; | 3406 | return err; |
2874 | } | 3407 | } |
2875 | 3408 | if (spec->num_amps > 0) { | |
2876 | if (spec->num_dmics > 0) | 3409 | err = stac92xx_auto_create_amp_output_ctls(codec); |
3410 | if (err < 0) | ||
3411 | return err; | ||
3412 | } | ||
3413 | if (spec->num_dmics > 0 && !spec->dinput_mux) | ||
2877 | if ((err = stac92xx_auto_create_dmic_input_ctls(codec, | 3414 | if ((err = stac92xx_auto_create_dmic_input_ctls(codec, |
2878 | &spec->autocfg)) < 0) | 3415 | &spec->autocfg)) < 0) |
2879 | return err; | 3416 | return err; |
3417 | if (spec->num_muxes > 0) { | ||
3418 | err = stac92xx_auto_create_mux_input_ctls(codec); | ||
3419 | if (err < 0) | ||
3420 | return err; | ||
3421 | } | ||
3422 | if (spec->num_smuxes > 0) { | ||
3423 | err = stac92xx_auto_create_spdif_mux_ctls(codec); | ||
3424 | if (err < 0) | ||
3425 | return err; | ||
3426 | } | ||
2880 | 3427 | ||
2881 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3428 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
2882 | if (spec->multiout.max_channels > 2) | 3429 | if (spec->multiout.max_channels > 2) |
@@ -2884,17 +3431,17 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
2884 | 3431 | ||
2885 | if (spec->autocfg.dig_out_pin) | 3432 | if (spec->autocfg.dig_out_pin) |
2886 | spec->multiout.dig_out_nid = dig_out; | 3433 | spec->multiout.dig_out_nid = dig_out; |
2887 | if (spec->autocfg.dig_in_pin) | 3434 | if (dig_in && spec->autocfg.dig_in_pin) |
2888 | spec->dig_in_nid = dig_in; | 3435 | spec->dig_in_nid = dig_in; |
2889 | 3436 | ||
2890 | if (spec->kctl_alloc) | 3437 | if (spec->kctl_alloc) |
2891 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 3438 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; |
2892 | 3439 | ||
2893 | spec->input_mux = &spec->private_imux; | 3440 | spec->input_mux = &spec->private_imux; |
2894 | if (!spec->dinput_mux) | 3441 | spec->dinput_mux = &spec->private_dimux; |
2895 | spec->dinput_mux = &spec->private_dimux; | 3442 | spec->sinput_mux = &spec->private_smux; |
2896 | spec->mono_mux = &spec->private_mono_mux; | 3443 | spec->mono_mux = &spec->private_mono_mux; |
2897 | 3444 | spec->amp_mux = &spec->private_amp_mux; | |
2898 | return 1; | 3445 | return 1; |
2899 | } | 3446 | } |
2900 | 3447 | ||
@@ -3074,6 +3621,12 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3074 | 3621 | ||
3075 | snd_hda_sequence_write(codec, spec->init); | 3622 | snd_hda_sequence_write(codec, spec->init); |
3076 | 3623 | ||
3624 | /* power down adcs initially */ | ||
3625 | if (spec->powerdown_adcs) | ||
3626 | for (i = 0; i < spec->num_adcs; i++) | ||
3627 | snd_hda_codec_write_cache(codec, | ||
3628 | spec->adc_nids[i], 0, | ||
3629 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3077 | /* set up pins */ | 3630 | /* set up pins */ |
3078 | if (spec->hp_detect) { | 3631 | if (spec->hp_detect) { |
3079 | /* Enable unsolicited responses on the HP widget */ | 3632 | /* Enable unsolicited responses on the HP widget */ |
@@ -3095,7 +3648,12 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3095 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 3648 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
3096 | hda_nid_t nid = cfg->input_pins[i]; | 3649 | hda_nid_t nid = cfg->input_pins[i]; |
3097 | if (nid) { | 3650 | if (nid) { |
3098 | unsigned int pinctl = AC_PINCTL_IN_EN; | 3651 | unsigned int pinctl = snd_hda_codec_read(codec, nid, |
3652 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
3653 | /* if PINCTL already set then skip */ | ||
3654 | if (pinctl & AC_PINCAP_IN) | ||
3655 | continue; | ||
3656 | pinctl = AC_PINCTL_IN_EN; | ||
3099 | if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) | 3657 | if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) |
3100 | pinctl |= stac92xx_get_vref(codec, nid); | 3658 | pinctl |= stac92xx_get_vref(codec, nid); |
3101 | stac92xx_auto_set_pinctl(codec, nid, pinctl); | 3659 | stac92xx_auto_set_pinctl(codec, nid, pinctl); |
@@ -3158,6 +3716,7 @@ static void stac92xx_free(struct hda_codec *codec) | |||
3158 | kfree(spec->bios_pin_configs); | 3716 | kfree(spec->bios_pin_configs); |
3159 | 3717 | ||
3160 | kfree(spec); | 3718 | kfree(spec); |
3719 | snd_hda_detach_beep_device(codec); | ||
3161 | } | 3720 | } |
3162 | 3721 | ||
3163 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | 3722 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, |
@@ -3279,7 +3838,12 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx) | |||
3279 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) | 3838 | val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) |
3280 | & 0x000000ff; | 3839 | & 0x000000ff; |
3281 | presence = get_hp_pin_presence(codec, nid); | 3840 | presence = get_hp_pin_presence(codec, nid); |
3282 | idx = 1 << idx; | 3841 | |
3842 | /* several codecs have two power down bits */ | ||
3843 | if (spec->pwr_mapping) | ||
3844 | idx = spec->pwr_mapping[idx]; | ||
3845 | else | ||
3846 | idx = 1 << idx; | ||
3283 | 3847 | ||
3284 | if (presence) | 3848 | if (presence) |
3285 | val &= ~idx; | 3849 | val &= ~idx; |
@@ -3295,13 +3859,22 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
3295 | struct sigmatel_spec *spec = codec->spec; | 3859 | struct sigmatel_spec *spec = codec->spec; |
3296 | int idx = res >> 26 & 0x0f; | 3860 | int idx = res >> 26 & 0x0f; |
3297 | 3861 | ||
3298 | switch ((res >> 26) & 0x30) { | 3862 | switch ((res >> 26) & 0x70) { |
3299 | case STAC_HP_EVENT: | 3863 | case STAC_HP_EVENT: |
3300 | stac92xx_hp_detect(codec, res); | 3864 | stac92xx_hp_detect(codec, res); |
3301 | /* fallthru */ | 3865 | /* fallthru */ |
3302 | case STAC_PWR_EVENT: | 3866 | case STAC_PWR_EVENT: |
3303 | if (spec->num_pwrs > 0) | 3867 | if (spec->num_pwrs > 0) |
3304 | stac92xx_pin_sense(codec, idx); | 3868 | stac92xx_pin_sense(codec, idx); |
3869 | break; | ||
3870 | case STAC_VREF_EVENT: { | ||
3871 | int data = snd_hda_codec_read(codec, codec->afg, 0, | ||
3872 | AC_VERB_GET_GPIO_DATA, 0); | ||
3873 | /* toggle VREF state based on GPIOx status */ | ||
3874 | snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, | ||
3875 | !!(data & (1 << idx))); | ||
3876 | break; | ||
3877 | } | ||
3305 | } | 3878 | } |
3306 | } | 3879 | } |
3307 | 3880 | ||
@@ -3478,9 +4051,9 @@ static struct hda_input_mux stac92hd73xx_dmux = { | |||
3478 | .num_items = 4, | 4051 | .num_items = 4, |
3479 | .items = { | 4052 | .items = { |
3480 | { "Analog Inputs", 0x0b }, | 4053 | { "Analog Inputs", 0x0b }, |
3481 | { "CD", 0x08 }, | ||
3482 | { "Digital Mic 1", 0x09 }, | 4054 | { "Digital Mic 1", 0x09 }, |
3483 | { "Digital Mic 2", 0x0a }, | 4055 | { "Digital Mic 2", 0x0a }, |
4056 | { "CD", 0x08 }, | ||
3484 | } | 4057 | } |
3485 | }; | 4058 | }; |
3486 | 4059 | ||
@@ -3495,6 +4068,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
3495 | return -ENOMEM; | 4068 | return -ENOMEM; |
3496 | 4069 | ||
3497 | codec->spec = spec; | 4070 | codec->spec = spec; |
4071 | codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; | ||
3498 | spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); | 4072 | spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); |
3499 | spec->pin_nids = stac92hd73xx_pin_nids; | 4073 | spec->pin_nids = stac92hd73xx_pin_nids; |
3500 | spec->board_config = snd_hda_check_board_config(codec, | 4074 | spec->board_config = snd_hda_check_board_config(codec, |
@@ -3527,17 +4101,14 @@ again: | |||
3527 | 4101 | ||
3528 | switch (spec->multiout.num_dacs) { | 4102 | switch (spec->multiout.num_dacs) { |
3529 | case 0x3: /* 6 Channel */ | 4103 | case 0x3: /* 6 Channel */ |
3530 | spec->multiout.hp_nid = 0x17; | ||
3531 | spec->mixer = stac92hd73xx_6ch_mixer; | 4104 | spec->mixer = stac92hd73xx_6ch_mixer; |
3532 | spec->init = stac92hd73xx_6ch_core_init; | 4105 | spec->init = stac92hd73xx_6ch_core_init; |
3533 | break; | 4106 | break; |
3534 | case 0x4: /* 8 Channel */ | 4107 | case 0x4: /* 8 Channel */ |
3535 | spec->multiout.hp_nid = 0x18; | ||
3536 | spec->mixer = stac92hd73xx_8ch_mixer; | 4108 | spec->mixer = stac92hd73xx_8ch_mixer; |
3537 | spec->init = stac92hd73xx_8ch_core_init; | 4109 | spec->init = stac92hd73xx_8ch_core_init; |
3538 | break; | 4110 | break; |
3539 | case 0x5: /* 10 Channel */ | 4111 | case 0x5: /* 10 Channel */ |
3540 | spec->multiout.hp_nid = 0x19; | ||
3541 | spec->mixer = stac92hd73xx_10ch_mixer; | 4112 | spec->mixer = stac92hd73xx_10ch_mixer; |
3542 | spec->init = stac92hd73xx_10ch_core_init; | 4113 | spec->init = stac92hd73xx_10ch_core_init; |
3543 | }; | 4114 | }; |
@@ -3546,27 +4117,34 @@ again: | |||
3546 | spec->aloopback_mask = 0x01; | 4117 | spec->aloopback_mask = 0x01; |
3547 | spec->aloopback_shift = 8; | 4118 | spec->aloopback_shift = 8; |
3548 | 4119 | ||
4120 | spec->digbeep_nid = 0x1c; | ||
3549 | spec->mux_nids = stac92hd73xx_mux_nids; | 4121 | spec->mux_nids = stac92hd73xx_mux_nids; |
3550 | spec->adc_nids = stac92hd73xx_adc_nids; | 4122 | spec->adc_nids = stac92hd73xx_adc_nids; |
3551 | spec->dmic_nids = stac92hd73xx_dmic_nids; | 4123 | spec->dmic_nids = stac92hd73xx_dmic_nids; |
3552 | spec->dmux_nids = stac92hd73xx_dmux_nids; | 4124 | spec->dmux_nids = stac92hd73xx_dmux_nids; |
4125 | spec->smux_nids = stac92hd73xx_smux_nids; | ||
4126 | spec->amp_nids = stac92hd73xx_amp_nids; | ||
4127 | spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids); | ||
3553 | 4128 | ||
3554 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); | 4129 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); |
3555 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); | 4130 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); |
3556 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); | 4131 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); |
3557 | spec->dinput_mux = &stac92hd73xx_dmux; | 4132 | memcpy(&spec->private_dimux, &stac92hd73xx_dmux, |
3558 | /* GPIO0 High = Enable EAPD */ | 4133 | sizeof(stac92hd73xx_dmux)); |
3559 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | ||
3560 | spec->gpio_data = 0x01; | ||
3561 | 4134 | ||
3562 | switch (spec->board_config) { | 4135 | switch (spec->board_config) { |
3563 | case STAC_DELL_M6: | 4136 | case STAC_DELL_M6: |
3564 | spec->init = dell_eq_core_init; | 4137 | spec->init = dell_eq_core_init; |
4138 | spec->num_smuxes = 0; | ||
4139 | spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; | ||
4140 | spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; | ||
4141 | spec->num_amps = 1; | ||
3565 | switch (codec->subsystem_id) { | 4142 | switch (codec->subsystem_id) { |
3566 | case 0x1028025e: /* Analog Mics */ | 4143 | case 0x1028025e: /* Analog Mics */ |
3567 | case 0x1028025f: | 4144 | case 0x1028025f: |
3568 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4145 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); |
3569 | spec->num_dmics = 0; | 4146 | spec->num_dmics = 0; |
4147 | spec->private_dimux.num_items = 1; | ||
3570 | break; | 4148 | break; |
3571 | case 0x10280271: /* Digital Mics */ | 4149 | case 0x10280271: /* Digital Mics */ |
3572 | case 0x10280272: | 4150 | case 0x10280272: |
@@ -3576,23 +4154,32 @@ again: | |||
3576 | case 0x10280255: | 4154 | case 0x10280255: |
3577 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4155 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); |
3578 | spec->num_dmics = 1; | 4156 | spec->num_dmics = 1; |
4157 | spec->private_dimux.num_items = 2; | ||
3579 | break; | 4158 | break; |
3580 | case 0x10280256: /* Both */ | 4159 | case 0x10280256: /* Both */ |
3581 | case 0x10280057: | 4160 | case 0x10280057: |
3582 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4161 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); |
3583 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4162 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); |
3584 | spec->num_dmics = 1; | 4163 | spec->num_dmics = 1; |
4164 | spec->private_dimux.num_items = 2; | ||
3585 | break; | 4165 | break; |
3586 | } | 4166 | } |
3587 | break; | 4167 | break; |
3588 | default: | 4168 | default: |
3589 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; | 4169 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; |
4170 | spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); | ||
3590 | } | 4171 | } |
4172 | if (spec->board_config > STAC_92HD73XX_REF) { | ||
4173 | /* GPIO0 High = Enable EAPD */ | ||
4174 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | ||
4175 | spec->gpio_data = 0x01; | ||
4176 | } | ||
4177 | spec->dinput_mux = &spec->private_dimux; | ||
3591 | 4178 | ||
3592 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); | 4179 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); |
3593 | spec->pwr_nids = stac92hd73xx_pwr_nids; | 4180 | spec->pwr_nids = stac92hd73xx_pwr_nids; |
3594 | 4181 | ||
3595 | err = stac92xx_parse_auto_config(codec, 0x22, 0x24); | 4182 | err = stac92xx_parse_auto_config(codec, 0x25, 0x27); |
3596 | 4183 | ||
3597 | if (!err) { | 4184 | if (!err) { |
3598 | if (spec->board_config < 0) { | 4185 | if (spec->board_config < 0) { |
@@ -3614,6 +4201,146 @@ again: | |||
3614 | return 0; | 4201 | return 0; |
3615 | } | 4202 | } |
3616 | 4203 | ||
4204 | static struct hda_input_mux stac92hd83xxx_dmux = { | ||
4205 | .num_items = 3, | ||
4206 | .items = { | ||
4207 | { "Analog Inputs", 0x03 }, | ||
4208 | { "Digital Mic 1", 0x04 }, | ||
4209 | { "Digital Mic 2", 0x05 }, | ||
4210 | } | ||
4211 | }; | ||
4212 | |||
4213 | static int patch_stac92hd83xxx(struct hda_codec *codec) | ||
4214 | { | ||
4215 | struct sigmatel_spec *spec; | ||
4216 | int err; | ||
4217 | |||
4218 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
4219 | if (spec == NULL) | ||
4220 | return -ENOMEM; | ||
4221 | |||
4222 | codec->spec = spec; | ||
4223 | codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; | ||
4224 | spec->mono_nid = 0x19; | ||
4225 | spec->digbeep_nid = 0x21; | ||
4226 | spec->dmic_nids = stac92hd83xxx_dmic_nids; | ||
4227 | spec->dmux_nids = stac92hd83xxx_dmux_nids; | ||
4228 | spec->adc_nids = stac92hd83xxx_adc_nids; | ||
4229 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | ||
4230 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | ||
4231 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | ||
4232 | spec->multiout.dac_nids = stac92hd83xxx_dac_nids; | ||
4233 | |||
4234 | spec->init = stac92hd83xxx_core_init; | ||
4235 | switch (codec->vendor_id) { | ||
4236 | case 0x111d7605: | ||
4237 | spec->multiout.num_dacs = STAC92HD81_DAC_COUNT; | ||
4238 | break; | ||
4239 | default: | ||
4240 | spec->num_pwrs--; | ||
4241 | spec->init++; /* switch to config #2 */ | ||
4242 | spec->multiout.num_dacs = STAC92HD83_DAC_COUNT; | ||
4243 | } | ||
4244 | |||
4245 | spec->mixer = stac92hd83xxx_mixer; | ||
4246 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | ||
4247 | spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); | ||
4248 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | ||
4249 | spec->num_dmics = STAC92HD83XXX_NUM_DMICS; | ||
4250 | spec->dinput_mux = &stac92hd83xxx_dmux; | ||
4251 | spec->pin_nids = stac92hd83xxx_pin_nids; | ||
4252 | spec->board_config = snd_hda_check_board_config(codec, | ||
4253 | STAC_92HD83XXX_MODELS, | ||
4254 | stac92hd83xxx_models, | ||
4255 | stac92hd83xxx_cfg_tbl); | ||
4256 | again: | ||
4257 | if (spec->board_config < 0) { | ||
4258 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | ||
4259 | " STAC92HD83XXX, using BIOS defaults\n"); | ||
4260 | err = stac92xx_save_bios_config_regs(codec); | ||
4261 | if (err < 0) { | ||
4262 | stac92xx_free(codec); | ||
4263 | return err; | ||
4264 | } | ||
4265 | spec->pin_configs = spec->bios_pin_configs; | ||
4266 | } else { | ||
4267 | spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config]; | ||
4268 | stac92xx_set_config_regs(codec); | ||
4269 | } | ||
4270 | |||
4271 | err = stac92xx_parse_auto_config(codec, 0x1d, 0); | ||
4272 | if (!err) { | ||
4273 | if (spec->board_config < 0) { | ||
4274 | printk(KERN_WARNING "hda_codec: No auto-config is " | ||
4275 | "available, default to model=ref\n"); | ||
4276 | spec->board_config = STAC_92HD83XXX_REF; | ||
4277 | goto again; | ||
4278 | } | ||
4279 | err = -EINVAL; | ||
4280 | } | ||
4281 | |||
4282 | if (err < 0) { | ||
4283 | stac92xx_free(codec); | ||
4284 | return err; | ||
4285 | } | ||
4286 | |||
4287 | codec->patch_ops = stac92xx_patch_ops; | ||
4288 | |||
4289 | return 0; | ||
4290 | } | ||
4291 | |||
4292 | #ifdef SND_HDA_NEEDS_RESUME | ||
4293 | static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr) | ||
4294 | { | ||
4295 | struct sigmatel_spec *spec = codec->spec; | ||
4296 | int i; | ||
4297 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
4298 | AC_VERB_SET_POWER_STATE, pwr); | ||
4299 | |||
4300 | msleep(1); | ||
4301 | for (i = 0; i < spec->num_adcs; i++) { | ||
4302 | snd_hda_codec_write_cache(codec, | ||
4303 | spec->adc_nids[i], 0, | ||
4304 | AC_VERB_SET_POWER_STATE, pwr); | ||
4305 | } | ||
4306 | }; | ||
4307 | |||
4308 | static int stac92hd71xx_resume(struct hda_codec *codec) | ||
4309 | { | ||
4310 | stac92hd71xx_set_power_state(codec, AC_PWRST_D0); | ||
4311 | return stac92xx_resume(codec); | ||
4312 | } | ||
4313 | |||
4314 | static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state) | ||
4315 | { | ||
4316 | stac92hd71xx_set_power_state(codec, AC_PWRST_D3); | ||
4317 | return 0; | ||
4318 | }; | ||
4319 | |||
4320 | #endif | ||
4321 | |||
4322 | static struct hda_codec_ops stac92hd71bxx_patch_ops = { | ||
4323 | .build_controls = stac92xx_build_controls, | ||
4324 | .build_pcms = stac92xx_build_pcms, | ||
4325 | .init = stac92xx_init, | ||
4326 | .free = stac92xx_free, | ||
4327 | .unsol_event = stac92xx_unsol_event, | ||
4328 | #ifdef SND_HDA_NEEDS_RESUME | ||
4329 | .resume = stac92hd71xx_resume, | ||
4330 | .suspend = stac92hd71xx_suspend, | ||
4331 | #endif | ||
4332 | }; | ||
4333 | |||
4334 | static struct hda_input_mux stac92hd71bxx_dmux = { | ||
4335 | .num_items = 4, | ||
4336 | .items = { | ||
4337 | { "Analog Inputs", 0x00 }, | ||
4338 | { "Mixer", 0x01 }, | ||
4339 | { "Digital Mic 1", 0x02 }, | ||
4340 | { "Digital Mic 2", 0x03 }, | ||
4341 | } | ||
4342 | }; | ||
4343 | |||
3617 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 4344 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
3618 | { | 4345 | { |
3619 | struct sigmatel_spec *spec; | 4346 | struct sigmatel_spec *spec; |
@@ -3624,9 +4351,12 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
3624 | return -ENOMEM; | 4351 | return -ENOMEM; |
3625 | 4352 | ||
3626 | codec->spec = spec; | 4353 | codec->spec = spec; |
4354 | codec->patch_ops = stac92xx_patch_ops; | ||
3627 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); | 4355 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); |
3628 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | 4356 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
3629 | spec->pin_nids = stac92hd71bxx_pin_nids; | 4357 | spec->pin_nids = stac92hd71bxx_pin_nids; |
4358 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux, | ||
4359 | sizeof(stac92hd71bxx_dmux)); | ||
3630 | spec->board_config = snd_hda_check_board_config(codec, | 4360 | spec->board_config = snd_hda_check_board_config(codec, |
3631 | STAC_92HD71BXX_MODELS, | 4361 | STAC_92HD71BXX_MODELS, |
3632 | stac92hd71bxx_models, | 4362 | stac92hd71bxx_models, |
@@ -3653,47 +4383,101 @@ again: | |||
3653 | case 0x111d76b5: | 4383 | case 0x111d76b5: |
3654 | spec->mixer = stac92hd71bxx_mixer; | 4384 | spec->mixer = stac92hd71bxx_mixer; |
3655 | spec->init = stac92hd71bxx_core_init; | 4385 | spec->init = stac92hd71bxx_core_init; |
4386 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | ||
3656 | break; | 4387 | break; |
3657 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 4388 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
4389 | switch (codec->subsystem_id) { | ||
4390 | case 0x103c361a: | ||
4391 | /* Enable VREF power saving on GPIO1 detect */ | ||
4392 | snd_hda_codec_write(codec, codec->afg, 0, | ||
4393 | AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); | ||
4394 | snd_hda_codec_write_cache(codec, codec->afg, 0, | ||
4395 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
4396 | (AC_USRSP_EN | STAC_VREF_EVENT | 0x01)); | ||
4397 | spec->gpio_mask |= 0x02; | ||
4398 | break; | ||
4399 | } | ||
4400 | if ((codec->revision_id & 0xf) == 0 || | ||
4401 | (codec->revision_id & 0xf) == 1) { | ||
4402 | #ifdef SND_HDA_NEEDS_RESUME | ||
4403 | codec->patch_ops = stac92hd71bxx_patch_ops; | ||
4404 | #endif | ||
4405 | spec->stream_delay = 40; /* 40 milliseconds */ | ||
4406 | } | ||
4407 | |||
3658 | /* no output amps */ | 4408 | /* no output amps */ |
3659 | spec->num_pwrs = 0; | 4409 | spec->num_pwrs = 0; |
3660 | spec->mixer = stac92hd71bxx_analog_mixer; | 4410 | spec->mixer = stac92hd71bxx_analog_mixer; |
4411 | spec->dinput_mux = &spec->private_dimux; | ||
3661 | 4412 | ||
3662 | /* disable VSW */ | 4413 | /* disable VSW */ |
3663 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | 4414 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; |
3664 | stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); | 4415 | stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); |
3665 | break; | 4416 | break; |
3666 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 4417 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
4418 | if ((codec->revision_id & 0xf) == 1) { | ||
4419 | #ifdef SND_HDA_NEEDS_RESUME | ||
4420 | codec->patch_ops = stac92hd71bxx_patch_ops; | ||
4421 | #endif | ||
4422 | spec->stream_delay = 40; /* 40 milliseconds */ | ||
4423 | } | ||
4424 | |||
3667 | /* no output amps */ | 4425 | /* no output amps */ |
3668 | spec->num_pwrs = 0; | 4426 | spec->num_pwrs = 0; |
3669 | /* fallthru */ | 4427 | /* fallthru */ |
3670 | default: | 4428 | default: |
4429 | spec->dinput_mux = &spec->private_dimux; | ||
3671 | spec->mixer = stac92hd71bxx_analog_mixer; | 4430 | spec->mixer = stac92hd71bxx_analog_mixer; |
3672 | spec->init = stac92hd71bxx_analog_core_init; | 4431 | spec->init = stac92hd71bxx_analog_core_init; |
4432 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | ||
3673 | } | 4433 | } |
3674 | 4434 | ||
3675 | spec->aloopback_mask = 0x20; | 4435 | spec->aloopback_mask = 0x50; |
3676 | spec->aloopback_shift = 0; | 4436 | spec->aloopback_shift = 0; |
3677 | 4437 | ||
3678 | /* GPIO0 High = EAPD */ | 4438 | if (spec->board_config > STAC_92HD71BXX_REF) { |
3679 | spec->gpio_mask = 0x01; | 4439 | /* GPIO0 = EAPD */ |
3680 | spec->gpio_dir = 0x01; | 4440 | spec->gpio_mask = 0x01; |
3681 | spec->gpio_data = 0x01; | 4441 | spec->gpio_dir = 0x01; |
4442 | spec->gpio_data = 0x01; | ||
4443 | } | ||
3682 | 4444 | ||
4445 | spec->powerdown_adcs = 1; | ||
4446 | spec->digbeep_nid = 0x26; | ||
3683 | spec->mux_nids = stac92hd71bxx_mux_nids; | 4447 | spec->mux_nids = stac92hd71bxx_mux_nids; |
3684 | spec->adc_nids = stac92hd71bxx_adc_nids; | 4448 | spec->adc_nids = stac92hd71bxx_adc_nids; |
3685 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | 4449 | spec->dmic_nids = stac92hd71bxx_dmic_nids; |
3686 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | 4450 | spec->dmux_nids = stac92hd71bxx_dmux_nids; |
4451 | spec->smux_nids = stac92hd71bxx_smux_nids; | ||
3687 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 4452 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
3688 | 4453 | ||
3689 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 4454 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); |
3690 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 4455 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); |
3691 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | 4456 | |
3692 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 4457 | switch (spec->board_config) { |
4458 | case STAC_HP_M4: | ||
4459 | spec->num_dmics = 0; | ||
4460 | spec->num_smuxes = 0; | ||
4461 | spec->num_dmuxes = 0; | ||
4462 | |||
4463 | /* enable internal microphone */ | ||
4464 | stac92xx_set_config_reg(codec, 0x0e, 0x01813040); | ||
4465 | stac92xx_auto_set_pinctl(codec, 0x0e, | ||
4466 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); | ||
4467 | break; | ||
4468 | default: | ||
4469 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | ||
4470 | spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); | ||
4471 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
4472 | }; | ||
3693 | 4473 | ||
3694 | spec->multiout.num_dacs = 1; | 4474 | spec->multiout.num_dacs = 1; |
3695 | spec->multiout.hp_nid = 0x11; | 4475 | spec->multiout.hp_nid = 0x11; |
3696 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; | 4476 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; |
4477 | if (spec->dinput_mux) | ||
4478 | spec->private_dimux.num_items += | ||
4479 | spec->num_dmics - | ||
4480 | (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1); | ||
3697 | 4481 | ||
3698 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); | 4482 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); |
3699 | if (!err) { | 4483 | if (!err) { |
@@ -3711,8 +4495,6 @@ again: | |||
3711 | return err; | 4495 | return err; |
3712 | } | 4496 | } |
3713 | 4497 | ||
3714 | codec->patch_ops = stac92xx_patch_ops; | ||
3715 | |||
3716 | return 0; | 4498 | return 0; |
3717 | }; | 4499 | }; |
3718 | 4500 | ||
@@ -3854,10 +4636,14 @@ static int patch_stac927x(struct hda_codec *codec) | |||
3854 | stac92xx_set_config_regs(codec); | 4636 | stac92xx_set_config_regs(codec); |
3855 | } | 4637 | } |
3856 | 4638 | ||
4639 | spec->digbeep_nid = 0x23; | ||
3857 | spec->adc_nids = stac927x_adc_nids; | 4640 | spec->adc_nids = stac927x_adc_nids; |
3858 | spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); | 4641 | spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); |
3859 | spec->mux_nids = stac927x_mux_nids; | 4642 | spec->mux_nids = stac927x_mux_nids; |
3860 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); | 4643 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); |
4644 | spec->smux_nids = stac927x_smux_nids; | ||
4645 | spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids); | ||
4646 | spec->spdif_labels = stac927x_spdif_labels; | ||
3861 | spec->dac_list = stac927x_dac_nids; | 4647 | spec->dac_list = stac927x_dac_nids; |
3862 | spec->multiout.dac_nids = spec->dac_nids; | 4648 | spec->multiout.dac_nids = spec->dac_nids; |
3863 | 4649 | ||
@@ -3900,9 +4686,11 @@ static int patch_stac927x(struct hda_codec *codec) | |||
3900 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); | 4686 | spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); |
3901 | break; | 4687 | break; |
3902 | default: | 4688 | default: |
3903 | /* GPIO0 High = Enable EAPD */ | 4689 | if (spec->board_config > STAC_D965_REF) { |
3904 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | 4690 | /* GPIO0 High = Enable EAPD */ |
3905 | spec->gpio_data = 0x01; | 4691 | spec->eapd_mask = spec->gpio_mask = 0x01; |
4692 | spec->gpio_dir = spec->gpio_data = 0x01; | ||
4693 | } | ||
3906 | spec->num_dmics = 0; | 4694 | spec->num_dmics = 0; |
3907 | 4695 | ||
3908 | spec->init = stac927x_core_init; | 4696 | spec->init = stac927x_core_init; |
@@ -3974,10 +4762,13 @@ static int patch_stac9205(struct hda_codec *codec) | |||
3974 | stac92xx_set_config_regs(codec); | 4762 | stac92xx_set_config_regs(codec); |
3975 | } | 4763 | } |
3976 | 4764 | ||
4765 | spec->digbeep_nid = 0x23; | ||
3977 | spec->adc_nids = stac9205_adc_nids; | 4766 | spec->adc_nids = stac9205_adc_nids; |
3978 | spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); | 4767 | spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); |
3979 | spec->mux_nids = stac9205_mux_nids; | 4768 | spec->mux_nids = stac9205_mux_nids; |
3980 | spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); | 4769 | spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); |
4770 | spec->smux_nids = stac9205_smux_nids; | ||
4771 | spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids); | ||
3981 | spec->dmic_nids = stac9205_dmic_nids; | 4772 | spec->dmic_nids = stac9205_dmic_nids; |
3982 | spec->num_dmics = STAC9205_NUM_DMICS; | 4773 | spec->num_dmics = STAC9205_NUM_DMICS; |
3983 | spec->dmux_nids = stac9205_dmux_nids; | 4774 | spec->dmux_nids = stac9205_dmux_nids; |
@@ -4013,6 +4804,9 @@ static int patch_stac9205(struct hda_codec *codec) | |||
4013 | */ | 4804 | */ |
4014 | spec->gpio_data = 0x01; | 4805 | spec->gpio_data = 0x01; |
4015 | break; | 4806 | break; |
4807 | case STAC_9205_REF: | ||
4808 | /* SPDIF-In enabled */ | ||
4809 | break; | ||
4016 | default: | 4810 | default: |
4017 | /* GPIO0 High = EAPD */ | 4811 | /* GPIO0 High = EAPD */ |
4018 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; | 4812 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
@@ -4332,6 +5126,8 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
4332 | { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, | 5126 | { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, |
4333 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, | 5127 | { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, |
4334 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, | 5128 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, |
5129 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, | ||
5130 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, | ||
4335 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, | 5131 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, |
4336 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | 5132 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, |
4337 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, | 5133 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |