Porting tlv audio card on the TX2 develop kit(p3310)

Hi Henry,

The register values modified via busybox are limited to the current boot cycle… This was for testing only. Can you confirm if audio works for you when you program these register via busybox?

With Jetson-IO tool you don’t have to modify any DT file and re-flash it. Reboot should generally do, we can come to it later. There is an alternate way to modify the pinmux configuration. Please follow TX2 adaptation guide.

Thanks.

Hi @spujar

OK, use busybox to set the 5 register values, and no reboot device.
run speaker-test.
signal can be cought on the pin7 header(AUDIO_MCLK).

but BCLK WCLK still go flat line, and no sound playback.
dmsg shows that “configs-gadget gadget: Wrong NDP SIGN”.

Regards
H

Hi Henry,

Please list the full commands you are using for playback and share the logs for me to check if there is any issue. Also please make sure you have configured the TLV codec in slave mode and Tegra I2S in master mode.

Thanks.

Hi @spujar
Sorry for my delay.
The dmesg shows error “Failed getting the mclk. The current implementation does not support the usage of this codec without mclk”,
We traced to tlv320aic32x4.c file which has been updated to the tlv320aic32x4.log in the previous comment #9, and found that devm_clk_get() function failed. Could you give us some advices?

int aic32x4_probe(struct device *dev, struct regmap *regmap)
{
	struct aic32x4_priv *aic32x4;
	struct aic32x4_pdata *pdata = dev->platform_data;
	struct device_node *np = dev->of_node;
	int ret;

	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	aic32x4 = devm_kzalloc(dev, sizeof(struct aic32x4_priv),
			       GFP_KERNEL);
	if (aic32x4 == NULL)
		return -ENOMEM;

	dev_set_drvdata(dev, aic32x4);

	if (pdata) {
		aic32x4->power_cfg = pdata->power_cfg;
		aic32x4->swapdacs = pdata->swapdacs;
		aic32x4->micpga_routing = pdata->micpga_routing;
		aic32x4->rstn_gpio = pdata->rstn_gpio;
	} else if (np) {
		ret = aic32x4_parse_dt(aic32x4, np);
		if (ret) {
			dev_err(dev, "Failed to parse DT node\n");
			return ret;
		}
	} else {
		aic32x4->power_cfg = 0;
		aic32x4->swapdacs = false;
		aic32x4->micpga_routing = 0;
		aic32x4->rstn_gpio = -1;
	}

	aic32x4->mclk = devm_clk_get(dev, "mclk");
	if (IS_ERR(aic32x4->mclk)) {
		dev_err(dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n");
		return PTR_ERR(aic32x4->mclk);
	}

	if (gpio_is_valid(aic32x4->rstn_gpio)) {
		ret = devm_gpio_request_one(dev, aic32x4->rstn_gpio,
				GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn");
		if (ret != 0)
			return ret;
	}

	ret = aic32x4_setup_regulators(dev, aic32x4);
	if (ret) {
		dev_err(dev, "Failed to setup regulators\n");
		return ret;
	}

	ret = snd_soc_register_codec(dev,
			&soc_codec_dev_aic32x4, &aic32x4_dai, 1);
	if (ret) {
		dev_err(dev, "Failed to register codec\n");
		aic32x4_disable_regulators(aic32x4);
		return ret;
	}

	return 0;
}

and please refer to tegra186-quill-common.dtsi, mclk has been added to DT, but why driver cannot find it.

Hi @spujar
according to this topic, we modified .cfg file.
However, “Failed getting the mclk” error is still here.

Hi @spujar
We have searched a lot of information, but still trapped in it.
Could you give some suggestions?

Hi Henry.Lou

Sorry for the delayed reply.

Following is the snippet from your TLV codec driver:

aic32x4->mclk = devm_clk_get(dev, "mclk");
	if (IS_ERR(aic32x4->mclk)) {
		dev_err(dev, "Failed getting the mclk. The current implementation does not support the usage of this codec without mclk\n");
		return PTR_ERR(aic32x4->mclk);
	}

It expects “mclk” clock from your TLV codec device node. Please add following entries in the TLV device node:

clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
clock-names = "mclk";

If TLV device node already has a clock/clock-names entries, append above to those existing entries.

Thanks,
Sameer.

Hi @spujar
But, clocks and clock-names have been added to the codec node.

	i2c@c240000 {//regist the device to i2c-1 bus
                // added by henry for tlv320
                tlv320: tlv320@18 {
                        compatible = "ti,tlv320aic32x4";
                        reg = <0x18>;	
                        clocks = <&tegra_car TEGRA186_CLK_AUD_MCLK>;
			clock-names = "mclk";
			henry = "henry_test";
                        status = "okay";
                };  
                // added by henry
	};

And for more details, please refer to tegra186-quill-common.dtsi (33.9 KB)

Hi @spujar
Could you help us confirm whether the audio_mclk and i2s1 are configed right?

root@t-desktop:/home/t# cat /sys/kernel/debug/tegra_gpio 
Port:Pin:ENB DBC IN OUT_CTRL OUT_VAL INT_CLR
...
J:0 0x1 0x0 0x0 0x1 0x0 0x0
J:1 0x1 0x0 0x0 0x1 0x0 0x0
J:2 0x1 0x0 0x0 0x1 0x0 0x0
J:3 0x1 0x0 0x0 0x1 0x0 0x0
J:4 0x1 0x0 0x0 0x1 0x0 0x0
J:5 0x1 0x0 0x0 0x1 0x0 0x0
J:6 0x1 0x0 0x1 0x1 0x0 0x0
J:7 0x0 0x0 0x0 0x1 0x0 0x0
cat /sys/kernel/debug/tegra_pinctrl_reg
Bank: 0 Reg: 0x02431020 Val: 0x00000400 -> aud_mclk_pj4
Bank: 0 Reg: 0x02431028 Val: 0x00000400 -> dap1_fs_pj3
Bank: 0 Reg: 0x02431030 Val: 0x00000458 -> dap1_din_pj2
Bank: 0 Reg: 0x02431038 Val: 0x00000400 -> dap1_dout_pj1
Bank: 0 Reg: 0x02431040 Val: 0x00000400 -> dap1_sclk_pj0

Hi @spujar
If aud_mclk configuration is so difficult, let`s leave it aside and figure it out later.
Now, we use jump wire to connect exterior 24Mhz oscillator with soud coard MCLK.
However, when we run

speaker-test -D hw:tegrasndt186ref,0 -c 2 -r 4800 -F S16_LE -t sine -f 500

no signal cought on BCLK or WCLK.
Attachment is serious console log.
2022-07-07_9_33_09.log (157.1 KB)

This looks correct. I hope MCLK error “Failed getting the mclk” is not seen anymore.

Yes, these setting look fine as well.

I don’t see any errors in above log, so not sure what is going wrong at your end.
Previously you were getting signal on AUD_MCLK after pinmux configuration. The problem is you are unable to see signals for BCLK and WCLK.

Can you configure Tegra I2S as master? Please check if following helps.

diff --git a/tegra186-quill-common.dtsi b/tegra186-quill-common.dtsi
index dd7181e..5ffab72 100644
--- a/tegra186-quill-common.dtsi
+++ b/tegra186-quill-common.dtsi
@@ -772,8 +772,6 @@
                        tx-mask = <0xFF>;
                        rx-mask = <0xFF>;
                        format = "i2s";
-                       bitclock-master;
-                       frame-master;
                        bitclock-noninversion;
                        frame-noninversion;
                        bit-format = "s16_le";

Thanks.

Hi @spujar
change bitclock-slave, frame-slave to bitclock-master, frame-master, sill no WCLK BCLK siganl.

I hope you just removed “bitclock-master” and “frame-master” properties from the DAI and tested.

If above is true then,
What is the behaviour you see when you run speaker-test? You can paste related log here.

Are you seeing AUD_MCLK clock or even that is also not coming?

Hi @spujar
We tried 3 times and the trace log are the same, which can be seen following.
First time remove bitclock-master and frame-master, second keep them in the right place, third change to bitclock-slave and frame-slave.

root@t-desktop:/home/t# cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 2/2   #P:4
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
#              | |       |   ||||       |         |
    speaker-test-8849  [000] ....   280.927789: snd_soc_dapm_path: *ADMAIF1 Receive <- (direct) <- Playback 1
    speaker-test-8849  [000] ....   280.927800: snd_soc_dapm_path: *ADMAIF1 Receive <- (direct) <- ADMAIF1 CIF Receive-ADMAIF1 Receive

When run the speaker-test command, signal coming out on the AUD_MCLK, which is 25Mhz. But, BCLK and WCLK go flat line.
If there is any more log needed, please tell us.
Regards

You can just check with “remove bitclock-master and frame-master”. No need to try other combinations for now.

In the trace dump I don’t see I2S1 logs. I am suspecting it is not connected to ADMAIF1 for some reason.

Can you share output of following?
amixer -c <card_num> cget name=“I2S1 Mux”

where <card_num> refers to sound card index. Likely you would see two sound cards. You have to use the index corresponding to name “tegrasndt186ref”.

Hi @spujar
remove bitclock-matser and frame-master

root@t-desktop:/home/t# amixer -c tegrasndt186ref cget name="I2S1 Mux"
numid=928,iface=MIXER,name='I2S1 Mux'
  ; type=ENUMERATED,access=rw------,values=1,items=81
  ; Item #0 'None'
  ; Item #1 'ADMAIF1'
  ; Item #2 'ADMAIF2'
  ; Item #3 'ADMAIF3'
  ; Item #4 'ADMAIF4'
  ; Item #5 'ADMAIF5'
  ; Item #6 'ADMAIF6'
  ; Item #7 'ADMAIF7'
  ; Item #8 'ADMAIF8'
  ; Item #9 'ADMAIF9'
  ; Item #10 'ADMAIF10'
  ; Item #11 'ADMAIF11'
  ; Item #12 'ADMAIF12'
  ; Item #13 'ADMAIF13'
  ; Item #14 'ADMAIF14'
  ; Item #15 'ADMAIF15'
  ; Item #16 'ADMAIF16'
  ; Item #17 'I2S1'
  ; Item #18 'I2S2'
  ; Item #19 'I2S3'
  ; Item #20 'I2S4'
  ; Item #21 'I2S5'
  ; Item #22 'I2S6'
  ; Item #23 'SFC1'
  ; Item #24 'SFC2'
  ; Item #25 'SFC3'
  ; Item #26 'SFC4'
  ; Item #27 'MIXER1-1'
  ; Item #28 'MIXER1-2'
  ; Item #29 'MIXER1-3'
  ; Item #30 'MIXER1-4'
  ; Item #31 'MIXER1-5'
  ; Item #32 'AMX1'
  ; Item #33 'AMX2'
  ; Item #34 'AMX3'
  ; Item #35 'AMX4'
  ; Item #36 'ARAD1'
  ; Item #37 'AFC1'
  ; Item #38 'AFC2'
  ; Item #39 'AFC3'
  ; Item #40 'AFC4'
  ; Item #41 'AFC5'
  ; Item #42 'AFC6'
  ; Item #43 'OPE1'
  ; Item #44 'SPKPROT1'
  ; Item #45 'MVC1'
  ; Item #46 'MVC2'
  ; Item #47 'IQC1-1'
  ; Item #48 'IQC1-2'
  ; Item #49 'IQC2-1'
  ; Item #50 'IQC2-2'
  ; Item #51 'DMIC1'
  ; Item #52 'DMIC2'
  ; Item #53 'DMIC3'
  ; Item #54 'DMIC4'
  ; Item #55 'ADX1-1'
  ; Item #56 'ADX1-2'
  ; Item #57 'ADX1-3'
  ; Item #58 'ADX1-4'
  ; Item #59 'ADX2-1'
  ; Item #60 'ADX2-2'
  ; Item #61 'ADX2-3'
  ; Item #62 'ADX2-4'
  ; Item #63 'ADX3-1'
  ; Item #64 'ADX3-2'
  ; Item #65 'ADX3-3'
  ; Item #66 'ADX3-4'
  ; Item #67 'ADX4-1'
  ; Item #68 'ADX4-2'
  ; Item #69 'ADX4-3'
  ; Item #70 'ADX4-4'
  ; Item #71 'ADMAIF17'
  ; Item #72 'ADMAIF18'
  ; Item #73 'ADMAIF19'
  ; Item #74 'ADMAIF20'
  ; Item #75 'ASRC1-1'
  ; Item #76 'ASRC1-2'
  ; Item #77 'ASRC1-3'
  ; Item #78 'ASRC1-4'
  ; Item #79 'ASRC1-5'
  ; Item #80 'ASRC1-6'
  : values=1

attachment is machine driver.
FYI
tegra_machine_driver_mobile.c (23.5 KB)

Looks like you have an issue with DAPM path and that is why I2S1 is not seen in the trace logs you attached earlier. The problem seems to be on the codec side. You need to check related codec resources for DAPM path completion or check with the codec vendor itself.

I will not be able to fully assist on codec side. However you can try if following helps.

diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index c27e347..518604b 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -251,7 +251,7 @@ static const struct snd_kcontrol_new in3l_to_rmixer_controls[] = {
 };

 static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
-       SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
+       SND_SOC_DAPM_DAC("Left DAC", "Playback", AIC32X4_DACSETUP, 7, 0),
        SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
                           &hpl_output_mixer_controls[0],
                           ARRAY_SIZE(hpl_output_mixer_controls)),
@@ -262,7 +262,7 @@ static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
                           ARRAY_SIZE(lol_output_mixer_controls)),
        SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),

-       SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
+       SND_SOC_DAPM_DAC("Right DAC", "Playback", AIC32X4_DACSETUP, 6, 0),
        SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
                           &hpr_output_mixer_controls[0],
                           ARRAY_SIZE(hpr_output_mixer_controls)),

With this I hope you would be able to see clocks for I2S1 BCLK/WCLK. There could be more controls required on codec side for playback to work and I suggest to check with the codec vendor.

Thanks.

Hi @spujar
unfortunately, comment #37 merged to our source code, but same response as previous.
In the past few days, we search and read “NVIDIA Jetson Linux Developer Guide” again.
is there any instruction to veriry the sound card route add to platform?
Regards

Hi @spujar
reference to this post, and compare with my previous comment #33 in this topic, it seems that the stream pipeline has not been setted.


How to verify the pipeline is completed, and how to debug.
Regards

Do you mean with below still you are not able to see the clocks? Can you share the trace log again with below change?

diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index c27e347..518604b 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -251,7 +251,7 @@ static const struct snd_kcontrol_new in3l_to_rmixer_controls[] = {
 };

 static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
-       SND_SOC_DAPM_DAC("Left DAC", "Left Playback", AIC32X4_DACSETUP, 7, 0),
+       SND_SOC_DAPM_DAC("Left DAC", "Playback", AIC32X4_DACSETUP, 7, 0),
        SND_SOC_DAPM_MIXER("HPL Output Mixer", SND_SOC_NOPM, 0, 0,
                           &hpl_output_mixer_controls[0],
                           ARRAY_SIZE(hpl_output_mixer_controls)),
@@ -262,7 +262,7 @@ static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = {
                           ARRAY_SIZE(lol_output_mixer_controls)),
        SND_SOC_DAPM_PGA("LOL Power", AIC32X4_OUTPWRCTL, 3, 0, NULL, 0),

-       SND_SOC_DAPM_DAC("Right DAC", "Right Playback", AIC32X4_DACSETUP, 6, 0),
+       SND_SOC_DAPM_DAC("Right DAC", "Playback", AIC32X4_DACSETUP, 6, 0),
        SND_SOC_DAPM_MIXER("HPR Output Mixer", SND_SOC_NOPM, 0, 0,
                           &hpr_output_mixer_controls[0],
                           ARRAY_SIZE(hpr_output_mixer_controls)),