主控:imx6q
内核:linux 3.14.52
我这硬件设计是:
int port1 <===> ext port6 CODEC(tlv320aic3104)
在 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM 情况下,驱动OK,运行aplay 时,用示波器看 FSYNC、BCLK、DOUT 信号都正常,此时 FSYNC 占空比是50%。
当我设置 dai_format = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM ,运行aplay时,DOUT完全没有输出,FSYNC、BCLK 由于 CODEC做主设备,所以是正常的,此时 FSYNC 脉宽是 ONE BCLK。
Hi gang,
SND_SOC_DAIFMT_DSP_A is used for TDM mode, which means you will tell SSI to work at TDM mode,
so except for "dai_format " configuration like "dai_format = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM", you must configure TDM slot by " snd_soc_dai_set_tdm_slot( )" function.
you can find the function in imx-cs42888.c / imx-wm8960.c and imx-si476x.c.
Hope above information is helpful for you!
Have a nice day!
BR,
Weidong
Hi Wigros,
音源是双声道,16bit采样,FSYNC 8khz,BCLK 256khz,我在代码中加入 snd_soc_dai_set_tdm_slot(cpu_dai, 0xfffffffc, 0xfffffffc, 2, 16); 可是结果还是一样。
Hi gang,
TDM is not supported by codec in Master mode, so please try to change mode: CPU is in Master mode, and codec is in Slave mode.
然后,跟踪一下一下代码,看fsl_ssi.c和你的codec.c有没有进入TDM mode。
Have a nice day!
BR,
Weidong
Hi Wigros,
1、6Q手册第61章SSI中写到“Network mode is used for creating a Time Division Multiplexed (TDM) network”,那这个Network mode 是否可以等同于你说的 “TDM mode”?
2、你上面说“TDM is not supported by codec in Master mode”,也就是说 6Q必须做主,可我在手册和 fsl_ssi.c代码中也没看到说 6Q必须做主,有点奇怪。如果 DSP_A模式下 6Q必须为主,那么我觉得在调试阶段有没有外部的设备都无所谓,我只需要测试 FSYNC、BCLK、DOUT这3个引脚在运行aplay时信号时序是否正常就可以了。
3、我调试这个SND_SOC_DAIFMT_DSP_A,是因为我们设计的板上有个4G模块,它的PCM接口信号如下图,这是否对应6Q的 SND_SOC_DAIFMT_DSP_A模式? (之前我只是想借助在I2S模式下已经调通的tlv320aic3104来调试DSP_A)
我们的i.MX6Q Sabre AI板子,上面使用的audio,就是工作在TDM(时分复用)模式,平台端驱动fsl_esai.c,codec端是cs42888.c,machine driver是imx-cs42888.c,你可以阅读以下它们的代码,然后配置fsl_ssi.c。
另外,你查看一下snd_soc_dai_set_tdm_slot()调用到的fsl_ssi.c中 实际配置tdm的函数,注释中说明了在CPU端工作在Master mode时,才配置TDM。
Have a nice day!
BR,
Weidong
Hi Wigros,
感觉 fsl_ssi.c 代码有两处有问题,至少我这的 3.14.52 内核是有问题的。
1、 _fsl_ssi_set_dai_fmt 函数里最下面
if (fmt & SND_SOC_DAIFMT_AC97)
fsl_ssi_setup_ac97(ssi_private);
我觉得应该改成:
if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97)
fsl_ssi_setup_ac97(ssi_private);
2、fsl_ssi_is_ac97 函数
return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97);
我觉得应该改成:
return (ssi_private->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97;
其实这两点本质上是同一个问题。
在 soc_dai.h 头文件中是这样定义的
#define SND_SOC_DAIFMT_DSP_A 4 /* L data MSB after FRM LRC */
#define SND_SOC_DAIFMT_AC97 6 /* AC97 */
如果 dai_fmt 设置 SND_SOC_DAIFMT_DSP_A 会导致上面条件为真
Hi Gang,
你现在用的是TDM模式。
1. SSI 支持I2S/PCM/AC97和TDM模式,ssi 驱动这几种模式都支持,你不需要修改代码。
2. 另外,现在BSP的最近版本是4.14.98, 已经发布出来很久了,3.14.52比较旧了。
如果你项目还没有发布,建议你直接用最近的BSP。
Have a nice day!
BR,
Weidong