Tegra-audio-graph-card: parse error

I’m trying to enable a codec connected to I2S on Tegra Thor platform. I try to follow the guide at https://docs.nvidia.com/jetson/archives/r38.2/DeveloperGuide/SD/Communications/AudioSetupAndDevelopment.html#device-tree-configuration-for-a-custom-audio-card When booting the kernel it all ends up with the sound card not proved correctly with this error:

[   25.594251] platform sound: deferred probe pending: tegra-audio-graph-card: parse error

My codec is a TAS5755m connected through i2c and i2s7. I have this in my dts file:

		i2c@810c680000 {
			status = "okay";

			tas5755m: codec@1a {
				compatible = "ti,tas5711";
				reg = <0x1a>;

				clocks = <&bpmp TEGRA264_CLK_AUD_MCLK>;
				clock-names = "mclk";

				reset-gpios = <&gpio_main AMP_RST_N GPIO_ACTIVE_LOW>;
				pdn-gpios = <&gpio_main AMP_PDN_N GPIO_ACTIVE_LOW>;

				AVDD-supply = <&vdd_3v3_ao>;
				DVDD-supply = <&vdd_3v3_ao>;
				PVDD_A-supply = <&vdd_20v_ao>;
				PVDD_B-supply = <&vdd_20v_ao>;
				PVDD_C-supply = <&vdd_20v_ao>;
				PVDD_D-supply = <&vdd_20v_ao>;

				sound-name-prefix = "CVB-TAS";

				status = "okay";

				port {
					tas5755m_ep: endpoint {
						link-name = "tas5755m-playback";
						remote-endpoint = <&i2s7_dap>;
						mclk-fs = <256>;
					};
				};
			};
		};

I can see that the driver for this chip is loaded correct. Then I configure i2s7 under the ahub node:

				i2s@92e0000 {
					status = "okay";
					ports {
						port@1 {
							endpoint {
								dai-format = "i2s";
								remote-endpoint = <&tas5755m_ep>;
							};
						};
					};
				};

