ASoC: Reduce power consumption for idle DAIs in WM8994
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 14 Jul 2011 08:11:38 +0000 (17:11 +0900)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Sun, 17 Jul 2011 08:51:10 +0000 (17:51 +0900)
If DAIs are idle but their clocks are in use for some reason (eg, as
SYSCLK or for accessory detect) then set the clock dividers to the maximum
to reduce slightly the power consumption of the unclocked circuits.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
sound/soc/codecs/wm8994.c

index c749ef339665e886d66c9b0c70467b1b1b107134..377ae646e20c16dfa596cb470d3d89a3ee8448c4 100644 (file)
@@ -2299,6 +2299,33 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
        return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
 }
 
+static void wm8994_aif_shutdown(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       int rate_reg = 0;
+
+       switch (dai->id) {
+       case 1:
+               rate_reg = WM8994_AIF1_RATE;
+               break;
+       case 2:
+               rate_reg = WM8994_AIF1_RATE;
+               break;
+       default:
+               break;
+       }
+
+       /* If the DAI is idle then configure the divider tree for the
+        * lowest output rate to save a little power if the clock is
+        * still active (eg, because it is system clock).
+        */
+       if (rate_reg && !dai->playback_active && !dai->capture_active)
+               snd_soc_update_bits(codec, rate_reg,
+                                   WM8994_AIF1_SR_MASK |
+                                   WM8994_AIF1CLK_RATE_MASK, 0x9);
+}
+
 static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
@@ -2365,6 +2392,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
        .set_sysclk     = wm8994_set_dai_sysclk,
        .set_fmt        = wm8994_set_dai_fmt,
        .hw_params      = wm8994_hw_params,
+       .shutdown       = wm8994_aif_shutdown,
        .digital_mute   = wm8994_aif_mute,
        .set_pll        = wm8994_set_fll,
        .set_tristate   = wm8994_set_tristate,
@@ -2374,6 +2402,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
        .set_sysclk     = wm8994_set_dai_sysclk,
        .set_fmt        = wm8994_set_dai_fmt,
        .hw_params      = wm8994_hw_params,
+       .shutdown       = wm8994_aif_shutdown,
        .digital_mute   = wm8994_aif_mute,
        .set_pll        = wm8994_set_fll,
        .set_tristate   = wm8994_set_tristate,