The NXP i.MX6 CPU has three I2C buses that operate at up to 400 Kbps. It provides the functionality of I2C master and slave according to the I2C Bus Specification v2.1. However, the Linux kernel only contains an I2C bus master driver.

On the ConnectCore 6:

  • I2C1 is not used

  • I2C2 connects internally to the power management IC (PMIC) and to the on-module MCA (Micro-Controller Assist)

  • I2C3 is available for peripherals use

On the ConnectCore 6 SBC, I2C3 is used to connect the following interfaces:

  • PCIe expansion cards

  • LVDS displays

  • HDMI monitors

  • MIPI DSI displays

  • Parallel LCD displays

  • CSI cameras

  • Audio codecs

I2C3 port is also available on the SBC board through an expansion connector.

Kernel configuration

You can manage the I2C driver support through the kernel configuration option IMX I2C interface (CONFIG_I2C_IMX) which is enabled as built-in on the ConnectCore 6 SBC kernel configuration file.

Kernel driver

The I2C bus driver for the system-on-module is located at drivers/i2c/busses/i2c-imx.c.

Device tree bindings and customization

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

The I2C interfaces are defined in the i.MX6 CPU, ConnectCore 6, and ConnectCore 6 SBC device tree files.

Example: I2C3

Definition of the bus

Common ConnectCore 6 device tree
i2c3: i2c@21a8000 {
	#address-cells = <1>;
	#size-cells = <0>;
	compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
	reg = <0x021a8000 0x4000>;
	interrupts = <0 38 IRQ_TYPE_LEVEL_HIGH>;
	clocks = <&clks IMX6QDL_CLK_I2C3>;
	status = "disabled";
};

IOMUX configuration

ConnectCore 6 SBC device tree
i2c3 {
	pinctrl_i2c3: i2c3 {
		fsl,pins = <
			MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
			MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
		>;
	};
};

Enable the bus and attach client devices

ConnectCore 6 SBC device tree
&i2c3 {
	clock-frequency = <100000>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_i2c3>;
	status = "okay";

	edid@50 {
		compatible = "fsl,imx6-hdmi-i2c";
		reg = <0x50>;
	};
	...
};

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-1   i2c             21a4000.i2c                             I2C adapter
i2c-2   i2c             21a8000.i2c                             I2C adapter

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

# i2cdetect 2
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-2.
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: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: 30 -- -- -- -- -- -- 37 -- -- 3a -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- 4a 4b -- -- -- --
50: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

The example above shows several devices on the bus. 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 0x30).

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 2 0x30
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-2, address 0x30, mode byte
Continue? [Y/n] y
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f    .???????????????
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f    ????????????????
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f     !"#$%&'()*+,-./
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f    0123456789:;<=>?
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f    @ABCDEFGHIJKLMNO
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f    PQRSTUVWXYZ[\]^_
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f    `abcdefghijklmno
70: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f    pqrstuvwxyz{|}~?
80: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f    ????????????????
90: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f    ????????????????
a0: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af    ????????????????
b0: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf    ????????????????
c0: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf    ????????????????
d0: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df    ????????????????
e0: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef    ????????????????
f0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff    ???????????????.

To get a single register value, use:

i2cget 2 0x30 0x10
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will read from device file /dev/i2c-2, chip address 0x30, data address
0x10, using read byte data.
Continue? [Y/n] y
0x10

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 the 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 6 platform.

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

See I2C API for more information about the I2C APIx.