imx8mm sai3 and adau1761 driver

cancel
Showing results for 
Search instead for 
Did you mean: 

imx8mm sai3 and adau1761 driver

588 Views
tanyid
Contributor I

在调试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模式下。

0 Kudos
8 Replies

422 Views
weidong_sun
NXP TechSupport
NXP TechSupport

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的配置方法:

pastedImage_2.png

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

0 Kudos

422 Views
xiewei_linux
Contributor I

您好!

  请问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

0 Kudos

422 Views
weidong_sun
NXP TechSupport
NXP TechSupport

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

0 Kudos

422 Views
xiewei_linux
Contributor I

Hi Weidong :

   代码中的imx-wm8960.c 不能在imx8mm 上直接用,具体是有啥区别,我看代码里面没有特定soc的配置,

上面用户在imx8mm linux 上本来是要调 adau1761 但是他后面换成wm8960 直接使用起来了

《非常感谢!adau1761 与wm8960差异太大。现在使用WM8960模块,驱动起来,功能正常。非常感谢!

再请教:imx8mm linux怎么设置成横屏?》

谢谢!

0 Kudos

422 Views
weidong_sun
NXP TechSupport
NXP TechSupport

横屏的问题,你再重新开一个ticket。这里讨论的音频,就算是结贴了。

weidong

0 Kudos

422 Views
tanyid
Contributor I

非常感谢!adau1761 与wm8960差异太大。现在使用WM8960模块,驱动起来,功能正常。非常感谢!

再请教:imx8mm linux怎么设置成横屏?

0 Kudos

422 Views
weidong_sun
NXP TechSupport
NXP TechSupport

你可以参考这里修改一下试试,如果不行,你单独提交一个帖子上来。我们一般希望一个帖子讨论一个问题。

LCD横竖屏显示_alifrank的博客-CSDN博客 

伟东

0 Kudos

422 Views
tanyid
Contributor I


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

谢谢你的协助。

0 Kudos