I2S audio codec issues on the TX2 NX using the SGTL5000 codec

We have a custom carrier board for the TX2 NX which includes an SGTL5000 audio codec. The design is very similar to the fe-pi-audio system. Unfortunately I can’t get the audio devices to come up.

The codec is on module I2S1 / tegra I2S3. We’re running JetPack 4.6.3/L4T 32.7.3. We have a 12.288MHz TCXO generating the MCLK.

I believe the I2C side of things is working since I see this in the dmesg logs:

    # dmesg | grep sgtl
    [    1.515816] sgtl5000 7-000a: sgtl5000 revision 0x11
    [    1.516709] sgtl5000 7-000a: Using internal LDO instead of VDDD: check ER1

I’ve made these device tree changes in tegra186-p3636-0001-a00.dtsi based on this post:

#include <audio/tegra-platforms-audio-dai-links.dtsi>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-common/jetson/tegra186-p3509-0000-p3636-0001.h>

/ {
	hda@3510000 {
		status = "okay";
	};

	clocks {
		sgtl5000_mclk: sgtl5000_mclk {
			compatible = "fixed-clock";
			#clock-cells = <0>;
			clock-frequency = <12288000>;
			clock-output-names = "sgtl5000-mclk";
			status = "okay";
		};
	};

	rt565x_dai_link: nvidia,dai-link-3 {
		link-name = "fe-pi-audio-z-v2";
		cpu-dai = <&tegra_i2s3>;
		codec-dai = <&sgtl5000>;
		cpu-dai-name = "I2S3";
		codec-dai-name = "sgtl5000";
		format = "i2s";
		bitclock-master;
		frame-master;
		bitclock-noninversion;
		frame-noninversion;
		bit-format = "s16_le";
		srate = <48000>;
		num-channel = <2>;
		ignore_suspend;
		name-prefix = "z";
		status = "okay";
	};

	tegra_sound: sound {
		nvidia,audio-routing =
			"z Headphone",          "z HP_OUT",
			"z MIC_IN",             "z Mic",
			"z ADC",                "z Mic Bias",
			"z LINE_IN",            "z Line In",
			"z Line Out",           "z LINE_OUT";
	};
	
	i2c@c250000 { 
		sgtl5000: sgtl5000@0a {
			compatible = "fsl,sgtl5000";
			reg = <0x0a>;
			clocks = <&sgtl5000_mclk>;
			micbias-resistor-k-ohms = <2>;
			micbias-voltage-m-volts = <1250>;
			VDDA-supply = <&vdd_1v8_ap>;
			VDDIO-supply = <&vdd_1v8_ap>;
			status = "okay";
		};
	};
};

I’ve made changes to the pinmux following this post:

# grep dmic /sys/kernel/debug/tegra_pinctrl_reg
Bank: 0 Reg: 0x02432000 Val: 0x00006401 -> dmic1_clk_pm1
Bank: 0 Reg: 0x02432008 Val: 0x00006459 -> dmic1_dat_pm0
Bank: 0 Reg: 0x02432010 Val: 0x00006401 -> dmic2_dat_pm2
Bank: 0 Reg: 0x02432018 Val: 0x00006401 -> dmic2_clk_pm3
Bank: 0 Reg: 0x02432020 Val: 0x00006416 -> dmic4_dat_pm4
Bank: 0 Reg: 0x02432028 Val: 0x00006416 -> dmic4_clk_pm5

Having done this I only see the HDMI playback device - the sgtl5000 is missing:

# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: tegrahda [tegra-hda], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: tegrahda [tegra-hda], device 7: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

But as mentioned earlier the sgtl5000 is coming up in dmesg:

# dmesg | grep sgtl
[    1.515816] sgtl5000 7-000a: sgtl5000 revision 0x11
[    1.516709] sgtl5000 7-000a: Using internal LDO instead of VDDD: check ER1

Here’s the audio routing displayed using this command:

