We want to use I2S microphone on our customized breakout board for Toradex colibri VF61 that provides ESAI connectivity. I have created below device tree that suppose to activate ESAI and offer it as a sound card within Linux; however when I start recording no clock signal is detectable on either of ESAI's clock pins. (Note: I had to tweak some portions of the kernel to even get ESAI registry written and start recording, logs attached further.)
#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>;
};
};
};
};
Note the wacky sampling frequency as oscilator provided in VF61 has seemingly nice frequency of 24 Mhz but due to clock tree requirements and HW limittations of divisors and multipliers it is not achievable to have final ESAI clock frequency of 3.072 MHz needed for 64 bit stereo samples produced by the I2S microphone at 48 kHz sampling rate.
The result (incl. my kernel debug output) is a failure and osciloscope doesn't show any clock signal on either of ESAI clock pins (e.g. at UART pin osciloscope shows data signal correctly).
I am pretty new to dealing with HW via Linux's device tree. Before I used to wrote registries directly in microcontrollers' programs.
So what do I miss in the device tree to make the ESAI module being I2S clock master and actually send out the clock signal to ESAI clock pins? Of course recording the samples is my overall goal so DMA configuration might lack something as well.
The content of clk_summary is as below (shortened for easier readability) so Linux is accepting my settings. Regardless of suppport of mentioned microphone, the clock signal shall appear even if the data are not accepted by driver.
Regarding the manufacturer advice I have raised question in Toradex's forum but no reply so far.