CS4270 evaluation board on NX: Soundcard jetsonxaviernxa not detected

Hi,
I am trying to connect CS4270 evaluation board on NX with Jetpack4.4.1, but I have some troubles with the device-tree and the machine driver.

I have added the Codec node at i2c@31e0000 and modified the codec dai link and audio-routing at sound node as follows

 diff --git a/hardware/nvidia/platform/t19x/jakku/kernel-dts/tegra194-p3668-all-p3509-0000.dts b/hardware/nvidia/platform/t19x/jakku/kernel-dts/tegra194-p3668-all-p3509-0000.dts
index b724f6279..d5a07393e 100644
--- a/hardware/nvidia/platform/t19x/jakku/kernel-dts/tegra194-p3668-all-p3509-0000.dts
+++ b/hardware/nvidia/platform/t19x/jakku/kernel-dts/tegra194-p3668-all-p3509-0000.dts
@@ -22,4 +22,50 @@

 	nvidia,dtbbuildtime = __DATE__, __TIME__;
 
 	compatible = "nvidia,p3449-0000+p3668-0000", "nvidia,p3449-0000+p3668-0001", "nvidia,p3509-0000+p3668-0000", "nvidia,p3509-0000+p3668-0001", "nvidia,tegra194";
+
+	hdr40_i2c1: i2c@31e0000 {
+		cs4270codec: cs4270@4c {
+			compatible = "cirrus,cs4270";
+			reg = <0x4c>;
+		};
+	};
+
+	tegra_sound: sound {
+		status = "okay";
+
+		nvidia,audio-routing =
+			"x Headphone",          "x OUT",
+			"x IN",                 "x Mic",
+			"y Headphone",          "y OUT",
+			"y IN",                 "y Mic",
+			"z Headphone",          "z OUT",
+			"z IN",                 "z Mic",
+			"m Headphone",          "m OUT",
+			"m IN",                 "m Mic",
+			"n Headphone",          "n AOUTL",
+			"n Headphone",          "n AOUTR",
+			"n AINL",               "n Mic",
+			"n AINR",               "n Mic",
+			"o Headphone",          "o OUT",
+			"o IN",                 "o Mic",
+			"a IN",                 "a Mic",
+			"b IN",                 "b Mic",
+			"c IN",                 "c Mic",
+			"d IN",                 "d Mic",
+			"d1 Headphone",         "d1 OUT",
+			"d2 Headphone",         "d2 OUT";
+
+		hdr40_snd_link_i2s: nvidia,dai-link-5 {
+			link-name = "cs4270-codec";
+			cpu-dai = <&tegra_i2s5>;
+			codec-dai = <&cs4270codec>;
+			cpu-dai-name = "I2S5";
+			codec-dai-name = "cs4270-hifi";
+			format = "i2s";
+			bit-format = "s16_le";
+			name-prefix = "n";
+			status = "okay";
+		};
+	};
+
 };

And the machine driver was updated as follows:

diff --git a/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c b/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
index fbca4699d..dee3447b8 100644
--- a/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
+++ b/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
@@ -311,6 +311,16 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
 	if (err < 0)
 		return err;
 
+	rtd = snd_soc_get_pcm_runtime(card, "cs4270-codec");
+	if (rtd) {
+		dai_params =
+		(struct snd_soc_pcm_stream *)rtd->dai_link->params;
+
+		dai_params->rate_min = srate;
+		dai_params->channels_min = channels;
+		dai_params->formats = formats;
+	}
+
 	rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback");
 	if (rtd) {
 		dai_params =
@@ -594,6 +604,19 @@ static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
 	return 0;
 }
 
+static int tegra_machine_cs4270_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct device *dev = rtd->card->dev;
+	int err;
+	err = snd_soc_dai_set_sysclk(rtd->codec_dai, 0, 12288000, SND_SOC_CLOCK_IN);
+	if (err) {
+		dev_err(dev, "failed to set cs4270 sysclk!\n");
+		return err;
+	}
+
+	return 0;
+}
+
 static int codec_init(struct tegra_machine *machine)
 {
 	struct snd_soc_dai_link *dai_links = machine->asoc->dai_links;
@@ -611,6 +634,8 @@ static int codec_init(struct tegra_machine *machine)
 			dai_links[i].init = tegra_machine_rt565x_init;
 		else if (strstr(dai_links[i].name, "fe-pi-audio-z-v2"))
 			dai_links[i].init = tegra_machine_fepi_init;
+		else if (strstr(dai_links[i].name, "cs4270-codec"))
+			dai_links[i].init = tegra_machine_cs4270_init;
 	}
 
 	return 0;

Changes of codec driver in kernel for dummy regulator

