Unverified Commit e341efc3 authored by Stefan Binding's avatar Stefan Binding Committed by Mark Brown
Browse files

ASoC: cs35l41: Add common cs35l41 enter hibernate function



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: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>

Signed-off-by: default avatarStefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: default avatarVitaly Rodionov <vitalyr@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220525131638.5512-12-vitalyr@opensource.cirrus.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 94e0bc31
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);
+19 −0
Original line number Diff line number Diff line
@@ -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;
+1 −9
Original line number Diff line number Diff line
@@ -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);