Hello Superlee!
If the codec is configured for normal I2S mode, then there is always 2 channels as defined by the I2S standard. You can check the current I2S format/mode for the I2S interface by …
$ cat /proc/device-tree/sound/nvidia,dai-link-1/format
Note that the following will tell you which I2S interface ‘nvidia,dai-link-1’ corresponds to …
cat /proc/device-tree/sound/nvidia,dai-link-1/cpu-dai-name
Typically dai-link-1 is for I2S1 and so if this is the interface you are using then you can check the above. Otherwise, you may need to check the configuration of a different dai-link.
For TX2 you need to refer to the kernel source file sound/soc/tegra-alt/tegra210_i2s_alt.c and here you will see …
static struct snd_soc_dai_driver tegra210_i2s_dais[] = {
{
.name = "CIF",
.playback = {
.stream_name = "CIF Receive",
.channels_min = 1,
.channels_max = 16,
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S8 |
SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S32_LE,
},
So yes mono is supported and to use mono, you can do one of two things …
- Keep the I2S interface configured for I2S mode but then within the device we can convert from 2 channels to 1 channel. I will point out that there is a known bug [0] in rel28 that has been fixed in rel32 (just released) and recommend that you upgrade to rel32 otherwise you would need to apply this fix for rel28. Using rel32 or with the fix in place for rel28 you would then …
Force the I2S interface to receive 2 channels (because the codec will always output 2 channels in I2S mode):
amixer -c tegrasndt186ref cset name='I2S1 Channels' 2
Convert the stereo to mono within Tegra:
rel28:
amixer -c tegrasndt186ref cset name='I2S1 TX stereo to mono conv' CH0
rel32:
amixer -c tegrasndt186ref cset name='I2S1 Capture stereo to mono conv' CH0
Capture mono audio
arecord -D hw:tegrasndt186,0 -c 1 -f S16_LE -r 16000 cap.wav
The above assume you are using I2S1.
- Configure the I2S interface to use dsp-a/b mode instead of I2S mode which supports a single channel. It appears that the codec should aupport this. With rel28 the I2S format needs to be configured by editing the device-tree source and recompiled. This is done by editing the source file t18x-common-platforms/tegra186-quill-common.dtsi and changing the format for the appropriate dai-link. For example for I2S1 …
rt565x_dai_link: nvidia,dai-link-1 {
link-name = "rt565x-playback";
cpu-dai = <&tegra_i2s1>;
codec-dai = <&spdif_dit0>;
cpu-dai-name = "I2S1";
codec-dai-name = "dit-hifi";
format = "i2s";
bitclock-slave;
frame-slave;
bitclock-noninversion;
frame-noninversion;
bit-format = "s16_le";
bclk_ratio = <0>;
srate = <48000>;
num-channel = <2>;
ignore_suspend;
name-prefix = "x";
status = "okay";
};
However, with rel32 you can now change the I2S mode directly from userspace using the following command …
amixer -c tegrasndt186ref cset name="I2S1 codec frame mode" dsp-a
And then record a single channel …
arecord -D hw:tegrasndt186,0 -c 1 -f S16_LE -r 16000 cap.wav
Hope this helps.
Regards,
Jon
[0] nv-tegra.nvidia Code Review - linux-nvidia.git/commit