你好:
我现在需要配置imx8mm的sai3 mclk时钟频率,让他输出i2s_mclk提供给外部audio codec(I2S slave mode),让audio codec的采样率为44.1kHz。而audio codec要想配置44.1kHz的采样率,他需要的mclk时钟只能选择:22579200 Hz、33868800 Hz、24000000 Hz,但是在配置设备树时候,发现他只支持2457600这一种频率(0误差),其他配置都会出现不同程度的误差:
出现误差导致在arecord命令执行时,调用fsl_sai_set_bclk()函数生成bclk时,出现无法分频的频率而异常退出结束:
请问这个问题怎么解决呢?
Hi xcy,
i.mx8mm's clock driver is drivers/clk/imx/clk-imx8mm.c, open the file, you will see audio pll settings, like below:
static const struct imx_int_pll_rate_table imx8mm_audiopll_tbl[] = {
PLL_1443X_RATE(786432000U, 262, 2, 2, 9437),
PLL_1443X_RATE(722534400U, 361, 3, 2, 17511),
};
786432000 / 24576000 = 32
722534400 / 22579200 = 32
So you can change sai3 node like below:
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
assigned-clocks = <&clk IMX8MM_CLK_SAI3_SRC>,
<&clk IMX8MM_CLK_SAI3_DIV>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;
assigned-clock-rates = <0>, <22579200>;
status = "okay";
};
Try it, please!
Have a nice day!
BR,
Weidong
hi Weidong,
非常感谢你的回复,但是我还是不太明白,请教下:
(1)当时我在追drivers/clk/imx/clk-imx8mm.c代码时,也想到修改audio时钟parent,但是在imx8mm手册中发现两者都是650MHz就没有改(722534400 和786432000 这两个频率含义不理解):
(2)为什么786432000 / 24576000 = 32和722534400 / 22579200 = 32,然后在设备树节点中修改assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL2_OUT>;呢?
IMX8MM_AUDIO_PLL1_OUT和IMX8MM_AUDIO_PLL2_OUT宏定义和32看不出联系是什么?
Hi
786432000和722534400,分别是配置PLL1和PLL2的输出频率,一个是24.576M的整数倍,一个是22.5792M的整数倍,那么当你需要48K的时候,用PLL1,44.1K的时候,用PLL2。
如果不是你时钟的整数倍,你怎么能去做整除分频呢?
伟东
你好!
我遇到和上面同样的问题,想要配置imx8qm的sai1 mclk时钟频率,让他输出i2s_mclk提供给外部audio codec(I2S slave mode),让audio codec的采样率为44.1kHz。
static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
{
struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
unsigned char offset = sai->soc->reg_offset;
unsigned long clk_rate;
unsigned int reg = 0;
u32 ratio, savesub = freq, saveratio = 0, savediv = 0;
u32 id;
int ret = 0;
/* Don't apply to slave mode */
if (sai->slave_mode[tx])
return 0;
for (id = 0; id < FSL_SAI_MCLK_MAX; id++) {
clk_rate = clk_get_rate(sai->mclk_clk[id]);
if (!clk_rate)
continue;
ratio = clk_rate / freq;
ret = clk_rate - ratio * freq;
dev_err(dai->dev, "clk_rate: %ld freq: %d ret: %d\n",clk_rate,freq,ret);//无论播放什么格式的音频文件这里clk_rate=49152000
......
if (saveratio == 0) {
dev_err(dai->dev, "failed to derive required %cx rate: %d\n",//
tx ? 'T' : 'R', freq);
return -EINVAL;
....
}
设备树中sai1的配置
&sai1 {
#sound-dai-cells = <0>;
assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
<&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
<&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
<&sai1_lpcg 0>; /* FIXME: should be sai1, original code is 0 */
assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1>;
status = "okay";
};
我这个要怎么修改?machine驱动使用的是simple-card.c.
问题出在哪里?
Hi,
I have the same problem could you share you soluion please?
Cheers.