ASoC: arizona: Change DAPM routes for AIF clocks when we change them
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Thu, 5 Jul 2012 16:26:59 +0000 (17:26 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 6 Jul 2012 18:07:00 +0000 (19:07 +0100)
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@ti.com>
sound/soc/codecs/arizona.c

index d0bcca9591112c2b108cf8b593c10f60e1e5f6bd..901b53e1d7bc5161bf0c51233742e94a6b71f467 100644 (file)
@@ -588,12 +588,25 @@ static int arizona_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
+static const char *arizona_dai_clk_str(int clk_id)
+{
+       switch (clk_id) {
+       case ARIZONA_CLK_SYSCLK:
+               return "SYSCLK";
+       case ARIZONA_CLK_ASYNCCLK:
+               return "ASYNCCLK";
+       default:
+               return "Unknown clock";
+       }
+}
+
 static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
                                  int clk_id, unsigned int freq, int dir)
 {
        struct snd_soc_codec *codec = dai->codec;
        struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
        struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
+       struct snd_soc_dapm_route routes[2];
 
        switch (clk_id) {
        case ARIZONA_CLK_SYSCLK:
@@ -603,15 +616,28 @@ static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
                return -EINVAL;
        }
 
-       if (clk_id != dai_priv->clk && dai->active) {
+       if (clk_id == dai_priv->clk)
+               return 0;
+
+       if (dai->active) {
                dev_err(codec->dev, "Can't change clock on active DAI %d\n",
                        dai->id);
                return -EBUSY;
        }
 
-       dai_priv->clk = clk_id;
+       memset(&routes, 0, sizeof(routes));
+       routes[0].sink = dai->driver->capture.stream_name;
+       routes[1].sink = dai->driver->playback.stream_name;
 
-       return 0;
+       routes[0].source = arizona_dai_clk_str(dai_priv->clk);
+       routes[1].source = arizona_dai_clk_str(dai_priv->clk);
+       snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
+
+       routes[0].source = arizona_dai_clk_str(clk_id);
+       routes[1].source = arizona_dai_clk_str(clk_id);
+       snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
+
+       return snd_soc_dapm_sync(&codec->dapm);
 }
 
 const struct snd_soc_dai_ops arizona_dai_ops = {