Enable I2s on production module

Hello!

I have a eMMC version of Jetson Nano module, we have a custom carrier board with a MAX98357 amplifier. This connected to the jetson nano module I2S0 port. As default the I2S was disabled, itried to enable it by modifying the device tree. Added a new node to the “sound” part and recompiled the modified device-tree file. I found many posts with similar situation and it looked to me that is the way to use the I2S(because the python based configurator script listed only the CSI lanes).
I tried to check the effect of the modification the following
cat /proc/device-tree/aconnect@702c0000/ahub/i2s@702d1000/status
return ‘okay’ which tells me the i2s enabled but the dai link not works I think because

aplay -l

Not listing I2S as device.
This is the node I added to the device tree:

	nvidia,dai-link-5 {
			link-name = "i2s1-max98357";
			cpu-dai = <&i2s1>;
			codec-dai = <&simple_audio_codec>;
			cpu-dai-name = "I2S1";
			codec-dai-name = "HIFI";
			format = "i2s";
			bitclock-master;
			frame-master;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			srate = <0xbb80>;
			num-channel = <0x2>;
			ignore_suspend;
			name-prefix = "x";
			status = "okay";
		};

I read the " Audio Setup and Development" documentation(and I will read it again), but not really sure how to move forward and I would be grateful any help or clue to the solution.

Some Updates!

I set the corresponding pins in the devic tree, but than realized there is no sign of the max98357a codec. I find the codec in the kernel sources and tried to enable it, by adding it to the Makefile and the tegra_defconfig file. I tried to do it a similar waz as I added a custom camera driver. But after flashing the board there is still no sign of the max98357a codec. If i understand correctly I just need to enable the codec because it is already part of the sources, but the way I used for the cmaera not works for the codec.

I would be grateful for any help.

Hi,
I understand you are trying to integrate MAX98357 codec with Jetson nano board. I will surely help you out to resolve the issue you are facing.

To start with, I need couple of details as asked below.

  1. Is Max98357 codec driver enabled for build as part of kernel image. If so, does the codec component visible on target with cat /sys/kernel/debug/asoc/components
  2. Can you attach the list of file changes you made like DT files, Drivers etc.
  3. Dump of cat /proc/asound/cards

Hi!

Thanks for your prompt response.
I am working with jetson nano production module and tegra version 4.9.337

  1. the asoc folder does not contains components element, only codecs dais platforms
    the content of the codecs file the following:
tegra210-ope.1
tegra210-ope.0
tegra210-mvc.1
tegra210-mvc.0
tegra210-afc.5
tegra210-afc.4
tegra210-afc.3
tegra210-afc.2
tegra210-afc.1
tegra210-afc.0
tegra210-sfc.3
tegra210-sfc.2
tegra210-sfc.1
tegra210-sfc.0
tegra210-mixer
tegra210-adx.1
tegra210-adx.0
tegra210-amx.1
tegra210-amx.0
tegra210-dmic.1
tegra210-dmic.0
tegra210-i2s.3
tegra210-i2s.2
tegra210-i2s.0
tegra210-admaif
tegra210-axbar
7.spdif-dit.7
6.spdif-dit.6
5.spdif-dit.5
4.spdif-dit.4
3.spdif-dit.3
2.spdif-dit.2
1.spdif-dit.1
0.spdif-dit.0
snd-soc-dummy
  1. I created a dailink in the decompiled dtb file:
nvidia,dai-link-5 {
			link-name = "i2s1-max98357";
			cpu-dai = <&i2s1>;
			codec-dai = <&max98357_codec>;
			cpu-dai-name = "I2S1";
			codec-dai-name = "max98357a-hifi";
			format = "i2s";
			bitclock-master;
			frame-master;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			srate = <0xbb80>;
			num-channel = <0x2>;
			ignore_suspend;
			name-prefix = "x";
			status = "okay";
		};

and added the codec at the and of the file:

    max98357_codec: max98357-codec {
        compatible = "maxim, max98357a";
        #sound-dai-cells = <0>;
        status = "okay";
    };

