Jetson Orin NX (L4T R36.4.4): TLV320AIC3109 over I2S2 (DAP2) - audio not working, please review DTS

Hello,

I am trying to enable an external audio codec TLV320AIC3109 on a Jetson Orin NX module running Jetson Linux (L4T) R36.4.4 (JetPack 6.x).

Hardware / connections:

  • Module: Jetson Orin NX
  • Codec: TLV320AIC3109 (driver compatible: “ti,tlv320aic3x”)
  • I2C bus: /bus@0/i2c@3160000, codec address 0x18
  • Audio interface: I2S2 (DAP2) at /bus@0/aconnect@2900000/ahub@2900800/i2s@2901100
  • MCLK pin configured on soc_gpio59_pac6 (function “aud”)
  • Fixed regulators: AVDD=3.3V, DVDD/IOVDD=1.8V

Software:

  • Jetson Linux / L4T: R36.4.4
  • Using ASoC audio graph card: “nvidia,tegra186-audio-graph-card”

Problem:
The codec does not work (no functional audio). I will attach my DTS overlay/snippet. Could someone please review the DTS for correctness (audio graph card dai-link, I2S2 configuration, pinmux/pinctrl, clocks/MCLK expectations, and power supplies)?

#include <dt-bindings/clock/tegra234-clock.h>
#include <dt-bindings/pinctrl/pinctrl-tegra.h>

/ {
    codec_avdd: regulator-codec-avdd {
        compatible = "regulator-fixed";
        regulator-name = "codec-avdd";
        regulator-min-microvolt = <3300000>;
        regulator-max-microvolt = <3300000>;
        regulator-always-on;
    };

    codec_dvdd: regulator-codec-dvdd {
        compatible = "regulator-fixed";
        regulator-name = "codec-dvdd";
        regulator-min-microvolt = <1800000>;
        regulator-max-microvolt = <1800000>;
        regulator-always-on;
    };

    tegra_sound: sound {
        compatible = "nvidia,tegra186-audio-graph-card";
        clocks = <&bpmp TEGRA234_CLK_PLLA>;
        clock-names = "pll_a";
        status = "okay";

        nvidia-audio-card,name = "TLV320AIC3109 on Orin NX";

        nvidia-audio-card,dai-link@0 {
            status = "okay";
            link-type = <0>;
            format = "i2s";

            cpu {
                sound-dai = <&tegra_i2s2 0>;
                dai-format = "i2s";
                bitclock-master = <&tegra_i2s2>;
                frame-master = <&tegra_i2s2>;
            };

            codec {
                sound-dai = <&tlv320aic3109>;
                prefix = "TLV";
            };
        };
    };

    bus@0 {
        pinmux@2430000 {
            dap2_active_state: dap2-active-pins {
                dap2_sclk {
                    nvidia,pins = "soc_gpio41_ph7";
                    nvidia,function = "i2s2";
                    nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                    nvidia,tristate = <TEGRA_PIN_DISABLE>;
                    nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                    nvidia,lpdr = <TEGRA_PIN_DISABLE>;
                };

                dap2_dout {
                    nvidia,pins = "soc_gpio42_pi0";
                    nvidia,function = "i2s2";
                    nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                    nvidia,tristate = <TEGRA_PIN_DISABLE>;
                    nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                    nvidia,lpdr = <TEGRA_PIN_DISABLE>;
                };

                dap2_din {
                    nvidia,pins = "soc_gpio43_pi1";
                    nvidia,function = "i2s2";
                    nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                    nvidia,tristate = <TEGRA_PIN_ENABLE>;
                    nvidia,enable-input = <TEGRA_PIN_ENABLE>;
                    nvidia,lpdr = <TEGRA_PIN_DISABLE>;
                };

                dap2_fs {
                    nvidia,pins = "soc_gpio44_pi2";
                    nvidia,function = "i2s2";
                    nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                    nvidia,tristate = <TEGRA_PIN_DISABLE>;
                    nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                    nvidia,lpdr = <TEGRA_PIN_DISABLE>;
                };
            };

            mclk_active_state: mclk-active-pins {
                mclk_pac6 {
                    nvidia,pins = "soc_gpio59_pac6";
                    nvidia,function = "aud";
                    nvidia,pull = <TEGRA_PIN_PULL_NONE>;
                    nvidia,tristate = <TEGRA_PIN_DISABLE>;
                    nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                    nvidia,lpdr = <TEGRA_PIN_DISABLE>;
                };
            };
        };

        i2c@3160000 {
            status = "okay";

            tlv320aic3109: codec@18 {
                compatible = "ti,tlv320aic3x";
                reg = <0x18>;
                status = "okay";
                #sound-dai-cells = <0>;
                ai3x-micbias-vg = <2>;
                AVDD-supply = <&codec_avdd>;
                DRVDD-supply = <&codec_avdd>;
                DVDD-supply = <&codec_dvdd>;
                IOVDD-supply = <&codec_dvdd>;
            };
        };

        aconnect@2900000 {
            status = "okay";

            ahub@2900800 {
                status = "okay";

                tegra_i2s2: i2s@2901100 {
                    status = "okay";
                    #sound-dai-cells = <1>;
                    pinctrl-names = "default";
                    pinctrl-0 = <&dap2_active_state &mclk_active_state>;
                };
            };
        };
    };
};

  1. Is “nvidia,tegra186-audio-graph-card” the correct approach on Orin (t234) for a simple I2S codec like AIC3109?
  2. Are the dai-link properties (format, master/slave settings, sound-dai phandles) correct for I2S2 on t234?
  3. Is the MCLK pin configuration sufficient, or do I need additional clock nodes / assigned-clocks settings for the codec to get a valid MCLK?
  4. Anything obviously missing in the DTS (routing, widgets, jack, etc.) that could prevent the card/codec from probing correctly?

