|
@@ -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)
|