ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it
authorHans de Goede <hdegoede@redhat.com>
Tue, 8 May 2018 15:35:53 +0000 (17:35 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 11 May 2018 02:23:51 +0000 (11:23 +0900)
When platform_clock_control() first selects PLL1 as sysclk the PLL_CTRL
registers have not been setup yet and we effectively have an invalid clock
configuration until byt_rt5640_aif1_hw_params() gets called.

Add a new byt_rt5640_prepare_and_enable_pll1() helper and use that from
both platform_clock_control() and byt_rt5640_aif1_hw_params() to fix this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/bytcr_rt5640.c

index ad5fcd5a1762ead2fbcae661b47f6856c14e1283..c540dfdf045d3164ff6698d537b422f4bfd6c89d 100644 (file)
@@ -141,6 +141,52 @@ static void log_quirks(struct device *dev)
        }
 }
 
+static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
+                                             int rate)
+{
+       int ret;
+
+       /* Configure the PLL before selecting it */
+       if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
+               /* use bitclock as PLL input */
+               if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
+                   (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
+                       /* 2x16 bit slots on SSP0 */
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                                 RT5640_PLL1_S_BCLK1,
+                                                 rate * 32, rate * 512);
+               } else {
+                       /* 2x15 bit slots on SSP2 */
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                                 RT5640_PLL1_S_BCLK1,
+                                                 rate * 50, rate * 512);
+               }
+       } else {
+               if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                                 RT5640_PLL1_S_MCLK,
+                                                 25000000, rate * 512);
+               } else {
+                       ret = snd_soc_dai_set_pll(codec_dai, 0,
+                                                 RT5640_PLL1_S_MCLK,
+                                                 19200000, rate * 512);
+               }
+       }
+
+       if (ret < 0) {
+               dev_err(codec_dai->codec->dev, "can't set pll: %d\n", ret);
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
+                                    rate * 512, SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               dev_err(codec_dai->codec->dev, "can't set clock %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
 
 #define BYT_CODEC_DAI1 "rt5640-aif1"
 #define BYT_CODEC_DAI2 "rt5640-aif2"
@@ -173,9 +219,7 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
                                return ret;
                        }
                }
-               ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
-                                            48000 * 512,
-                                            SND_SOC_CLOCK_IN);
+               ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
        } else {
                /*
                 * Set codec clock source to internal clock before
@@ -299,55 +343,9 @@ static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
                                        struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
-       int ret;
-
-       ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
-                                    params_rate(params) * 512,
-                                    SND_SOC_CLOCK_IN);
-
-       if (ret < 0) {
-               dev_err(rtd->dev, "can't set codec clock %d\n", ret);
-               return ret;
-       }
+       struct snd_soc_dai *dai = rtd->codec_dai;
 
-       if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
-               /* use bitclock as PLL input */
-               if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
-                       (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
-
-                       /* 2x16 bit slots on SSP0 */
-                       ret = snd_soc_dai_set_pll(codec_dai, 0,
-                                               RT5640_PLL1_S_BCLK1,
-                                               params_rate(params) * 32,
-                                               params_rate(params) * 512);
-               } else {
-                       /* 2x15 bit slots on SSP2 */
-                       ret = snd_soc_dai_set_pll(codec_dai, 0,
-                                               RT5640_PLL1_S_BCLK1,
-                                               params_rate(params) * 50,
-                                               params_rate(params) * 512);
-               }
-       } else {
-               if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
-                       ret = snd_soc_dai_set_pll(codec_dai, 0,
-                                               RT5640_PLL1_S_MCLK,
-                                               25000000,
-                                               params_rate(params) * 512);
-               } else {
-                       ret = snd_soc_dai_set_pll(codec_dai, 0,
-                                               RT5640_PLL1_S_MCLK,
-                                               19200000,
-                                               params_rate(params) * 512);
-               }
-       }
-
-       if (ret < 0) {
-               dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
+       return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
 }
 
 static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)