Jetson Xavier NX soundcard not shown

Hi Team,

We have an audio codec, zls38100, connected to our custom carrier board at i2c1 and i2s1 of xavier nx. The i2c driver codec is getting loaded, but there are no soundcards shown.

root@localhost:~# cat /proc/asound/cards
— no soundcards —

We had done the following changes in the platform/tegra/common/kernel-dts/audio/tegra-platforms-audio-dai-links.dtsi file

tegra_sound: sound {
status = “okay”;
nvidia,num-codec-link = <12>;
nvidia,num-clk = <8>;
nvidia,clk-rates = < 270950400 /* PLLA_x11025_RATE */


nvidia,dai-link-3 {
link-name = “spdif-dit-2”;
cpu-dai = <&tegra_i2s3>;
codec-dai = <&codec>;
cpu-dai-name = “I2S3”;
codec-dai-name = “zl380tw0-hifi”;
format = “i2s”;
bit-format = “s16_le”;
srate = <48000>;


status = “okay”;
};
};
sound_codec: i2c@31e0000 {
status=“okay”;
codec:zl380tw@45 {
compatible = “zl40”,“ms,zl380tw”;
reg = <0x45>;
status = “okay”;
};
};

};

Are we missing something? Also please find the attached kernel log, we see the below message in the log
[ 2.749816] ALSA device list:
[ 2.749819] No soundcards found.

codec_dmesg.txt (58.1 KB)

Hi blessy.abraham,

Please check the Troubleshooting form L4T doc: Welcome — Jetson Linux<br/>Developer Guide 34.1 documentation

Hello!

It is very odd that dmesg shows nothing. Did you only modify the device-tree? If so I would have expected dmesg to show something.

Per the audio documentation, the device-tree file that needs to be modified for the Jetson Xavier NX platform is hardware/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-audio-p3668.dtsi.

Regards,
Jon

Hi jonathan,

Thankyou for your help.
It was an issue from our end, we had accidently commented off one of the audio dtsi files.

Right now we are getting the soundcards.

Thankyou for your help kayccc and jonathanh

Thanks for letting us know!

Regards
Jon

Hi Jonathan,

We have got the sound cards under /proc/asound/cards.
root@localhost:/home/nvidia# cat /proc/asound/cards
0 [tegrahdaxnx ]: tegra-hda-xnx - tegra-hda-xnx
tegra-hda-xnx at 0x3518000 irq 66
1 [jetsonxaviernxa]: jetson-xaviernx - jetson-xaviernx-ape
jetson-xaviernx-ape

But I see the below error under the kernel log

[ 2.922980] tegra-asoc: sound: ADMAIF1 <-> ADMAIF1 mapping ok
[ 2.923086] tegra-asoc: sound: ADMAIF2 <-> ADMAIF2 mapping ok
[ 2.923188] tegra-asoc: sound: ADMAIF3 <-> ADMAIF3 mapping ok
[ 2.923280] tegra-asoc: sound: ADMAIF4 <-> ADMAIF4 mapping ok
[ 2.923382] tegra-asoc: sound: ADMAIF5 <-> ADMAIF5 mapping ok
[ 2.923480] tegra-asoc: sound: ADMAIF6 <-> ADMAIF6 mapping ok
[ 2.923583] tegra-asoc: sound: ADMAIF7 <-> ADMAIF7 mapping ok
[ 2.923679] tegra-asoc: sound: ADMAIF8 <-> ADMAIF8 mapping ok
[ 2.923793] tegra-asoc: sound: ADMAIF9 <-> ADMAIF9 mapping ok
[ 2.923905] tegra-asoc: sound: ADMAIF10 <-> ADMAIF10 mapping ok
[ 2.924029] tegra-asoc: sound: ADMAIF11 <-> ADMAIF11 mapping ok
[ 2.924129] tegra-asoc: sound: ADMAIF12 <-> ADMAIF12 mapping ok
[ 2.924226] tegra-asoc: sound: ADMAIF13 <-> ADMAIF13 mapping ok
[ 2.924325] tegra-asoc: sound: ADMAIF14 <-> ADMAIF14 mapping ok
[ 2.924421] tegra-asoc: sound: ADMAIF15 <-> ADMAIF15 mapping ok
[ 2.924531] tegra-asoc: sound: ADMAIF16 <-> ADMAIF16 mapping ok
[ 2.924633] tegra-asoc: sound: ADMAIF17 <-> ADMAIF17 mapping ok
[ 2.924760] tegra-asoc: sound: ADMAIF18 <-> ADMAIF18 mapping ok
[ 2.924890] tegra-asoc: sound: ADMAIF19 <-> ADMAIF19 mapping ok
[ 2.925002] tegra-asoc: sound: ADMAIF20 <-> ADMAIF20 mapping ok

