ASOC cannot find DAPM widgets for TLV320ADC3100

Dear Nvidia support,

I get the following error log from the ASoC

[   10.782943] tegra-adma 2930000.dma-controller: Tegra210 ADMA driver registered 32 channels
[   10.836989] tegra-asoc: sound: ASoC: no sink widget found for CVB-TLV IN_2L
[   10.836996] tegra-asoc: sound: ASoC: Failed to add route CVB-TLV Mic Jack → direct → CVB-TLV IN_2L
[   10.837014] tegra-asoc: sound: ASoC: no sink widget found for CVB-TLV IN_2R
[   10.837016] tegra-asoc: sound: ASoC: Failed to add route CVB-TLV Mic Jack → direct → CVB-TLV IN_2R
[   10.840758] tegra-asoc: sound: snd_soc_register_card failed (-19)

I tried the troubleshooting but the driver appears to have instantiated and the chip appears at 0x18 on the i2c1 bus.
Audio Setup and Development — NVIDIA Jetson Linux Developer Guide

Can you help me figure out what is wrong?

$ i2cdetect -y -r 0
    0 1 2 3 4 5 6 7 8 9 a b c d e f
00:                 – – – – – – – –
10: – – – – – – – – UU – – – – – – –
20: – – – – – – – – – – – – – – – –
30: – – – – – – – – – – – – – – – –
40: – – – – – – – – – – – – – – – –
50: UU – – – – – – – – – – – – – – –
60: – – – – – – – – – – – – – – – –
70: – – – – – – – –
$ cat /sys/kernel/debug/asoc/components
2910000.asrc
290e400.arad
290f000.admaif
2908000.processing-engine
290a200.mvc
2907500.afc
290a000.mvc
2907400.afc
2905100.dspk
2907300.afc
2905000.dspk
2907200.afc
2907100.afc
2904300.dmic
2907000.afc
290bb00.amixer
2904100.dmic
2904000.dmic
2902600.sfc
2902400.sfc
2902200.sfc
2903b00.adx
2902000.sfc
2903a00.adx
2903900.adx
2901400.i2s
2903300.amx
2903200.amx
2903800.adx
2901200.i2s
2903100.amx
2903000.amx
2901100.i2s
2900800.ahub
tlv320adc3xxx-codec.0-0018
snd-soc-dummy
snd-soc-dummy
$ amixer -c APE controls
Invalid card number 'APE'.

Environment

FW: l4t r36.4.4

I am using a custom carrier board for the Orin Nx that has a TLV320ADC3100 connected to the following pins on the Orin NX.

  • I2S4_SDATA_IN
  • I2S4_SCLK
  • I2S4_LRCLK
  • AUD_MCLK
  • I2C1_CLK
  • I2C1_DAT
  • GPIO3_PQ6(reset pin)

Device Tree

i2c@3160000 {
			clocks-frequency = <100000>;
			status = "okay";

			/delete-node/ eeprom@50;
			/delete-node/ eeprom@57;
		    /* ADC */
			tlv320adc3100: tlv320adc3100@18 {
				#sound-dai-cells = <0>;
				compatible = "ti,tlv320adc3100";
				status ="okay";
				reg = <0x18>;

				reset-gpios = <&gpio TEGRA234_MAIN_GPIO(Q, 6) GPIO_ACTIVE_LOW>;

				clocks = <&bpmp TEGRA234_CLK_AUD_MCLK>;
				clock-names = "mclk";
				ti,micbias1-vg = <ADC3XXX_MICBIAS_2_0V>;
				AVDD-supply = <&reg_3p3v>;
				IOVDD-supply = <&reg_1p8v>;
				DVDD-supply = <&reg_1p8v>;

			};
		};
sound {
		nvidia-audio-card,widgets =
			"Microphone",            "CVB-TLV Mic Jack";

		nvidia-audio-card,routing =
				"CVB-TLV IN_2L",       "CVB-TLV Mic Jack",
				"CVB-TLV IN_2R",       "CVB-TLV Mic Jack";

		nvidia-audio-card,mclk-fs = <256>;

		/* ADC */
		i2s4_to_codec: nvidia-audio-card,dai-link@79 {
			link-name = "tlv320adc3xxx-hifi";
			codec {
				sound-dai = <&tlv320adc3100 0>;
				prefix = "CVB-TLV";
			};
		};
	};

Changes to tegra_codec.c

+ #include <drivers-private/sound/soc/codecs/tlv320adc3xxx.h>

+ static int tegra_machine_tlv320adc3xxx_init(struct snd_soc_pcm_runtime *rtd)
+ {
+ 	struct snd_soc_card *card = rtd->card;
+ 	struct device *dev = rtd->card->dev;
+ 	dev_err(dev, "Enter tegra_machine_tlv320adc3xxx_init\n");
+ 	snd_soc_dapm_sync(&card->dapm);
+ 	return tegra_audio_dai_init(rtd);
+ }

