The NXP i.MX8QXP CPU has ten I2C buses. The following I2C interfaces are available on the ConnectCore 8X SOM (multiplexed with other functionality):

  • Four with DMA support (I2C0, I2C1, I2C2, I2C3)

  • Two in the display ports (MIPI-DSI0, MIPI-DSI1)

  • Two in the camera ports (MIPI-CSI0, CSI)

  • One dedicated for the PMIC

  • One dedicated for the Cortex M4 (CM40)

The CPU facilitates the functionality of both I2C master and slave according to the I2C Bus Specification v2.1, but the Linux kernel only contains an I2C bus master driver.

On the ConnectCore 8X system-on-module:

  • Dedicated PMIC I2C port connects internally to the power management IC (PMIC) at the following address:

    Interface Address (7-bit)

    PMIC

    0x08

  • I2C0 connects to the on-module Micro Controller Assist (MCA), and the Atmel Cryptochip at the following addresses:

    Interface Address (7-bit)

    Cryptochip

    0x60

    MCA

    0x63

On the ConnectCore 8X SBC Pro:

  • I2C3 is connected to the on-board audio chip and routed to the parallel camera so it can connect to an image sensor.

    Interface Address (7-bit)

    Maxim MAX98089 sound chip

    0x10

    OmniVision CSI camera

    0x3C

  • I2C3 is also available on the miniPCIe connector and the expansion connector, where you can connect additional devices.

  • MIPI-DSI0 I2C is routed to LVDS0 connector so it can connect to a touch controller.

  • MIPI-DSI1 I2C is routed to LVDS1 connector so it can connect to a touch controller.

    Interface Address (7-bit) Notes

    Goodix touch controller

    0x14, 0x5D

    On the ConnectCore 8X boards, an inconsistent reset sequence makes the display’s Goodix touch controller respond on one of two I2C addresses: 0x14 or 0x5D.

  • MIPI-CSI0 I2C is routed to MIPI camera connector so it can connect to an image sensor.

    Interface Address (7-bit)

    MIPI-CSI2 OmniVision camera

    0x3C

Kernel configuration

You can manage the I2C driver support through the kernel configuration:

  • IMX Low Power I2C interface (CONFIG_I2C_IMX_LPI2C)

This kernel configuration option is enabled as built-in on the default ConnectCore 8X kernel configuration file.

Kernel driver

The driver for the I2C interface is located at:

File Description

drivers/i2c/busses/i2c-imx-lpi2c.c

i.MX low power I2C controller driver

Device tree bindings and customization

The i.MX8QXP I2C interface device tree binding is documented at Documentation/devicetree/bindings/i2c/i2c-imx.txt.

The I2C interfaces are defined in the CPU, system-on-module, and carrier board device tree files.

Example: MIPI-DSI0 I2C port

Bus definition

i.MX8QXP device tree
i2c0_mipi_lvds0: i2c@56226000 {
	 compatible = "fsl,imx8qxp-lpi2c", "fsl,imx8qm-lpi2c";
	 reg = <0x0 0x56226000 0x0 0x1000>;
	 interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
	 interrupt-parent = <&irqsteer_mipi_lvds0>;
	 clocks = <&clk IMX8QXP_MIPI0_I2C0_CLK>,
		  <&clk IMX8QXP_MIPI0_I2C0_IPG_CLK>;
	 clock-names = "per", "ipg";
	 assigned-clocks = <&clk IMX8QXP_MIPI0_I2C0_DIV>;
	 assigned-clock-rates = <24000000>;
	 power-domains = <&pd_mipi_dsi_0_i2c0>;
	 status = "disabled";
};

Bus enabling, I2C slave devices, and IOMUX

ConnectCore 8X SBC Pro device tree
&i2c0_mipi_lvds0 {
	#address-cells = <1>;
	#size-cells = <0>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c0_mipi_lvds0>;
	clock-frequency = <100000>;
	status = "okay";

	/* I2C slave devices */
	goodix_touch1: gt9271@14 {
	    [...]
	};

	goodix_touch2: gt9271@5D {
	    [...]
	};
};

pinctrl_i2c0_mipi_lvds0: mipi_lvds0_i2c0_grp {
	fsl,pins = <
		SC_P_MIPI_DSI0_I2C0_SCL_MIPI_DSI0_I2C0_SCL 0xc6000020
		SC_P_MIPI_DSI0_I2C0_SDA_MIPI_DSI0_I2C0_SDA 0xc6000020
	>;
};

Using the I2C bus

The I2C bus driver exposes device data through the sysfs at /sys/class/i2c-dev/.

The correct way to access an I2C device is through a kernel driver. Accessing the I2C bus from the file system can confuse your I2C bus and cause data loss on devices like EEPROMs. The following tools are recommended for debugging purposes only.

I2C device interface

You can access I2C devices on an adapter from user space, through the /dev interface. This support requires that you enable the kernel configuration option I2C device interface (CONFIG_I2C_CHARDEV).

Once you have enabled the option, you can use the /dev/i2c-N device node where N corresponds to the adapter number, starting at zero.

i2c-tools

You can install the i2c-tools package to access the I2C devices from user space. The package contains the following tools:

Tool Description

i2cdetect

Bus scanning

i2cdump

Device register dumping

i2cget

Device register reading

i2cset

Device register setting

All I2C tools operate on a specific I2C bus which is identified by number.

To obtain a formatted list of all I2C adapters on your system, run:

~# i2cdetect -l
i2c-2   i2c             5a820000.i2c                            I2C adapter
i2c-0   i2c             56226000.i2c                            I2C adapter
i2c-3   i2c             5a830000.i2c                            I2C adapter
i2c-1   i2c             5a800000.i2c                            I2C adapter

Query the I2C bus using the I2C bus number to find devices connected to that bus:

~# i2cdetect 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- UU -- -- -- -- -- -- --
10: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- UU --
70: -- -- -- -- -- -- -- --

The example above shows several devices on the bus at addresses 0x08, 0x10, 0x60, and 0x6e. The ones showing UU denote this address is currently in use by a driver, while devices without a registered driver show the address (in the example 0x60).

You can dump the registers of any of these devices using the i2cdump command with the I2C bus number as the first argument and the chip address as the second argument:

~# i2cdump 0 0x60
No size specified (using byte-data access)
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0, address 0x60, mode byte
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: XX XX XX 04 11 33 43 04 11 33 43 04 11 33 43 04    XXX??3C??3C??3C?
10: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
20: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
30: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
40: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
50: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
60: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
70: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
80: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
90: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
a0: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
b0: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
c0: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
d0: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
e0: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?
f0: 11 33 43 04 11 33 43 04 11 33 43 04 11 33 43 04    ?3C??3C??3C??3C?

Accessing the I2C bus using Digi APIx

An example application called apix-i2c-example is included in the dey-examples-digiapix recipe (part of dey-examples package) of meta-digi layer. This application is an example of how to write data to an external EEPROM (24FC1026) and read it back using Digi APIx library on the ConnectCore 8X platform.

Go to GitHub to see the application instructions and source code.

See I2C API for more information about the I2C APIx.