I2C EEPROM slave on Jetson Nano (B02 dev board)

I am trying to get the EEPROM simulated I2C Slave client working with the Jetson Nano Devboard.

I have changed the kernel config to have:

CONFIG_I2C_TEGRA_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=y

I then added a new .dtsi and added it as Linux_for_Tegra/sources/hardware/nvidia/platform/t210/porg/kernel-dts/porg-platforms/tegra210-i2c-eeprom.dtsi

The contents of the dtsi are:

#include <dt-bindings/platform/t210/t210.h>

/ {
	i2c@7000c400 {  /* I2C 1(7000c400)*/
		compatible = "nvidia,tegra210-i2c-slave";
		eeprom@64 {
			reg = <0x64>;
			compatible="slave-24c02";
			status = "okay";
		};
	};
};

Then I added #include "porg-platforms/tegra210-i2c-eeprom.dtsi" to tegra210-p3448-0000-p3449-0000-b00.dts.

I build and flash the image to the Jetson devboard. It fails to boot and I see this in the serial console logs:

...
[ 4.851921] tegra-i2cslv 7000c400.i2c: clock prepare failed -22
[ 4.859927] tegra-i2cslv: probe of 7000c400.i2c failed with error -22
[ 4.916616] using random self ethernet address
[ 4.924382] using random host ethernet address
[ 16.316239] Please complete system configuration setup on the serial port provided by Jetson's USB device mode connection. e.g. /dev/ttyACMx where x can 0, 1, 2 etc.

This is where the boot process stops. Can anyone help me with this? I am trying to piece how to do this together with forum posts and my very limited knowledge of device trees.

Thanks, Joseph

hello joseph-jonathan.salzano,

is this your 1st flashing process, had you complete the default system configuration yet?
please refer to Headless Mode Flow in oem-config, you should finish the initial configuration for booting into linux.
thanks

Ah I didn’t run the default user script for this image. That would be something I will have to do. But I am more concerned about this error:

[ 4.851921] tegra-i2cslv 7000c400.i2c: clock prepare failed -22
[ 4.859927] tegra-i2cslv: probe of 7000c400.i2c failed with error -22

is this not something that is not really an issue? If I setup the default user or use the USB to finish the config will the error be taken care of?

hello joseph-jonathan.salzano,

it’s the failure reported by tegra_i2cslv_probe(),
that should be fix by review the device tree and assign correct properties, please specify the controller clock.
thanks

I know next to nothing about device trees. Can you help me out? Where should the controller clock be specified? should it be in the same structure the eeprom@64 is in?

Should the dtsi file contain this:

/ {
	i2c@7000c400 {  /* I2C 1(7000c400)*/
		compatible = "nvidia,tegra210-i2c-slave";
        clock-frequency = <1000000>;
		eeprom@64 {
			reg = <0x64>;
			compatible="slave-24c02";
			status = "okay";
		};
	};
};

hello joseph-jonathan.salzano,

you should add the clock sources, which it’s something like below.

    clocks = <&tegra_car TEGRA210_CLK_I2C2>, <&tegra_car TEGRA210_CLK_PLL_P>;
    clock-names = "div-clk", "parent";

I edited the DTSI file to have the following:

#include <dt-bindings/platform/t210/t210.h>
/ {
	i2c@7000c400 {  /* I2C 1(7000c400)*/
		compatible = "nvidia,tegra210-i2c-slave";
		clocks = <&tegra_car TEGRA210_CLK_I2C2>, <&tegra_car TEGRA210_CLK_PLL_P>;
		clock-names = "div-clk", "parent";
		clock-frequency = <1000000>;
		eeprom@64 {
			reg = <0x64>;
			compatible="slave-24c02";
			status = "okay";
		};
	};
};

I remembered to setup the user to finish the configuration. The Jetson boots but I still see this in dmesg:

[    4.134395] tegra-i2cslv 7000c400.i2c: clock prepare failed -22
[    4.140628] tegra-i2cslv: probe of 7000c400.i2c failed with error -22

hello joseph-jonathan.salzano,

please review the device tree via filesystem, you should also check whether div-clk is available
for example, $ ls -la /proc/device-tree/i2c@7000c400/

This is the output of the ls