And as a last piece I try to connect them in the sound node:

	sound {
		status = "okay";

		dais = /* ADMAIF (FE) Ports */
		       <&admaif0_port>, <&admaif1_port>, <&admaif2_port>, <&admaif3_port>,
		       <&admaif4_port>, <&admaif5_port>, <&admaif6_port>, <&admaif7_port>,
		       <&admaif8_port>, <&admaif9_port>, <&admaif10_port>, <&admaif11_port>,
		       <&admaif12_port>, <&admaif13_port>, <&admaif14_port>, <&admaif15_port>,
		       <&admaif16_port>, <&admaif17_port>, <&admaif18_port>, <&admaif19_port>,
		       <&admaif20_port>, <&admaif21_port>, <&admaif22_port>, <&admaif23_port>,
		       <&admaif24_port>, <&admaif25_port>, <&admaif26_port>, <&admaif27_port>,
		       <&admaif28_port>, <&admaif29_port>, <&admaif30_port>, <&admaif31_port>,
		       /* XBAR Ports */
		       <&xbar_i2s7_port>,
		       <&xbar_sfc1_in_port>, <&xbar_sfc2_in_port>,
		       <&xbar_sfc3_in_port>, <&xbar_sfc4_in_port>,
		       <&xbar_mvc1_in_port>, <&xbar_mvc2_in_port>,
		       <&xbar_amx1_in1_port>, <&xbar_amx1_in2_port>,
		       <&xbar_amx1_in3_port>, <&xbar_amx1_in4_port>,
		       <&xbar_amx2_in1_port>, <&xbar_amx2_in2_port>,
		       <&xbar_amx2_in3_port>, <&xbar_amx2_in4_port>,
		       <&xbar_amx3_in1_port>, <&xbar_amx3_in2_port>,
		       <&xbar_amx3_in3_port>, <&xbar_amx3_in4_port>,
		       <&xbar_amx4_in1_port>, <&xbar_amx4_in2_port>,
		       <&xbar_amx4_in3_port>, <&xbar_amx4_in4_port>,
		       <&xbar_amx5_in1_port>, <&xbar_amx5_in2_port>,
		       <&xbar_amx5_in3_port>, <&xbar_amx5_in4_port>,
		       <&xbar_amx6_in1_port>, <&xbar_amx6_in2_port>,
		       <&xbar_amx6_in3_port>, <&xbar_amx6_in4_port>,
		       <&xbar_adx1_in_port>, <&xbar_adx2_in_port>,
		       <&xbar_adx3_in_port>, <&xbar_adx4_in_port>,
		       <&xbar_adx5_in_port>, <&xbar_adx6_in_port>,
		       <&xbar_mix_in1_port>, <&xbar_mix_in2_port>,
		       <&xbar_mix_in3_port>, <&xbar_mix_in4_port>,
		       <&xbar_mix_in5_port>, <&xbar_mix_in6_port>,
		       <&xbar_mix_in7_port>, <&xbar_mix_in8_port>,
		       <&xbar_mix_in9_port>, <&xbar_mix_in10_port>,
		       <&xbar_asrc_in1_port>, <&xbar_asrc_in2_port>,
		       <&xbar_asrc_in3_port>, <&xbar_asrc_in4_port>,
		       <&xbar_asrc_in5_port>, <&xbar_asrc_in6_port>,
		       <&xbar_asrc_in7_port>,
		       <&xbar_ope1_in_port>,
		       /* HW accelerators */
		       <&sfc1_out_port>, <&sfc2_out_port>,
		       <&sfc3_out_port>, <&sfc4_out_port>,
		       <&mvc1_out_port>, <&mvc2_out_port>,
		       <&amx1_out_port>, <&amx2_out_port>,
		       <&amx3_out_port>, <&amx4_out_port>,
		       <&amx5_out_port>, <&amx6_out_port>,
		       <&adx1_out1_port>, <&adx1_out2_port>,
		       <&adx1_out3_port>, <&adx1_out4_port>,
		       <&adx2_out1_port>, <&adx2_out2_port>,
		       <&adx2_out3_port>, <&adx2_out4_port>,
		       <&adx3_out1_port>, <&adx3_out2_port>,
		       <&adx3_out3_port>, <&adx3_out4_port>,
		       <&adx4_out1_port>, <&adx4_out2_port>,
		       <&adx4_out3_port>, <&adx4_out4_port>,
		       <&adx5_out1_port>, <&adx5_out2_port>,
		       <&adx5_out3_port>, <&adx5_out4_port>,
		       <&adx6_out1_port>, <&adx6_out2_port>,
		       <&adx6_out3_port>, <&adx6_out4_port>,
		       <&mix_out1_port>, <&mix_out2_port>, <&mix_out3_port>,
		       <&mix_out4_port>, <&mix_out5_port>,
		       <&asrc_out1_port>, <&asrc_out2_port>, <&asrc_out3_port>,
		       <&asrc_out4_port>, <&asrc_out5_port>, <&asrc_out6_port>,
		       <&ope1_out_port>,
		       /* BE I/O Ports */
		       <&i2s7_port>;

		label = "NVIDIA Jetson Thor AGX APE";

		widgets =
			"Speakers",	"CVB-TAS Playback";
		routing =
			"CVB-TAS Playback", "I2S7 DAP-Playback",
			"CVB-TAS Playback", "CVB-TAS DACL",
			"CVB-TAS Playback", "CVB-TAS DACR";
	};

I have struggled a bit now to understand and solve this issue but feel a bit stuck. I have identified that the error is in this call chain starting here: tegra_audio_graph_card.c « tegra « soc « sound - ubuntu/+source/linux-nvidia-tegra - [no description]

Looks like the routing issue to me, please try with below widget and routing

    widgets = 
        "Speaker", "CVB-TAS Output";
    
    routing = 
        "CVB-TAS Playback", "I2S7 DAP-Playback",
        "CVB-TAS Output", "CVB-TAS OUT_A",
        "CVB-TAS Output", "CVB-TAS OUT_B";
};

Incase still won’t work please share the kernel logs and updated DT file from the target.

I tried to change as suggested but unfortunately no change.

Attached is a kernel log and also the dtb produced with `dtc -I fs -O dts /proc/device-tree`. Please take a look and see if you can find something odd there.

Jan 01 00:00:40 hostname kernel: 5:185m5:185mplatform sound: deferred probe pending: tegra-audio-graph-card: parse error

A note also for the kernel log is that I enabled DEBUG in soc-core.c, so some additional output there.

dtb.log (579.6 KB)

kernel.log (162.3 KB)

From kernel logs looks like codec is not detected, tas571x: probe of 7-001a failed with error -121 ,which is leading to parse error. Please check if codec shows up on i2c bus 7 and address 0x1a using the i2cdetect tool.

