ASoC: wm8962: Clear master mode when enter runtime suspend
authorShengjiu Wang <shengjiu.wang@nxp.com>
Wed, 30 Jul 2025 06:40:54 +0000 (14:40 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 30 Jul 2025 10:45:46 +0000 (11:45 +0100)
The enabled master mode causes power consumption to increase in idle
state. Clear the MSTR bit in runtime supsend and recover it in runtime
resume to reduce power.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20250730064054.3006409-1-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/wm8962.c

index d69aa8b15629a7e25904459f5a84876405bde0ce..27b4326429a0e9fb4cad46831cedcdd4dc2831ef 100644 (file)
@@ -82,6 +82,7 @@ struct wm8962_priv {
 #endif
 
        int irq;
+       bool master_flag;
 };
 
 /* We can't use the same notifier block for more than one supply and
@@ -2715,6 +2716,7 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
        struct snd_soc_component *component = dai->component;
+       struct wm8962_priv *wm8962 = snd_soc_component_get_drvdata(component);
        int aif0 = 0;
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -2761,9 +2763,11 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
                return -EINVAL;
        }
 
+       wm8962->master_flag = false;
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBP_CFP:
                aif0 |= WM8962_MSTR;
+               wm8962->master_flag = true;
                break;
        case SND_SOC_DAIFMT_CBC_CFC:
                break;
@@ -3903,6 +3907,9 @@ static int wm8962_runtime_resume(struct device *dev)
                           WM8962_BIAS_ENA | WM8962_VMID_SEL_MASK,
                           WM8962_BIAS_ENA | 0x180);
 
+       if (wm8962->master_flag)
+               regmap_update_bits(wm8962->regmap, WM8962_AUDIO_INTERFACE_0,
+                                  WM8962_MSTR, WM8962_MSTR);
        msleep(5);
 
        return 0;
@@ -3916,6 +3923,10 @@ static int wm8962_runtime_suspend(struct device *dev)
 {
        struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
 
+       if (wm8962->master_flag)
+               regmap_update_bits(wm8962->regmap, WM8962_AUDIO_INTERFACE_0,
+                                  WM8962_MSTR, 0);
+
        regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1,
                           WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);