How to set i2s number of channels?


#1

The older hikey board has this; https://android.googlesource.com/kernel/hikey-linaro/+/android-hikey-linaro-4.9/sound/soc/hisilicon/hi6210-i2s.c#433

But on the 960, there is no corresponding code in the i2s driver, nor is there any documentation describing the corresponding register or what should be written to it.

I need to be able to set it to 1-channel (mono).


#2

Did 1-channel work for you?

Thanks!


#3

This is what I got;
https://bugs.96boards.org/show_bug.cgi?id=674


#4

16K mono, worked. Thanks a lot for your help!


#5

Above suggested changes did not work for me (tinyplay immediately returns without any error). Do you remember any additional changes needed to get mono working?

My changes are here.


#6

According to this, I can capture 16K 16bit mono data. But the data is incorrect like this, “16bit-valid-data, 16bit-0xFFFFF, 16bit-valid-data, 16bit-0xFFFFF, …”.
Measured i2s ws(word select) clock and data, the data(from codec) appears in the left channel of ws, and no data in the right channel of ws. It means the codec sends the correct data.
If I try to force the codec to send two channels data(both left and right channel of ws have data), then the captured data becomes “16bit-valid-data, 16bit-valid-data, 16bit-valid-data, 16bit-valid-data, …”. But the sound is distorted.
I guess in mono capturing, hisilicon captures first sample from I2S-L and captures the second sample from I2S-R and captures the third sample from I2S-L and captures the fourth sample from I2S-R…
Did you meet this before? And how to fix it?
Thanks.
Kui


#7

i2s is fundamentally a STEREO protocol. Your first example of VALID – FFFF – VALID – FFFF is how i2s transfers mono data. It is then up to the receiver to simply ignore the second (right) channel.

As you can see, https://android.googlesource.com/kernel/hikey-linaro/+/android-hikey-linaro-4.9/sound/soc/hisilicon/hisi-i2s.c#373 – there is still no provision in the sound driver for single channel audio. This means that ALL captured audio will be received in STEREO, and it will NOT be correctly discarding the second channel.

The solution I ended up implementing to solve this is simply to drop the second channel myself – in the audio HAL. This function converts a 16 bit stereo buffer into a 16 bit mono buffer: https://gitlab.com/HiKey960-Car/android_device_linaro_hikey/blob/master_091118_car96/car96audio/audio_hal.c#L1273

Android has other audio channel manipulation functions available to use here; https://android.googlesource.com/platform/system/media/+/master/audio_utils/channels.c – however, their channel reduction functions use mixing to reduce the channel count, and thus were unsuitable for directly dropping the second (invalid) channel. So for instance, you can use adjust_channels(…) like this; https://gitlab.com/HiKey960-Car/android_device_linaro_hikey/blob/master_091118_car96/car96audio/audio_hal.c#L1580 to expand a mono buffer into stereo by duplicating the left channel to the right channel.

Also note that I have found that the SoC does sometimes just completely distort the audio. It seems to be a very random event. The good news is that I was able to identify the precise nature of the distortion, implement a detection mechanism, and correct it when it is detected.

https://gitlab.com/HiKey960-Car/android_device_linaro_hikey/blob/master_091118_car96/car96audio/audio_hal.c#L1549 through line 1570 detects the audio distortion. This function repairs the data in the buffers when the distortion is detected: https://gitlab.com/HiKey960-Car/android_device_linaro_hikey/blob/master_091118_car96/car96audio/audio_hal.c#L1280


#8

Thanks for your information.
It seems the mono capturing is still not supported.
I’ve filed a bug https://bugs.96boards.org/show_bug.cgi?id=801 to see if anybody can help.
But you mean even in stereo capturing, the SoC also sometimes captures wrong data(distortion)?
What a serious hardware bug it is!!


#9

There is no reason at all to assume that it is a hardware bug. I’m very confident that its a software bug. i2s uses DMA, and when you go through the bug system, you can see that there are a lot of issues with DMA on this board.