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

Hi

  • 1 BSP environment:
    TX2 jetpack 4.6 L4T R32.6.1 kernel 4.9 aarch64
    TX2 develop kit(p3310)
  • 2 operation:
    Porting tlv audio card on the TX2 develop kit. The project need playback only, so mic can be ingnored.
    We connected audio card to TX2 via 40-pin expansion header or J21.
    pin27 → SDL pin28-> SCL
    tegra186-quill-common.dtsi & tegra_machine_driver_mobile.c have been modified.
    The codec tlv driver has been added to kernel, and compiled successfully.
  • 3 Problems:
    the codec cannot be detected.
    demesg shows that “no acknowledge from address 0x18”.
    and no signal cought on the J21 pin27 & pin28 by the oscilloscope.

any help would be greate appreciate.
Regards
Henry

FYI

root@t-desktop:/home/t#cat /sys/kernel/debug/asoc/codecs
...
tlv320aic32x4.1-0018
...
root@t-desktop:/home/t#cat /sys/kernel/debug/asoc/dais
tlv320aic32x4-hifi
...
root@t-desktop:/home/t#i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- -- 

We run a bash shell to read data on i2c bus 1.But no signal cought by oscilloscope.

#!/bin/bash
while true
do
    i2cdetect -r -y 1;
done

any help would be greately appreciate.
Regards
Henry

according to the following picture, pin27 & pin28 are i2c-1 bus, but when run the bash shell, pin27 & pin28 go flat line, and signal can be cought on the pin8. We are confused.
any help would be greately appreciate.
Regards
Henry

according to “TX2 serious pinmux”, GEN1_I2C_SCL maps to GPIO3_PC.05, GEN1_I2C_SDA maps to GPIO3_PC.06.
reference to topic,

cat /sys/kernel/debug/gpio | grep -C 5 342
gpio-337 (                                         )
gpio-338 (                                         )
gpio-339 (                                         )
gpio-340 (                                         )
gpio-341 (                                         )
gpio-342 (                                         )
gpio-343 (                                         )
gpio-345 (                                         )
gpio-346 (                                         )

anyone?

Hi Henry.Lou

As per above your codec seems to have registered fine.

Can you attach the codec driver and complete dmesg log? If this error is seen from codec driver, generally probe() fails and codec registration should not happen. So this is bit confusing.

Can you confirm the I2C lines used by your audio card?
Please check if you see signals on pin-3 and pin-5 in case you are using I2C_GP0 lines.

Thanks.

Hi @spujar
Thanks for your reply!
The whole dmesg has been upload to henry_tlv0.log.
The codec driver is “tlv320aic32x4.c”, which you can see in the SDK. The codec driver has been rarely modified. only some debugs added.

static int aic32x4_codec_probe(struct snd_soc_codec *codec)
{
	printk(KERN_ERR "henry debug aic3204 codec probe enter!!!!!!!!!!!!!!!!!!!\n");
	struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec);
	u32 tmp_reg;

	if (gpio_is_valid(aic32x4->rstn_gpio)) {
		ndelay(10);
		gpio_set_value(aic32x4->rstn_gpio, 1);
	}

	snd_soc_write(codec, AIC32X4_RESET, 0x01);

	/* Power platform configuration */
	if (aic32x4->power_cfg & AIC32X4_PWR_MICBIAS_2075_LDOIN) {
		snd_soc_write(codec, AIC32X4_MICBIAS, AIC32X4_MICBIAS_LDOIN |
						      AIC32X4_MICBIAS_2075V);
	}
	if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE)
		snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE);

	tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ?
			AIC32X4_LDOCTLEN : 0;
	snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg);

	tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE);
	if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36)
		tmp_reg |= AIC32X4_LDOIN_18_36;
	if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED)
		tmp_reg |= AIC32X4_LDOIN2HP;
	snd_soc_write(codec, AIC32X4_CMMODE, tmp_reg);

	/* Mic PGA routing */
	if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K)
		snd_soc_write(codec, AIC32X4_LMICPGANIN,
				AIC32X4_LMICPGANIN_IN2R_10K);
	else
		snd_soc_write(codec, AIC32X4_LMICPGANIN,
				AIC32X4_LMICPGANIN_CM1L_10K);
	if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K)
		snd_soc_write(codec, AIC32X4_RMICPGANIN,
				AIC32X4_RMICPGANIN_IN1L_10K);
	else
		snd_soc_write(codec, AIC32X4_RMICPGANIN,
				AIC32X4_RMICPGANIN_CM1R_10K);

	/*
	 * Workaround: for an unknown reason, the ADC needs to be powered up
	 * and down for the first capture to work properly. It seems related to
	 * a HW BUG or some kind of behavior not documented in the datasheet.
	 */
	tmp_reg = snd_soc_read(codec, AIC32X4_ADCSETUP);
	snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg |
				AIC32X4_LADC_EN | AIC32X4_RADC_EN);
	snd_soc_write(codec, AIC32X4_ADCSETUP, tmp_reg);
	printk(KERN_ERR "henry debug aic3204 codec probe leave!!!!!!!!!!!!!!!!!!!\n");
	return 0;
}

