OSDN Git Service

ASoC: arizona: Only allow input volume updates when inputs are enabled
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 15 Feb 2013 17:27:22 +0000 (17:27 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Mon, 4 Mar 2013 03:01:01 +0000 (11:01 +0800)
Since we are automatically managing the mutes we may as well also manage
the volume update bits, disabling volume updates while none of the inputs
are active. Since we are doing this we may as well allow the volumes to
ramp together so only enable volume updates once at the end of power up.

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

index 6837863..debd184 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/delay.h>
 #include <linux/gcd.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
@@ -332,9 +333,27 @@ const struct soc_enum arizona_ng_hold =
                        4, arizona_ng_hold_text);
 EXPORT_SYMBOL_GPL(arizona_ng_hold);
 
+static void arizona_in_set_vu(struct snd_soc_codec *codec, int ena)
+{
+       struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+       unsigned int val;
+       int i;
+
+       if (ena)
+               val = ARIZONA_IN_VU;
+       else
+               val = 0;
+
+       for (i = 0; i < priv->num_inputs; i++)
+               snd_soc_update_bits(codec,
+                                   ARIZONA_ADC_DIGITAL_VOLUME_1L + (i * 4),
+                                   ARIZONA_IN_VU, val);
+}
+
 int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
                  int event)
 {
+       struct arizona_priv *priv = snd_soc_codec_get_drvdata(w->codec);
        unsigned int reg;
 
        if (w->shift % 2)
@@ -343,13 +362,29 @@ int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
                reg = ARIZONA_ADC_DIGITAL_VOLUME_1R + ((w->shift / 2) * 8);
 
        switch (event) {
+       case SND_SOC_DAPM_PRE_PMU:
+               priv->in_pending++;
+               break;
        case SND_SOC_DAPM_POST_PMU:
                snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE, 0);
+
+               /* If this is the last input pending then allow VU */
+               priv->in_pending--;
+               if (priv->in_pending == 0) {
+                       msleep(1);
+                       arizona_in_set_vu(w->codec, 1);
+               }
                break;
        case SND_SOC_DAPM_PRE_PMD:
-               snd_soc_update_bits(w->codec, reg, ARIZONA_IN1L_MUTE,
-                                   ARIZONA_IN1L_MUTE);
+               snd_soc_update_bits(w->codec, reg,
+                                   ARIZONA_IN1L_MUTE | ARIZONA_IN_VU,
+                                   ARIZONA_IN1L_MUTE | ARIZONA_IN_VU);
                break;
+       case SND_SOC_DAPM_POST_PMD:
+               /* Disable volume updates if no inputs are enabled */
+               reg = snd_soc_read(w->codec, ARIZONA_INPUT_ENABLES);
+               if (reg == 0)
+                       arizona_in_set_vu(w->codec, 0);
        }
 
        return 0;
index 3f84943..d592adc 100644 (file)
@@ -65,6 +65,9 @@ struct arizona_priv {
        int sysclk;
        int asyncclk;
        struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
+
+       int num_inputs;
+       unsigned int in_pending;
 };
 
 #define ARIZONA_NUM_MIXER_INPUTS 99
index 5515d85..44d4c69 100644 (file)
@@ -973,22 +973,28 @@ SND_SOC_DAPM_INPUT("IN3R"),
 
 SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 
 SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
                    ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
@@ -1599,13 +1605,6 @@ static int wm5102_codec_remove(struct snd_soc_codec *codec)
 #define WM5102_DIG_VU 0x0200
 
 static unsigned int wm5102_digital_vu[] = {
-       ARIZONA_ADC_DIGITAL_VOLUME_1L,
-       ARIZONA_ADC_DIGITAL_VOLUME_1R,
-       ARIZONA_ADC_DIGITAL_VOLUME_2L,
-       ARIZONA_ADC_DIGITAL_VOLUME_2R,
-       ARIZONA_ADC_DIGITAL_VOLUME_3L,
-       ARIZONA_ADC_DIGITAL_VOLUME_3R,
-
        ARIZONA_DAC_DIGITAL_VOLUME_1L,
        ARIZONA_DAC_DIGITAL_VOLUME_1R,
        ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -1648,6 +1647,7 @@ static int wm5102_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, wm5102);
 
        wm5102->core.arizona = arizona;
+       wm5102->core.num_inputs = 6;
 
        wm5102->core.adsp[0].part = "wm5102";
        wm5102->core.adsp[0].num = 1;
index 2d9b55f..a64d3b8 100644 (file)
@@ -416,28 +416,36 @@ SND_SOC_DAPM_INPUT("IN4R"),
 
 SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT,
                   0, NULL, 0, arizona_in_ev,
-                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+                  SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD |
+                  SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
 
 SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
                    ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
@@ -993,15 +1001,6 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec)
 #define WM5110_DIG_VU 0x0200
 
 static unsigned int wm5110_digital_vu[] = {
-       ARIZONA_ADC_DIGITAL_VOLUME_1L,
-       ARIZONA_ADC_DIGITAL_VOLUME_1R,
-       ARIZONA_ADC_DIGITAL_VOLUME_2L,
-       ARIZONA_ADC_DIGITAL_VOLUME_2R,
-       ARIZONA_ADC_DIGITAL_VOLUME_3L,
-       ARIZONA_ADC_DIGITAL_VOLUME_3R,
-       ARIZONA_ADC_DIGITAL_VOLUME_4L,
-       ARIZONA_ADC_DIGITAL_VOLUME_4R,
-
        ARIZONA_DAC_DIGITAL_VOLUME_1L,
        ARIZONA_DAC_DIGITAL_VOLUME_1R,
        ARIZONA_DAC_DIGITAL_VOLUME_2L,
@@ -1046,6 +1045,7 @@ static int wm5110_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, wm5110);
 
        wm5110->core.arizona = arizona;
+       wm5110->core.num_inputs = 8;
 
        for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++)
                wm5110->fll[i].vco_mult = 3;