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 | ||
