[Tegra TK1] i2s is not working properly in slave mode


We are using TI cadec tlv320aic3100 chip with i2s3 interface of Tegra.
Codec is Master for both BCLK and WCLK and i2s is configured in Slave mode.

Audio with format S32_LE is working fine. But with S16_LE audio played with noise.
Mic(ADC) functionality is working fine.

To fix the issue, we have to configure BCLK=(WCLK*64) in Codec.

Note: Same codec and driver working fine with other SoC(Freescale i.MX6).

Question :
BCLK should be (WCLK * bits_as_per_format * no_of_chanels).
Why codec have to set BCLK=(WCLK*64)? Any limitations?

I have found one comment(“Tegra requires 64*fs as bitclk in slave mode”) in other codec(rt5639) driver as below,
https://github.com/NVIDIA/android-linux-3.10/blob/jtk1-android-l/sound/soc/codecs/rt5639.c [Line No : 2543]

Do we also have to apply same changes in our driver?

Not sure how you are trying to make it work for master mode.
From the data sheet I see below,
“Communication on the I2C bus always takes place between two devices, one acting as the master and the other acting as the slave. Both masters and slaves can read and write, but slaves can only do so under the direction of the master. Some I 2C devices can act as masters or slaves, but the TLV320AIC3100 can only act as a slave device”

Yes, you are right but for I2C bus. and we have I2C in slave mode.

“Codec is Master” is for I2S mode as below,
SCLK [I2S3] <<<<< BCLK[Codec]
FSync[I2S3] <<<<< WCLK[Codec]
Data [I2S3] <<->> Data[Codec]

So Audio sounds good if we set BCLK=(WCLK*64) from Codec even if I2S3_sync clock is set as per (WCLK * no_of_channel * bits_as_per_format).

Checked I2S3_sync clock using below command,

cat /sys/kernel/debug/clock/clock_tree | grep i2s


Can you attach the clock tree dump to verify if the clock values are fine?
Codec register dump will also help us to debug the issue.


Find attached files with clock tree dump and Codec register dump.
File played is “Signed 16 bit Little Endian, Rate 48000 Hz, Stereo”.

BCLK = no_of_channels * bits_per_format * WCLK;
BCLK = 2 * 16 * 48000 = 1536000


BCLK = 64 * WCLK;
BCLK = 64 * 48000 = 3072000


Tegra-Codec-issue.zip (8.44 KB)

@ Sandipkumar
Clock tree attached for working and non-working case look identical.
For the working case, the BCLK is still 1536000 (Clock-tree-sound-OK.txt).
Since codec is operated in master mode, the clock tree would be same.

Could you actually collect dumps for tegra and non-tegra platforms, with bclk = 2 * 16 * 48k.
Usually MCLK clock is supplied by the SoC to the codec.
If this clock is not in sync with the BCLK, then there could be chances of noisy playback.
Above dump will quickly help to check, what could be the different between two platforms.


On our board, MCLK(12MHz) is supplied by external crystal to the Codec.
Please find attached Codec register dumps for both platforms.

Codec-register-dump.zip (1.98 KB)

I assume the clock supplied is 12.288MHz, which should be fine for the use case.
The dumped format of the registers is not easily readable.
Could you dump the registers from regmap.
cat /sys/kernel/debug/regmap//registers > reg_dump


On our board, Clock supplied is 12MHz.
Please find attached Codec regmap dumps for both platforms.
Codec-regmap-dump.zip (6.42 KB)

Thanks for your hard worked on this issue. I just check the internal git history it did show the TK1 need 64*fs as bitclk in slave mode, I will try if I can get much information but as you know TK1 is much older-fashioned. However TX1 and TX2 didn’t need this require. I will update if I get more information.


Thanks for your help.
I have already applied patch as mentioned in Comment#2.