[ 2.936388] tegra-asoc: sound: ASoC: no source widget found for z OUT
[ 2.936557] tegra-asoc: sound: ASoC: Failed to add route z OUT → direct → z Headphone
[ 2.936746] tegra-asoc: sound: ASoC: no sink widget found for z IN
[ 2.936865] tegra-asoc: sound: ASoC: Failed to add route z Mic → direct → z IN
[ 2.937085] tegra-asoc: sound: ASoC: no source widget found for n OUT
[ 2.937204] tegra-asoc: sound: ASoC: Failed to add route n OUT → direct → n Headphone
[ 2.937387] tegra-asoc: sound: ASoC: no sink widget found for n IN
[ 2.937505] tegra-asoc: sound: ASoC: Failed to add route n Mic → direct → n IN

The below shown is the content of the file “platform/t19x/jakku/kernel-dts/common/tegra194-audio-p3668.dtsi”

aconnect@2a41000 {
	status = "okay";

	agic-controller@2a41000 {
		status = "okay";
	};

	adsp@2993000 {
		status = "okay";
	};
};

hda@3510000 {
	hda,card-name = "tegra-hda-xnx";
	status = "okay";
};

    i2c@31e0000 {
            status = "okay";

            codec: zl380tw.1-0045@45 {
                    compatible = "zl40","ms,zl380tw";
                    reg = <0x45>;
                    status = "okay";
            };
    };

    aconnect@2a41000 {
            status = "okay";

            ahub {
                    status = "okay";
                    i2s@2901200 {
                            status = "okay";
                            fsync-width = <0>;
                            bclk-ratio = <4>;
                    };
            };
    };

tegra_sound: sound {
	status = "okay";
	compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x";
	nvidia,model = "jetson-xaviernx-ape";
	clocks = <&bpmp_clks TEGRA194_CLK_PLLA>,
		 <&bpmp_clks TEGRA194_CLK_PLLA_OUT0>,
		 <&bpmp_clks TEGRA194_CLK_AUD_MCLK>;
	clock-names = "pll_a", "pll_a_out0", "extern1";
	assigned-clocks = <&bpmp_clks TEGRA194_CLK_PLLA_OUT0>,
			  <&bpmp_clks TEGRA194_CLK_AUD_MCLK>;
	assigned-clock-parents = <&bpmp_clks TEGRA194_CLK_PLLA>,
				 <&bpmp_clks TEGRA194_CLK_PLLA_OUT0>;

	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 OUT",
		"n IN",                 "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";

	mclk-fs = <256>;

	nvidia,dai-link-3 {
		link-name = "zl380tw0-playback";
		codec-dai = <&codec>;
		codec-dai-name = "zl380tw0-hifi";
		cpu-dai-name = "I2S3";
		name-prefix = "x";
	};


	/*nvidia,dai-link-1 {
		name-prefix = "n";
	};*/

	hdr40_snd_link_i2s: nvidia,dai-link-5 {
		name-prefix = "x";
	};

};

Is there any change that I have to do in audio routing part? How do we do that?

Hello!

Yes you need to update the nvidia,audio-routing for the codec. The ‘x Headphone’ and ‘x Mic’ widgets are defined by the Tegra audio machine driver and the default ‘x OUT’ and ‘x IN’ are defined by the dummy spdif driver. When you replace the spdif codec with your codec you need to update the widgets accordingly. These will be defined in the codec driver.

