summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/cs35l56.c
diff options
context:
space:
mode:
authorRichard Fitzgerald <rf@opensource.cirrus.com>2023-07-21 16:21:14 +0300
committerMark Brown <broonie@kernel.org>2023-07-24 01:40:18 +0300
commit9974d5b57697770cba2a99c6fe925d01152cd544 (patch)
treeb89710651ac3a78b3796b8635909626c004446cb /sound/soc/codecs/cs35l56.c
parent8a731fd37f8b33026e545f5ee5cdd7b9a837cbeb (diff)
downloadlinux-9974d5b57697770cba2a99c6fe925d01152cd544.tar.xz
ASoC: cs35l56: Move runtime suspend/resume to shared library
The majority of runtime_suspend and runtime_resume handling doesn't have anything specific to the ASoC driver, so can be shared by the HDA driver. Move this code into the shared library. Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20230721132120.5523-6-rf@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/cs35l56.c')
-rw-r--r--sound/soc/codecs/cs35l56.c120
1 files changed, 4 insertions, 116 deletions
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 5598000187a7..701f1072a609 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -849,131 +849,19 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l56 = {
.suspend_bias_off = 1, /* see cs35l56_system_resume() */
};
-static const struct reg_sequence cs35l56_hibernate_seq[] = {
- /* This must be the last register access */
- REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_HIBERNATE_NOW),
-};
-
-static const struct reg_sequence cs35l56_hibernate_wake_seq[] = {
- REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_WAKEUP),
-};
-
-int cs35l56_runtime_suspend(struct device *dev)
+static int __maybe_unused cs35l56_runtime_suspend_i2c_spi(struct device *dev)
{
struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
- unsigned int val;
- int ret;
-
- if (!cs35l56->base.init_done)
- return 0;
-
- /* Firmware must have entered a power-save state */
- ret = regmap_read_poll_timeout(cs35l56->base.regmap,
- CS35L56_TRANSDUCER_ACTUAL_PS,
- val, (val >= CS35L56_PS3),
- CS35L56_PS3_POLL_US,
- CS35L56_PS3_TIMEOUT_US);
- if (ret)
- dev_warn(cs35l56->base.dev, "PS3 wait failed: %d\n", ret);
-
- /* Clear BOOT_DONE so it can be used to detect a reboot */
- regmap_write(cs35l56->base.regmap, CS35L56_IRQ1_EINT_4, CS35L56_OTP_BOOT_DONE_MASK);
-
- if (!cs35l56->base.can_hibernate) {
- regcache_cache_only(cs35l56->base.regmap, true);
- dev_dbg(dev, "Suspended: no hibernate");
-
- return 0;
- }
- /*
- * Enable auto-hibernate. If it is woken by some other wake source
- * it will automatically return to hibernate.
- */
- cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE);
-
- /*
- * Must enter cache-only first so there can't be any more register
- * accesses other than the controlled hibernate sequence below.
- */
- regcache_cache_only(cs35l56->base.regmap, true);
-
- regmap_multi_reg_write_bypassed(cs35l56->base.regmap,
- cs35l56_hibernate_seq,
- ARRAY_SIZE(cs35l56_hibernate_seq));
-
- dev_dbg(dev, "Suspended: hibernate");
-
- return 0;
+ return cs35l56_runtime_suspend_common(&cs35l56->base);
}
-EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend, SND_SOC_CS35L56_CORE);
static int __maybe_unused cs35l56_runtime_resume_i2c_spi(struct device *dev)
{
struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
- if (!cs35l56->base.init_done)
- return 0;
-
- return cs35l56_runtime_resume_common(cs35l56);
-}
-
-int cs35l56_runtime_resume_common(struct cs35l56_private *cs35l56)
-{
- unsigned int val;
- int ret;
-
- if (!cs35l56->base.can_hibernate)
- goto out_sync;
-
- if (!cs35l56->sdw_peripheral) {
- /*
- * Dummy transaction to trigger I2C/SPI auto-wake. This will NAK on I2C.
- * Must be done before releasing cache-only.
- */
- regmap_multi_reg_write_bypassed(cs35l56->base.regmap,
- cs35l56_hibernate_wake_seq,
- ARRAY_SIZE(cs35l56_hibernate_wake_seq));
-
- usleep_range(CS35L56_CONTROL_PORT_READY_US,
- CS35L56_CONTROL_PORT_READY_US + 400);
- }
-
-out_sync:
- regcache_cache_only(cs35l56->base.regmap, false);
-
- ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);
- if (ret) {
- dev_err(cs35l56->base.dev, "Hibernate wake failed: %d\n", ret);
- goto err;
- }
-
- ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
- if (ret)
- goto err;
-
- /* BOOT_DONE will be 1 if the amp reset */
- regmap_read(cs35l56->base.regmap, CS35L56_IRQ1_EINT_4, &val);
- if (val & CS35L56_OTP_BOOT_DONE_MASK) {
- dev_dbg(cs35l56->base.dev, "Registers reset in suspend\n");
- regcache_mark_dirty(cs35l56->base.regmap);
- }
-
- regcache_sync(cs35l56->base.regmap);
-
- dev_dbg(cs35l56->base.dev, "Resumed");
-
- return 0;
-
-err:
- regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
- CS35L56_MBOX_CMD_HIBERNATE_NOW);
-
- regcache_cache_only(cs35l56->base.regmap, true);
-
- return ret;
+ return cs35l56_runtime_resume_common(&cs35l56->base, false);
}
-EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common, SND_SOC_CS35L56_CORE);
int cs35l56_system_suspend(struct device *dev)
{
@@ -1414,7 +1302,7 @@ void cs35l56_remove(struct cs35l56_private *cs35l56)
EXPORT_SYMBOL_NS_GPL(cs35l56_remove, SND_SOC_CS35L56_CORE);
const struct dev_pm_ops cs35l56_pm_ops_i2c_spi = {
- SET_RUNTIME_PM_OPS(cs35l56_runtime_suspend, cs35l56_runtime_resume_i2c_spi, NULL)
+ SET_RUNTIME_PM_OPS(cs35l56_runtime_suspend_i2c_spi, cs35l56_runtime_resume_i2c_spi, NULL)
SYSTEM_SLEEP_PM_OPS(cs35l56_system_suspend, cs35l56_system_resume)
LATE_SYSTEM_SLEEP_PM_OPS(cs35l56_system_suspend_late, cs35l56_system_resume_early)
NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l56_system_suspend_no_irq, cs35l56_system_resume_no_irq)