aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/codecs/lpass-rx-macro.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/lpass-rx-macro.c')
-rw-r--r--sound/soc/codecs/lpass-rx-macro.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
index aec5127260fd..1a97ce40f18d 100644
--- a/sound/soc/codecs/lpass-rx-macro.c
+++ b/sound/soc/codecs/lpass-rx-macro.c
@@ -5,6 +5,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/clk.h>
#include <sound/soc.h>
#include <sound/pcm.h>
@@ -2688,8 +2689,8 @@ static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
int reg, b2_reg;
/* Address does not automatically update if reading */
- reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx;
- b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
+ reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx;
+ b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
snd_soc_component_write(component, reg,
((band_idx * BAND_MAX + coeff_idx) *
@@ -2718,7 +2719,7 @@ static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
static void set_iir_band_coeff(struct snd_soc_component *component,
int iir_idx, int band_idx, uint32_t value)
{
- int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
+ int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
snd_soc_component_write(component, reg, (value & 0xFF));
snd_soc_component_write(component, reg, (value >> 8) & 0xFF);
@@ -2739,7 +2740,7 @@ static int rx_macro_put_iir_band_audio_mixer(
int iir_idx = ctl->iir_idx;
int band_idx = ctl->band_idx;
u32 coeff[BAND_MAX];
- int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx;
+ int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx;
memcpy(&coeff[0], ucontrol->value.bytes.data, params->max);
@@ -3556,6 +3557,12 @@ static int rx_macro_probe(struct platform_device *pdev)
if (ret)
return ret;
+ pm_runtime_set_autosuspend_delay(dev, 3000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
rx_macro_register_mclk_output(rx);
ret = devm_snd_soc_register_component(dev, &rx_macro_component_drv,
@@ -3583,11 +3590,41 @@ static const struct of_device_id rx_macro_dt_match[] = {
};
MODULE_DEVICE_TABLE(of, rx_macro_dt_match);
+static int __maybe_unused rx_macro_runtime_suspend(struct device *dev)
+{
+ struct rx_macro *rx = dev_get_drvdata(dev);
+ regcache_cache_only(rx->regmap, true);
+ regcache_mark_dirty(rx->regmap);
+
+ clk_disable_unprepare(rx->clks[2].clk);
+ clk_disable_unprepare(rx->clks[3].clk);
+ clk_disable_unprepare(rx->clks[4].clk);
+
+ return 0;
+}
+
+static int __maybe_unused rx_macro_runtime_resume(struct device *dev)
+{
+ struct rx_macro *rx = dev_get_drvdata(dev);
+
+ clk_prepare_enable(rx->clks[2].clk);
+ clk_prepare_enable(rx->clks[3].clk);
+ clk_prepare_enable(rx->clks[4].clk);
+ regcache_cache_only(rx->regmap, false);
+ regcache_sync(rx->regmap);
+ return 0;
+}
+
+static const struct dev_pm_ops rx_macro_pm_ops = {
+ SET_RUNTIME_PM_OPS(rx_macro_runtime_suspend, rx_macro_runtime_resume, NULL)
+};
+
static struct platform_driver rx_macro_driver = {
.driver = {
.name = "rx_macro",
.of_match_table = rx_macro_dt_match,
.suppress_bind_attrs = true,
+ .pm = &rx_macro_pm_ops,
},
.probe = rx_macro_probe,
.remove = rx_macro_remove,