diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-28 08:49:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-28 08:49:31 -0400 |
commit | 6f56c218666b5c7eff354364357307d18c10058b (patch) | |
tree | 5c18d12d2410d25b0f8b5a2150e2f2f4df20e95b /sound | |
parent | 95b6886526bb510b8370b625a49bc0ab3b8ff10f (diff) | |
parent | 8d34e6d3ec0393a286569587fbd9675abd258d93 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
sound: oss: rename local change_bits to avoid powerpc bitsops.h definition
ALSA: hda - Fix duplicated DAC assignments for Realtek
ALSA: asihpi - off by one in asihpi_hpi_ioctl()
ALSA: hda - Fix Oops with Realtek quirks with NULL adc_nids
ALSA: asihpi - bug fix pa use before init.
ALSA: hda - Add support for vref-out based mute LED control on IDT codecs
Diffstat (limited to 'sound')
-rw-r--r-- | sound/oss/ad1848.c | 6 | ||||
-rw-r--r-- | sound/oss/sb_mixer.c | 6 | ||||
-rw-r--r-- | sound/pci/asihpi/hpioctl.c | 13 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 29 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 199 |
5 files changed, 183 insertions, 70 deletions
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index 4d2a6ae978f7..8a197fd3c57e 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c | |||
@@ -458,7 +458,7 @@ static int ad1848_set_recmask(ad1848_info * devc, int mask) | |||
458 | return mask; | 458 | return mask; |
459 | } | 459 | } |
460 | 460 | ||
461 | static void change_bits(ad1848_info * devc, unsigned char *regval, | 461 | static void oss_change_bits(ad1848_info *devc, unsigned char *regval, |
462 | unsigned char *muteval, int dev, int chn, int newval) | 462 | unsigned char *muteval, int dev, int chn, int newval) |
463 | { | 463 | { |
464 | unsigned char mask; | 464 | unsigned char mask; |
@@ -516,10 +516,10 @@ static void ad1848_mixer_set_channel(ad1848_info *devc, int dev, int value, int | |||
516 | 516 | ||
517 | if (muteregoffs != regoffs) { | 517 | if (muteregoffs != regoffs) { |
518 | muteval = ad_read(devc, muteregoffs); | 518 | muteval = ad_read(devc, muteregoffs); |
519 | change_bits(devc, &val, &muteval, dev, channel, value); | 519 | oss_change_bits(devc, &val, &muteval, dev, channel, value); |
520 | } | 520 | } |
521 | else | 521 | else |
522 | change_bits(devc, &val, &val, dev, channel, value); | 522 | oss_change_bits(devc, &val, &val, dev, channel, value); |
523 | 523 | ||
524 | spin_lock_irqsave(&devc->lock,flags); | 524 | spin_lock_irqsave(&devc->lock,flags); |
525 | ad_write(devc, regoffs, val); | 525 | ad_write(devc, regoffs, val); |
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c index 2039d31b7e22..f8f3b7a66b73 100644 --- a/sound/oss/sb_mixer.c +++ b/sound/oss/sb_mixer.c | |||
@@ -232,7 +232,7 @@ static int detect_mixer(sb_devc * devc) | |||
232 | return 1; | 232 | return 1; |
233 | } | 233 | } |
234 | 234 | ||
235 | static void change_bits(sb_devc * devc, unsigned char *regval, int dev, int chn, int newval) | 235 | static void oss_change_bits(sb_devc *devc, unsigned char *regval, int dev, int chn, int newval) |
236 | { | 236 | { |
237 | unsigned char mask; | 237 | unsigned char mask; |
238 | int shift; | 238 | int shift; |
@@ -284,7 +284,7 @@ int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right) | |||
284 | return -EINVAL; | 284 | return -EINVAL; |
285 | 285 | ||
286 | val = sb_getmixer(devc, regoffs); | 286 | val = sb_getmixer(devc, regoffs); |
287 | change_bits(devc, &val, dev, LEFT_CHN, left); | 287 | oss_change_bits(devc, &val, dev, LEFT_CHN, left); |
288 | 288 | ||
289 | if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /* | 289 | if ((*devc->iomap)[dev][RIGHT_CHN].regno != regoffs) /* |
290 | * Change register | 290 | * Change register |
@@ -304,7 +304,7 @@ int sb_common_mixer_set(sb_devc * devc, int dev, int left, int right) | |||
304 | * Read the new one | 304 | * Read the new one |
305 | */ | 305 | */ |
306 | } | 306 | } |
307 | change_bits(devc, &val, dev, RIGHT_CHN, right); | 307 | oss_change_bits(devc, &val, dev, RIGHT_CHN, right); |
308 | 308 | ||
309 | sb_setmixer(devc, regoffs, val); | 309 | sb_setmixer(devc, regoffs, val); |
310 | 310 | ||
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 65fcf4770731..9683f84ecdc8 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c | |||
@@ -107,7 +107,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
107 | union hpi_response_buffer_v1 *hr; | 107 | union hpi_response_buffer_v1 *hr; |
108 | u16 res_max_size; | 108 | u16 res_max_size; |
109 | u32 uncopied_bytes; | 109 | u32 uncopied_bytes; |
110 | struct hpi_adapter *pa = NULL; | ||
111 | int err = 0; | 110 | int err = 0; |
112 | 111 | ||
113 | if (cmd != HPI_IOCTL_LINUX) | 112 | if (cmd != HPI_IOCTL_LINUX) |
@@ -182,8 +181,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
182 | /* -1=no data 0=read from user mem, 1=write to user mem */ | 181 | /* -1=no data 0=read from user mem, 1=write to user mem */ |
183 | int wrflag = -1; | 182 | int wrflag = -1; |
184 | u32 adapter = hm->h.adapter_index; | 183 | u32 adapter = hm->h.adapter_index; |
184 | struct hpi_adapter *pa = &adapters[adapter]; | ||
185 | 185 | ||
186 | if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) { | 186 | if ((adapter >= HPI_MAX_ADAPTERS) || (!pa->type)) { |
187 | hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, | 187 | hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, |
188 | HPI_ADAPTER_OPEN, | 188 | HPI_ADAPTER_OPEN, |
189 | HPI_ERROR_BAD_ADAPTER_NUMBER); | 189 | HPI_ERROR_BAD_ADAPTER_NUMBER); |
@@ -197,9 +197,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
197 | goto out; | 197 | goto out; |
198 | } | 198 | } |
199 | 199 | ||
200 | pa = &adapters[adapter]; | 200 | if (mutex_lock_interruptible(&pa->mutex)) { |
201 | |||
202 | if (mutex_lock_interruptible(&adapters[adapter].mutex)) { | ||
203 | err = -EINTR; | 201 | err = -EINTR; |
204 | goto out; | 202 | goto out; |
205 | } | 203 | } |
@@ -235,8 +233,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
235 | "stream buffer size %d\n", | 233 | "stream buffer size %d\n", |
236 | size); | 234 | size); |
237 | 235 | ||
238 | mutex_unlock(&adapters | 236 | mutex_unlock(&pa->mutex); |
239 | [adapter].mutex); | ||
240 | err = -EINVAL; | 237 | err = -EINVAL; |
241 | goto out; | 238 | goto out; |
242 | } | 239 | } |
@@ -277,7 +274,7 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
277 | uncopied_bytes, size); | 274 | uncopied_bytes, size); |
278 | } | 275 | } |
279 | 276 | ||
280 | mutex_unlock(&adapters[adapter].mutex); | 277 | mutex_unlock(&pa->mutex); |
281 | } | 278 | } |
282 | 279 | ||
283 | /* on return response size must be set */ | 280 | /* on return response size must be set */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 694327ae8b71..e125c60fe352 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -895,13 +895,15 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
895 | if (present == 3) | 895 | if (present == 3) |
896 | spec->automute_hp_lo = 1; /* both HP and LO automute */ | 896 | spec->automute_hp_lo = 1; /* both HP and LO automute */ |
897 | 897 | ||
898 | if (!cfg->speaker_pins[0]) { | 898 | if (!cfg->speaker_pins[0] && |
899 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
899 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | 900 | memcpy(cfg->speaker_pins, cfg->line_out_pins, |
900 | sizeof(cfg->speaker_pins)); | 901 | sizeof(cfg->speaker_pins)); |
901 | cfg->speaker_outs = cfg->line_outs; | 902 | cfg->speaker_outs = cfg->line_outs; |
902 | } | 903 | } |
903 | 904 | ||
904 | if (!cfg->hp_pins[0]) { | 905 | if (!cfg->hp_pins[0] && |
906 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
905 | memcpy(cfg->hp_pins, cfg->line_out_pins, | 907 | memcpy(cfg->hp_pins, cfg->line_out_pins, |
906 | sizeof(cfg->hp_pins)); | 908 | sizeof(cfg->hp_pins)); |
907 | cfg->hp_outs = cfg->line_outs; | 909 | cfg->hp_outs = cfg->line_outs; |
@@ -920,6 +922,7 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
920 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 922 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
921 | } | 923 | } |
922 | if (spec->automute && cfg->line_out_pins[0] && | 924 | if (spec->automute && cfg->line_out_pins[0] && |
925 | cfg->speaker_pins[0] && | ||
923 | cfg->line_out_pins[0] != cfg->hp_pins[0] && | 926 | cfg->line_out_pins[0] != cfg->hp_pins[0] && |
924 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { | 927 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { |
925 | for (i = 0; i < cfg->line_outs; i++) { | 928 | for (i = 0; i < cfg->line_outs; i++) { |
@@ -1911,7 +1914,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
1911 | return err; | 1914 | return err; |
1912 | } | 1915 | } |
1913 | } | 1916 | } |
1914 | if (spec->cap_mixer) { | 1917 | if (spec->cap_mixer && spec->adc_nids) { |
1915 | const char *kname = kctl ? kctl->id.name : NULL; | 1918 | const char *kname = kctl ? kctl->id.name : NULL; |
1916 | for (knew = spec->cap_mixer; knew->name; knew++) { | 1919 | for (knew = spec->cap_mixer; knew->name; knew++) { |
1917 | if (kname && strcmp(knew->name, kname) == 0) | 1920 | if (kname && strcmp(knew->name, kname) == 0) |
@@ -3677,7 +3680,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
3677 | if (board_config != ALC_MODEL_AUTO) | 3680 | if (board_config != ALC_MODEL_AUTO) |
3678 | setup_preset(codec, &alc880_presets[board_config]); | 3681 | setup_preset(codec, &alc880_presets[board_config]); |
3679 | 3682 | ||
3680 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 3683 | if (!spec->no_analog && !spec->adc_nids) { |
3681 | alc_auto_fill_adc_caps(codec); | 3684 | alc_auto_fill_adc_caps(codec); |
3682 | alc_rebuild_imux_for_auto_mic(codec); | 3685 | alc_rebuild_imux_for_auto_mic(codec); |
3683 | alc_remove_invalid_adc_nids(codec); | 3686 | alc_remove_invalid_adc_nids(codec); |
@@ -3804,7 +3807,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
3804 | if (board_config != ALC_MODEL_AUTO) | 3807 | if (board_config != ALC_MODEL_AUTO) |
3805 | setup_preset(codec, &alc260_presets[board_config]); | 3808 | setup_preset(codec, &alc260_presets[board_config]); |
3806 | 3809 | ||
3807 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 3810 | if (!spec->no_analog && !spec->adc_nids) { |
3808 | alc_auto_fill_adc_caps(codec); | 3811 | alc_auto_fill_adc_caps(codec); |
3809 | alc_rebuild_imux_for_auto_mic(codec); | 3812 | alc_rebuild_imux_for_auto_mic(codec); |
3810 | alc_remove_invalid_adc_nids(codec); | 3813 | alc_remove_invalid_adc_nids(codec); |
@@ -3983,7 +3986,7 @@ static int patch_alc882(struct hda_codec *codec) | |||
3983 | if (board_config != ALC_MODEL_AUTO) | 3986 | if (board_config != ALC_MODEL_AUTO) |
3984 | setup_preset(codec, &alc882_presets[board_config]); | 3987 | setup_preset(codec, &alc882_presets[board_config]); |
3985 | 3988 | ||
3986 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 3989 | if (!spec->no_analog && !spec->adc_nids) { |
3987 | alc_auto_fill_adc_caps(codec); | 3990 | alc_auto_fill_adc_caps(codec); |
3988 | alc_rebuild_imux_for_auto_mic(codec); | 3991 | alc_rebuild_imux_for_auto_mic(codec); |
3989 | alc_remove_invalid_adc_nids(codec); | 3992 | alc_remove_invalid_adc_nids(codec); |
@@ -4137,7 +4140,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
4137 | if (board_config != ALC_MODEL_AUTO) | 4140 | if (board_config != ALC_MODEL_AUTO) |
4138 | setup_preset(codec, &alc262_presets[board_config]); | 4141 | setup_preset(codec, &alc262_presets[board_config]); |
4139 | 4142 | ||
4140 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 4143 | if (!spec->no_analog && !spec->adc_nids) { |
4141 | alc_auto_fill_adc_caps(codec); | 4144 | alc_auto_fill_adc_caps(codec); |
4142 | alc_rebuild_imux_for_auto_mic(codec); | 4145 | alc_rebuild_imux_for_auto_mic(codec); |
4143 | alc_remove_invalid_adc_nids(codec); | 4146 | alc_remove_invalid_adc_nids(codec); |
@@ -4293,7 +4296,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
4293 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 4296 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
4294 | } | 4297 | } |
4295 | 4298 | ||
4296 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 4299 | if (!spec->no_analog && !spec->adc_nids) { |
4297 | alc_auto_fill_adc_caps(codec); | 4300 | alc_auto_fill_adc_caps(codec); |
4298 | alc_rebuild_imux_for_auto_mic(codec); | 4301 | alc_rebuild_imux_for_auto_mic(codec); |
4299 | alc_remove_invalid_adc_nids(codec); | 4302 | alc_remove_invalid_adc_nids(codec); |
@@ -4705,7 +4708,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
4705 | if (board_config != ALC_MODEL_AUTO) | 4708 | if (board_config != ALC_MODEL_AUTO) |
4706 | setup_preset(codec, &alc269_presets[board_config]); | 4709 | setup_preset(codec, &alc269_presets[board_config]); |
4707 | 4710 | ||
4708 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 4711 | if (!spec->no_analog && !spec->adc_nids) { |
4709 | alc_auto_fill_adc_caps(codec); | 4712 | alc_auto_fill_adc_caps(codec); |
4710 | alc_rebuild_imux_for_auto_mic(codec); | 4713 | alc_rebuild_imux_for_auto_mic(codec); |
4711 | alc_remove_invalid_adc_nids(codec); | 4714 | alc_remove_invalid_adc_nids(codec); |
@@ -4843,7 +4846,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
4843 | if (board_config != ALC_MODEL_AUTO) | 4846 | if (board_config != ALC_MODEL_AUTO) |
4844 | setup_preset(codec, &alc861_presets[board_config]); | 4847 | setup_preset(codec, &alc861_presets[board_config]); |
4845 | 4848 | ||
4846 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 4849 | if (!spec->no_analog && !spec->adc_nids) { |
4847 | alc_auto_fill_adc_caps(codec); | 4850 | alc_auto_fill_adc_caps(codec); |
4848 | alc_rebuild_imux_for_auto_mic(codec); | 4851 | alc_rebuild_imux_for_auto_mic(codec); |
4849 | alc_remove_invalid_adc_nids(codec); | 4852 | alc_remove_invalid_adc_nids(codec); |
@@ -4984,7 +4987,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
4984 | add_verb(spec, alc660vd_eapd_verbs); | 4987 | add_verb(spec, alc660vd_eapd_verbs); |
4985 | } | 4988 | } |
4986 | 4989 | ||
4987 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 4990 | if (!spec->no_analog && !spec->adc_nids) { |
4988 | alc_auto_fill_adc_caps(codec); | 4991 | alc_auto_fill_adc_caps(codec); |
4989 | alc_rebuild_imux_for_auto_mic(codec); | 4992 | alc_rebuild_imux_for_auto_mic(codec); |
4990 | alc_remove_invalid_adc_nids(codec); | 4993 | alc_remove_invalid_adc_nids(codec); |
@@ -5200,7 +5203,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
5200 | if (board_config != ALC_MODEL_AUTO) | 5203 | if (board_config != ALC_MODEL_AUTO) |
5201 | setup_preset(codec, &alc662_presets[board_config]); | 5204 | setup_preset(codec, &alc662_presets[board_config]); |
5202 | 5205 | ||
5203 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 5206 | if (!spec->no_analog && !spec->adc_nids) { |
5204 | alc_auto_fill_adc_caps(codec); | 5207 | alc_auto_fill_adc_caps(codec); |
5205 | alc_rebuild_imux_for_auto_mic(codec); | 5208 | alc_rebuild_imux_for_auto_mic(codec); |
5206 | alc_remove_invalid_adc_nids(codec); | 5209 | alc_remove_invalid_adc_nids(codec); |
@@ -5336,7 +5339,7 @@ static int patch_alc680(struct hda_codec *codec) | |||
5336 | #endif | 5339 | #endif |
5337 | } | 5340 | } |
5338 | 5341 | ||
5339 | if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { | 5342 | if (!spec->no_analog && !spec->adc_nids) { |
5340 | alc_auto_fill_adc_caps(codec); | 5343 | alc_auto_fill_adc_caps(codec); |
5341 | alc_rebuild_imux_for_auto_mic(codec); | 5344 | alc_rebuild_imux_for_auto_mic(codec); |
5342 | alc_remove_invalid_adc_nids(codec); | 5345 | alc_remove_invalid_adc_nids(codec); |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fcf4c7142103..aa376b59c006 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -213,6 +213,7 @@ struct sigmatel_spec { | |||
213 | unsigned int gpio_mute; | 213 | unsigned int gpio_mute; |
214 | unsigned int gpio_led; | 214 | unsigned int gpio_led; |
215 | unsigned int gpio_led_polarity; | 215 | unsigned int gpio_led_polarity; |
216 | unsigned int vref_led; | ||
216 | 217 | ||
217 | /* stream */ | 218 | /* stream */ |
218 | unsigned int stream_delay; | 219 | unsigned int stream_delay; |
@@ -672,6 +673,30 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, | |||
672 | return 0; | 673 | return 0; |
673 | } | 674 | } |
674 | 675 | ||
676 | static int stac_vrefout_set(struct hda_codec *codec, | ||
677 | hda_nid_t nid, unsigned int new_vref) | ||
678 | { | ||
679 | int error, pinctl; | ||
680 | |||
681 | snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref); | ||
682 | pinctl = snd_hda_codec_read(codec, nid, 0, | ||
683 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
684 | |||
685 | if (pinctl < 0) | ||
686 | return pinctl; | ||
687 | |||
688 | pinctl &= 0xff; | ||
689 | pinctl &= ~AC_PINCTL_VREFEN; | ||
690 | pinctl |= (new_vref & AC_PINCTL_VREFEN); | ||
691 | |||
692 | error = snd_hda_codec_write_cache(codec, nid, 0, | ||
693 | AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); | ||
694 | if (error < 0) | ||
695 | return error; | ||
696 | |||
697 | return 1; | ||
698 | } | ||
699 | |||
675 | static unsigned int stac92xx_vref_set(struct hda_codec *codec, | 700 | static unsigned int stac92xx_vref_set(struct hda_codec *codec, |
676 | hda_nid_t nid, unsigned int new_vref) | 701 | hda_nid_t nid, unsigned int new_vref) |
677 | { | 702 | { |
@@ -4069,6 +4094,8 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | |||
4069 | { | 4094 | { |
4070 | unsigned int gpiostate, gpiomask, gpiodir; | 4095 | unsigned int gpiostate, gpiomask, gpiodir; |
4071 | 4096 | ||
4097 | snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data); | ||
4098 | |||
4072 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, | 4099 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, |
4073 | AC_VERB_GET_GPIO_DATA, 0); | 4100 | AC_VERB_GET_GPIO_DATA, 0); |
4074 | gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); | 4101 | gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); |
@@ -4258,10 +4285,12 @@ static void stac_store_hints(struct hda_codec *codec) | |||
4258 | spec->eapd_switch = val; | 4285 | spec->eapd_switch = val; |
4259 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); | 4286 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); |
4260 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { | 4287 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { |
4261 | spec->gpio_mask |= spec->gpio_led; | 4288 | if (spec->gpio_led <= 8) { |
4262 | spec->gpio_dir |= spec->gpio_led; | 4289 | spec->gpio_mask |= spec->gpio_led; |
4263 | if (spec->gpio_led_polarity) | 4290 | spec->gpio_dir |= spec->gpio_led; |
4264 | spec->gpio_data |= spec->gpio_led; | 4291 | if (spec->gpio_led_polarity) |
4292 | spec->gpio_data |= spec->gpio_led; | ||
4293 | } | ||
4265 | } | 4294 | } |
4266 | } | 4295 | } |
4267 | 4296 | ||
@@ -4431,11 +4460,26 @@ static void stac92xx_free_kctls(struct hda_codec *codec) | |||
4431 | snd_array_free(&spec->kctls); | 4460 | snd_array_free(&spec->kctls); |
4432 | } | 4461 | } |
4433 | 4462 | ||
4463 | static void stac92xx_shutup_pins(struct hda_codec *codec) | ||
4464 | { | ||
4465 | unsigned int i, def_conf; | ||
4466 | |||
4467 | if (codec->bus->shutdown) | ||
4468 | return; | ||
4469 | for (i = 0; i < codec->init_pins.used; i++) { | ||
4470 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
4471 | def_conf = snd_hda_codec_get_pincfg(codec, pin->nid); | ||
4472 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE) | ||
4473 | snd_hda_codec_write(codec, pin->nid, 0, | ||
4474 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
4475 | } | ||
4476 | } | ||
4477 | |||
4434 | static void stac92xx_shutup(struct hda_codec *codec) | 4478 | static void stac92xx_shutup(struct hda_codec *codec) |
4435 | { | 4479 | { |
4436 | struct sigmatel_spec *spec = codec->spec; | 4480 | struct sigmatel_spec *spec = codec->spec; |
4437 | 4481 | ||
4438 | snd_hda_shutup_pins(codec); | 4482 | stac92xx_shutup_pins(codec); |
4439 | 4483 | ||
4440 | if (spec->eapd_mask) | 4484 | if (spec->eapd_mask) |
4441 | stac_gpio_set(codec, spec->gpio_mask, | 4485 | stac_gpio_set(codec, spec->gpio_mask, |
@@ -4833,10 +4877,11 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) | |||
4833 | if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { | 4877 | if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { |
4834 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, | 4878 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, |
4835 | NULL, dev))) { | 4879 | NULL, dev))) { |
4836 | if (sscanf(dev->name, "HP_Mute_LED_%d_%d", | 4880 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", |
4837 | &spec->gpio_led_polarity, | 4881 | &spec->gpio_led_polarity, |
4838 | &spec->gpio_led) == 2) { | 4882 | &spec->gpio_led) == 2) { |
4839 | spec->gpio_led = 1 << spec->gpio_led; | 4883 | if (spec->gpio_led < 4) |
4884 | spec->gpio_led = 1 << spec->gpio_led; | ||
4840 | return 1; | 4885 | return 1; |
4841 | } | 4886 | } |
4842 | if (sscanf(dev->name, "HP_Mute_LED_%d", | 4887 | if (sscanf(dev->name, "HP_Mute_LED_%d", |
@@ -4935,17 +4980,6 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer, | |||
4935 | #endif | 4980 | #endif |
4936 | 4981 | ||
4937 | #ifdef CONFIG_PM | 4982 | #ifdef CONFIG_PM |
4938 | static int stac92xx_pre_resume(struct hda_codec *codec) | ||
4939 | { | ||
4940 | struct sigmatel_spec *spec = codec->spec; | ||
4941 | |||
4942 | /* sync mute LED */ | ||
4943 | if (spec->gpio_led) | ||
4944 | stac_gpio_set(codec, spec->gpio_mask, | ||
4945 | spec->gpio_dir, spec->gpio_data); | ||
4946 | return 0; | ||
4947 | } | ||
4948 | |||
4949 | static int stac92xx_resume(struct hda_codec *codec) | 4983 | static int stac92xx_resume(struct hda_codec *codec) |
4950 | { | 4984 | { |
4951 | struct sigmatel_spec *spec = codec->spec; | 4985 | struct sigmatel_spec *spec = codec->spec; |
@@ -4964,7 +4998,65 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4964 | return 0; | 4998 | return 0; |
4965 | } | 4999 | } |
4966 | 5000 | ||
5001 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | ||
5002 | { | ||
5003 | stac92xx_shutup(codec); | ||
5004 | return 0; | ||
5005 | } | ||
5006 | |||
4967 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5007 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5008 | static int stac92xx_pre_resume(struct hda_codec *codec) | ||
5009 | { | ||
5010 | struct sigmatel_spec *spec = codec->spec; | ||
5011 | |||
5012 | /* sync mute LED */ | ||
5013 | if (spec->gpio_led) { | ||
5014 | if (spec->gpio_led <= 8) { | ||
5015 | stac_gpio_set(codec, spec->gpio_mask, | ||
5016 | spec->gpio_dir, spec->gpio_data); | ||
5017 | } else { | ||
5018 | stac_vrefout_set(codec, | ||
5019 | spec->gpio_led, spec->vref_led); | ||
5020 | } | ||
5021 | } | ||
5022 | return 0; | ||
5023 | } | ||
5024 | |||
5025 | static int stac92xx_post_suspend(struct hda_codec *codec) | ||
5026 | { | ||
5027 | struct sigmatel_spec *spec = codec->spec; | ||
5028 | if (spec->gpio_led > 8) { | ||
5029 | /* with vref-out pin used for mute led control | ||
5030 | * codec AFG is prevented from D3 state, but on | ||
5031 | * system suspend it can (and should) be used | ||
5032 | */ | ||
5033 | snd_hda_codec_read(codec, codec->afg, 0, | ||
5034 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
5035 | } | ||
5036 | return 0; | ||
5037 | } | ||
5038 | |||
5039 | static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, | ||
5040 | unsigned int power_state) | ||
5041 | { | ||
5042 | unsigned int afg_power_state = power_state; | ||
5043 | struct sigmatel_spec *spec = codec->spec; | ||
5044 | |||
5045 | if (power_state == AC_PWRST_D3) { | ||
5046 | if (spec->gpio_led > 8) { | ||
5047 | /* with vref-out pin used for mute led control | ||
5048 | * codec AFG is prevented from D3 state | ||
5049 | */ | ||
5050 | afg_power_state = AC_PWRST_D1; | ||
5051 | } | ||
5052 | /* this delay seems necessary to avoid click noise at power-down */ | ||
5053 | msleep(100); | ||
5054 | } | ||
5055 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | ||
5056 | afg_power_state); | ||
5057 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | ||
5058 | } | ||
5059 | |||
4968 | /* | 5060 | /* |
4969 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed | 5061 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed |
4970 | * as mute LED state is updated in check_power_status hook | 5062 | * as mute LED state is updated in check_power_status hook |
@@ -4973,8 +5065,12 @@ static int stac92xx_update_led_status(struct hda_codec *codec) | |||
4973 | { | 5065 | { |
4974 | struct sigmatel_spec *spec = codec->spec; | 5066 | struct sigmatel_spec *spec = codec->spec; |
4975 | int i, num_ext_dacs, muted = 1; | 5067 | int i, num_ext_dacs, muted = 1; |
5068 | unsigned int muted_lvl, notmtd_lvl; | ||
4976 | hda_nid_t nid; | 5069 | hda_nid_t nid; |
4977 | 5070 | ||
5071 | if (!spec->gpio_led) | ||
5072 | return 0; | ||
5073 | |||
4978 | for (i = 0; i < spec->multiout.num_dacs; i++) { | 5074 | for (i = 0; i < spec->multiout.num_dacs; i++) { |
4979 | nid = spec->multiout.dac_nids[i]; | 5075 | nid = spec->multiout.dac_nids[i]; |
4980 | if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | 5076 | if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & |
@@ -4999,17 +5095,27 @@ static int stac92xx_update_led_status(struct hda_codec *codec) | |||
4999 | muted = 0; /* extra output is not muted */ | 5095 | muted = 0; /* extra output is not muted */ |
5000 | } | 5096 | } |
5001 | } | 5097 | } |
5002 | if (muted) | 5098 | /*polarity defines *not* muted state level*/ |
5003 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | 5099 | if (spec->gpio_led <= 8) { |
5004 | else | 5100 | if (muted) |
5005 | spec->gpio_data |= spec->gpio_led; /* white */ | 5101 | spec->gpio_data &= ~spec->gpio_led; /* orange */ |
5102 | else | ||
5103 | spec->gpio_data |= spec->gpio_led; /* white */ | ||
5006 | 5104 | ||
5007 | if (!spec->gpio_led_polarity) { | 5105 | if (!spec->gpio_led_polarity) { |
5008 | /* LED state is inverted on these systems */ | 5106 | /* LED state is inverted on these systems */ |
5009 | spec->gpio_data ^= spec->gpio_led; | 5107 | spec->gpio_data ^= spec->gpio_led; |
5108 | } | ||
5109 | stac_gpio_set(codec, spec->gpio_mask, | ||
5110 | spec->gpio_dir, spec->gpio_data); | ||
5111 | } else { | ||
5112 | notmtd_lvl = spec->gpio_led_polarity ? | ||
5113 | AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD; | ||
5114 | muted_lvl = spec->gpio_led_polarity ? | ||
5115 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; | ||
5116 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; | ||
5117 | stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); | ||
5010 | } | 5118 | } |
5011 | |||
5012 | stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); | ||
5013 | return 0; | 5119 | return 0; |
5014 | } | 5120 | } |
5015 | 5121 | ||
@@ -5023,13 +5129,7 @@ static int stac92xx_check_power_status(struct hda_codec *codec, | |||
5023 | 5129 | ||
5024 | return 0; | 5130 | return 0; |
5025 | } | 5131 | } |
5026 | #endif | 5132 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ |
5027 | |||
5028 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | ||
5029 | { | ||
5030 | stac92xx_shutup(codec); | ||
5031 | return 0; | ||
5032 | } | ||
5033 | #endif /* CONFIG_PM */ | 5133 | #endif /* CONFIG_PM */ |
5034 | 5134 | ||
5035 | static const struct hda_codec_ops stac92xx_patch_ops = { | 5135 | static const struct hda_codec_ops stac92xx_patch_ops = { |
@@ -5041,7 +5141,6 @@ static const struct hda_codec_ops stac92xx_patch_ops = { | |||
5041 | #ifdef CONFIG_PM | 5141 | #ifdef CONFIG_PM |
5042 | .suspend = stac92xx_suspend, | 5142 | .suspend = stac92xx_suspend, |
5043 | .resume = stac92xx_resume, | 5143 | .resume = stac92xx_resume, |
5044 | .pre_resume = stac92xx_pre_resume, | ||
5045 | #endif | 5144 | #endif |
5046 | .reboot_notify = stac92xx_shutup, | 5145 | .reboot_notify = stac92xx_shutup, |
5047 | }; | 5146 | }; |
@@ -5555,10 +5654,17 @@ again: | |||
5555 | 5654 | ||
5556 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5655 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5557 | if (spec->gpio_led) { | 5656 | if (spec->gpio_led) { |
5558 | spec->gpio_mask |= spec->gpio_led; | 5657 | if (spec->gpio_led <= 8) { |
5559 | spec->gpio_dir |= spec->gpio_led; | 5658 | spec->gpio_mask |= spec->gpio_led; |
5560 | spec->gpio_data |= spec->gpio_led; | 5659 | spec->gpio_dir |= spec->gpio_led; |
5561 | /* register check_power_status callback. */ | 5660 | spec->gpio_data |= spec->gpio_led; |
5661 | } else { | ||
5662 | codec->patch_ops.set_power_state = | ||
5663 | stac92xx_set_power_state; | ||
5664 | codec->patch_ops.post_suspend = | ||
5665 | stac92xx_post_suspend; | ||
5666 | } | ||
5667 | codec->patch_ops.pre_resume = stac92xx_pre_resume; | ||
5562 | codec->patch_ops.check_power_status = | 5668 | codec->patch_ops.check_power_status = |
5563 | stac92xx_check_power_status; | 5669 | stac92xx_check_power_status; |
5564 | } | 5670 | } |
@@ -5883,10 +5989,17 @@ again: | |||
5883 | 5989 | ||
5884 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5990 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5885 | if (spec->gpio_led) { | 5991 | if (spec->gpio_led) { |
5886 | spec->gpio_mask |= spec->gpio_led; | 5992 | if (spec->gpio_led <= 8) { |
5887 | spec->gpio_dir |= spec->gpio_led; | 5993 | spec->gpio_mask |= spec->gpio_led; |
5888 | spec->gpio_data |= spec->gpio_led; | 5994 | spec->gpio_dir |= spec->gpio_led; |
5889 | /* register check_power_status callback. */ | 5995 | spec->gpio_data |= spec->gpio_led; |
5996 | } else { | ||
5997 | codec->patch_ops.set_power_state = | ||
5998 | stac92xx_set_power_state; | ||
5999 | codec->patch_ops.post_suspend = | ||
6000 | stac92xx_post_suspend; | ||
6001 | } | ||
6002 | codec->patch_ops.pre_resume = stac92xx_pre_resume; | ||
5890 | codec->patch_ops.check_power_status = | 6003 | codec->patch_ops.check_power_status = |
5891 | stac92xx_check_power_status; | 6004 | stac92xx_check_power_status; |
5892 | } | 6005 | } |