diff mbox series

[6/8] ASoC: wm_adsp: Add support for "toggle" preloaders

Message ID 20220105113026.18955-7-ckeepax@opensource.cirrus.com (mailing list archive)
State Superseded
Commit ba235634b138cd9d012dbe983e7920481211e132
Headers show
Series Add low power hibernation support to cs35l41 | expand

Commit Message

Charles Keepax Jan. 5, 2022, 11:30 a.m. UTC
In the case a device can support retaining the firmware memory across
low power states it is useful for the preloader widget to only power up
whilst actually loading/unloading the core, as opposed to the normal
operation where the widget is powered for the entire time a firmware is
preloaded onto the core. Add support for this mode and a flag to enable
it.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
 sound/soc/codecs/wm_adsp.c | 14 +++++++++++---
 sound/soc/codecs/wm_adsp.h |  8 ++++++++
 2 files changed, 19 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index c3112bf238666..f3672e3d1703e 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -896,11 +896,12 @@  int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
 	struct wm_adsp *dsp = &dsps[mc->shift - 1];
 	char preload[32];
 
-	snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
+	if (dsp->preloaded == ucontrol->value.integer.value[0])
+		return 0;
 
-	dsp->preloaded = ucontrol->value.integer.value[0];
+	snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->cs_dsp.name);
 
-	if (ucontrol->value.integer.value[0])
+	if (ucontrol->value.integer.value[0] || dsp->toggle_preload)
 		snd_soc_component_force_enable_pin(component, preload);
 	else
 		snd_soc_component_disable_pin(component, preload);
@@ -909,6 +910,13 @@  int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
 
 	flush_work(&dsp->boot_work);
 
+	dsp->preloaded = ucontrol->value.integer.value[0];
+
+	if (dsp->toggle_preload) {
+		snd_soc_component_disable_pin(component, preload);
+		snd_soc_dapm_sync(dapm);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 0e2f113bd3422..7f4fabbc6ad3a 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -41,6 +41,14 @@  struct wm_adsp {
 
 	struct list_head compr_list;
 	struct list_head buffer_list;
+
+	/*
+	 * Flag indicating the preloader widget only needs power toggled
+	 * on state change rather than held on for the duration of the
+	 * preload, useful for devices that can retain firmware memory
+	 * across power down.
+	 */
+	bool toggle_preload;
 };
 
 #define WM_ADSP1(wname, num) \