I2C0 or I2C-16 in user space on the Colibri iMX8X and evaluation board doesn't appear to work

Hi,
I am using I2C1 bus for a Smart battery (SMBUS specifications) which is the host rather than a slave (flips back and forth - master then slave), and so need a second I2C bus for a standard slave device, so I tried using I2C0 but it does not seem to work. I had a good look at the device tree and there doesn’t seem to be a reason for that.

What is going on !??? This should work!

User space I2C-16 is I2C0 (Pins 140,142) - neither device show addresses solo or in combination
User space I2C-17 is I2C1 (Pins 196, 194) - works fine and both devices show an address

I2C0 is defined in the device tree and feeds X2 and the SODIMM connections, (extract from im8qxp-Colibri here)…

/* On-module MIPI CSI I2C accessible on FFC (X3) */
&i2c0_mipi_lvds1 {
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0_mipi_lvds1>;
};

/* Colibri I2C */
&i2c1 {
#address-cells = <1>;
#size-cells = <0>;
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
};

Then later…

	/* On Module I2C */
	pinctrl_i2c0: i2c0grp {
		fsl,pins = <
			IMX8QXP_MIPI_CSI0_GPIO0_00_ADMA_I2C0_SCL	0x06000021
			IMX8QXP_MIPI_CSI0_GPIO0_01_ADMA_I2C0_SDA	0x06000021
		>;
	};

	/* Colibri I2C */
	pinctrl_i2c1: i2c1grp {
		fsl,pins = <
			IMX8QXP_MIPI_DSI0_GPIO0_00_ADMA_I2C1_SCL	0x06000021	/* SODIMM 196 */
			IMX8QXP_MIPI_DSI0_GPIO0_01_ADMA_I2C1_SDA	0x06000021	/* SODIMM 194 */
		>;
	};

Then later

	pinctrl_i2c0_mipi_lvds0: mipi_lvds0_i2c0_grp {
		fsl,pins = <
			IMX8QXP_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 	0xc6000020	/* SODIMM 140 */
			IMX8QXP_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 	0xc6000020	/* SODIMM 142 */
		>;
	};

Dear @FatLinux,

Could you provide further information about your setup? Are you using a custom carrier board or a carrier provided by Toradex? Can you see the version of the Colibri module you use?

Additionally it would be helpful to know which versions of software you use on your setup?

Best Regards
Kevin

Hi Kevin,

Thanks for your message. We are using a Colibri iMX8X 2GB IT Revision V1.0D
The carrier is a standard Colibri evaluation board.
We also have a 7 inch resistive touch screen.

We have a RRC SMBUS battery on i2c-17 (pins 186/188), and a I2C sensor on i2c-16 (142/140). At least I think i2c-16 in the user space is sodimm 142/140 ?

I have tried all the combinations, and I am thinking the i2c-16 is not available on the SODIMM X1 connector?

colibri-imx8x-06800883:~$ uname -a
Linux colibri-imx8x-06800883 5.4.77-5.1.0+git.afc2df4893e6 #1-TorizonCore SMP PREEMPT Wed Dec 30 18:41:13 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux

(after this we run Debian through the Docker with --privileged so the userspace is accessible).

We installed the software through the easy installer.

Don’t hesitate to ask if I need give more info, I have been working all weekend on this as I need to get it done!

Apart from this I2C hiccup, this has been a smooth journey so far. I just have to implement a UART simple TX/RX and a get a pair of PIO’s left then.

Kind regards

Richard

Hi Kevin,

It is a Colibri standard carrier board provided by Toradex. The Colibri is a iMX8QX and it’s a version 1.0D.

Version of Torizoncore is 5.4.77

colibri-imx8x-06800883:~$ uname -a
Linux colibri-imx8x-06800883 5.4.77-5.1.0+git.afc2df4893e6 #1-TorizonCore SMP PREEMPT Wed Dec 30 18:41:13 UTC 2020 aarch64 aarch64 aarch64 GNU/Linux

Let me know if you need more. This is quite a tough one, I have tried every combination the pinout designer suggested and I cant find which pins are for I2C-16

Hi @FatLinux,

I think there’s a bit of misunderstanding going on and admittedly it’s due in part to the confusing naming conventions going on here. Let me try and break it down and hopefully not make it more confusing.

