Porting realtek rt5639 codec to Nano

Hi,nvidia:

I’m trying to porting realtek’s 5639 codec to Nano, with nano’s I2S and I2C interface.

When i use aplay to play 1.wav, but it exit with err !

test@test-desktop:~$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: tegrahda [tegra-hda], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: tegraaudiort563 [tegra-audio-rt5639], device 0: RT5640 PCM rt5640-aif1-0
Subdevices: 0/1
Subdevice #0: subdevice #0

test@test-desktop:~$ aplay -D plughw:1,0 1.wav

Playing WAVE ‘1.wav’ : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
aplay: pcm_write:2011: write error: Invalid argument
test@test-desktop:~$

Thanks in advance for your help!

Hi Qiangfei.Wang,

Please check the Audio troubleshooting section to see if can help on resolving your issue: https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide%2Fasoc_driver.18.2.html%23wwpID0E0VD0HA

Hello!

There is a section in the above guide on how to integrate codecs with the Tegra audio driver. The device-tree and Tegra audio machine driver need to be updated to work with the codec. Please see the following for more details …

https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide%2Fasoc_driver.18.2.html%23wwpID0E0VT0HA

Please note that there are other people also using the same codec on Nano and so also refer to these threads as well …

Regards,
Jon

Hi jonathanh & kayccc:
now , aplay -l:

I use aplay -D plughw:1,0 48kk.wav , It only play 3 secnods,then exit ! The 48kk.wav normal playback is 2 minutes.

And, In principle, the "I2S1 DAP Transmit-ss AIF1 Playback " control should be open when playing normally, however, it is not.

What should I do to make “I2S1 DAP Transmit-ss AIF1 Playback” open ?

thank you very much !

Hi ,

In addition, the driver’s porting process.

tegra_machine_driver_mobile.c
— public/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c 2020-05-27 19:27:36.395905641 +0800
+++ src_out/kernel_src_build/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c 2020-05-28 11:26:48.159288408 +0800
@@ -32,6 +32,7 @@
#include “sgtl5000.h”
#include “tegra_asoc_machine_alt.h”
#include “tegra210_xbar_alt.h”
+#include “rt5640.h”

#define DRV_NAME “tegra-asoc:”

@@ -431,6 +432,35 @@
dai_params->formats = formats;
}

  • // baron ,add 5640 audio
  • printk(“baron — 5640!\n”);
    +/*
  • rtd = snd_soc_get_pcm_runtime(card, “rt5640-playback”);
  • if (rtd) {
  •    dai_params =
    
  •            (struct snd_soc_pcm_stream *)rtd->dai_link->params;
    
  •    dai_params->rate_min = srate;//clk_rate;
    
  •    dai_params->channels_min = channels;
    
  •    dai_params->formats = formats;
    
  • }*/
  • rtd = snd_soc_get_pcm_runtime(card, “rt5640-playback”);
  • if (rtd) {
  •   dai_params =
    
  •   (struct snd_soc_pcm_stream *)rtd->dai_link->params;
    
  •   dai_params->rate_min = srate;
    
  •   dai_params->formats = (machine->fmt_via_kcontrol == 2) ?
    
  •   	(1ULL << SNDRV_PCM_FORMAT_S32_LE) : formats;
    
  •   err = snd_soc_dai_set_sysclk(rtd->codec_dai, RT5640_SCLK_S_MCLK,
    
  •   			     aud_mclk, SND_SOC_CLOCK_IN);
    
  •   if (err < 0) {
    
  •   	dev_err(card->dev, "codec_dai clock not set\n");
    
  •   	return err;
    
  •   }
    
  • }
  • return 0;
    }