snd_soc_write() function results in “no acknowledge from address 0x18”.
Of course! no siginal cought on pin27 pin28, even no audio card connected on the headers.
Unfortunately, pin3 and pin5 are the same phenomena, no signal either.

Regrads
Henry
FYI
henry_tlv0.log (74.0 KB)
tlv320aic32x4.log (32.2 KB)

Hi Henry,

From the logs you attached it seems like codec access seems to be failing. There is no direct codec access in aic32x4_probe(). The errors happening in codec_probe() are not captured and thus it goes ahead with registering codec. Can you confirm if you captured the logs with audio card connected?

Since i2cdetect command works, it means I2C bus is working fine. Not sure why you are not seeing signals with oscilloscope.

Please share the changes you made in DTSI file.
Also please share schematics of your audio card connection with TX2.

Thanks.

Hi @spujar
Thanks for your reply.
Yes, the dmesg log was captured with audio card connected.
We modifiled DTSI again, and now signal can be cought on i2c bus 1. The previous error “no acknowledge from address 0x18” has gone, which is comforting.
But the pin7 MCLK still goes flat line on the oscilloscope.
Could you give some advices on how to config MCLK, and how to set frequency.
And dmsg log shows that “Failed to add route x OUT → direct → x Headphone”

[    4.559915] tegra-asoc: sound: ASoC: no source widget found for x OUT
[    4.559917] tegra-asoc: sound: ASoC: Failed to add route x OUT -> direct -> x Headphone
[    4.559936] tegra-asoc: sound: ASoC: no sink widget found for x IN
[    4.559938] tegra-asoc: sound: ASoC: Failed to add route x Mic -> direct -> x IN

according to this topic, shell has been run, and audio debug log has been upload.
Regarde
Henry

FYI
dmesg
henry_tlv01.log (131.7 KB)
audio debug log
tegra-audio-debug.txt (518.7 KB)
DTSI
tegra186-quill-common.dtsi (33.6 KB)

33 Audio.SchDoc (342 KB)

Hi Henry,

Good to know that I2C transactions are good now.

How to open this schematic file? Or you can attach an image file for a quick view.

I see that you have commented out all routes under “nvidia,audio-routing” except following:
"x Headphone", "x OUT";
So I am expecting only following errors the widgets are missing:

[    4.559915] tegra-asoc: sound: ASoC: no source widget found for x OUT
[    4.559917] tegra-asoc: sound: ASoC: Failed to add route x OUT -> direct -> x Headphone

Please see if there is any disconnect between logs and your DTSI file.

However can you try if following helps? :

nvidia,audio-routing =
    "x Headphone",     "x HPL",
    "x Headphone",     "x HPR",
    "x IN1_L",         "x Mic",
    "x IN1_R",         "x Mic";

Please note that HPL and HPR widgets come from your codec driver. Same is true for IN1_L and IN1_R. Check aic32x4_dapm_widgets() array.

Probe this pin when you run playback (aplay) or capture (arecord).
What is your MCLK requirement?

Thanks.

Hi @spujar
Thanks for your reply.
The Audio.SchDoc is edited by AD, so you can open it by Altium Designer. And we captured images for a quick view, which has been uploaded.

Only playback is needed on our project, so mic can be ignored.
In the dtsi, we commented “x OUT”, and add HPL & HPR.

nvidia,audio-routing =
    "x Headphone",     "x HPL",
    "x Headphone",     "x HPR";

the previous errors “no source widget found for x OUT” has gone. It seems that tegra-asoc runs well. dmesg has been uploaded to henry_tlv02.log.

we run the speaker-test command, but MCLK BCLK WCLK go flat line on the oscilloscope. No sound playback. So confused that how could I2C transactions perform well, without a nomal MCLK? So, could you give some advices no how to config MCLK.

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_path/enable
echo 1 | sudo tee /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable
root@t-desktop:/home/t# speaker-test -D hw:tegrasndt186ref,0 -c 2 -r 48000 -F S16_LE -t sine -f 500
Playback device is hw:tegrasndt186ref,0
Stream parameters are 48000Hz, S16_LE, 2 channels
Sine wave rate is 500.0000Hz
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 32 to 8192
Period size range from 32 to 4096
Using max buffer size 8192
Periods = 4
was set period_size = 2048
was set buffer_size = 8192
 0 - Front Left
 1 - Front Right

Time per period = 0.197480
 0 - Front Left
 1 - Front Right