So you are correct that there are 2 I2C interfaces by default on Colibri i.MX8X. Going off this article here: https://developer.toradex.com/knowledge-base/i2c-linux#Colibri

They are i2c16 & i2c17, however i2c16 is labeled as “on-module”. This isn’t very clear in the documentation but it essentially means it’s an internal i2c on the SoM itself used for other components and is not readily available on the X1 edge connector.

What you are referencing in the device tree isn’t i2c0 it’s i2c0_mipi_lvds1. These are different despite the naming (confusingly). You can see the node for the true on-module i2c0 here: http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm64/boot/dts/freescale/imx8qxp-colibri.dtsi?h=toradex_5.4-2.1.x-imx#n356

However this doesn’t help you much since as I said the pins for i2c0 aren’t available on the edge connector. But you can use i2c0_mipi_lvds1 (SODIMM 140 & 142) as i2c for your purposes. In the device tree we reserved them as pins for LVDS but they aren’t actually in use by default. Judging by the device tree it seems i2c0_mipi_lvds1 isn’t actually enabled in any way. So once enabled you should be able to make use of it as a normal i2c. Though I believe the 140/142 I2C is different than the 194/196 I2C in that they’re low speed and have no DMA support.

But depending on your needs you can choose other i2c pins as given by the datasheet. Though you may need to add these to the device tree and resolve any conflicts as these pins may be in use by other functions by default.

Best Regards,
Jeremias

Hi Jeremias,

140 and 142 look like a good bet. The DMA is not absolutely essential. The application is to connect to a SM-BUS standard smart battery. So its SMBus subset of I2C. There is a dmasafe version of send and recv, but not used, as the data rate is standard.

Here is the entry from the linux kernel https://www.kernel.org/doc/html/latest/driver-api/i2c.html.

I can’t be the first to do this, is there a technical note that can give me some pointers?

Thanks again for your help

Best Regards

Richard

Well first of all have you been able to enable i2c0_mipi_lvds1 in the device tree and verify that SODIMM 140/142 are working as a generic I2C interface?

As for using smbus I don’t really have an specific tips or anything, but it would depend on what language you plan to use in your application to interface with this device. We have an example article here of using I2C on Torizon: https://developer.toradex.com/knowledge-base/how-to-use-i2c-on-torizon

In this example we use Python to interface with a sensor. If you’re using python I imagine it’d be a similar method. For other languages it depends on some research would need to be done on what exactly is used to interface with smbus devices.

Best Regards,
Jeremias

Hi Jermias,

I added this to the imx8qxp-colibri-eval-v3.dtsi

&i2c0_mipi_lvds0 {
status = “okay”;
};

Then I used Torizoncore to modify the device tree on my module, and rebooted.

Now we have a new I2c device, i2c-18 which when probed

root@9c3b0112d1ba:/dev# i2cdetect -l
i2c-17 i2c 5a810000.i2c I2C adapter
i2c-18 i2c 56226000.i2c I2C adapter
i2c-16 i2c 5a800000.i2c I2C adapter

We have a device (0d) on it. So it probes OK.

root@9c3b0112d1ba:/dev# i2cdetect -y 17

 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

00: – – – – – – – – 0b – – – –

10: – – – – – – – – – – – – – – – –

20: – – – – – – – – – – – – – – – –

30: – – – – – – – – – – – – – – – –

40: – – – – – – – – – – – – – – – –

50: – – – – – – – – – – – – – – – –

60: – – – – – – – – UU – – – – – – –

70: – – – – – – – –

root@9c3b0112d1ba:/dev# i2cdetect -y 18

 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

00: – – – – – – – – – – 0d – –

10: – – – – – – – – – – – – – – – –

20: – – – – – – – – – – – – – – – –

30: – – – – – – – – – – – – – – – –

40: – – – – – – – – – – – – – – – –

50: – – – – – – – – – – – – – – – –

60: – – – – – – – – – – – – – – – –

70: – – – – – – – –

So the next thing is to go and write some C code to test it, and that is what I am doing awake at this very late hour!

Kind regards

Richard

Glad we were able to clear up the whole confusing i2c naming.

Best Regards,
Jeremias