Unverified Commit bcd9a325 authored by Hans de Goede's avatar Hans de Goede Committed by Mark Brown
Browse files

ASoC: Intel: bytcr_rt5640: Configure PLL1 before using it



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: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b16188a2
Loading
Loading
Loading
Loading
+49 −51
Original line number Diff line number Diff line
@@ -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);
	struct snd_soc_dai *dai = rtd->codec_dai;

	if (ret < 0) {
		dev_err(rtd->dev, "can't set codec clock %d\n", ret);
		return ret;
	}

	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)