在imx8mm上设置audio codec为从设备

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

在imx8mm上设置audio codec为从设备

5,745 Views
xcyhere
Contributor I

你好:

imx8mm声卡配置为从设备,imx8mm为主设备,需要怎么修改,没有什么思路?

0 Kudos
8 Replies

4,710 Views
xcyhere
Contributor I

你好:

      我的程序现在能够正常录音了,但是原因我没有找到。我只再原来基础上加入imx_wm8988_late_probe函数

      struct snd_soc_card snd_soc_card_imx_wm8988 = {

            .late_probe = imx_wm8988_late_probe,

      }

      pastedImage_34.png在命令行执行:arecord -Dhw:0,0 -f S16_LE -r 44100  -d 10 -t wav 111.wav :

(1)我在命令行采集指定的采样率是44100Hz,但是arecord执行报警告:warning:rate is not  accurate (requested = 44100Hz, got = 48000Hz) please, try the plug plugin

(2)在machine代码(sound/soc/fsl/imx-wm8988.c)中的imx_hifi_hw_params函数中打印采样率强制为48KHz了:

pastedImage_76.png

pastedImage_77.png

pastedImage_78.png

现在只是能够正常录音和放音了,但是还没找到原因,希望能够找到具体原因,避免接下来再出问题。

0 Kudos

4,710 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi,

   这个late probe 函数很重要,它是告诉codec 24.576MHz时钟输入给它的意思。所以,原来的问题就解决了。

另外,24.576MHz的时钟,不是44.1K的整数倍,是48K的整数倍,所以你用44.1k采样播放的时候,会有警告。

不会有其他隐患,不必担心。

This late probe function is very important. It tells codec what the 24.576 MHz clock input means to it. So the original problem was solved.
In addition, the 24.576 MHz clock is not an integral multiple of 44.1K, but an integral multiple of 48K, so when you play with 44.1k sampling, there will be a warning.

Have a nice day!

Weidong

0 Kudos

4,710 Views
xcyhere
Contributor I

你好:

      那有一点我不明白,既然在late_probe函数中是为了告诉codec输入给他的MCLK时钟是24.576MHz,那么为什么从设备树读取到的codec_clk = 22469486 Hz?这就导致程序执行到snd_soc_dai_set_sysclk就异常退出了?

pastedImage_6.png

pastedImage_7.png

      在late_probe函数中获取到imx_wm8524_probe函数中从设备树中得到的时钟(22469486Hz,不是24.576MHz):

pastedImage_1.png

      在imx_wm8524_probe函数中得到的struct clk句柄确是wm8524的I2S的时钟:

pastedImage_3.png

pastedImage_5.png

0 Kudos

4,710 Views
xcyhere
Contributor I

你好:

      我还是没太明白,我现在其实是需要设置imx8mm作为I2S的主设备,codec为从设备,实现全双工通信,但是参考的ak5558驱动是只设为单工(录音)。然后我将驱动代码修改的地方(imx_hifi_hw_params函数:函数):

      (1)设置:cpu_dai和codec_dai都是SND_SOC_DAIFMT_CBS_CFS

      (2)配置sysclk:ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1, pll_out,SND_SOC_CLOCK_OUT)

               FSL_SAI_CLK_MAST0、FSL_SAI_CLK_MAST1、FSL_SAI_CLK_MAST2、FSL_SAI_CLK_MAST3,该使用哪个我也不知道

      最终执行代码出现错误,问题还没有定位到。

0 Kudos

4,710 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi

>>执行到clk_set_rate()返回错误编码是-EBUSY

It seems that SAI_CLK_ROOT had been enabled before you set the 24576000 clock, so you should check who enabled it.

这个错误,可能是SAI_CLK_ROOT 被enable了,所有,你设置不成功。你最好检查一下,谁把它打开的。 我和design team写audio driver的同事确认了你的这个问题。 用法没啥问题。

另外,我看了你又发了一个新的case,你要注意的是MCLK,仅仅是I.MX8MM给出来的一个时钟,用于CODEC工作而已,它和I2S是master/slave,没有任何关系。有关系的,只有Bitclock / LRCLK由谁来提供的问题。

Have a nice day!

BR,

Weidong

0 Kudos

4,710 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hello xcy here,

Open imx-ak5558.c file(sound/soc/fsl), you will find the machine driver supports SAI master mode.

static int imx_aif_hw_params(struct snd_pcm_substream *substream,
                struct snd_pcm_hw_params *params)
{

......

    if (data->tdm_mode) /* tdm mode */
        fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
            SND_SOC_DAIFMT_CBS_CFS;
    else /* Normal mode */
        fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
            SND_SOC_DAIFMT_CBS_CFS;  /* setting format for Master & I2S mode  */

....

    mclk_freq = ak5558_get_mclk_rate(substream, params);
    ret = snd_soc_dai_set_sysclk(cpu_dai, FSL_SAI_CLK_MAST1, mclk_freq,
                     SND_SOC_CLOCK_OUT); /* Setting clock for Master */

......

}

So you can refer to above source code for your application.

Have a nice day!

BR,

Weidong

0 Kudos

4,710 Views
xcyhere
Contributor I

你好: 我参考你给的方案修改了: 在snd_soc_dai_set_sysclk() -> fsl_sai_set_dai_sysclk() -> fsl_sai_set_mclk_rate() -> clk_set_rate(),执行到clk_set_rate()返回错误编码是-EBUSY,我已经确认MCLK时钟是正确的(24576000),请问这个有什么思路吗?

0 Kudos

4,710 Views
weidong_sun
NXP TechSupport
NXP TechSupport

Hi xcy,

The idea is this: This means that SAI_CLK_ROOT is not an integer multiple of 24.576 MHz, and there are two directions you can try to adjust. One is where FSL_SAI_CLK_MAST1 is defined in fsl_sai.h, and FSL_SAI_CLK_MAST2, etc. The other is to look at the SAI clock defined in device tree and you can calculate whether it is an integer multiple of 24.576 MHz. Because not all sampling frequencies can be supported.

思路是这样的:这个意味着SAI_CLK_ROOT不是24.576MHz的整数倍,有2个方向你可以尝试调整。一个是fsl_sai.h中,定义FSL_SAI_CLK_MAST1的地方,还有FSL_SAI_CLK_MAST2等;另一个是查看device tree里定义的SAI clock,你可以计算一下是否是24.576MHz的整数倍。因为不是任何采样频率都可以支持的。

[另外] 有的codec,内置的PLL很精准,所以你会常见到codec做Master。对于应用来说,codec做Master,给CPU端提供BCLK和LRCLK,也是一样的。

Have a nice day!

BR,

Weidong

0 Kudos