int tegra_codecs_runtime_setup(struct snd_soc_card *card,
			       unsigned int srate,
			       unsigned int channels,
			       unsigned int aud_mclk)
{
.
.
.
+ rtd = get_pcm_runtime(card, "tlv320adc3xxx-hifi");
+	if (rtd) {
+		err = snd_soc_dai_set_sysclk(rtd->dais[rtd->dai_link->num_cpus],
+						 0,
+					     aud_mclk, SND_SOC_CLOCK_IN);
+		if (err < 0) {
+			dev_err(card->dev, "dais[%d] clock not set\n",
+				rtd->dai_link->num_cpus);
+			return err;
+		}
+	}
.
.
.
}

int tegra_codecs_init(struct snd_soc_card *card)
{
.
.
.
+ else if (strstr(dai_links[i].name, "tlv320adc3xxx-hifi"))
			dai_links[i].init = tegra_machine_tlv320adc3xxx_init;
.
.
.
}

Driver code

I am using driver code that is modified.

The inputs are configured like this in the driver code:

	SND_SOC_DAPM_INPUT("IN_2L"),
	SND_SOC_DAPM_INPUT("IN_2R"),

Thank You

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

Based on the provided context, I’ll try to help you troubleshoot the issue with the ASoC error log on your custom carrier board for the Jetson Orin NX.

Firstly, I’d like to acknowledge that you’ve already tried troubleshooting and the driver appears to have instantiated, and the chip is visible at 0x18 on the i2c1 bus. This suggests that the hardware connection and basic configuration are likely correct.

To better understand the issue, I’d like to compare the pin connections you provided with the recommended pin usage for the Jetson Orin NX, as described in the Jetson Orin NX Series and Jetson Orin Nano Series Product Design Guide (DG-10931-001_v1.4).

According to the guide, the recommended pin usage for the I2S interface is:

  • I2S4_SCLK (GP206_DAP4_CLK)
  • I2S4_FS (GP209_DAP4_FS)
  • I2S4_DOUT (GP207_DAP4_DOUT)
  • I2S4_DIN (GP208_DAP4_DIN)

Your pin connections seem to match the recommended usage:

  • I2S4SDATAIN ( likely corresponds to I2S4_DIN)
  • I2S4SCLK (likely corresponds to I2S4_SCLK)
  • I2S4LRCLK (likely corresponds to I2S4_FS)
  • AUDMCLK ( likely corresponds to the clock signal for the audio codec)
  • I2C1CLK and I2C1DAT (correctly connected to the i2c1 bus)
  • GPIO3PQ6 (reset pin, likely correctly connected)

Given that the pin connections appear to be correct, the next step would be to investigate the software configuration and the ASoC driver.

The error log you provided doesn’t give much information about the specific error. However, I can suggest some potential causes:

  1. ASoC driver configuration: Double-check that the ASoC driver is correctly configured for the TLV320ADC3100 codec. Verify that the driver is loaded and that the codec is properly registered.
  2. I2C communication: Ensure that the i2c1 bus is properly configured and that communication with the codec is working correctly. You can try using the i2cdetect command to verify that the codec is visible on the i2c1 bus.
  3. Clock configuration: Verify that the clock signals for the audio codec (AUDMCLK) and the I2S interface (I2S4_SCLK) are correctly configured and enabled.
  4. GPIO configuration: Ensure that the GPIO pins used for the reset signal (GPIO3PQ6) are correctly configured and that the reset signal is properly asserted.

To further troubleshoot the issue, I recommend:

  1. Checking the kernel logs for any error messages related to the ASoC driver or the audio codec.
  2. Using the i2cdetect command to verify that the codec is visible on the i2c1 bus.
  3. Using the i2cget and i2cset commands to verify that the codec is properly configured and that communication with the codec is working correctly.
  4. Checking the ASoC driver documentation and the Linux kernel documentation for any specific configuration requirements for the TLV320ADC3100 codec.

If you’re still unable to resolve the issue, please provide more information about the error log and the specific symptoms you’re experiencing. I’ll do my best to help you troubleshoot the problem.

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

Like i mentioned, I have already checked i2cdetect and have used i2cdump and the results seem correct. I have looked over the driver and there does not seem to be any obvious problems.

I am using this codec as a base and modified some stuff.
tlv320adc3xxx.c source code [linux/sound/soc/codecs/tlv320adc3xxx.c] - Codebrowser

tlv320adc3xxx.h source code [linux/include/dt-bindings/sound/tlv320adc3xxx.h] - Codebrowser

