I2s slave on Apalis iMX8 sai2

Hi,

We are trying to setup an I2S slave on Apalis iMX8.

I have added this to our custom device tree:

/ {
        codec_custom: codec_custom {
                compatible = "linux,snd-soc-dummy";
                #sound-dai-cells = <0>;
        };

        sound_custom {
                compatible = "simple-audio-card";
                simple-audio-card,name = "custom";
                simple-audio-card,format = "i2s";

                simple-audio-card,frame-master = <&custom_codec>;
                simple-audio-card,bitclock-master = <&custom_codec>;

                custom_sai: simple-audio-card,cpu {
                       sound-dai = <&sai2>;
                };

                custom_codec: simple-audio-card,codec {
                        sound-dai = <&codec_custom>;
                };
        };
};

              pinctrl_sai2: sai2grp {
                        fsl,pins = <
                                IMX8QM_ESAI1_TX0_AUD_SAI2_RXD                   0xc600004c
                                IMX8QM_ESAI1_TX1_AUD_SAI2_RXFS                  0xc600004c
                                IMX8QM_ESAI1_SCKT_AUD_SAI2_RXC                  0xc600004c
                        >;
                };

&sai2 {
        #sound-dai-cells = <0>;
        assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
                        <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
                        <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
                        <&sai1_lpcg 0>; 
        assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai2>;
        fsl,sai-asynchronous;
        status = "okay";
};

I have also added this patch to the yocto build

diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index c5f809d3a710c..e2d475925f50e 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -13,6 +13,7 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <linux/module.h>

 int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots)
 {
@@ -152,9 +153,17 @@ static int snd_soc_dummy_probe(struct platform_device *pdev)
        return ret;
 }

+static const struct of_device_id soc_dummy_ids[] = {
+       { .compatible = "linux,snd-soc-dummy", },
+       {},
+};
+
+
+
 static struct platform_driver soc_dummy_driver = {
        .driver = {
                .name = "snd-soc-dummy",
+               .of_match_table = of_match_ptr(soc_dummy_ids),
        },
        .probe = snd_soc_dummy_probe,
 };

I get the sound cards listed:

root@881304ff64ec:/app# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: imxspdif [imx-spdif], device 0: S/PDIF PCM snd-soc-dummy-dai-0 [S/PDIF PCM snd-soc-dummy-dai-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: apalisimx8qmsgt [apalis-imx8qm-sgtl5000], device 0: 59050000.sai-sgtl5000 sgtl5000-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: custom [custom], device 0: 59040000.sai-snd-soc-dummy-dai snd-soc-dummy-dai-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

I have a nice i2s stream with BCLK, WCLK, DATA connected toApalis iMX8 pins 198, 164, 35. I can view the logic levels and decode them with my logic analyzer software.

I am testing on an Apalis Evaluation board and have removed C115 to get a better signal on the data line.

I am running arecord -D plughw:2,0 -f S16_LE -c2 -r48000 -d 10 output.wav 1 from within a Docker with privileges. The output.wav gets recorded, but the wav-file is empty, as if there was no input signal.

What might i be missing?

Hi @jugge !

Sorry for the delay.

Could you please share the output of tdx-info (reference: Getting Device Information with Tdx-Info | Toradex Developer Center)?

I see that you are trying to use a dummy codec. I am not sure it will work, as you need to communicate with the actual codec hardware to deal with real audio date stream. Could you please share how you are connecting your hardware? You will most probably need to use the actual driver for the codec IC you are using.

Please check a reference we have at imx8qm-mek-sof-wm8960.dts « freescale « dts « boot « arm64 « arch - linux-toradex.git - Linux kernel for Apalis, Colibri and Verdin modules, line 18. You can see there that the codec is the frame and bitclock master, therefore the CPU is the slave. This seems to be a good reference for what you are trying to accomplish.

About the patch you did on soc-utils.c, I understand you did that to create your linux,snd-soc-dummy. But why would you need to do this? Can you please elaborate? I am not sure this is recommended :thinking:

Best regards,

This is the tdx-info:

#sudo sh ./tdx-info

Software summary
------------------------------------------------------------
Bootloader:               U-Boot
Kernel version:           5.4.193-5.7.0-devel+git.f78299297185 #1-TorizonCore SMP PREEMPT Thu May 11 08:53:23 UTC 2023
Kernel command line:      pci=nomsi root=LABEL=otaroot rootfstype=ext4 quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash ostree=/ostree/boot.1/torizon/0dce0ef4758c070a8509d9b6fcbb83136214e2d045a7f3b7669cc8266b40852b/0
Distro name:              NAME="Custom TorizonCore Variant"
Distro version:           VERSION_ID=5.7.0-devel-20230511085225-build.0
Hostname:                 apalis-imx8-07278529
------------------------------------------------------------

Hardware info
------------------------------------------------------------
HW model:                 Toradex Apalis iMX8QM V1.1 on Custom Carrier Board
Toradex version:          0037 V1.1E
Serial number:            07278529
Processor arch:           aarch64
------------------------------------------------------------

The hardware setup is that we have a connector for I2S input from something external. We are routing that I2S bus directly onto pins 198, 164 and 35 on the Apalis module. There is no IC in between.

The setup I am testing is getting an I2S stream from an external device. I am testing with an old CP2114 USB-to-I2S dev board, but that just something I had lying around and using to get an i2s signal (BLCK, WLCK, DATA)

To be honest I cannot fully explain the patch on the soc-utils. I have inherited this solution and I have been told this approach worked when trying it on an Apalis Evaluation board before.

I added status = “okay” in device tree node sound_custom, and now I can record left channel of stereo input.

Hi @jugge !

Thanks for the feedback!

If your last message solved your issue, please mark it as the Solution :slight_smile:

Best regards,