mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user