summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorXingyu Wu <xingyu.wu@starfivetech.com>2023-02-08 10:52:13 +0300
committerXingyu Wu <xingyu.wu@starfivetech.com>2023-02-10 06:06:05 +0300
commit086b4bc6d7ca417596ac6d52e66c31f778a4ddd7 (patch)
treee14de20a04b06904436519fa8f80a7a988effd9c /sound
parent7447339118f624bc7ef7d8fdb6ae7903296b0fca (diff)
downloadlinux-086b4bc6d7ca417596ac6d52e66c31f778a4ddd7.tar.xz
sound: codecs: wm8960: Add context saving and restoring when hibernation
Add context saving and restoring when suspend and resume. Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
Diffstat (limited to 'sound')
-rw-r--r--[-rwxr-xr-x]sound/soc/codecs/wm8960.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 969ae8d8d504..7e7c00925844 100755..100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -139,6 +139,8 @@ struct wm8960_priv {
struct dentry *debug_file;
bool first_capture;
bool is_capture;
+
+ u16 wm8960_reg_context[WM8960_REG_MAX];
};
#define wm8960_reset(c) regmap_write(c, WM8960_RESET, 0)
@@ -1516,6 +1518,49 @@ static int wm8960_probe(struct snd_soc_component *component)
return 0;
}
+#ifdef CONFIG_PM
+static int wm8960_suspend(struct snd_soc_component *component)
+{
+ struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
+ int i;
+
+ /* save registers context */
+ for (i = 0; i < WM8960_REG_MAX; i++) {
+ /* except Power and Reserved registers */
+ if (i == WM8960_POWER1 || i == WM8960_POWER2 || i == WM8960_POWER3 ||
+ i == 0xc || i == 0xd || i == 0xe || i == WM8960_RESET ||
+ i == 0x1e || i == 0x1f || i == 0x23 || i == 0x24 || i == 0x32)
+ continue;
+ else
+ wm8960->wm8960_reg_context[i] = snd_soc_component_read(component, i);
+ }
+
+ return 0;
+}
+
+static int wm8960_resume(struct snd_soc_component *component)
+{
+ struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
+ int i;
+
+ /* restore registers context */
+ for (i = 0; i < WM8960_REG_MAX; i++) {
+ /* except Power and Reserved registers */
+ if (i == WM8960_POWER1 || i == WM8960_POWER2 || i == WM8960_POWER3 ||
+ i == 0xc || i == 0xd || i == 0xe || i == WM8960_RESET ||
+ i == 0x1e || i == 0x1f || i == 0x23 || i == 0x24 || i == 0x32)
+ continue;
+ else
+ snd_soc_component_update_bits(component, i, 0x1ff, wm8960->wm8960_reg_context[i]);
+ }
+
+ return 0;
+}
+#else
+#define wm8960_suspend NULL
+#define wm8960_resume NULL
+#endif
+
static const struct snd_soc_component_driver soc_component_dev_wm8960 = {
.probe = wm8960_probe,
.set_bias_level = wm8960_set_bias_level,
@@ -1524,6 +1569,8 @@ static const struct snd_soc_component_driver soc_component_dev_wm8960 = {
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
+ .suspend = wm8960_suspend,
+ .resume = wm8960_resume,
};
static const struct regmap_config wm8960_regmap = {