Also because the device is connected to he jetson nano 193,195,197 pins. I modified the following section to instead of reserved they connected to i2s1:

       dap1_din_pb1 {
			nvidia,pins = "dap1_din_pb1";
			nvidia,function = "i2s1";
			nvidia,pull = <0x1>;
			nvidia,tristate = <0x1>;
			nvidia,enable-input = <0x0>;
		};

		dap1_dout_pb2 {
			nvidia,pins = "dap1_dout_pb2";
			nvidia,function = "i2s1";
			nvidia,pull = <0x1>;
			nvidia,tristate = <0x1>;
			nvidia,enable-input = <0x0>;
		};

		dap1_fs_pb0 {
			nvidia,pins = "dap1_fs_pb0";
			nvidia,function = "i2s1";
			nvidia,pull = <0x1>;
			nvidia,tristate = <0x1>;
			nvidia,enable-input = <0x0>;
		};

		dap1_sclk_pb3 {
			nvidia,pins = "dap1_sclk_pb3";
			nvidia,function = "i2s1";
			nvidia,pull = <0x1>;
			nvidia,tristate = <0x1>;
			nvidia,enable-input = <0x0>;
		};

Also modified the 702d1000 this way:

i2s1: i2s@702d1000 {
				compatible = "nvidia,tegra210-i2s";
				reg = <0x702d1000 0x100>;
				nvidia,ahub-i2s-id = <0x0>;
				status = "okay";
				clocks = <0x26 0x1e 0x26 0xf9 0x26 0x109 0x26 0x15e>;
				clock-names = "i2s", "i2s_clk_parent", "ext_audio_sync", "audio_sync";
				assigned-clocks = <0x26 0x1e>;
				assigned-clock-parents = <0x26 0xf9>;
				assigned-clock-rates = <0x177000>;
				fsync-width = <1>;
				pinctrl-names = "dap_active", "dap_inactive";
				pinctrl-0;
				pinctrl-1;
				linux,phandle = <0xd0>;
				phandle = <0xd0>;
			};

After this i did not see any clue of the codec so I went back to the source files (kernel-4.9sound/soc/codecs/) modified the Makefile by adding this line:
obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
and in the Kconfig file I modified this:

config SND_SOC_MAX98357A
	tristate

to this:

config SND_SOC_MAX98357A
	tristate "Maxim MAX98357A CODEC"
	depends on SND_SOC && GPIOLIB

Lastly in the tegra_defconfig file I added this line:
CONFIG_SND_SOC_MAX98357A=m

rebuilt the kernel sources and flashed the jetson but I still not see any sign of presence of the codec/driver.

This is the result of cat /proc/asound/cards:

0 [tegrahda ]: tegra-hda - tegra-hda
tegra-hda at 0x70038000 irq 82
1 [tegrasndt210ref]: tegra-snd-t210r - tegra-snd-t210ref-mobile-rt565x
tegra-snd-t210ref-mobile-rt565x

Hi,
Thanks for your information.

Based on the log, here is my suggestion.

  1. We need to make sure Codec driver probe is called during the boot. Based on the dump provided, codec probe is not happening.

I see an extra space in the compatible which could be a problem. Can you try the below entry and add a print in the probe functions @ kernel/kernel-4.9/sound/soc/codecs/max98357a.c

max98357_codec: max98357-codec {
    compatible = "maxim,max98357a";
    #sound-dai-cells = <0>;
    status = "okay";
};

I think we should first fix the codec registration issue before we go further. Please do this and let me know the result.

Thanks for the suggestion thats’s my bad. I corrected the dtb file, now if I check for the codec I got at least some error:

dmesg | grep max98
[ 1.391726] tegra-asoc: sound: ASoC: no source widget found for max98357a-hifi
[ 1.391729] tegra-asoc: sound: ASoC: Failed to add route max98357a-hifi → direct → x OUT

I still have dubts that I added successfully the codec to the kernel when I updated the source files.
Because when i check the /proc/config.gz there is no sign of it.

Could you please confirm if codec driver is actually getting built?.

Did you tried the suggestion “Can you try the below entry and add a print in the probe functions @ kernel/kernel-4.9/sound/soc/codecs/max98357a.c”

Please enable the defconfig for the codec to build and probe should be called for codec to proceed further.

