Use more than one I2S port in TDM mode

We are using the Jetson TX2 Development board. We have ICS-52000 TDM microphones mounted on custom boards. They work as expected with the 40-pin header I2S port when configured using the Jetson-IO tool.

Now our goal is to have two TDM inputs working at the same time using the 30-pin header I2S input and the 40-pin input at the same time. Ideally, we would use the same clocks for both inputs.

My understanding is that we still need to change the device tree and flash to setup the I2S input on TDM mode on the 30-pin GPIO, following TDM mode on the I2S port

A few questions :

  • If this is the way to go, what would be the correct pinmux setup to achieve what we want?
  • Is there any way to link the clocks internally?

Thank you in advance!

Hello!

Each I2S interface can capture up to 16 channels, but if you need to interface multiple microphones and they cannot be connected to the same I2S, then yes you may need to use more than one interface.

Is there a Linux driver available for this MEMS mic? Or does it work with the dummy spdif driver (default codec driver) for the I2S interfaces? If it works like the Adafruit MEMS mic [0] which does not require a specific codec driver, then it could be possible to configure one I2S as the master and one as a slave and then use the BCLK and FSYNC from I2S1 (40-pin header) to drive I2S2 (30-pin header) as well as the MEMS mics.

Please note that the I2S signals on the 40-pin header can operate at 1.8V or 3.3V and this is configured by jumper J24. The I2S signals on the 30-pin header only support 1.8V and so you will need to configure J24 so that the I2S on the 40-pin header are 1.8V. Placing the jumper in position 2-3 should configure for 1.8V operation.

With regard to pinmux, you can check the current configuration by …

$ sudo grep "dap1\|dap2" /sys/kernel/debug/tegra_pinctrl_reg 

For I2S2/DAP2 you want something like …

$ grep dap2 Linux_for_Tegra/bootloader/t186ref/BCT/tegra186-mb1-bct-pinmux-quill-p3310-1000-c03.cfg 
pinmux.0x02434018 = 0x00000440; # dap2_sclk_pc1: i2s2, tristate-disable, input-enable, lpdr-disable
pinmux.0x02434008 = 0x00000400; # dap2_dout_pc2: i2s2, tristate-disable, input-disable, lpdr-disable
pinmux.0x02434000 = 0x00000458; # dap2_din_pc3: i2s2, pull-up, tristate-enable, input-enable, lpdr-disable
pinmux.0x02434010 = 0x00000440; # dap2_fs_pc4: i2s2, tristate-disable, input-enable, lpdr-disable

The above should allow the I2S2 to function as either slave or master.

Finally, it should be noted that Tegra has an Audio Multiplexer (AMX) [1][2] that can be used for multiplexing multiple audio streams into a single stream of up to 16 channels. So you could route the output from the I2S interfaces to the AMX and then capture the audio from both I2S interfaces as a single audio stream. Assuming that there are 16 of less channels in total.

Regards,
Jon

[0] https://www.adafruit.com/product/3421
[1] https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide%2Fasoc_driver.18.2.html%23wwpID0E0HCB0HA
[2] https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide%2Fasoc_driver.18.2.html%23wwpID0E0LH0HA

Hello Jon!

Thank you very much for your quick feedback. I will test this as soon as I get access to the hardware and keep you updated with the results.

Hello Jon,

Apologies for the delay. Our microphones indeed work like the Adafruit you mentionned. They work like a charm when using I2S1 (40pin GPIO), but we have trouble making them work when using I2S2.
The default pinmux when flashing Jetpack 3.3 with the SDK corresponds exactly to the configuration you suggested above. However, when probing the clocks, we see that the FS clock (pin 26) works properly, but the SCLK (pin 23) is just noise. Is this a known issue?
Thank you once again.

Hello joelle.frechette-viens,

We need some info from your side:

  • What is the Jumper J24 configuration on your board? Is it 1-2 (3.3V) or 2-3 (1.8V)?

  • Kindly share I2S register configs during the capture usecase.

Please dump during capture usecase via I2S1 (40 pin Header):

cat /sys/kernel/debug/regmap/tegra210-i2s.0/registers

Please dump during capture usecase via I2S2 (30 pin Header):

