summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.cirrus.com>2022-01-05 11:30:24 +0000
committerMark Brown <broonie@kernel.org>2022-01-05 13:53:54 +0000
commitba235634b138cd9d012dbe983e7920481211e132 (patch)
tree46857a9ab3d2fec77916d70fe3f5685161e6ee30
parent7aa1cc1091e0a424e9e7711ca381ebe98b6865bc (diff)
downloadlinux-stable-ba235634b138cd9d012dbe983e7920481211e132.tar.gz
linux-stable-ba235634b138cd9d012dbe983e7920481211e132.tar.bz2
linux-stable-ba235634b138cd9d012dbe983e7920481211e132.zip
ASoC: wm_adsp: Add support for "toggle" preloaders
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> Link: https://lore.kernel.org/r/20220105113026.18955-7-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/wm_adsp.c14
-rw-r--r--sound/soc/codecs/wm_adsp.h8
2 files changed, 19 insertions, 3 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index c3112bf23866..f3672e3d1703 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 0e2f113bd342..7f4fabbc6ad3 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) \