Setting up SGTL5000

Hey guys,

I’m hoping one of you guys can help me out with setting up the SGTL5000 chip with my Xavier NX. Let’s just say I’m kind of a newbie. I’ve read the official documents for trying to set up a custom board and populating nodes and what not. However, I still feel it isn’t very clear to me. Like what exact file am I supposed to be writing this on, or how am I supposed to know if it is even connected. Can someone please provide detailed steps as to how I am supposed to be approaching this because at this point I have no clue. Thank you.

Hello!

We have tested the SGTL5000 codec with Jetson Xavier NX and so we should be able to help you. We have used the FE-PI Audio Z V2 module but unfortunately this is no longer available. If you did have one of these modules then it is possible to use the ‘jetson-io’ tool to configure the board for this module. It might even be possible to use the same FE-PI configuration for your setup depending on how the codec is connected. So some questions …

  1. Are you using an off-the-shelf module for the SGTL5000 codec and if so which? Otherwise are you creating some custom hardware for this?
  2. What provides the clock to the SGTL5000 codec MCLK?
  3. What I2S interface are you using for the SGTL5000 codec?

Thanks
Jon

Thanks for the response jonathanh! So I configured the pins using the jetson-io.py files and I just used one of the configured hardware modules which was the FE-PI Audio V1 and Z V2.

  1. I am using the Dev-12767 board from SparkFun electronics.
  2. I am using a 12MHz clock.
  3. The SGTL5000 codec is hooked up to the I2S0 on pin 38/40.

I made a mistake in my last response. The board I am using is the Dev-15845. That other one is obsolete now.

Hello!

Sorry for the delay. The procedure for adding the codec is as follows.

  1. Configure the pinmux for the appropriate I2S pins.
  2. Add the codec node to device-tree. For the sgtl5000 codec we need to add the following under the appropriate I2C node.
	sgtl5000: sgtl5000@0a {
		compatible = "fsl,sgtl5000";
		reg = <0x0a>;
		clocks = <&sgtl5000_mclk>;
		micbias-resistor-k-ohms = <2>;
		micbias-voltage-m-volts = <3000>;
		VDDA-supply = <&hdr40_vdd_3v3>;
		VDDIO-supply = <&hdr40_vdd_3v3>;
		status = "okay";
	};
  1. Given that you are using a fixed rate clock for the codec we also need to add a new clock node for this fixed rate clock. For example …
	clocks {
		sgtl5000_mclk: sgtl5000_mclk {
			compatible = "fixed-clock";
			#clock-cells = <0>;
			clock-frequency = <12000000>;
			clock-output-names = "sgtl5000-mclk";
			status = "okay";
			};
	};
  1. Then it is necessary to link the I2S interface to the codec in device-tree. Recommend that you use the ‘fe-pi-audio-z-v2’ link-name because then it will simplify the changes you need to make to the audio machine driver.
	hdr40_snd_link_i2s: i2s_dai_link1: nvidia,dai-link-1 {
		link-name = "fe-pi-audio-z-v2";
		cpu-dai = <&tegra_i2s4>;
		codec-dai = <&sgtl5000>;
		cpu-dai-name = "I2S4";
		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 = "x";
		status = "okay";
	};
  1. Next it is necessary to modify the ‘nvidia,audio-routing’ property to route the codec inputs and outputs to the Tegra audio machine driver. Note that these names come from the sgtl5000 codec and Tegra audio machine driver. The ‘x’ prefix comes from the dai-link ‘name-prefix’ property in step 3.
	nvidia,audio-routing =
		"x Headphone",          "x HP_OUT",
		"x MIC_IN",             "x Mic",
		"x ADC",                "x Mic Bias",
		"x LINE_IN",            "x Line In",
		"x Line Out",           "x LINE_OUT";
	};
  1. Update the Tegra audio machine driver to set the 12MHz clock rate for codec. In other words, change the 12288000 to 12000000 in the function tegra_machine_fepi_init().

  2. Recompile the kernel and device-tree sources.

  3. Re-flash Jetson.

  4. Test audio capture and playback

