diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-01-11 06:34:11 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-01-11 06:34:11 -0500 |
commit | f2cbba7602383cd9cdd21f0a5d0b8bd1aad47b33 (patch) | |
tree | d2585c3c5dde41bd28450f784e5824484cfac77a | |
parent | 4808d12d1dddb046ec86425e5f6766f02e950292 (diff) |
ALSA: hda - Fix the lost power-setup of seconary pins after PM resume
When multiple headphone or other detectable output pins are present,
the power-map has to be updated after resume appropriately, but the
current driver doesn't check all pins but only the first pin (since
it's enough to check it for the mute-behavior). This resulted in the
silent output from the secondary outputs after PM resume.
This patch fixes the problem by checking all pins at (re-)init time.
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=740347
Cc: <stable@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 03145aec65f1..87e684fa830f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -4236,6 +4236,27 @@ static void stac_store_hints(struct hda_codec *codec) | |||
4236 | } | 4236 | } |
4237 | } | 4237 | } |
4238 | 4238 | ||
4239 | static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins, | ||
4240 | const hda_nid_t *pins) | ||
4241 | { | ||
4242 | while (num_pins--) | ||
4243 | stac_issue_unsol_event(codec, *pins++); | ||
4244 | } | ||
4245 | |||
4246 | /* fake event to set up pins */ | ||
4247 | static void stac_fake_hp_events(struct hda_codec *codec) | ||
4248 | { | ||
4249 | struct sigmatel_spec *spec = codec->spec; | ||
4250 | |||
4251 | if (spec->autocfg.hp_outs) | ||
4252 | stac_issue_unsol_events(codec, spec->autocfg.hp_outs, | ||
4253 | spec->autocfg.hp_pins); | ||
4254 | if (spec->autocfg.line_outs && | ||
4255 | spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0]) | ||
4256 | stac_issue_unsol_events(codec, spec->autocfg.line_outs, | ||
4257 | spec->autocfg.line_out_pins); | ||
4258 | } | ||
4259 | |||
4239 | static int stac92xx_init(struct hda_codec *codec) | 4260 | static int stac92xx_init(struct hda_codec *codec) |
4240 | { | 4261 | { |
4241 | struct sigmatel_spec *spec = codec->spec; | 4262 | struct sigmatel_spec *spec = codec->spec; |
@@ -4286,10 +4307,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4286 | stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], | 4307 | stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], |
4287 | AC_PINCTL_OUT_EN); | 4308 | AC_PINCTL_OUT_EN); |
4288 | /* fake event to set up pins */ | 4309 | /* fake event to set up pins */ |
4289 | if (cfg->hp_pins[0]) | 4310 | stac_fake_hp_events(codec); |
4290 | stac_issue_unsol_event(codec, cfg->hp_pins[0]); | ||
4291 | else if (cfg->line_out_pins[0]) | ||
4292 | stac_issue_unsol_event(codec, cfg->line_out_pins[0]); | ||
4293 | } else { | 4311 | } else { |
4294 | stac92xx_auto_init_multi_out(codec); | 4312 | stac92xx_auto_init_multi_out(codec); |
4295 | stac92xx_auto_init_hp_out(codec); | 4313 | stac92xx_auto_init_hp_out(codec); |
@@ -4948,19 +4966,11 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer, | |||
4948 | #ifdef CONFIG_PM | 4966 | #ifdef CONFIG_PM |
4949 | static int stac92xx_resume(struct hda_codec *codec) | 4967 | static int stac92xx_resume(struct hda_codec *codec) |
4950 | { | 4968 | { |
4951 | struct sigmatel_spec *spec = codec->spec; | ||
4952 | |||
4953 | stac92xx_init(codec); | 4969 | stac92xx_init(codec); |
4954 | snd_hda_codec_resume_amp(codec); | 4970 | snd_hda_codec_resume_amp(codec); |
4955 | snd_hda_codec_resume_cache(codec); | 4971 | snd_hda_codec_resume_cache(codec); |
4956 | /* fake event to set up pins again to override cached values */ | 4972 | /* fake event to set up pins again to override cached values */ |
4957 | if (spec->hp_detect) { | 4973 | stac_fake_hp_events(codec); |
4958 | if (spec->autocfg.hp_pins[0]) | ||
4959 | stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); | ||
4960 | else if (spec->autocfg.line_out_pins[0]) | ||
4961 | stac_issue_unsol_event(codec, | ||
4962 | spec->autocfg.line_out_pins[0]); | ||
4963 | } | ||
4964 | return 0; | 4974 | return 0; |
4965 | } | 4975 | } |
4966 | 4976 | ||