Thank you for any help.

*** Please note that this reply is generated by LLM automatically ***

I’ll review the provided information and offer a comprehensive answer.

Jetson Orin NX and TLV320AIC3109 Codec

First, let’s confirm that the Jetson Orin NX module is compatible with the TLV320AIC3109 codec. The codec is a popular choice for audio applications, and it’s supported by the titlv320aic3x driver.

Hardware Connections

The hardware connections seem to be correct:

  • Module: Jetson Orin NX
  • Codec: TLV320AIC3109
  • I2C bus: bus0-i2c-3160000
  • Codec address: 0x18
  • Audio interface: I2S2 (DAP2) at bus0-aconnect-2900000-ahub-2900800-i2s-2901100
  • MCLK pin: configured on soc-gpio-59 (pac6 function: aud)

Software Configuration

The software configuration is using Jetson Linux L4T R3644 with JetPack 6.x. The ASoC audio graph card is set to nvidiategra186audiographcard.

DTS Overlays

To review the DTS overlays, I would need to see the actual code snippet. However, I can provide some general guidance on what to check:

  1. dailink properties: Verify that the dailink properties are set correctly for I2S2 on the Jetson Orin NX. Specifically, check the format, masters, and slave settings.
  2. sound dai: Ensure that the sound dai node is configured correctly for the TLV320AIC3109 codec.
  3. phandles: Verify that the phandles are set correctly for the I2S2 interface.
  4. MCLK pin configuration: Check that the MCLK pin configuration is sufficient. You may need to add additional clock nodes or assigned-clocks settings for the codec to get a valid MCLK.
  5. power supplies: Ensure that the power supplies are configured correctly for the codec.

nvidiategra186audiographcard

The nvidiategra186audiographcard is a valid approach for simple I2S codecs like the TLV320AIC3109 on the Jetson Orin NX. However, you may need to modify the DTS overlays to accommodate the specific requirements of your codec.

Comparison with Other Jetson Modules

The Jetson Orin NX has a different architecture compared to other Jetson modules, such as the Jetson Xavier NX or Jetson AGX Xavier. Therefore, the DTS overlays may need to be modified to accommodate the specific requirements of the Jetson Orin NX.

Recommendations

Based on the provided information, I recommend the following:

  1. Review the DTS overlays carefully to ensure that all properties are set correctly.
  2. Verify that the MCLK pin configuration is sufficient and add additional clock nodes or assigned-clocks settings if necessary.
  3. Check the power supplies to ensure they are configured correctly for the codec.
  4. Consider modifying the DTS overlays to accommodate the specific requirements of the TLV320AIC3109 codec on the Jetson Orin NX.

If you provide the actual DTS overlays code snippet, I can offer more specific guidance and recommendations.

*** Please give the thumbs up if you get answers you like. Or provide feedback to help us improve the answer. ***

Thank you for the detailed review!

Our configuration is correct — the tlv320aic3x driver is successfully bound to the TLV320AIC3109 codec via I2C bus (bus0-i2c-3160000, address 0x18), and the hardware connections are verified.

One important note regarding DTS: we are not using DTS overlays. Instead, we compile a combined monolithic DTS directly within our build system. The final .dtb is built as a whole, not applied as a patch on top of the base device tree.

Could you provide an example of DTS configuration for the nvidiategra186audiographcard with TLV320AIC3109 implemented as a full DTS (not an overlay)? This would be very helpful for comparison with our current implementation.

Hi ,

Please refer to NVIDIA’s R36.4.3 custom sound card guide:
https://docs.nvidia.com/jetson/archives/r36.4.3/DeveloperGuide/SD/Communications/AudioSetupAndDevelopment.html#to-interface-a-customized-sound-card
That section contains an example DTS for custom codec integration.

A few things to verify against the guide:

  • Use NVIDIA-specific nvidia-audio-card,* properties, not generic audio-graph property names.
  • Update the correct nvidia-audio-card,dai-link@… node for the I2S interface in use.
  • Set codec { sound-dai = <…>; prefix = “…”; } correctly for the TLV320AIC3109.
  • Make sure bitclock-master and frame-master match the actual clocking: Tegra master vs codec master.
  • Ensure routing/widgets use the same prefix as the codec.

Also, please clarify what “audio not working” means: is the sound card not registered, is registration failing, or does it register but playback/capture fails?