arecord -D hw:tegrasndt210ref -c 2 -r 48000 -f S16_LE -d 30 cap.wav
aplay -D hw:tegrasndt210ref -c 2 -r 48000 -f S16_LE cap.wav

Regards,
Jon

Thanks for the response! So far I have updated the device trees for the codecs, but I’m not sure where to find tegra_machine_fepi_init(). Under what file is that under and what is the path for it? Also you refer to the Jetson Nano, would these steps work for the Xavier NX as well?

Hello!

With regard to the tegra_machine_fepi_init() it is in the source file sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c. Please see above link. I have corrected some of the other links to references for Jetson Nano to Jetson Xavier NX. Sorry I think some one else was asking about Nano and mixed these up.

Jon

Hi,

I don’t see that path anywhere on the Jetson. Did I forget to download something?

Thanks

Hello!

Sorry this is not a path on the target but a path on the host PC and assumes that you have downloaded the kernel sources. For more information please see this doc.

Regards,
Jon

Hi,

I managed to find it after following the instructions in the documentation. I feel like the solution is almost there and you’ve been super helpful.

This is my device tree which was copied from a sample file which I used as a template:

/dts-v1/;

/ {
    overlay-name = "SGTL5000 Codec";
    compatible = "nvidia,p3509-0000+p3668-0000", "nvidia,p3509-0000+p3668-0001";

    fragment@0 {
            target-path = "/";

            __overlay__ {

                    clocks {

                            sgtl5000_mclk: sgtl5000_mclk {
                                    compatible = "fixed-clock";
                                    #clock-cells = <0>;
                                    clock-frequency = <12000000>;
                                    clock-output-names = "sgtl5000-mclk";
                                    status = "okay";
                                    linux,phandle = <0x1>;
                                    phandle = <0x1>;
                            };
                    };
            };
    };

    fragment@1 {
            target = <0xffffffff>;

            __overlay__ {
                    #address-cells = <0x1>;
                    #size-cells = <0x0>;

                    sgtl5000: sgtl5000@0a {
                            compatible = "fsl,sgtl5000";
                            reg = <0x0a>;
                            clocks = <&sgtl5000_mclk>;
                            micbias-resistor-k-ohms = <2>;
                            micbias-voltage-m-volts = <3000>;
                            status = "okay";
                            VDDA-supply = <&hdr40_vdd_3v3>;
                            VDDIO-supply = <&hdr40_vdd_3v3>;
                            status = "okay"
                            linux,phandle = <0x2>;
                            phandle = <0x2>;

                    };
            };
    };

    fragment@2 {
            target = <0xffffffff>;

            __overlay__ {
                    nvidia,audio-routing = "x Headphone", "x HP_OUT", "x MIC_IN", "x Mic", "x ADC", "x Mic Bias", "x LINE_IN", "x Line In", "x Line Out", "x LINE_OUT";
            };
    };

    fragment@3 {
            target = <0xffffffff>;

            __overlay__ {
                    hdr40_snd_link_i2s: i2s_dai_link1: nvidia,dai-link-1 {
                            link-name = "fe-pi-audio-z-v2";
                            cpu-dai = <&tegra_i2s4>;
                            codec-dai = <&sgtl5000>;
                            cpu-dai-name = "I2S4";
                            codec-dai-name = "sgtl5000";
                            format = "i2s";
                            bitclock-master;
                            frame-master;
                            bitclock-noninversion;
                            frame-noninversion;
                            bit-format = "s16_le";
                            srate = <48000>;
                            num-channel = <2>;
                            name-prefix = "x";
                            status = "okay";
                    };
            };
    };

    fragment@4 {
            target = <0xffffffff>;

            __overlay__ {
                    pinctrl-names = "default";
                    pinctrl-0 = <0x3>;

                    header-40pin-pinmux {
                            linux,phandle = <0x3>;
                            phandle = <0x3>;

                            pin12 {
                                    nvidia,pins = "dap5_sclk_pt5";
                                    nvidia,function = "i2s5";
                                    nvidia,pull = <0x1>;
                                    nvidia,tristate = <0x0>;
                                    nvidia,enable-input = <0x1>;
                            };

                            pin35 {
                                    nvidia,pins = "dap5_fs_pu0";
                                    nvidia,function = "i2s5";
                                    nvidia,pull = <0x1>;
                                    nvidia,tristate = <0x0>;
                                    nvidia,enable-input = <0x1>;
                            };

                            pin38 {
                                    nvidia,pins = "dap5_din_pt7";
                                    nvidia,function = "i2s5";
                                    nvidia,pull = <0x1>;
                                    nvidia,tristate = <0x1>;
                                    nvidia,enable-input = <0x1>;
                            };

                            pin40 {
                                    nvidia,pins = "dap5_dout_pt6";
                                    nvidia,function = "i2s5";
                                    nvidia,pull = <0x1>;
                                    nvidia,tristate = <0x0>;
                                    nvidia,enable-input = <0x0>;
                            };
                    };
            };
    };

    fragment@5 {

            i2s@2901400 {
                    status = "okay";
            };
    };

    __symbols__ {
            sgtl5000_mclk = "/fragment@0/__overlay__/clocks/sgtl5000_mclk";
            sgtl5000 = "/fragment@1/__overlay__/sgtl5000@0a";
            hdr40_pinmux = "/fragment@4/__overlay__/header-40pin-pinmux";
    };

    __fixups__ {
            hdr40_i2c1 = "/fragment@1:target:0";
            hdr40_vdd_3v3 = "/fragment@1/__overlay__/sgtl5000@0a:VDDA-supply:0", "/fragment@1/__overlay__/sgtl5000@0a:VDDIO-supply:0";
            tegra_sound = "/fragment@2:target:0";
            hdr40_snd_link_i2s = "/fragment@3:target:0";
            pinmux = "/fragment@4:target:0";
    };

    __local_fixups__ {

            fragment@1 {

                    __overlay__ {

                            sgtl5000@0a {
                                    clocks = <0x0>;
                            };
                    };
            };

            fragment@3 {

                    __overlay__ {
                            codec-dai = <0x0>;
                    };
            };

            fragment@4 {

                    __overlay__ {
                            pinctrl-0 = <0x0>;
                    };
            };
    };
};