I added a log that will print the link-name of dai-links in the tegra_codec.c: tegra_codecs_init() function. In the logs the link-name for the dai-link@79 (“tlv320adc3xxx-hifi”) is not appearing.

When checking the device tree on the device the link-name appears.

$ strings /proc/device-tree/sound/nvidia-audio-card\,dai-link\@79/link-name
tlv320adc3xxx-hifi

I cannot figure out why the dai-link is not registering.

Can you help me figure out why?

Greetings!

Apologies for delayed response. Let me go through and get back!

Thanks!

Hi,

Machine driver parses the dai-links ( Audio Setup and Development — NVIDIA Jetson Linux Developer Guide ), tegra_codec.c is not relevant ASoC component driver.

Could you provide entire dmesg kernel log to inspect error prints

Further, I am suspecting routing. Check TLV320ADCx140 audio adc with TX2 - #31 by jonathanh and see if additional routes could be added.

For ex:

"CVB-TLV Capture", "CVB-TLV AIF_OUT"
"CVB-TLV Capture", "CVB-TLV AIF_OUT"

Codec vendor may be the right contact to propose correct routes

Thanks

Hi Atalambedu,

I attached the dmesg logs, they contain the debug logs I have added.

kernel/nvidia-oot/sound/soc/tegra/tegra_codecs.c

tegra_codec.c: tegra_codecs_init() is called by this function chain in the following file.

kernel/nvidia-oot/sound/soc/tegra/tegra_machine_driver.c

The function chain is tegra_machine_driver.c : tegra_machine_driver_probe() → add_dai_links() → tegra_codecs_init()

It appears that in the function tegra_asoc_machine.c : parse_dt_dai_links() the link-name in the device tree is not parsed correctly or just not parsed for some reason and adds a basic “tegra-dlink-xx” name to the dai-link list.

kernel/nvidia-oot/sound/soc/tegra/tegra_asoc_machine.c

dmesg_log_for_nvidia_audio_problem.log (72.6 KB)

I figured out that in a different dts file I2S4 was being disabled. When I enabled it the widgets and routes were registered.

1 Like

Great! Now you may need to set suitable mixer controls to get the capture working

Thanks!

Yes,

I am currently trying to figure out why i am getting these error logs now.

[    9.528951] ALSA: Control name 'CVB-TLV Right Input DIF_2R_3R Capture Volume' truncated to 'CVB-TLV Right Input DIF_2R_3R Capture Volum'
[    9.528958] ALSA: Control name 'CVB-TLV Right Input DIF_2L_2R Capture Volume' truncated to 'CVB-TLV Right Input DIF_2L_2R Capture Volum'
[    9.528964] ALSA: Control name 'CVB-TLV Right Input DIF_2L_3L Capture Volume' truncated to 'CVB-TLV Right Input DIF_2L_3L Capture Volum'
[    9.528974] ALSA: Control name 'CVB-TLV ADC Fine Volume Control Capture Volume' truncated to 'CVB-TLV ADC Fine Volume Control Capture Vol'
[    9.528979] ALSA: Control name 'CVB-TLV Left ADC Unselected CM Bias Capture Switch' truncated to 'CVB-TLV Left ADC Unselected CM Bias Capture'
[    9.528986] ALSA: Control name 'CVB-TLV Right ADC Unselected CM Bias Capture Switch' truncated to 'CVB-TLV Right ADC Unselected CM Bias Captur'
[    9.528996] tlv320adc3xxx-codec 0-0018: ## adc3100_add_widgets
[    9.529205] tegra-asoc: sound: control 2:0:0:CVB-TLV PGA Capture Volume:0 is already present
[    9.529208] tlv320adc3xxx-codec 0-0018: ASoC: Failed to add PGA Capture Volume: -16
[    9.529247] tegra-asoc: sound: ASoC: failed to instantiate card -16
[    9.531877] tegra-asoc: sound: snd_soc_register_card failed (-16)
[    9.531916] tegra-asoc:: probe of sound failed with error -16

This control seems to be the problem.

