I2C

Note This section contains Linux BSP documentation for kernel v4.1. Click here for v4.9 BSP documentation.

The NXP i.MX6UL CPU has four I2C buses that operate at up to 400 Kbps. 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 6UL:

Interface

Address (7-bit)

PMIC

0x08

Cryptochip

0x60

MCA

0x7E

On the ConnectCore 6UL SBC Express:

On the ConnectCore 6UL SBC Pro:

The following table lists the three devices on board the ConnectCore 6UL SBC Pro I2C bus:

Interface

Address (7-bit)

Audio codec

0x10

NTAG

0x55

I/O Expander

0x6E

The ConnectCore 6UL SBC Pro device tree defines the following additional I2C devices:

Note The Fusion display touch controller has I2C address 0x10, but since the audio codec on the ConnectCore 6UL SBC Pro also has address 0x10, an I2C address translator on the Video Adapter Board moves the touch controller to address 0x14.

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 default ConnectCore 6UL kernel configuration file.

Platform driver mapping

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

Device tree bindings and customization

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

The I2C interfaces are defined in the i.MX6UL CPU, ConnectCore 6UL system-on-module, and ConnectCore 6UL SBC Express and SBC Pro device tree files.

Example: I2C1

Define the bus

Common i.MX6UL device tree
i2c1: i2c@021a0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";
reg = <0x021a0000 0x4000>;
interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_I2C1>;
status = "disabled";
};

Configure IOMUX

ConnectCore 6UL device tree
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
>;
};

Enable the bus and define attached client devices

ConnectCore 6UL SBC Pro device tree
&i2c1 {
 
 
fusion_touch: fusion@14 {
compatible = "touchrev,fusion-touch";
reg = <0x14>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fusion_touch>;
interrupt-parent = <&gpio5>;
interrupts = <2 IRQ_TYPE_EDGE_RISING>;
status = "disabled";
[...]
 
};

I2C user space usage examples

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

CAUTION! 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:

root@ccimx6ulsbc:~# i2cdetect -l
i2c-0   i2c             21a0000.i2c                             I2C adapter

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

root@ccimx6ulsbc:~# 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:

root@ccimx6ulsbc:~# 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?