-r--r--r--   1 root root  4 Jul 21 18:52 '#address-cells'
drwxr-xr-x   2 root root  0 Jul 21 18:52  ak8963@0d
-r--r--r--   1 root root  4 Jul 21 18:52  clock-frequency
-r--r--r--   1 root root 15 Jul 21 18:52  clock-names
-r--r--r--   1 root root 16 Jul 21 18:52  clocks
drwxr-xr-x   2 root root  0 Jul 21 18:52  cm32180@48
-r--r--r--   1 root root 26 Jul 21 18:52  compatible
-r--r--r--   1 root root  6 Jul 21 18:52  dma-names
-r--r--r--   1 root root 16 Jul 21 18:52  dmas
drwxr-xr-x   2 root root  0 Jul 21 18:52  eeprom@64
drwxr-xr-x   2 root root  0 Jul 21 18:52  gpio@20
drwxr-xr-x   6 root root  0 Jul 21 18:52  i2cmux@70
drwxr-xr-x   2 root root  0 Jul 21 18:52  icm20628@68
-r--r--r--   1 root root 12 Jul 21 18:52  interrupts
-r--r--r--   1 root root  8 Jul 21 18:52  iommus
drwxr-xr-x   2 root root  0 Jul 21 18:52  iqs263@44
-r--r--r--   1 root root  4 Jul 21 18:52  linux,phandle
-r--r--r--   1 root root  4 Jul 21 18:52  name
-r--r--r--   1 root root  4 Jul 21 18:52  phandle
-r--r--r--   1 root root 16 Jul 21 18:52  reg
-r--r--r--   1 root root  4 Jul 21 18:52  reset-names
-r--r--r--   1 root root  8 Jul 21 18:52  resets
drwxr-xr-x   2 root root  0 Jul 21 18:52  rt5659.1-001a@1a
-r--r--r--   1 root root  4 Jul 21 18:52 '#size-cells'
-r--r--r--   1 root root  5 Jul 21 18:52  status

If I cat clock-names I have: div-clkparent
I haven’t changed anything else in the device trees except for pulling in the PinMux files that were generated by the excel sheet.

How do you check if div-clk is available?

I was looking through the sources and I didn’t see any other file contain div-clk in Linux_for_Tegra/sources/hardware/nvidia/platform/t210. However there were examples of the same i2c@7000c400 using div-clk in ``Linux_for_Tegra/sources/hardware/nvidia/soc/t21`. From what we can tell the soc directory is not used at all in the kernel build.

Am I putting the dtsi in the right location even?

hello joseph-jonathan.salzano,

please refer to i2c driver, i2c-tegra-slave.c. have you actually get the clock, div-clk?
if yes, then this failure caused by prepare a clock source. you may also dig into kernel/kernel-4.9/drivers/clk/clk.c for details.
thanks

Can anyone else confirm that this is the correct way that the I2C EEPROM client is supposed to be enabled? In the other forum posts this seems to work for other people. I am not making any other changes to the kernel so it should be the same as anyone else’s 4.9 Kernel for Tegra.

hello joseph-jonathan.salzano,

I don’t have experience to implement this, may other forum developers to share the experience.

I am still trying to get this working. I have tried both I2C-0 and I2C-1. I can build the device tree, flash the Jetson Nano, and boot to the OS. I decompile the dtb to make sure the dts contains what I expect. All seems correct but I am seeing this still in dmesg:

[    4.214667] tegra-dvfs: rate 408000000 too high for dvfs on i2c2
[    4.214676] tegra-i2cslv 7000c400.i2c: clock prepare failed -22
[    4.222231] tegra-i2cslv: probe of 7000c400.i2c failed with error -22

That first line seems to be the root cause, the device tree from labi that I used turned out to not be working correctly and the bootloader version was being loaded.

Can you tell me why are you making tegra controller as slave?
And who is master , this slave is connected to?

compatible = “nvidia,tegra210-i2c-slave”;

Also, the output of ls -la /proc/device-tree/i2c@7000c400/ which you have pasted shows that there are many other slaves like
ak8963@0d
cm32180@48
etc

connected to this controller. Can you chose a controller which is free and no other devices are there under it except your eeprom.
This controller has some critical devices from the dump you have shown.

Hi Bibek,

It is part of our project that the Jetson is the slave on one bus. I cant discuss who the master is. But for testing I was going to be using a Raspberry Pi as the master. Does the master have to be driving the bus clock before the Jetson driver is loaded?

I did put compatible = “nvidia,tegra210-i2c-slave”; in the device tree.

In the device tree all of these other devices are disabled so they should not be an issue correct? Our HW design already has bus 1 as the bus we are using.
When trying to debug this I tried the same on Bus 0 which doesn’t have any other devices with the exact same result. I also edited the kernel’s DTB to remove all the extra disabled slaves and recompiled it, same result.

Can you try decreasing clock-frequency to 100 Khz and then check.

clock-frequency = <100000>;

I tried changing the clock to that both in the DTSI and on the fly be decompiling the DTB and recompiling with the change. I have tried both the default 400Khz and the 100Khz. No luck

Is there a guide somewhere for this? Or someone who has done it before and can share the process? I am starting from a clean kernel so I would think there have been others who have already accomplished this.