ASoC: rockchip: multicodecs: fix the excessive mclk_fs

Usually, the MCLK should be 256 times that of LRCLK,
the excessive mclk (@FS 16KHz and mclk 12.288MHz) may
cause frequency aliasing.

Change-Id: I2665c44dfcdfb51cc4708427782eb68b897c52c4
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
This commit is contained in:
Xing Zheng
2018-05-03 16:42:42 +08:00
committed by Tao Huang
parent 121bd73bed
commit beafee85e0

View File

@@ -30,50 +30,38 @@
#define DRV_NAME "rk-multicodecs"
#define MAX_CODECS 2
#define DEFAULT_MCLK_FS 256
struct multicodecs_data {
unsigned int mclk_fs;
};
static int rk_multicodecs_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int mclk;
struct multicodecs_data *mc_data = snd_soc_card_get_drvdata(rtd->card);
unsigned int mclk;
int ret;
switch (params_rate(params)) {
case 8000:
case 16000:
case 24000:
case 32000:
case 48000:
case 64000:
case 96000:
mclk = 12288000;
break;
case 11025:
case 22050:
case 44100:
case 88200:
mclk = 11289600;
break;
case 176400:
mclk = 11289600 * 2;
break;
case 192000:
mclk = 12288000 * 2;
break;
default:
return -EINVAL;
}
ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
SND_SOC_CLOCK_OUT);
mclk = params_rate(params) * mc_data->mclk_fs;
ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, SND_SOC_CLOCK_IN);
if (ret && ret != -ENOTSUPP) {
dev_err(cpu_dai->dev, "Can't set cpu clock %d\n", ret);
return ret;
pr_err("Set codec_dai sysclk failed: %d\n", ret);
goto out;
}
return 0;
ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, SND_SOC_CLOCK_OUT);
if (ret && ret != -ENOTSUPP) {
pr_err("Set cpu_dai sysclk failed: %d\n", ret);
goto out;
}
out:
return ret;
}
static struct snd_soc_ops rk_ops = {
@@ -101,13 +89,19 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
struct device_node *np = pdev->dev.of_node;
struct snd_soc_dai_link *link = card->dai_link;
struct snd_soc_dai_link_component *codecs;
struct multicodecs_data *mc_data;
struct of_phandle_args args;
struct device_node *node;
u32 val;
int count;
int ret = 0, i = 0, idx = 0;
card->dev = &pdev->dev;
mc_data = devm_kzalloc(&pdev->dev, sizeof(*mc_data), GFP_KERNEL);
if (!mc_data)
return -ENOMEM;
count = of_count_phandle_with_args(np, "rockchip,codec", NULL);
if (count < 0 || count > MAX_CODECS)
return -EINVAL;
@@ -154,6 +148,12 @@ static int rk_multicodecs_probe(struct platform_device *pdev)
link->platform_of_node = link->cpu_of_node;
mc_data->mclk_fs = DEFAULT_MCLK_FS;
if (!of_property_read_u32(np, "rockchip,mclk-fs", &val))
mc_data->mclk_fs = val;
snd_soc_card_set_drvdata(card, mc_data);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret == -EPROBE_DEFER)
return -EPROBE_DEFER;