For example, when using the SGTL5000 audio codec we update the routing as shown here. The SGTL5000 codec defines these widgets.

Regards,
Jon

Hi Jonathan

I appreciate your crisp answers to our questions. Thankyou.

Please find the attached codec driver. There is no routes and widgets specified in the driver.
zl380tw.c (109.5 KB)

Hello!

That is strange. This driver does not appear to populate the ‘component_driver’ structure that is expected. I guess you could add this. However, you may wish to ask the vendor of the codec driver if they have a version that populates this information because we really need that to setup and configure the audio route between Jetson and the codec.

Regards,
Jon

Hi Jonathan.

Thankyou for the early response.
we couldnt find any version of microsemi which populates the component driver structure. Do you have any suggestion on how to add this structure? Is there any protocol to be followed?

Just following the below works?
static const struct snd_soc_dapm_widget dit_widgets = {
SND_SOC_DAPM_OUTPUT(“OUT”),
SND_SOC_DAPM_INPUT(“IN”),
};

static const struct snd_soc_dapm_route dit_routes = {
{ “OUT”, NULL, “Playback” },
{ “Capture”, NULL, “IN” },
};

static struct snd_soc_codec_driver soc_codec_spdif_dit = {
.component_driver = {
.dapm_widgets = dit_widgets,
.num_dapm_widgets = ARRAY_SIZE(dit_widgets),
.dapm_routes = dit_routes,
.num_dapm_routes = ARRAY_SIZE(dit_routes),

Hello!

You can try it, but I am not familiar enough with this codec or driver to know if this will work. You may wish to ask the author of the driver about this.

Regards,
Jon

Thankyou Jonathan.

I just tried adding that change. Now that particular error is not shown.

Next, we tried executing amixer command.
We are observing a kernel crash.

[ 109.750045] Unable to handle kernel NULL pointer dereference at virtual address 00000008
[ 109.750225] Mem abort info:
[ 109.750283] ESR = 0x96000005
[ 109.750345] Exception class = DABT (current EL), IL = 32 bits
[ 109.750451] SET = 0, FnV = 0
[ 109.750515] EA = 0, S1PTW = 0
[ 109.750579] Data abort info:
[ 109.750636] ISV = 0, ISS = 0x00000005
[ 109.750711] CM = 0, WnR = 0
[ 109.750779] user pgtable: 4k pages, 39-bit VAs, pgd = ffffffc1ddcb4000
[ 109.750892] [0000000000000008] *pgd=0000000000000000, *pud=0000000000000000
[ 109.751042] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 109.751146] Modules linked in: bnep btusb btrtl btbcm btintel zram overlay spidev nvgpu bluedroid_pm ip_tables x_tables
[ 109.751452] CPU: 1 PID: 9569 Comm: amixer Not tainted 4.9.140-tegra #28
[ 109.751729] Hardware name: NVIDIA Jetson Xavier NX Developer Kit (DT)
[ 109.752228] task: ffffffc1d1765400 task.stack: ffffffc1e4a44000
[ 109.752686] PC is at zl380tw_hbi_rd16.isra.0+0x54/0x148
[ 109.753076] LR is at zl380tw_hbi_rd16.isra.0+0x40/0x148
[ 109.755437] pc : [] lr : [] pstate: 80400145
[ 109.762785] sp : ffffffc1e4a47c90
[ 109.766201] x29: ffffffc1e4a47c90 x28: ffffffc1d1765400
[ 109.771980] x27: ffffff8008f72000 x26: 000000000000001d
[ 109.777406] x25: 0000000000000123 x24: 0000000000000001
[ 109.783253] x23: 0000000000000001 x22: ffffffc1e4a47d3e
[ 109.788505] x21: 0000000000000008 x20: 0000000000000003
[ 109.793594] x19: 0000000000000001 x18: 0000000000000020
[ 109.799442] x17: 0000007f8cac7b10 x16: ffffff8008272980
[ 109.804881] x15: ffffffffffffffff x14: ffffff800a13c1e0
[ 109.810815] x13: ffffff800a13be0e x12: 0000000000000006
[ 109.816340] x11: 0000000000000000 x10: 0000000000000ad8
[ 109.822368] x9 : 0000000000000001 x8 : ffffffc1ffd033df
[ 109.828142] x7 : ffffffc1e4a47c90 x6 : ffffff800a13b0ae
[ 109.833404] x5 : 0000000000000000 x4 : 0000000000000000
[ 109.838990] x3 : ffffffffffffffff x2 : 0000000000000004
[ 109.844329] x1 : 00000000fffffffe x0 : 0000000000000002

[ 109.850814] Process amixer (pid: 9569, stack limit = 0xffffffc1e4a44000)
[ 109.857457] Call trace:
[ 109.859826] [] zl380tw_hbi_rd16.isra.0+0x54/0x148
[ 109.865688] [] zl380tw_control_read+0x70/0xd0
[ 109.871288] [] snd_ctl_elem_read+0xc8/0x100
[ 109.876623] [] snd_ctl_ioctl+0x8ec/0xa50
[ 109.881703] [] do_vfs_ioctl+0xb0/0x8d8
[ 109.886772] [] SyS_ioctl+0x8c/0xa8
[ 109.891324] [] el0_svc_naked+0x34/0x38
[ 109.896403] —[ end trace 843db07a6311f9a2 ]—

Debugging it, I see the kernel crash is coming from

static int zl380tw_control_read(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct zl380tw_priv *zl380tw = snd_soc_codec_get_drvdata(codec);

zl380tw is always = NULL. Why is that so?

Hello!

Looks like the drvdata is only stored for SPI and not I2C …

	/* Initialize the driver data */
	spi_set_drvdata(spi, zl380tw);
	printk(KERN_ERR "SPI slave device found at bus::cs = %d::%d\n", spi->master->bus_num, spi->chip_select);

So most likely the drvdata has not been stored during initialisation.

Regards,
Jon

Hi Jonathan,

We are initializing the driver data,
i2c_set_clientdata(i2c, zl380tw);

Hello!

Oh yes, I do see that. Hmmm … then I am not sure why that would be. You need to debug the driver and see what device codec->dev is pointing to.

Regards
Jon

Hi Jonathan,

Thankyou for the help.
How do we verify whether the audio routing is correct? How do we debug it?

Hello!

The best way is to use the kernel tracing as follows …

$ echo 0 | sudo tee /sys/kernel/debug/tracing/trace
$ echo 0 | sudo tee /sys/kernel/debug/tracing/events/enable
$ echo 1 | sudo tee /sys/kernel/debug/tracing/tracing_on
$ echo 1 | sudo tee /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable
$ aplay <args>
$ sudo cat /sys/kernel/debug/tracing/trace

If the trace is empty or incomplete then this shows that something is not right. You should see something like thishttps://forums.developer.nvidia.com/t/configuring-a-pcm1863-codec-on-tx2/149561/7?u=jonathanh but obviously this is a different codec.

Regards,
Jon

Hi Jonathan,

Please find the below output from the debug trace

root@localhost:/home/nvidia# sudo cat /sys/kernel/debug/tracing/trace

tracer: nop

entries-in-buffer/entries-written: 30/30 #P:6

                          _-----=> irqs-off
                         / _----=> need-resched
                        | / _---=> hardirq/softirq
                        || / _--=> preempt-depth
                        ||| /     delay
       TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
          | |       |   ||||       |         |
       aplay-15857 [000] ....  1188.783405: snd_soc_dapm_widget_power: widget=Playback 1 val=1

    aplay-15857 [000] ....  1188.783412: snd_soc_dapm_widget_power: widget=ADMAIF1 Receive val=1
       aplay-15857 [000] ....  1188.783416: snd_soc_dapm_widget_power: widget=ADMAIF1 RX val=1
       aplay-15857 [000] ....  1188.783421: snd_soc_dapm_widget_power: widget=I2S5 Mux val=1
       aplay-15857 [000] ....  1188.783424: snd_soc_dapm_widget_power: widget=I2S5 TX val=1
       aplay-15857 [000] ....  1188.783425: snd_soc_dapm_widget_power: widget=I2S5 Transmit val=1
       aplay-15857 [000] ....  1188.783427: snd_soc_dapm_widget_power: widget=I2S5 Transmit-I2S5 CIF Receive val=1
       aplay-15857 [000] ....  1188.783429: snd_soc_dapm_widget_power: widget=I2S5 CIF Receive val=1
       aplay-15857 [000] ....  1188.783431: snd_soc_dapm_widget_power: widget=I2S5 CIF RX val=1
       aplay-15857 [000] ....  1188.783433: snd_soc_dapm_widget_power: widget=I2S5 DAP TX val=1
       aplay-15857 [000] ....  1188.783435: snd_soc_dapm_widget_power: widget=I2S5 DAP Transmit val=1
       aplay-15857 [000] ....  1188.783437: snd_soc_dapm_widget_power: widget=I2S5 DAP Transmit-x Playback val=1
       aplay-15857 [000] ....  1188.783439: snd_soc_dapm_widget_power: widget=x Playback val=1
       aplay-15857 [000] ....  1188.783440: snd_soc_dapm_widget_power: widget=x OUT val=1
       aplay-15857 [000] ....  1188.783442: snd_soc_dapm_widget_power: widget=x Headphone val=1
       aplay-15857 [000] ....  1198.818264: snd_soc_dapm_widget_power: widget=Playback 1 val=0
       aplay-15857 [000] ....  1198.818270: snd_soc_dapm_widget_power: widget=ADMAIF1 Receive val=0
       aplay-15857 [000] ....  1198.818273: snd_soc_dapm_widget_power: widget=ADMAIF1 RX val=0
       aplay-15857 [000] ....  1198.818278: snd_soc_dapm_widget_power: widget=I2S5 Mux val=0
       aplay-15857 [000] ....  1198.818281: snd_soc_dapm_widget_power: widget=I2S5 TX val=0
       aplay-15857 [000] ....  1198.818282: snd_soc_dapm_widget_power: widget=I2S5 Transmit val=0
       aplay-15857 [000] ....  1198.818284: snd_soc_dapm_widget_power: widget=I2S5 Transmit-I2S5 CIF Receive val=0
       aplay-15857 [000] ....  1198.818286: snd_soc_dapm_widget_power: widget=I2S5 CIF Receive val=0
       aplay-15857 [000] ....  1198.818288: snd_soc_dapm_widget_power: widget=I2S5 CIF RX val=0
       aplay-15857 [000] ....  1198.818290: snd_soc_dapm_widget_power: widget=I2S5 DAP TX val=0
       aplay-15857 [000] ....  1198.818291: snd_soc_dapm_widget_power: widget=I2S5 DAP Transmit val=0
       aplay-15857 [000] ....  1198.818293: snd_soc_dapm_widget_power: widget=I2S5 DAP Transmit-x Playback val=0
       aplay-15857 [000] ....  1198.818295: snd_soc_dapm_widget_power: widget=x Playback val=0
       aplay-15857 [000] ....  1198.818297: snd_soc_dapm_widget_power: widget=x OUT val=0
       aplay-15857 [000] ....  1198.818299: snd_soc_dapm_widget_power: widget=x Headphone val=0

Is it okay? Our audio codec is connected to I2S1 of jetson xaver nx. So thats supposed to be I2S3 right?

Hello!

I2S3 is the I2S interface available via the M.2 connector. If this is the interface you are using, then from the above trace I can see that audio is being played to I2S5 and not I2S3. Per the audio documentation you need to mux the I2S3 to one of the DMA interfaces, for example …

amixer -c jetsonxaviernxa cset name="I2S3 Mux" ADMAIF2
aplay -D hw:jetsonxaviernxa,1 <args> <wav>

Regards,
Jon

Hi Jonathan,

After executing

amixer -c jetsonxaviernxa cset name=“ADMAIF2 Mux” I2S3

We get the below error while recording.

arecord -D hw:jetsonxaviernxa,1 -r 16000 -c 1 -d 10 -f S16_LE out.wav
Recording WAVE ‘out.wav’ : Signed 16 bit Little Endian, Rate 16000 Hz, Mono
arecord: pcm_read:2103: read error: Input/output error