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 Express:
-
I2C2 and I2C3 are available on the expansion connector.
-
MIPI-DSI0 I2C is routed to the LVDS 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.
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 |
---|---|
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
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
&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
>;
};
I2C user space usage examples
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. You must first 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:
Description | Tool |
---|---|
Bus scanning |
i2cdetect |
Device register dumping |
i2cdump |
Device register reading |
i2cget |
Device register setting |
i2cset |
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?