I’m thinking that I am missing a whole lot more from this file since the errors I receive is that the reference node/label is non-existant.

Hello!

So just to back up there are a couple ways to do this …

  1. Edit the device-tree sources directly, re-build device-tree and then flash the device-tree on the target.
  2. Create a device-tree overlay and apply to the default device-tree image

The above is a device-tree overlay and you can go down this path if you wish. This can be a good option for prototyping. There are some issues with the above overlay, which are …

  1. ‘target’ should reference a device-tree phandle or node and not be set to 0xffffffff.
  2. Nodes symbols, fixups and local_fixups are generated by the device-tree compiler and so should not be in the source.

For the fe-pi module the majority of the overlay is located in this file. This dtsi file is include by this file for jetson-xavier nx that generates the actual dtbo file.

There is some more information here about creating custom overlays.

Regards,
Jon

Hi,

I’m editing the overlay file since I am prototyping with the device. After following the example in the first link from the last message, and including /plugin/ at the top of the file, I compiled it with the jetson-io.py file. It seemed like it was going to work, but afterwards the screen wouldn’t turn on. The device seemed to be on since the LED was active, but the screen said it was receiving no signal. So I had to re-flash with a fresh image and now I’m just trying to figure out what caused it to not display anything.

Thanks

Hello!

To compile that dtsi file you would need to include this in a dts file as mentioned in the 2nd link of my previous message. There are some definitions that that dtsi file needs.

It is possible that if the dtb is not created correctly that Linux will not boot and so you will not see anything on the screen. In such scenarios you need to access the serial console to see what is happening. The serial console can be accessed in the same way as the newer version of the Jetson Nano as shown in this video.

Regards,
Jon