Time per period = 0.202294
 0 - Front Left
 1 - Front Right
Time per period = 0.202225
 0 - Front Left
 1 - Front Right

sudo cat /sys/kernel/debug/tracing/trace
...
 alsa-sink-ADMAI-7483  [003] ....   610.633346: snd_soc_dapm_path: *ADMAIF1 Receive <- (direct) <- Playback 1
 alsa-sink-ADMAI-7483  [003] ....   610.633357: snd_soc_dapm_path: *ADMAIF1 Receive <- (direct) <- ADMAIF1 CIF Receive-ADMAIF1 Receive
    speaker-test-8463  [000] ....   620.729798: snd_soc_dapm_path: *ADMAIF1 Receive <- (direct) <- Playback 1
    speaker-test-8463  [000] ....   620.729804: snd_soc_dapm_path: *ADMAIF1 Receive <- (direct) <- ADMAIF1 CIF Receive-ADMAIF1 Receive


Regards
H.Lou
FYI
quick view


dmesg
henry_tlv02.log (64.7 KB)

Hi @spujar

cat /sys/kernel/debug/gpio | grep -C 5 396
gpio-391 (                                                     )
gpio-392 ( I2S0_CLK                                   )
gpio-393 ( I2S0_SDOUT                              )
gpio-394 ( I2S0_SDIN                                 )
gpio-395 ( I2S0_LRCLK                              )
gpio-396 ( AUDIO_MCLK                            )
gpio-397 ( GPIO20_AUD_INT                    )
gpio-398 ( GPIO1_AUD_RST                     )
gpio-399 (                                                     )
gpio-400 (                                                     )
gpio-401 (                                                     )

gpio-396 AUDIO_MCLK seems OK,
how to turn it on, and set it`s frequency?
Regards
Henry

Hi @spujar

root@t-desktop:/home/t# cat /sys/kernel/debug/tegra_pinctrl_reg | egrep ‘dap1|mclk’
Bank: 0 Reg: 0x02431020 Val: 0x00000059 → aud_mclk_pj4
Bank: 0 Reg: 0x02431028 Val: 0x00000055 → dap1_fs_pj3
Bank: 0 Reg: 0x02431030 Val: 0x00000055 → dap1_din_pj2
Bank: 0 Reg: 0x02431038 Val: 0x00000055 → dap1_dout_pj1
Bank: 0 Reg: 0x02431040 Val: 0x00000055 → dap1_sclk_pj0

is the pinctl reg right?

Hi Henry

Good to know this part is resolved now. You are one step closer.

This does not look correct.

Can you follow Jetson-IO guide and configure these pins for I2S and MCLK functionality? Once configured, you can probe as well when playback is running.

Thanks.

Hi @spujar
The project audio output is a speaker, not headphone. So, i wonder that is the audio-routine right?

nvidia,audio-routing =
    "x Headphone",     "x HPL",
    "x Headphone",     "x HPR";

does the Headphone widget can cover speaker?

Hi @spujar

We use jetson-io.py and enable aud_mclk pin7 i2s1. kernel_tegra186-quill-p3310-1000-c03-00-base-hdr40-user-custom.dtbo has been exported successfully. But, all changes not work.
it seems that Device-Tree Overlay not work.
Could you give more details?

Regards
H

Did you reboot the board after updating DTB file?

Can you please add details on what you mean by this?

For testing you can update the values directly. For reference:
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

Thanks.

Hi @spujar
yes, we reboot our device.

OK, let me explain it.
We used jetson-io.py to enable aud_mclk and i2s1 in the “manually” mode, than saved. the screen showd that kernel_tegra186-quill-p3310-1000-c03-00-base-hdr40-user-custom.dtb had been exported.
rebooted device.
used jetson-io.py, it showed that aud_mclk and i2s1 were still disanled.

thanks for listing the right value.
but, whatever we did, our test results were always the following.

.So, we wonder, is there any method to modify DTS directly to enable aud_mclk and i2s1?

Can you quickly test by writing these values directly?
Please check if you have busybox tool and try run below:

busybox devmem 0x02431020 32 0x00000400
busybox devmem 0x02431028 32 0x00000400 
busybox devmem 0x02431030 32 0x00000458 
busybox devmem 0x02431038 32 0x00000400 
busybox devmem 0x02431040 32 0x00000400

Hi @spujar
Thanks for your reply.

use busybox devmem to set value, than cat /sys/kernel/debug/tegra_pinctrl_reg | egrep ‘dap1|mclk’. it turns out that busybox realy works.
But, after reboot device, all these 5 regs goes back to previous status.

According to logs, jetson-io.py is used to modify DT. We expact other method to modify DTSI, and than “make dtbs”, reflash kernel-dtb.
We wonder which DTSI to modify, could you give some advice?

Regards
H.L