diff options
author | Xingyu Wu <xingyu.wu@starfivetech.com> | 2023-02-08 10:52:13 +0300 |
---|---|---|
committer | Xingyu Wu <xingyu.wu@starfivetech.com> | 2023-02-10 06:06:05 +0300 |
commit | 086b4bc6d7ca417596ac6d52e66c31f778a4ddd7 (patch) | |
tree | e14de20a04b06904436519fa8f80a7a988effd9c /sound | |
parent | 7447339118f624bc7ef7d8fdb6ae7903296b0fca (diff) | |
download | linux-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.c | 47 |
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 = { |