在调试adau1761时,驱动正常加载上去,但gplay a.wav时,总是报
[ 43.439222] fsl-sai 30030000.sai: failed to derive required Rx rate: 2822400
[ 43.446285] fsl-sai 30030000.sai: ASoC: can't set 30030000.sai hw params: -22
错误 提示,跟进源码中,发现在函数:
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;
fsl_sai_check_ver(dai);
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;
printk("fsl_sai_set_bclk ret:%d \n",ret);//1996800
/*
* Drop the source that can not be
* divided into the required rate.
*/
if (ret != 0 && clk_rate / ret < 1000) //
continue;
printk("fsl_sai_set_bclk line:%d \n",__LINE__);
if ((ratio % 2 == 0 && ratio >= 2 && ratio <= 512) ||(ratio == 1 && sai->verid.id >= FSL_SAI_VERID_0301))
{
printk("fsl_sai_set_bclk line:%d \n",__LINE__);
if (ret < savesub) {
printk("fsl_sai_set_bclk line:%d \n",__LINE__);
saveratio = ratio;
sai->mclk_id[tx] = id;
savesub = ret;
}
printk("fsl_sai_set_bclk line:%d ret %d\n",__LINE__,ret);
if (ret == 0)
break;
}
}
if (saveratio == 0) {
printk("ratio %d sai->verid.id %d\n",ratio,sai->verid.id);//8 0
dev_err(dai->dev, "failed to derive required %cx rate: %d\n",tx ? 'T' : 'R', freq);
return -EINVAL;
}
中
if (ret != 0 && clk_rate / ret < 1000) //
continue;
,这个判断条件值引用的sai3的配置
&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_PLL1_OUT>;
assigned-clock-rates = <0>, <49152000>;
status = "okay";
};
按这些条件计算,根本不会大于1000,配成最大值 得到的结果也只有:41.967213。
所以,这个是sai3配置是否有错?这个问题要如何解决?
我的需求是sai配成master模式,收发时钟都要提供,adau1761工作在slave模式下。
Hi Tan,
有这样几个建议,供你参考:
1. 关于硬件ADAU1761
我看了一下它的datasheet,它的用法与WM8960外部接口非常相似,首先要保证您的硬件连接是正确的。它有I2C接口,与I.MX8MM-EVK的WM8524不太一样。
2. 关于sai3节点配置
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
assigned-clock-rates = <24576000>;
status = "okay";
};
这里的24.576MHz是给audio codec的工作时钟,这个时钟对您来说,不需要修改。ADAU1761的PLL输入clock是8-27MHz,您用49.152MHz是很容易出错的: 内部的PLL是无法使用的。
这是它datasheet中,给出对24.576MHz的配置方法:
3. 您可以参考的代码
对于Linux ALSA SoC driver,需要3个部分才能把声卡驱动起来:
1. platform driver: fsl_sai.c
2. codec driver : adau17x1.c (linux 系统提供了这个driver)
另外的DSP firmware,我看到ADI提供了方法如何加载带目标板上,供linux driver调用它:
SigmaDSP Firmware Utility for Linux [Analog Devices Wiki]
3. Machine driver :
这个需要您自己动手写,可以参考的代码是imx-wm8960.c,这个driver,就是基于 sai I2S的,所以您的驱动架构需要和它差不多。
4. 关于CPU端做Master的配置,是这样的:
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
如果您这样配置:
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS;
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
那么CPU端就是slave了。
5. 关于SAI3引脚复用
我们EVK给出了SAI这样的复用:
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6
MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
数据线只有TXD,您还需要再加上RXD接收线:
MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6
这样就完整了。
上面的建议,对于您移植 adau1761来说,够用了!
Have a nice day!
B.R,
Weidong
你好我准备在imx8mp芯片上使用TLV320AIC3110音频解码芯片。当前环境是没有TLV320AIC3110芯片的
数据手册:
设备树配置:
看了设备树
https://www.kernel.org/doc/Documentation/devicetree/bindings/sound/simple-card.txt
我又尝试了在wm8960上的播放。
我先前的理解可能有错误:
1. 下面函数中的sai->mclk_clk[]中的值应该与codec无关。
2.是与下面的函数中的rate有关? struct snd_pcm_hw_params *params 请问这个参数是与谁有关呢?
(因为刚接触还不了解alsa,所以问题可能问的不是很清楚。我自己正在追寻params的源头,但是如果能直接告诉我的,那就更好了)
您好!
请问imx8mm sai3上接wm8960 dts怎么配置?我的软件版本是imx-p9.0.0_2.3.0 linux是4.14.98
我目前的配置如下:
wm8960: wm8960@1a {
compatible = "wlf,wm8960";
reg = <0x1a>;
clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
clock-names = "mclk";
wlf,shared-lrclk;
status = "okay";
};
sound-wm8960 {
compatible = "fsl,imx7d-evk-wm8960",
"fsl,imx-audio-wm8960";
model = "wm8960-audio";
cpu-dai = <&sai3>;
audio-codec = <&wm8960>;
//codec-rpmsg;
codec-master;
/*
* hp-det = <hp-det-pin hp-det-polarity>;
* hp-det-pin: JD1 JD2 or JD3
* hp-det-polarity = 0: hp detect high for headphone
* hp-det-polarity = 1: hp detect high for speaker
*/
//hp-det = <2 0>;
//hp-det-gpios = <&gpio1 13 0>;
//mic-det-gpios = <&gpio1 13 0>;
audio-routing =
"Headphone Jack", "HP_L",
"Headphone Jack", "HP_R",
"Ext Spk", "SPK_LP",
"Ext Spk", "SPK_LN",
"Ext Spk", "SPK_RP",
"Ext Spk", "SPK_RN",
"LINPUT2", "Mic Jack",
"LINPUT3", "Mic Jack",
"RINPUT1", "Main MIC",
"RINPUT2", "Main MIC",
"Mic Jack", "MICB",
"Main MIC", "MICB";
status = "okay";
};
pinctrl_sai3: sai3grp {
fsl,pins = <
MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6
MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6
MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6
MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6
MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6
>;
};
&sai3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai3>;
assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
assigned-clock-rates = <24576000>; //12288000 24576000 12289600
fsl,sai-asynchronous;
status = "okay";
};
以上配置,
tinyplay 播放wav文件 始终没有输出,并且有提示播放采样率错误
[ 891.073461] wm8960_set_dai_sysclk 1277
[ 891.077774] wm8960_hw_params 802
[ 891.081543] wm8960_hw_params 830 wm8960->lrclk=16000
[ 891.087233] wm8960_configure_clocking 738 wm8960->freq_in=24576000
[ 891.093883] wm8960_configure_sysclk 640 bclk=512000 lrclk=16000
Playing sample: 2 ch, 16000 hz, 16 bit
[ 891.102622] wm8960_set_bias_level_out3 888
[ 891.110270] wm8960_configure_clocking 738 wm8960->freq_in=24576000
[ 891.116979] [wm8960_configure_sysclk 640 bclk=512000 lrclk=16000
[ 891.124857] wm8960_mute 868 mute = 0
Error playing sample
[ 901.221110] wm8960_mute 868 mute = 1
evk_8mm:/storage/emulated/0/Download # [ 905.696469] healthd: battery l=85 v=3 t=35.0 h=2 st=2 c=400 fc=4000000 cc=32 chg=a
[ 905.832237] healthd: battery l=85 v=3 t=35.0 h=2 st=2 c=400 fc=4000000 cc=32 chg=a
[ 906.341049] wm8960_set_bias_level_out3 888
[ 906.345724] wm8960_set_bias_level_out3 914
[ 906.352038] wm8960_set_bias_level_out3 929
Hi wei xie,
WM8960在我们的I.MX6UL的开发板上有使用,linux BSP也支持它。
---platform: fsl_sai.c
---codec: wm8960.c
--Machine : imx-wm8960.c
这里的 imx-wm8960.c是for i.MX6UL的Machine driver,对您使用i.MX8MM SOC来说,你需要根据imx-wm8960.c再写一个Machine driver,而不能直接使用。例如,您可以起一个新的名字imx8mm-wm8960.c,做为您的Machine driver.
而device tree的配置方法,您可以参考imx6ul-14x14-evk.dts中的配置,两个节点:
sound和I2C 节点。同时注意node中member的含义,比如:gpr = <&gpr 4 0x100000 0x100000>;这个您就不需要,这是配置I.MX6UL中MCLK为24MHz输出,做为WM8960时钟的。
对您的I.MX8MM来说,codec的工作时钟配置的是24.576MHz,而且,i.mx8mm是master,所以,你节点中的codec_master应该去掉。
另外,你在调试audio的时候,play的时候,要注意的是,sample rate是在machine driver中硬件初始化时,从音频流中获取的,也就是说它来时您要播放的文件,所以,你要跟踪一下。 这一点参考imx-wm8960.c就可以,只是要注意的是master和slave的配置方法是不一样的。
Hope above information is helpful for you.
Have a nice day!
B.R,
Weidong
Hi Weidong :
代码中的imx-wm8960.c 不能在imx8mm 上直接用,具体是有啥区别,我看代码里面没有特定soc的配置,
上面用户在imx8mm linux 上本来是要调 adau1761 但是他后面换成wm8960 直接使用起来了
《非常感谢!adau1761 与wm8960差异太大。现在使用WM8960模块,驱动起来,功能正常。非常感谢!
再请教:imx8mm linux怎么设置成横屏?》
谢谢!
横屏的问题,你再重新开一个ticket。这里讨论的音频,就算是结贴了。
weidong
1.这个参考我试过,不能解决。
2.请移步这个问题,里面igorpadykov有提示patch的问题,目前还没有得到回复。请从内部帮我问一问。
https://community.nxp.com/thread/521316
How To Rotate 90 Degree Video For Display In I.MX8X
Hi Bright
rotation patch was sent via mail.
Best regards
igor
3.我单独的开了一 个贴子,但没有解答。请支持。
https://community.nxp.com/thread/534933
谢谢你的协助。