aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorStefan Binding <sbinding@opensource.cirrus.com>2022-06-30 01:23:30 +0100
committerTakashi Iwai <tiwai@suse.de>2022-07-15 16:21:39 +0200
commit1873ebd30cc818eefd151e40a4bd05fd8f83b85a (patch)
tree3ba220d2d995f51e5e7df6925b360dc0559b1ba9 /sound/pci/hda/patch_realtek.c
parentMerge tag 'asoc-v5.20' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next (diff)
downloadlinux-dev-1873ebd30cc818eefd151e40a4bd05fd8f83b85a.tar.xz
linux-dev-1873ebd30cc818eefd151e40a4bd05fd8f83b85a.zip
ALSA: hda: cs35l41: Support Hibernation during Suspend
CS35L41 supports hibernation during suspend when using DSP firmware. When the driver suspends it will hibernate the part, if firmware is running, and resume will wake from hibernation. CS35L41 driver will suspend/resume when requested by hda driver. Note that suspend/resume and hibernation is only supported when firmware is running. Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com> Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com> Link: https://lore.kernel.org/r/20220630002335.366545-10-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 44744d568404..7c21bc439c46 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4021,15 +4021,22 @@ static void alc5505_dsp_init(struct hda_codec *codec)
static int alc269_suspend(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ int i;
if (spec->has_alc5505_dsp)
alc5505_dsp_suspend(codec);
+
+ for (i = 0; i < HDA_MAX_COMPONENTS; i++)
+ if (spec->comps[i].suspend_hook)
+ spec->comps[i].suspend_hook(spec->comps[i].dev);
+
return alc_suspend(codec);
}
static int alc269_resume(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
+ int i;
if (spec->codec_variant == ALC269_TYPE_ALC269VB)
alc269vb_toggle_power_output(codec, 0);
@@ -4060,6 +4067,10 @@ static int alc269_resume(struct hda_codec *codec)
if (spec->has_alc5505_dsp)
alc5505_dsp_resume(codec);
+ for (i = 0; i < HDA_MAX_COMPONENTS; i++)
+ if (spec->comps[i].resume_hook)
+ spec->comps[i].resume_hook(spec->comps[i].dev);
+
return 0;
}
#endif /* CONFIG_PM */
@@ -6610,8 +6621,20 @@ static int comp_bind(struct device *dev)
{
struct hda_codec *cdc = dev_to_hda_codec(dev);
struct alc_spec *spec = cdc->spec;
+ int ret, i;
+
+ ret = component_bind_all(dev, spec->comps);
+ if (ret)
+ return ret;
- return component_bind_all(dev, spec->comps);
+ if (snd_hdac_is_power_on(&cdc->core)) {
+ codec_dbg(cdc, "Resuming after bind.\n");
+ for (i = 0; i < HDA_MAX_COMPONENTS; i++)
+ if (spec->comps[i].resume_hook)
+ spec->comps[i].resume_hook(spec->comps[i].dev);
+ }
+
+ return 0;
}
static void comp_unbind(struct device *dev)