diff --git a/kernel/kernel-4.9/sound/soc/codecs/cs4270.c b/kernel/kernel-4.9/sound/soc/codecs/cs4270.c
index 84f86745c..04ad282c5 100644
--- a/kernel/kernel-4.9/sound/soc/codecs/cs4270.c
+++ b/kernel/kernel-4.9/sound/soc/codecs/cs4270.c
@@ -124,7 +124,7 @@ static const struct reg_default cs4270_reg_defaults[] = {
 };
 
 static const char *supply_names[] = {
-	"va", "vd", "vlc"
+	"dummy"
 };
 
 /* Private data for the CS4270 */

And the kernel config was

CONFIG_SND_SOC_CS4270=m
CONFIG_REGULATOR_DUMMY=y

After the changes made above, I found the sound card jetsonxaviernxa not detected:

user@Jetson-xavier-NX:~$ cat /proc/asound/cards
 0 [tegrahdaxnx    ]: tegra-hda-xnx - tegra-hda-xnx
                      tegra-hda-xnx at 0x3518000 irq 64

dmesg showed codec dai cs4270-hifi not registered:

[    5.570274] tegra-asoc: sound: ASoC: CODEC DAI cs4270-hifi not registered
[    5.570665] tegra-asoc: sound: snd_soc_register_card failed (-517)
[    5.573235] tegra-asoc: sound: ASoC: CODEC DAI cs4270-hifi not registered
[    5.573478] tegra-asoc: sound: snd_soc_register_card failed (-517)
[    5.899106] tegra-asoc: sound: ASoC: CODEC DAI cs4270-hifi not registered
[    5.899357] tegra-asoc: sound: snd_soc_register_card failed (-517)
[    6.112458] tegra-asoc: sound: ASoC: CODEC DAI cs4270-hifi not registered
[    6.112711] tegra-asoc: sound: snd_soc_register_card failed (-517)

The complete kernel dmesg is attached here:
dmesg.txt (67.8 KB)

I wonder why the sound card jetsonxaviernxa is not detected after the modification. Is there something wrong in the device-tree or machine driver?

Thanks

Hello!

Looking at the dmesg I see that …

[  207.856634] tegra-i2c 31e0000.i2c: no acknowledge from address 0x4c
[  207.856829] cs4270 8-004c: failed to read i2c at addr 4C
[  207.857458] cs4270: probe of 8-004c failed with error -121

So the probe of the codec is failing and this is why the cs4270-hifi is not registered. Have you ensured that the evaluation module is configured for I2C and SPI? I see that the control interface can be configured either way. You may also want to confirm that the I2C signals operate at 3.3V on the CS4270 evaluation board. If that all looks good, you may need to check that the codec is powered and clocked as expected.

Regards
Jon

Hi Jon,
Thanks for your reply! The reason that failed to read i2c at addr 4C is that I didn’t reset CS4270 when it poweron.
I got another problem that I need to configure the 40-pin and then I found the changes were saved to the file /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb.
And I found in /boot/extlinux/extlinux.conf shows:

user@Jetson-xavier-NX:~$ cat /boot/extlinux/extlinux.conf
TIMEOUT 30
DEFAULT JetsonIO

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

# When testing a custom kernel, it is recommended that you create a backup of
# the original kernel and add a new entry to this file so that the device can
# fallback to the original kernel. To do this:
#
# 1, Make a backup of the original kernel
#      sudo cp /boot/Image /boot/Image.backup
#
# 2, Copy your custom kernel into /boot/Image
#
# 3, Uncomment below menu setting lines for the original kernel
#
# 4, Reboot

# LABEL backup
#    MENU LABEL backup kernel
#    LINUX /boot/Image.backup
#    INITRD /boot/initrd
#    APPEND ${cbootargs}

LABEL User Custom [2021-03-30-101212]
        MENU LABEL User Custom [2021-03-30-101212]
        LINUX /boot/Image
        FDT /boot/tegra194-p3668-all-p3509-0000-user-custom-[2021-03-30-101212].dtb
        INITRD /boot/initrd
        APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

FDT     /boot/tegra194-p3668-all-p3509-0000.dtb

LABEL JetsonIO
        MENU LABEL Custom 40-pin Header Config
        LINUX /boot/Image
        FDT /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb
        INITRD /boot/initrd
        APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0
user@Jetson-xavier-NX:~$

As I had added the subnode CS4270 under i2c@31e0000, so I need to use
FDT /boot/tegra194-p3668-all-p3509-0000.dtb
which enables my configuration on CS4270, however I also need to configure the 40-pin to enable the i2s pin( as mentioned above changes saved to an dtb file), and these changes need the below command:
FDT /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb
Then I found the two covers each other whatever I change the command sequence.
How can enable the two configurations at the same time?
Or how can I add the 40-pin changes into the /boot/tegra194-p3668-all-p3509-0000.dtb ?

Thanks
Yun

Hi,
I got one more problem that I can playback with CS4270 connected but can not capture.
I use aplay jj.wav to playback audio and arecord -D hw:1,0 -r 44100 -f S16_LE -c 2 -d 10 i2s.wav to capture audio.
My settings are:

amixer -c 1 cset name="I2S5 Mux" ADMAIF1
amixer -c 1 cset name="I2S5 Mux" I2S5

Is there any problem with my settings ?

Thanks
Yun

Hello!

Thanks for the update. The above setting will connect the RX of I2S5 to the TX and so you do not want that.

What you do want is the following …

# Playback
amixer -c 1 cset name="I2S5 Mux" ADMAIF1
# Capture
amixer -c 1 cset name="ADMAIF1 Mux" I2S5

For more details see this doc.

Regards,
Jon

Hi jon,
Sorry, that is my typo, I do set as that doc said,

amixer -c 1 cset name="I2S5 Mux" ADMAIF1

amixer -c 1 cset name="ADMAIF1 Mux" I2S5

So any idea about this problem?

hi jon,
Actually, I still don’t know how to resolve the conflict dtbs mentioned above

YHuang0915

Mar 30

Hi Jon,
Thanks for your reply! The reason that failed to read i2c at addr 4C is that I didn’t reset CS4270 when it poweron.
I got another problem that I need to configure the 40-pin and then I found the changes were saved to the file /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb.
And I found in /boot/extlinux/extlinux.conf shows:

user@Jetson-xavier-NX:~$ cat /boot/extlinux/extlinux.conf
TIMEOUT 30
DEFAULT JetsonIO

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

# When testing a custom kernel, it is recommended that you create a backup of
# the original kernel and add a new entry to this file so that the device can
# fallback to the original kernel. To do this:
#
# 1, Make a backup of the original kernel
#      sudo cp /boot/Image /boot/Image.backup
#
# 2, Copy your custom kernel into /boot/Image
#
# 3, Uncomment below menu setting lines for the original kernel
#
# 4, Reboot

# LABEL backup
#    MENU LABEL backup kernel
#    LINUX /boot/Image.backup
#    INITRD /boot/initrd
#    APPEND ${cbootargs}

LABEL User Custom [2021-03-30-101212]
        MENU LABEL User Custom [2021-03-30-101212]
        LINUX /boot/Image
        FDT /boot/tegra194-p3668-all-p3509-0000-user-custom-[2021-03-30-101212].dtb
        INITRD /boot/initrd
        APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0

FDT     /boot/tegra194-p3668-all-p3509-0000.dtb

LABEL JetsonIO
        MENU LABEL Custom 40-pin Header Config
        LINUX /boot/Image
        FDT /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb
        INITRD /boot/initrd
        APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0
user@Jetson-xavier-NX:~$

As I had added the subnode CS4270 under i2c@31e0000, so I need to use
FDT /boot/tegra194-p3668-all-p3509-0000.dtb
which enables my configuration on CS4270, however I also need to configure the 40-pin to enable the i2s pin( as mentioned above changes saved to an dtb file), and these changes need the below command:
FDT /boot/tegra194-p3668-all-p3509-0000-user-custom.dtb
Then I found the two covers each other whatever I change the command sequence.
How can enable the two configurations at the same time?
Or how can I add the 40-pin changes into the /boot/tegra194-p3668-all-p3509-0000.dtb ?

Thanks
Yun

Hi,

I have read the Troubleshooting Doc and get some logs from jetson NX, settings.txt (285.1 KB) kernel_log (66.6 KB) i2s5_reg_dump (585 Bytes) dt.log (244.1 KB), could you @jonathanh help me find out the reason why NX with CS4270 connected playback is ok but failed to record audio?

Thanks
Yun

Hi,
Update,

// Playback
amixer -c 1 cset name="I2S5 Mux" ADMAIF1
// Capture
amixer -c 1 cset name="ADMAIF1 Mux" I2S5

Above routes set works well.
Issues are because of cs4270’s capture input.
Thanks for you Jon @jonathanh!

Regrads,
Yun

Hello!

Sorry for the delay. There are a couple options here …

  1. When using the jetson-io tool to setup the pinmux, generate a device-tree overlay instead of the DTB. For example, you can …
sudo /opt/nvidia/jetson-io/config-by-function.py -o dtbo i2s5

This will create a dtbo file and then you can try to manually apply this …

sudo fdtoverlay -i  /boot/tegra194-p3668-all-p3509-0000.dtb -o /boot/tegra194-p3668-all-p3509-0000-cs4270.dtb <overlay-dtbo>

Then update your extlinux.conf to boot the new /boot/tegra194-p3668-all-p3509-0000-cs4270.dtb.

  1. Instead of using the jetson-io, use the pinmux spreadsheet to make the necessary changes to the default pinmux.

Regards,
Jon

hi Jon,

Thank you very much.

I tried your suggesttions and I got another way that writting all the changes to the dts file,
Linux_for_Tegra/source/public/hardware/nvidia/platform/t19x/jakku/kernel-dts/tegra194-p3668-all-p3509-0000.dts
and generate my own dtb file which is also works well. :)

Regards,
Yun

Hi Yun,

Yes that is the best long term option.

Jon