@Sheetal.G thank you for finding this is the log. And for the suggested changes in the routing and widgets.

To give some background I had my i2c codec probed correctly during my work, then started working on getting the routing and widgets correct and the codec driver obviously stopped probe my i2c device correct. It turned out I changed initialization of my reset GPIO in pinmux that held my device in reset. For others in similar situation I have trouble using my GPIO from Linux: Some GPIO can't not be used?

With the reset GPIO in correct state I have a alsa card up and can continue the bring up.

Still having trouble getting some sound of this. Original error with parse error is gone. I have communication with my i2c codec (tas571x).

Here is how I initialize alsa from command-line setting up I2S7 <> ADMAIF4:

amixer -c APE cset name='I2S7 Mux' 'ADMAIF4'
amixer -c APE cset name='ADMAIF4 Mux' 'I2S7'
amixer -c APE sset 'CVB-TAS Master' 180
amixer -c APE cset name='CVB-TAS Speaker Switch' on

speaker-test -D hw:APE,3 -r 48000 -c 2 -F S16_LE -t wav

`speaker-test` starts and looks normal, but I can not hear any output. Only a pop at the start then silence.

From the driver (tas571x.c):

static const struct snd_soc_dapm_widget tas571x_dapm_widgets[] = {
	SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
	SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),

	SND_SOC_DAPM_OUTPUT("OUT_A"),
	SND_SOC_DAPM_OUTPUT("OUT_B"),
	SND_SOC_DAPM_OUTPUT("OUT_C"),
	SND_SOC_DAPM_OUTPUT("OUT_D"),
};

static const struct snd_soc_dapm_route tas571x_dapm_routes[] = {
	{ "DACL",  NULL, "Playback" },
	{ "DACR",  NULL, "Playback" },

	{ "OUT_A", NULL, "DACL" },
	{ "OUT_B", NULL, "DACL" },
	{ "OUT_C", NULL, "DACR" },
	{ "OUT_D", NULL, "DACR" },
};

static const struct snd_soc_component_driver tas571x_component = {
	.set_bias_level		= tas571x_set_bias_level,
	.dapm_widgets		= tas571x_dapm_widgets,
	.num_dapm_widgets	= ARRAY_SIZE(tas571x_dapm_widgets),
	.dapm_routes		= tas571x_dapm_routes,
	.num_dapm_routes	= ARRAY_SIZE(tas571x_dapm_routes),
	.use_pmdown_time	= 1,
	.endianness		= 1,
};

static struct snd_soc_dai_driver tas571x_dai = {
	.name = "tas571x-hifi",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 2,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S32_LE |
			   SNDRV_PCM_FMTBIT_S24_LE |
			   SNDRV_PCM_FMTBIT_S16_LE,
	},
	.ops = &tas571x_dai_ops,
};

And the routing in dts suggested above:

    widgets = 
        "Speaker", "CVB-TAS Output";
    
    routing = 
        "CVB-TAS Playback", "I2S7 DAP-Playback",
        "CVB-TAS Output", "CVB-TAS OUT_A",
        "CVB-TAS Output", "CVB-TAS OUT_B";

What else to look for?

For others as reference I can try to summarize my journey getting this to work.

  1. GPIO pins must have a default value in the pinmux dts in order to be able to use from Linux user space. Some GPIO can't not be used?

  2. The I2S interface we used I2S7 is not present in pinmux tool Excel sheet and I had to manually map those pins in the pinmux dts. I2S7 pinmux - not possible to map to I2S

  3. The rate of `aud_mclk` that we used for our codec was set too high (48MHz) for our chip. I had to tune this in the device-tree with `assigned-clock-rates` to 12.2288MHz.

    sound {
		compatible = "nvidia,tegra264-audio-graph-card";

		clocks = <&bpmp TEGRA264_CLK_PLLA1>,
				<&bpmp TEGRA264_CLK_PLLA1_OUT1>;
		clock-names = "pll_a", "plla_out0";
		assigned-clocks = <&bpmp TEGRA264_CLK_PLLA1>,
			<&bpmp TEGRA264_CLK_PLLA1_OUT1>,
			<&bpmp TEGRA264_CLK_AUD_MCLK>;
		assigned-clock-parents = <0>,
			<&bpmp TEGRA264_CLK_PLLA1>,
			<&bpmp TEGRA264_CLK_PLLA1_OUT1>;
		assigned-clock-rates = <98304000>, <49152000>, <12288000>;

		status = "okay";
        ...
    };