static const struct snd_kcontrol_new adc3100_snd_controls[] = {
	SOC_DOUBLE_R_TLV("PGA Capture Volume", ADC3XXX_LEFT_APGA_CTRL,
			 ADC3XXX_RIGHT_APGA_CTRL, 0, 80, 0, pga_tlv),

Hi,

Are you adding the control explicitly? It should not have caused any issue if part of codec driver provided by codec vendor. Change prefix to minimal length like ex: xy and give a try

Thanks!

Sorry for not updating,

I accidentally added code to the codec driver that added the widgets and routes twice so that error log occurred.

[    9.529208] tlv320adc3xxx-codec 0-0018: ASoC: Failed to add PGA Capture Volume: -16

I am currently using these widgets and routes in the device tree file.

nvidia-audio-card,widgets =
			"Microphone",            "CVB-TLV Mic Jack";

		nvidia-audio-card,routing =
				"CVB-TLV IN_2L",       "CVB-TLV Mic Jack",
				"CVB-TLV IN_2R",       "CVB-TLV Mic Jack",
				"CVB-TLV Left ADC",    "CVB-TLV AIF_OUT",
				"CVB-TLV Right ADC",   "CVB-TLV AIF_OUT",
				"CVB-TLV AIF_OUT",     "CVB-TLV Capture";

The last problem i am having is when calling arecord the program hangs/freezes when adding the pll routes.

In the codec driver i linked, snd_soc_dapm_add_routes() is the last function that is called.

static int adc3xxx_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params,
			     struct snd_soc_dai *dai)
{
.
.
.	
		if (!adc3xxx->use_pll) {
			snd_soc_dapm_add_routes(dapm, adc3xxx_pll_intercon,
						ARRAY_SIZE(adc3xxx_pll_intercon));
			adc3xxx->use_pll = 1;
		}
.
.
.
}

I got arecord working,

however the audio file has no audio.

command

arecord -Dhw:APE,0 -c 2 -r 48000 -f S16_LE -d 15 audio_test3.wav

trace log

arecord-2100    [000] .......   180.218898: snd_soc_dapm_widget_power: widget=I2S4 XBAR-RX val=0
         arecord-2100    [000] .......   180.218902: snd_soc_dapm_path: *I2S4 XBAR-Playback -> (direct) -> I2S4 XBAR-RX
         arecord-2100    [000] .......   180.218902: snd_soc_dapm_widget_power: widget=I2S4 XBAR-Playback val=0
         arecord-2100    [000] .......   180.218904: snd_soc_dapm_path: *tegra-dlink-42-capture -> (direct) -> I2S4 XBAR-Playback
         arecord-2100    [000] .......   180.218905: snd_soc_dapm_widget_power: widget=tegra-dlink-42-capture val=0
         arecord-2100    [000] .......   180.218906: snd_soc_dapm_path: *I2S4 CIF-Capture -> (direct) -> tegra-dlink-42-capture
         arecord-2100    [000] .......   180.218907: snd_soc_dapm_widget_power: widget=I2S4 CIF-Capture val=0
         arecord-2100    [000] .......   180.218908: snd_soc_dapm_path: *I2S4 TX -> (direct) -> I2S4 CIF-Capture
         arecord-2100    [000] .......   180.218908: snd_soc_dapm_widget_power: widget=I2S4 TX val=0
         arecord-2100    [000] .......   180.218910: snd_soc_dapm_path: *I2S4 DAP-Playback -> (direct) -> I2S4 TX
         arecord-2100    [000] .......   180.218910: snd_soc_dapm_widget_power: widget=I2S4 DAP-Playback val=0
         arecord-2100    [000] .......   180.218912: snd_soc_dapm_path: *tlv320adc3xxx-hifi-capture -> (direct) -> I2S4 DAP-Playback
         arecord-2100    [000] .......   180.218912: snd_soc_dapm_widget_power: widget=tlv320adc3xxx-hifi-capture val=0
         arecord-2100    [000] .......   180.218960: snd_soc_dapm_path: *CVB-TLV Capture -> (direct) -> CVB-TLV AIF_OUT
         arecord-2100    [000] .......   180.218962: snd_soc_dapm_path: *CVB-TLV AIF_OUT -> (direct) -> CVB-TLV Right ADC
         arecord-2100    [000] .......   180.218963: snd_soc_dapm_path: *CVB-TLV Right ADC -> (direct) -> CVB-TLV Capture
         arecord-2100    [000] .......   180.218964: snd_soc_dapm_path: *CVB-TLV Right ADC -> (direct) -> CVB-TLV AIF_OUT
         arecord-2100    [000] .......   180.218966: snd_soc_dapm_path: *CVB-TLV AIF_OUT -> (direct) -> CVB-TLV Left ADC
         arecord-2100    [000] .......   180.218967: snd_soc_dapm_path: *CVB-TLV Left ADC -> (direct) -> CVB-TLV Capture
         arecord-2100    [000] .......   180.218968: snd_soc_dapm_path: *CVB-TLV Left ADC -> (direct) -> CVB-TLV AIF_OUT
         arecord-2100    [000] .......   180.218969: snd_soc_dapm_path: *CVB-TLV AIF_OUT -> (direct) -> CVB-TLV Right ADC
         arecord-2100    [000] .......   180.218969: snd_soc_dapm_path: *CVB-TLV AIF_OUT -> (direct) -> CVB-TLV Capture
         arecord-2100    [000] .......   180.218970: snd_soc_dapm_path: *CVB-TLV Capture -> (direct) -> tlv320adc3xxx-hifi-capture

Can you help me figure out what i am doing wrong ?