cat /sys/kernel/debug/regmap/tegra210-i2s.1/registers

  • Kindly share clock signal probe snapshots for both ports I2S1 and I2S2 : SCLK and FS.

Thanks,
Sharad

Hello!

It is not a known issue and in fact I have probed the same pins today and they are working for me. Attached is a trace from the o-scope.

Here are the pinmux settings that I am using …

$ sudo grep "dap1\|dap2" /sys/kernel/debug/tegra_pinctrl_reg
Bank: 0 Reg: 0x02431028 Val: 0x00000444 -> dap1_fs_pj3
Bank: 0 Reg: 0x02431030 Val: 0x00000454 -> dap1_din_pj2
Bank: 0 Reg: 0x02431038 Val: 0x00000404 -> dap1_dout_pj1
Bank: 0 Reg: 0x02431040 Val: 0x00000444 -> dap1_sclk_pj0
Bank: 0 Reg: 0x02434000 Val: 0x00000458 -> dap2_din_pc3
Bank: 0 Reg: 0x02434008 Val: 0x00000400 -> dap2_dout_pc2
Bank: 0 Reg: 0x02434010 Val: 0x00000440 -> dap2_fs_pc4
Bank: 0 Reg: 0x02434018 Val: 0x00000440 -> dap2_sclk_pc1

Regards,
Jon

Hello sharadg,

  • The jumper J24 is in position 2-3 (1.8 V)

  • Here are the registers I get during capture :

$ sudo cat /sys/kernel/debug/regmap/tegra210-i2s.0/registers

00: 00000001
04: 00000000
08: 00000000
0c: 00000001
10: 00000000
14: 00000003
18: 00000000
1c: 00000000
20: 03aa3700
24: 00000100
28: 000007ff
2c: 00000000
30: 00000000
34: 00000000
38: 00000000
3c: 00000000
40: 00000001
44: 00000000
48: 00000000
4c: 00000001
50: 00000000
54: 00000003
58: 00000000
5c: 00000000
60: 00aa7700
64: 00000100
68: 000007ff
6c: 00000000
70: 00000000
74: 00000000
78: 00000000
7c: 00000000
80: 00000001
84: 00000000
88: 00000001
8c: 00000000
90: 00000000
94: 00000000
98: 00000000
9c: 00000000
a0: 00001607
a4: 0000015f
a8: 0000000a
ac: 00000000
b0: 00000000

$ sudo cat /sys/kernel/debug/regmap/tegra210-i2s.1/registers
00: 00000000
04: 00000000
08: 00000000
0c: 00000002
10: 00000000
14: 00000003
18: 00000000
1c: 00000000
20: 00007700
24: 00000100
28: 00000003
2c: 00000000
30: 00000000
34: 00000000
38: 00000000
3c: 00000000
40: 00000001
44: 00000000
48: 00000000
4c: 00000001
50: 00000001
54: 00000003
58: 00000000
5c: 00000000
60: 00117700
64: 00000100
68: 00000003
6c: 00000000
70: 00000000
74: 00000000
78: 00000000
7c: 00000000
80: 00000001
84: 00000000
88: 00000001
8c: 00000000
90: 00000001
94: 00000000
98: 00000000
9c: 00000000
a0: 00001607
a4: 0000003f
a8: 00000001
ac: 00000000
b0: 00000000

  • Here are the probe signals read during capture of each port separately using Audacity. SCLK is is yellow and FS in cyan.

I2S1 (the frequency detected for SCLK is actually 3.01 MHz) :

We can see these clocks even when no capture is ongoing…

I2S2 :

The FS clock is only activated when the capture is on. SCLK is only noise whether capture is on or not.

Thank you very much for your help!

Hi joelle.frechette-viens,

The jumper J24 is in position 2-3 (1.8 V)

Does this MIC card work with 3.3 V configuration as well on 40pin Header? Will it be possible for you try this by changing jumper J24 in 1-2 position and verify captured audio data, if not tried already?

As Jon mentioned, we don’t see any issue with I2S2 signals at our end.

Thanks,
Sharad

Hello sharadg,
Unfortunately, the card only works in 1.8 V.