cat /proc/device-tree/sound/nvidia,audio-routing
links=$(find /proc/device-tree/sound -type d -name nvidia,dai-link-*)
for link in ${links}; do cat ${link}/link-name; echo -n " " ; cat ${link}/cpu-dai-name ; echo -n " " ; cat ${link}/name-prefix ; echo; done

Output:

z Headphonez HP_OUTz MIC_INz Micz ADCz Mic Biasz LINE_INz Line Inz Line Outz LINE_OUT
spdif-dit-8 DMIC2 b
spdif-dit-6 I2S6 o
spdif-dit-3 I2S4 m
dspk1-playback DSPK1 d1
spdif-dit-1 I2S2 y
spdif-dit-9 DMIC3 c
spdif-dit-7 DMIC1 a
spdif-dit-4 I2S5 n
dspk2-playback DSPK2 d2
spdif-dit-2 I2S3 z
spdif-dit-10 DMIC4 d
spdif-dit-0 I2S1 x

Do you have any suggestions where we could look next for the issue?

Update: I found an issue with the dai link name and I’ve fixed it.

Now the link output is:

spdif-dit-8 DMIC2 b
spdif-dit-6 I2S6 o
spdif-dit-3 I2S4 m
dspk1-playback DSPK1 d1
spdif-dit-1 I2S2 y
spdif-dit-9 DMIC3 c
spdif-dit-7 DMIC1 a
spdif-dit-4 I2S5 n
dspk2-playback DSPK2 d2
fe-pi-audio-z-v2 I2S3 z
spdif-dit-10 DMIC4 d
spdif-dit-0 I2S1 x

The device tree file tegra186-p3636-0001-a00.dtsi is now:

#include <audio/tegra-platforms-audio-dai-links.dtsi>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
#include <dt-common/jetson/tegra186-p3509-0000-p3636-0001.h>

/ {
	hda@3510000 {
		status = "okay";
	};

	clocks {
		sgtl5000_mclk: sgtl5000_mclk {
			compatible = "fixed-clock";
			#clock-cells = <0>;
			clock-frequency = <12288000>;
			clock-output-names = "sgtl5000-mclk";
			status = "okay";
		};
	};

	tegra_sound: sound {
		nvidia,audio-routing =
			"z Headphone",          "z HP_OUT",
			"z MIC_IN",             "z Mic",
			"z ADC",                "z Mic Bias",
			"z LINE_IN",            "z Line In",
			"z Line Out",           "z LINE_OUT";

		rt565x_dai_link: nvidia,dai-link-3 {
			link-name = "fe-pi-audio-z-v2";
			cpu-dai = <&tegra_i2s3>;
			codec-dai = <&sgtl5000>;
			cpu-dai-name = "I2S3";
			codec-dai-name = "sgtl5000";
			format = "i2s";
			bitclock-master;
			frame-master;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			srate = <48000>;
			num-channel = <2>;
			ignore_suspend;
			name-prefix = "z";
			status = "okay";
		};
	};
	
	i2c@c250000 { 
		sgtl5000: sgtl5000@0a {
			compatible = "fsl,sgtl5000";
			reg = <0x0a>;
			clocks = <&sgtl5000_mclk>;
			micbias-resistor-k-ohms = <2>;
			micbias-voltage-m-volts = <1250>;
			VDDA-supply = <&vdd_1v8_ap>;
			VDDIO-supply = <&vdd_1v8_ap>;
			VDDD-supply = <&vdd_1v8_ap>;
			status = "okay";
		};
	};
};

But unfortunately there’s still no joy from aplay - only the HDMI audio devices are shown:

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: tegrahda [tegra-hda], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: tegrahda [tegra-hda], device 7: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Update: I reinstated the tegra-snd-t186ref-mobile-rt565x section in the device tree and now I get devices in aplay -l. I’m not entirely sure why I need entries for a device I don’t have but checking the source code it seems like this is the missing link.

The problem is resolved so feel free to close this issue.