我们希望在为 Toradex colibri VF61 定制的分线板上使用 I 2S 麦克风,该分线板提供 ESAI 连接。我在设备树下创建了本应激活 ESAI 并将其作为 Linux中的声卡提供;但是当我开始录制时,ESAI 的任何一个时钟引脚上都无法检测到时钟信号。(注:我必须对内核的某些部分进行调整,才能写入ESAI注册表并开始记录,日志附后)。
#include "vf610-colibri-eval-v3.dts"
&iomuxc {
vf610-colibri {
pinctrl_gpio_bl_on: gpio_bl_on {
fsl,pins = <
VF610_PAD_PTB19__GPIO_41 0x30
>;
};
// Pin/pad definitions are in vf610-pinfunc.h in the same dir. as this file
// Output only pins - not needed for our use case
// VF610_PAD_PTC2__ESAI_SDO0 0x30d2
// VF610_PAD_PTC3__ESAI_SDO1 0x30d2
esai_pins: esai_pins {
fsl,pins = <
VF610_PAD_PTC0__ESAI_SCKT 0x31C3
VF610_PAD_PTC1__ESAI_FST 0x31C3
VF610_PAD_PTC4__ESAI_SDO2 0x0041
VF610_PAD_PTC5__ESAI_SDO3 0x0041
VF610_PAD_PTC6__ESAI_SDI0 0x0041
VF610_PAD_PTC7__ESAI_SDI1 0x0041
>;
};
};
};
&clks {
clocks = <&sxosc>, <&fxosc>;
clock-names = "sxosc", "fxosc";
};
&aips0 {
esai: esai@40062000 {
compatible = "fsl,vf610-esai";
reg = <0x40062000 0x1000>; // Base address and size of ESAI registers
#sound-dai-cells = <0>;
interrupts = <88 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks VF610_CLK_ESAI>, <&clks VF610_CLK_ESAI>, <&clks VF610_CLK_ESAI>;
clock-names = "core", "extal", "fsys";
assigned-clocks = <&clks VF610_CLK_PLL4>, <&clks VF610_CLK_PLL4_MAIN_DIV>, <&clks VF610_CLK_ESAI_SEL>, <&clks VF610_CLK_ESAI_DIV>, <&clks VF610_CLK_ESAI>;
assigned-clock-parents = <&clks VF610_CLK_PLL4_BYPASS_SRC>, <&clks VF610_CLK_PLL4_AUDIO>, <&clks VF610_CLK_PLL4_MAIN_DIV>, <&clks VF610_CLK_ESAI_EN>, <&clks VF610_CLK_ESAI_DIV>;
assigned-clock-rates = <768000000>, <48000000>, <0>, <12000000>, <0>;
dmas = <&edma0 0 30>, <&edma0 0 31>;
dma-names = "rx", "tx";
fsl,fifo-depth = <128>;
fsl,esai-rx-channels = <4>;
fsl,esai-tx-channels = <2>;
// fsl,esai-synchronous;
pinctrl-names = "default";
pinctrl-0 = <&esai_pins>;
status = "okay";
};
};
/ {
sph0645: mic-codec {
compatible = "linux,snd-soc-dummy";
#sound-dai-cells = <0>;
status = "okay";
};
pure-digital-sound {
compatible = "simple-audio-card";
simple-audio-card,name = "ESAI-Multi-Channel";
status = "okay";
simple-audio-card,dai-link@0 {
format = "i2s";
bitclock-master = <&esai>;
frame-master = <&esai>;
// This is pristine hacking. 48 kHz * 1024 = audio_ext_clk.clock-frequency.
// Really just a hack to trigger the code that registers sound card for input.
mclk-fs = <128>;
cpu {
sound-dai = <&esai>;
system-clock-frequency = <6000000>;
dai-tdm-slot-num = <2>; // Number of slots
dai-tdm-slot-width = <32>; // Width in bits per slot
//dai-tdm-slot-rx-mask = <1 1 1 1 0 0>;
};
codec {
sound-dai = <&sph0645>;
};
};
};
};当我使用
arecord -v -D hw:1,0 -c 2 -f S24_LE -r 46875 -d 5 test.wav结果(包括我的内核调试输出)失效,示波器在ESAI时钟引脚上没有显示任何时钟信号(例如,在UART引脚上示波器能正确显示数据信号)。
arecord -v -D hw:1,0 -c 2 -f S24_LE -r 46875 -d 5 test.wav
[ 1713.779730] fsl-esai-dai 40062000.esai: Startup: syncx=0
Recording WAVE 't[ 1713.786470] fsl-esai-dai 40062000.esai: SYSCLK clk_id=2 freq=6000000 dir=1
est.wav' : Signed[ 1713.794171] fsl-esai-dai 40062000.esai: HWP slot_width=32 params_rate=46875 slots=2
24 bit Little En[ 1713.803342] fsl-esai-dai 40062000.esai: BCLK ratio=2 hck_rate=6000000 freq=3000000 tx=0
dian, Rate 46875 [ 1713.812834] fsl-esai-dai 40062000.esai: HWP[ub] REG_ESAI_xCR(tx)=220 channels=2
Hz, Stereo
[ 1713.821634] fsl-esai-dai 40062000.esai: HWP[ub] REG_ESAI_xFCR(tx)=24
[ 1713.829056] fsl-esai-dai 40062000.esai: HWP[ub] mask=7ff3e val=27f04
[ 1713.835458] fsl-esai-dai 40062000.esai: HWP[ub] REG_ESAI_xCR(tx)=220 mask=7c00 val=7c00
[ 1713.843499] fsl-esai-dai 40062000.esai: HWP[ub] REG_ESAI_PRRC
[ 1713.849311] fsl-esai-dai 40062000.esai: HWP[ub] REG_ESAI_PCRC
[ 1713.855197] fsl-esai-dai 40062000.esai: HWP return
Hardware PCM card[ 1713.881667] fsl-esai-dai 40062000.esai: Trigger: tx=0 channels=2 pins=1 cmd=1
[ 1713.889006] fsl-esai-dai 40062000.esai: Trigger[START]: REG_ESAI_xFCR(tx)=24 REG_ESAI_xCR(tx)=220 ESAI_xCR_TE(pins)=1 ESAI_xCR_RE(pins)=1
1 'ESAI-Multi-Channel' device 0 subdevice 0
Its setup is:
stream : CAPTURE
access : RW_INTERLEAVED
format : S24_LE
subformat : STD
channels : 2
rate : 46875
exact rate : 46875 (46875/1)
msbits : 32
buffer_size : 29295
period_size : 5859
period_time : 124992
tstamp_mode : NONE
tstamp_type : MONOTONIC
period_step : 1
avail_min : 5859
period_event : 0
start_threshold : 1
stop_threshold : 29295
silence_threshold: 0
silence_size : 0
boundary : 1919877120
appl_ptr : 0
hw_ptr : 0
arecord: pcm_read[ 1723.895948] fsl-esai-dai 40062000.esai: Trigger: tx=0 channels=2 pins=1 cmd=0
:2096: read error: Input/output error我对通过 Linux 的设备树处理硬件还很陌生。以前,我直接在微控制器程序中编写注册表。
那么,为了让 ESAI 模块成为 I2S 时钟主控器并真正向 ESAI 时钟引脚发送时钟信号,我在设备树中错过了什么?当然,录制采样是我的总体目标,因此 DMA 配置可能也有欠缺。
感谢您提供的任何小提示。
马丁
clk_summary的内容如下(为便于阅读而缩短),因此 Linux 接受了我的设置。无论上述麦克风是否支持,即使驱动器不接受数据,时钟信号也会出现。
关于制造商的建议,我已经在 Toradex 论坛上提出了问题,但至今没有得到答复。
clock enable_cnt prepare_cnt rate accuracy phase
----------------------------------------------------------------------------------------
...
sxosc 0 0 32768 0 0
ftm3_fix_sel 0 0 32768 0 0
ftm2_fix_sel 0 0 32768 0 0
ftm1_fix_sel 0 0 32768 0 0
ftm0_fix_sel 0 0 32768 0 0
fxosc 1 1 24000000 0 0
fast_clk_sel 6 6 24000000 0 0
pll7_bypass_src 1 1 24000000 0 0
pll7 1 1 480000000 0 0
pll7_bypass 1 1 480000000 0 0
pll7_usb_host 1 1 480000000 0 0
usbphy1 1 1 480000000 0 0
...
pll4_bypass_src 1 1 24000000 0 0
pll4 1 1 768000000 0 0
pll4_bypass 1 1 768000000 0 0
pll4_audio 1 1 768000000 0 0
pll4_audio_div 1 2 48000000 0 0
esai_sel 0 1 48000000 0 0
esai_en 0 1 48000000 0 0
esai_div 0 1 12000000 0 0
esai 0 1 12000000 0 0
sai2_sel 0 0 48000000 0 0
sai2_en 0 0 48000000 0 0
sai2_div 0 0 48000000 0 0
sai0_sel 1 1 48000000 0 0
sai0_en 1 1 48000000 0 0
sai0_div 1 1 48000000 0 0
...你好
首先,我建议你咨询制造商电路板支持包是否能够支持该麦克风,并确认不需要额外的驱动程序。
cat /sys/kernel/debug/clk/clk_summary -n
确认无误后,请检查是否正确配置并启用了 ESAI 时钟,可通过下一条命令查看:
查看 ESAI 及其父时钟,确认它们已启用并以预期频率运行。
您试过使用 fsl,esai-synchronous; 取消注释吗?
顺祝商祺!