Hello!

I had some progression.
I built a kernel version with the codec-driver, and now I have some cloue about the max98357a presence:

zcat /proc/config.gz | grep MAX98357A
CONFIG_SND_SOC_MAX98357A=y

and it listed as codec too:

sudo > cat /sys/kernel/debug/asoc/codecs

tegra210-ope.1
tegra210-ope.0
tegra210-mvc.1
tegra210-mvc.0
tegra210-afc.5
tegra210-afc.4
tegra210-afc.3
tegra210-afc.2
tegra210-afc.1
tegra210-afc.0
tegra210-sfc.3
tegra210-sfc.2
tegra210-sfc.1
tegra210-sfc.0
tegra210-mixer
tegra210-adx.1
tegra210-adx.0
tegra210-amx.1
tegra210-amx.0
tegra210-dmic.1
tegra210-dmic.0
tegra210-i2s.3
tegra210-i2s.2
tegra210-i2s.0
tegra210-admaif
tegra210-axbar
7.spdif-dit.7
6.spdif-dit.6
5.spdif-dit.5
4.spdif-dit.4
3.spdif-dit.3
2.spdif-dit.2
1.spdif-dit.1
0.spdif-dit.0
max98357-codec
snd-soc-dummy

but for the dmesg grep i still got back the source based errors:

~$ dmesg | grep max9
[ 1.410825] tegra-asoc: sound: ASoC: no source widget found for max98357a-hifi
[ 1.410829] tegra-asoc: sound: ASoC: Failed to add route max98357a-hifi → direct → x OUT

I fixed the extra space issue in the device tree but maybe my implementation still falls somewhere.
UPDATE
I modified the following line:

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”, “x OUT”, “max98357a-hifi”;

into this:

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”, “Speaker”, “x OUT”;

Also if I list the ‘dais’ too the “HiFi” appeared as option. Now the dmesg error message disappeared and now the previously added debug print appeared.

aplay -l

Still not listing the device. Also not sure about I enabled the corresponding pins on the schematic it connected to the (193, 195, 197, 199) and enabled the
dap1_din_pb1,
dap1_dout_pb2,
dap1_fs_pb0
dap1_sclk_pb3

Maybe I should enable other pins too? How can I move forward?

Hi bence,
Good part is Codec driver got registered which is a great news!. The next step would be to bind the codec with the sound card and routing.

Please try replace the nvidia,audio-routing with below entry in DT.

nvidia,audio-routing = “x Headphone”, “x Speaker";

The above is based on the code in driver

static const struct snd_soc_dapm_widget max98357a_dapm_widgets = {
SND_SOC_DAPM_OUTPUT(“Speaker”),
};

Please try with this and let me know if any issue.

Hi!

I tried to modified device tree file and tested it the following commands and responses:

play -n synth 2 sine 1000
play WARN alsa: can’t encode 0-bit Unknown or not applicable

File Size: 0
Encoding: n/a
Channels: 1 @ 32-bit
Samplerate: 48000Hz
Replaygain: off
Duration: unknown

In:0.00% 00:00:02.05 [00:00:00.00] Out:96.0k [ | ] Hd:0.0 Clip:0
Done.

and

speaker-test -D hw:0,0 -c 2 -t sine

speaker-test 1.1.3

Playback device is hw:0,0
Stream parameters are 48000Hz, S16_LE, 2 channels
Sine wave rate is 440.0000Hz
Playback open error: -2,No such file or directory

This returns immediately.

This is my current version of the parts with audio-routing:

sound {
		iommus = <0x30 0x22>;
		dma-mask = <0x0 0xfff00000>;
		iommu-resv-regions = <0x0 0x0 0x0 0x70300000 0x0 0xfff00000 0xffffffff 0xffffffff>;
		iommu-group-id = <0x2>;
		status = "okay";
		compatible = "nvidia,tegra-audio-t210ref-mobile-rt565x";
		nvidia,model = "tegra-snd-t210ref-mobile-rt565x";
		clocks = <0x26 0xf8 0x26 0xf9 0x26 0x78>;
		clock-names = "pll_a", "pll_a_out0", "extern1";
		assigned-clocks = <0x26 0x78 0x26 0xf9 0x26 0xf8>;
		assigned-clock-parents = <0x26 0xf9>;
		assigned-clock-rates = <0xbb8000 0x2ee0000 0x15f90000>;
		nvidia,num-codec-link = <0x4>;
		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", " x Speaker", "x OUT";
		nvidia,xbar = <0x52>;
		mclk-fs = <0x100>;
		linux,phandle = <0xb4>;
		phandle = <0xb4>;

and

		overrides@9 {
				target = <0xb4>;

				_overlay_ {
					nvidia,audio-routing = "x Headphone Jack", "x HPO L Playback", "x Headphone Jack", "x HPO R Playback", "x IN1P", "x Mic Jack", "x Int Spk", "x SPO Playback", "x DMIC L1", "x Int Mic", "x DMIC L2", "x Int Mic", "x DMIC R1", "x Int Mic", "x DMIC R2", "x Int Mic", "y Headphone", "y OUT", "y IN", "y Mic", "a IN", "a Mic", "b IN", "b Mic", "x Headphone", "x Speaker";
				};
			};

I tried it also when both audio-routing was trimmed this way:

nvidia,audio-routing = “x Headphone”, “x Speaker”;

Maybe I misunderstood your instructions, should I already see the max98 between the sound cards? or seeing it in the codecs is enough?

Can you provide the amixer controls set before the playback.

Am suspecting amixer configs are not set proper here. please provide the info as asked above.

I was saying, you just need to have below entry in DT for your codec which is sufficient.

nvidia,audio-routing = “x Headphone”, “x Speaker”;

Hi!

Sorry for the misunderstanding I attached the amixer settings:

amixer -c 1 controls | grep I2s*
numid=546,iface=MIXER,name=‘I2S1 Mux’
numid=547,iface=MIXER,name=‘I2S2 Mux’
numid=510,iface=MIXER,name=‘I2S3 BCLK Ratio’
numid=512,iface=MIXER,name=‘I2S3 Capture mono to stereo conv’
numid=511,iface=MIXER,name=‘I2S3 Capture stereo to mono conv’
numid=509,iface=MIXER,name=‘I2S3 Channels’
numid=504,iface=MIXER,name=‘I2S3 Loopback’
numid=548,iface=MIXER,name=‘I2S3 Mux’
numid=515,iface=MIXER,name=‘I2S3 Playback FIFO threshold’
numid=514,iface=MIXER,name=‘I2S3 Playback mono to stereo conv’
numid=513,iface=MIXER,name=‘I2S3 Playback stereo to mono conv’
numid=508,iface=MIXER,name=‘I2S3 Sample Rate’
numid=506,iface=MIXER,name=‘I2S3 codec bit format’
numid=638,iface=MIXER,name=‘I2S3 codec frame mode’
numid=639,iface=MIXER,name=‘I2S3 codec master mode’
numid=507,iface=MIXER,name=‘I2S3 fsync width’
numid=505,iface=MIXER,name=‘I2S3 input bit format’
numid=498,iface=MIXER,name=‘I2S4 BCLK Ratio’
numid=500,iface=MIXER,name=‘I2S4 Capture mono to stereo conv’
numid=499,iface=MIXER,name=‘I2S4 Capture stereo to mono conv’
numid=497,iface=MIXER,name=‘I2S4 Channels’
numid=492,iface=MIXER,name=‘I2S4 Loopback’
numid=549,iface=MIXER,name=‘I2S4 Mux’
numid=503,iface=MIXER,name=‘I2S4 Playback FIFO threshold’
numid=502,iface=MIXER,name=‘I2S4 Playback mono to stereo conv’
numid=501,iface=MIXER,name=‘I2S4 Playback stereo to mono conv’
numid=496,iface=MIXER,name=‘I2S4 Sample Rate’
numid=494,iface=MIXER,name=‘I2S4 codec bit format’
numid=636,iface=MIXER,name=‘I2S4 codec frame mode’
numid=637,iface=MIXER,name=‘I2S4 codec master mode’
numid=495,iface=MIXER,name=‘I2S4 fsync width’
numid=493,iface=MIXER,name=‘I2S4 input bit format’
numid=550,iface=MIXER,name=‘I2S5 Mux’

In the DTS file I now using only the suggested line:

nvidia,audio-routing = “x Headphone”, “x Speaker”;

I also used the

sudo amixer -c 1 sset “I2S1 Mux”
To set the amixer value to 1.

Can you try the below commands and provide the kernel log if issue exists

amixer -c APE cset name=“I2S1 Mux” “ADMAIF1”
amixer -c APE cset name=“ADMAIF1 Mux” “I2S1”
speaker-test -D hw:1,0 -r 48000 -c 2 -F S16_LE -t sine -f 1000 -l 10

I tried run both of them each attempt returned with a invalid card based error:

Invalid card number.

speaker-test -D hw:“APE”,0 -r 48000 -c 2 -F S16_LE -t sine -f 1000 -l 10

speaker-test 1.1.3

Playback device is hw:“APE”,0
Stream parameters are 48000Hz, S16_LE, 2 channels
Sine wave rate is 1000.0000Hz
ALSA lib pcm_hw.c:1713:(_snd_pcm_hw_open) Invalid value for card
Playback open error: -19,No such device

I listed the the amixer controls:

amixer -c 0 scontrols
Simple mixer control ‘IEC958’,0
Simple mixer control ‘HDA Comfort Noise’,0
Simple mixer control ‘HDA Decode Capability’,0
Simple mixer control ‘HDA Maximum PCM Channels’,0

With aplay -l and cat /proc/asound/cards I still listing the previously listed cards:

card0: tegrahda
card1: tegrasndt210ref [tegra-snd-t210ref-mobile-rt565x], device 0: ADMAIF1 CIF ADMAIF1

Hi,
Please try with

speaker-test -D hw:1,0 -r 48000 -c 2 -F S16_LE -t sine -f 1000 -l 10

it starts the test and tried with different parameters in the following way:

speaker-test -D hw:1,0 -r 48000 -c 2 -F S16_LE -t sine -f 1000 -l 10
speaker-test -D hw:1,0 -r 48000 -c 3 -F S16_LE -t sine -f 1000 -l 10
speaker-test -D hw:1,0 -r 48000 -c 5 -F S16_LE -t sine -f 1000 -l 10

it runs the tests but no sound and also checked the jetson module corresponding pins with a oscilloscope, but we did not find any signal on them.

I believe got the issue, you are using I2S1 which is not correct. Jetson Nano exposes I2S4 on 40 pin header. If you enable the I2S4 pinmux with jetson io tool and make change in DT to use I2S4 for codec should solve your problem

To enable I2S4 pinmux refer I2S not working on Jetson Nano Devkit - Jetson & Embedded Systems / Jetson Nano - NVIDIA Developer Forums

I modified the dap1 pins back to reserved and updated the dap4 pins to i2s4 and updated the i2s1 label to i2s4 and moved label from 702d1000 to 702d1300.
This produced the following :

[ 0.438668] tegra210-pinctrl 700008d4.pinmux: function ‘i2s4’ not supported
[ 0.438706] tegra210-pinctrl 700008d4.pinmux: invalid function i2s4 in map table

Then I tried the same pins with the i2s1 label with the following result:

[ 0.438587] tegra210-pinctrl 700008d4.pinmux: invalid group “dap4_din_pj5” for function “i2s1”

I must have to use the DAP4_DIN,DAP4_OUT, DAP4_FS, DAP4_SCLK pins because my amplifier wired to these pins, but I do not understand why they can not labeled to i2s function.

I am ot able to use Jetson-IO tool because when I run the following command:
sudo /opt/nvidia/jetson-io/jetson-io.py
It closes immediately the application after I started to run. can it be because I have the production module not the SD card based one.

Alternately you can try directly writing to I2S4 pinmux registers to make sure functionality works and then we can try changing directly on DT later.

sudo devmem2 0x70003144 0x6044
sudo devmem2 0x70003148 0x6044
sudo devmem2 0x7000314c 0x6044
sudo devmem2 0x70003150 0x6044

After above command, check the signals of I2S4 with oscilloscope.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.