mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-01 16:57:18 +09:00
ALSA: hda - Fix the lost power-setup of seconary pins after PM resume
commit f2cbba7602 upstream.
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
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
0c7fe97698
commit
c2a3399e46
@@ -4326,6 +4326,27 @@ static void stac_store_hints(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
|
||||
const hda_nid_t *pins)
|
||||
{
|
||||
while (num_pins--)
|
||||
stac_issue_unsol_event(codec, *pins++);
|
||||
}
|
||||
|
||||
/* fake event to set up pins */
|
||||
static void stac_fake_hp_events(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
|
||||
if (spec->autocfg.hp_outs)
|
||||
stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
|
||||
spec->autocfg.hp_pins);
|
||||
if (spec->autocfg.line_outs &&
|
||||
spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
|
||||
stac_issue_unsol_events(codec, spec->autocfg.line_outs,
|
||||
spec->autocfg.line_out_pins);
|
||||
}
|
||||
|
||||
static int stac92xx_init(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
@@ -4376,10 +4397,7 @@ static int stac92xx_init(struct hda_codec *codec)
|
||||
stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
|
||||
AC_PINCTL_OUT_EN);
|
||||
/* fake event to set up pins */
|
||||
if (cfg->hp_pins[0])
|
||||
stac_issue_unsol_event(codec, cfg->hp_pins[0]);
|
||||
else if (cfg->line_out_pins[0])
|
||||
stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
|
||||
stac_fake_hp_events(codec);
|
||||
} else {
|
||||
stac92xx_auto_init_multi_out(codec);
|
||||
stac92xx_auto_init_hp_out(codec);
|
||||
@@ -5028,19 +5046,11 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
|
||||
#ifdef CONFIG_PM
|
||||
static int stac92xx_resume(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
|
||||
stac92xx_init(codec);
|
||||
snd_hda_codec_resume_amp(codec);
|
||||
snd_hda_codec_resume_cache(codec);
|
||||
/* fake event to set up pins again to override cached values */
|
||||
if (spec->hp_detect) {
|
||||
if (spec->autocfg.hp_pins[0])
|
||||
stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
|
||||
else if (spec->autocfg.line_out_pins[0])
|
||||
stac_issue_unsol_event(codec,
|
||||
spec->autocfg.line_out_pins[0]);
|
||||
}
|
||||
stac_fake_hp_events(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user