ASoC: cs35l41: Add common cs35l41 enter hibernate function
authorStefan Binding <sbinding@opensource.cirrus.com>
Wed, 25 May 2022 13:16:32 +0000 (14:16 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 6 Jun 2022 11:34:35 +0000 (12:34 +0100)
Since the CS35L41 HDA driver also support hibernation, it
makes sense to move code from the ASoC driver to enter
hibernation into common code.

Since HDA must support laptops which do not support hibernation
due to lack of external boost GPIO it is necessary to
ensure the function returns an error when an unsupported
boost type is in use.

Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220525131638.5512-12-vitalyr@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/cs35l41.h
sound/soc/codecs/cs35l41-lib.c
sound/soc/codecs/cs35l41.c

index 7759f2e14d96d4ad50b5eb1b96543a959c2d6273..a66ef37184fd522626b8d86df076b0fdf0ebe2dd 100644 (file)
@@ -881,6 +881,8 @@ void cs35l41_configure_cs_dsp(struct device *dev, struct regmap *reg, struct cs_
 int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap,
                              enum cs35l41_cspl_mbox_cmd cmd);
 int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap);
+int cs35l41_enter_hibernate(struct device *dev, struct regmap *regmap,
+                           enum cs35l41_boost_type b_type);
 int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap);
 int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
                       struct cs35l41_hw_cfg *hw_cfg);
index cc5366c8bdd61ed2ab47ec7ab7329efc656c51cd..10b754481ca2a2f3812200bb644c7b0de85f9186 100644 (file)
@@ -1321,6 +1321,25 @@ int cs35l41_write_fs_errata(struct device *dev, struct regmap *regmap)
 }
 EXPORT_SYMBOL_GPL(cs35l41_write_fs_errata);
 
+int cs35l41_enter_hibernate(struct device *dev, struct regmap *regmap,
+                           enum cs35l41_boost_type b_type)
+{
+       if (!cs35l41_safe_reset(regmap, b_type)) {
+               dev_dbg(dev, "System does not support Suspend\n");
+               return -EINVAL;
+       }
+
+       dev_dbg(dev, "Enter hibernate\n");
+       regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0088);
+       regmap_write(regmap, CS35L41_WAKESRC_CTL, 0x0188);
+
+       // Don't wait for ACK since bus activity would wake the device
+       regmap_write(regmap, CS35L41_DSP_VIRT1_MBOX_1, CSPL_MBOX_CMD_HIBERNATE);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(cs35l41_enter_hibernate);
+
 static void cs35l41_wait_for_pwrmgt_sts(struct device *dev, struct regmap *regmap)
 {
        const int pwrmgt_retries = 10;
index be7d0251773966708921d15c4b999bb2e66aef9b..a115ea35b92d46f5046c15572f1fc2219ea55a2f 100644 (file)
@@ -1335,15 +1335,7 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev)
        if (!cs35l41->dsp.preloaded || !cs35l41->dsp.cs_dsp.running)
                return 0;
 
-       dev_dbg(cs35l41->dev, "Enter hibernate\n");
-
-       cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
-       regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088);
-       regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188);
-
-       // Don't wait for ACK since bus activity would wake the device
-       regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1,
-                    CSPL_MBOX_CMD_HIBERNATE);
+       cs35l41_enter_hibernate(dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type);
 
        regcache_cache_only(cs35l41->regmap, true);
        regcache_mark_dirty(cs35l41->regmap);