tegra210-porg-p3448-common.dtsi
— public/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-porg-p3448-common.dtsi 2020-04-09 08:59:12.000000000 +0800
+++ src_out/kernel_src_build/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-porg-p3448-common.dtsi 2020-05-27 17:22:04.076393599 +0800
@@ -333,8 +333,8 @@
};

	ahub {
  •   	i2s@702d1000 {
    
  •   		status = "disabled";
    
  •   	i2s@702d1000 {	/* i2s1 */
    
  •   		status = "okay";
      	};
    
      	i2s@702d1100 {
    

@@ -387,6 +387,29 @@
hda@70030000 {
status = “okay”;
};
+

  • i2c@7000c500 { // baron
  •   status = "okay";
    
  •   rt5640: rt5640.0-001c@1c {
    
  •   	status = "okay";
    
  •   	compatible = "realtek,rt5640";
    
  •   	realtek,ldo1-en-gpios = <&gpio TEGRA_GPIO(BB, 3) GPIO_ACTIVE_HIGH>;
    
  •   	reg = <0x1c>;
    
  •   };
    
  • };
tegra_sound: sound {
	status = "okay";

@@ -400,7 +423,7 @@
assigned-clocks = <&tegra_car TEGRA210_CLK_EXTERN1>;
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>;

  •   nvidia,num-codec-link = <4>;
    
  •   nvidia,num-codec-link = <5>;
    
      nvidia,audio-routing =
      	"x Headphone",	"x OUT",
    

@@ -477,6 +500,21 @@
name-prefix = “b”;
status = “okay”;
};

  •   nvidia,dai-link-5 {	// baron
    
  •   	link-name = "rt5640-playback";
    
  •   	cpu-dai = <&tegra_i2s1>;
    
  •   	codec-dai = <&rt5640>;
    
  •   	cpu-dai-name = "I2S1";
    
  •   	codec-dai-name = "rt5640-aif1";
    
  •   	format = "i2s";
    
  •   	bit-format = "s16_le";
    
  •   	bclk_ratio = <0>;
    
  •   	srate = <8000>;
    
  •   	num-channel = <2>;
    
  •   	ignore_suspend;
    
  •   	name-prefix = "ss";
    
  •   	status = "okay";
    
  •   };
    

    };

    clock@70110000 {
    status = “okay”;

image

Hello!

Have you updated the ‘nvidia,audio-routing’ for the ‘ss’ prefix? If not then we need to add routing information for the ‘ss’ prefix in the ‘nvidia,audio-routing’.

Also have you mapped one of the ADMAIFs to I2S1? By default ADMAIF1 is mapped to I2S4, so you need to remap to I2S1 …

$ amixer -c tegrasndt210ref sset "I2S4 Mux" None
$ amixer -c tegrasndt210ref sset "I2S1 Mux" ADMAIF1
$ amixer -c tegrasndt210ref sset "ADMAIF1 Mux" I2S1

It can be also be useful to run a trace of the audio routing when testing playback …

$ 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
$ aplay ...
$ sudo cat /sys/kernel/debug/tracing/trace

Regards,
Jon

Hi ,

Now I changed the prefix ss to x, and then do I need to update the route in DTS ?
nvidia,dai-link-5 { // baron
link-name = “rt5640-playback”;
cpu-dai = <&tegra_i2s1>;
codec-dai = <&rt5640>;
cpu-dai-name = “I2S1”;
codec-dai-name = “rt5640-aif1”;
format = “i2s”;
bit-format = “s16_le”;
bclk_ratio = <0>;
srate = <8000>;
num-channel = <2>;
ignore_suspend;
name-prefix = “x”;
status = “okay”;
};

now route:
nvidia,audio-routing =
“x Headphone”, “x OUT”,
“x IN”, “x Mic”,
“y Headphone”, “y OUT”,
“y IN”, “y Mic”,
“a IN”, “a Mic”,
“b IN”, “b Mic”;

image

thanks !

Hello!

Please ensure that you do not have the same prefix for dai-link-1 and dai-link-5. However, if you use ‘x’ as the prefix then that should be fine. Otherwise have you configured the codec? There is an example here for setting up the codec for playback via the headphone output …

Regards,
Jon

Hi Jon,

The functions I want to achieve are as follows,
Audio is output from i2s1 of nano to I2S of codec (5640), and then output from SPK of codec.
(nano i2s1 (in) -->codec5640 i2s–> codec5640 spk(out))

  1. I change prefix for dai-link-1 to ss, and set prefix for dai-link-5 to x。

  2. The routing of cdoec is obtained from the codec manufacturer。

  3. result:
    image

thanks
Regards,
Baron

Hello!

Yes it appears to be either a problem with the codec routing or codec configuration. I know that other users have been able to get this codec working with Nano so probably worth reviewing the following thread …

Regards,
Jon

Hello!

I just realised that you said that you are using I2S1. I2S1 is not available on the Nano module. The default I2S interface is I2S4 (via the 40-pin header). I2S3 is also available via the M.2 connector. Can you confirm which I2S interface you are using?

Regards,
Jon

Hi Jon,

Please check if the I2S of the circuit diagram can be used,

thanks !

Hello!

Please can you indicate the document where this schematic capture was taken from?

Jon

Hi Joh.

This schematic is the circuit of Jeston nano development board.( from dev kit).

What is the addr of the I2S0’ addr in this schematic ? it can be used ?

thanks !

Hello!

Thanks. Yes so I2S0 in the above is actually I2S4 on the chip and not I2S1. Please update your DT accordingly. Please note that the audio interfaces supported on the Jetson platforms are listed here …

https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide%2Fasoc_driver.18.2.html%23wwpID0E0OU0HA

I can see from our HW documentation that it is not clear what I2S interface maps to what pins.

Regards,
Jon

Hi Jon,

I’ve changed it to I2S4(0x702d1300) in DTS, and then, Do I need map AMDF <? > to i2s4 ?

That is, how to configure the route on the nano side ?

thanks !

Hello!

Yes you need to map ADMAIF1 to I2S4. If you execute the following command, it should configure this as this is the default …

$ alsactl init tegrasndt210ref

Also, you should remove the dai-link-5 you added and just modify dai-link-1 accordingly.

Regards,
Jon

Hi Jon,

I’m sorry ! Now , I changed DTS as follows, then exce command “alsactl init tegrasndt210ref” ,but it still fails 。There are other areas that need to be modified or debug ?

	hdr40_snd_link_i2s: i2s_dai_link1: nvidia,dai-link-1 {
		link-name = "rt5640-playback";
		cpu-dai = <&tegra_i2s4>;
		codec-dai = <&rt5640>;
		cpu-dai-name = "I2S4";
		codec-dai-name = "rt5640-aif1";
		format = "i2s";
		bitclock-slave;
		frame-slave;
		bitclock-noninversion;
		frame-noninversion;
		bit-format = "s16_le";
		srate = <48000>;
		num-channel = <2>;
		ignore_suspend;
		name-prefix = "x";
		status = "okay";
	};

image

There is no output of nano I2S4 measured by oscilloscope, nor is there any output of sysclk .

thanks.

Hello!

I assume that you have updated the nvidia,audio-routing in DT? If so, then run the trace again …

$ 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
$ aplay ...
$ sudo cat /sys/kernel/debug/tracing/trace

Regards,
Jon

Hi Jon,

There is no output of nano I2S4 measured by oscilloscope, nor is there any output of mclk .

thanks .