Search by Tags

I2C (Linux)

 

Article updated at 11 Aug 2020
Compare with Revision




Subscribe for this article updates

Introduction

The Apalis standard provides 3 I2C busses on the MXM pins 201/203, 205/207 and 209/211.

The Colibri standard provides one I2C bus on the SODIMM pins 194/196.

Colibri iMX6, T20 and T30 provide an Extension Connector with an additional I2C on its pins 15/16 usually used for the display DDC channel.

Colibri iMX8X, has two FFC extension connectors with dedicated I2C buses, also available as alternative pin functions in the SODIMM. Pins 15/16 of X2 have a dedicated I2C for the first LVDS/MIPI-DSI. Pins 13/14 of X3 have a dedicated I2C for the second LVDS/MIPI-DSI.

The Verdin standard provides 3 I2C buses on compatible pins (always available on all Verdin modules) + 1 I2C bus on reserved pins (if available on the SoM, it will always be on specific pins):

  • On compatible pins: I2C for generic usage on pins 12/14; I2C for MIPI DSI on pins 53/55; I2C for MIPI CSI-2 on pins 93/95.
  • On reserved pins: I2C for HDMI DDC on pins 57/59.

On top of that most modules use an I2C bus for on-module components like the audio codec, PMIC or touch controller.

Additional I2Cs

Depending on the module type additional I2C buses might be available as alternate functions of other pins given the kernel gets configured accordingly in the device tree or the platform data. Read the Computer on Module datasheet carefully and check the Pinout Designer Tool for more information about extra I2C and the impact on the default pinout of the module.

Bus Assignment

The tables below displays the I2C enumeration for the Embedded Linux BSP unchanged. If you decide to enable extra I2C controllers, or disable existing ones, the index numbers may change. In such a case, the most reliable means to get the correct I2C index is from the controller address, which is a hardware feature and does not change. Check the sub-section Get the Linux Index from the Controller Address below for reference.

Apalis

Module
(Proposed use)
I2C1 / MXM_209/211
(Generic)
I2C2 / MXM_205/207
(DDC)
I2C3 / MXM_201/203
(CAM)
On-Module Non-Standard
Apalis iMX6 i2c-0 i2c-3 *) i2c-1 i2c-2
Apalis iMX8 i2c-4 i2c-2 i2c-5 i2c-3
Apalis iMX8X i2c-18 i2c-16 i2c-19 i2c-17
Apalis T30 i2c-0 i2c-3 i2c-2 i2c-4
Apalis TK1 V1.1 i2c-0 i2c-1 i2c-2 i2c-4 i2c-3 (GPIO3/GPIO4)
Apalis TK1 V1.2 i2c-0 i2c-3 i2c-2 i2c-4

*) uses the GPIO bitbang driver.

Colibri

Module
(Proposed use)
SODIMM_194/196
(Generic)
Extension Connector 15/16
(DDC)
On-Module
Colibri iMX6 i2c-1 i2c-4 i2c-0
Colibri iMX6ULL i2c-0 N/A i2c-1
Colibri iMX7 i2c-3 N/A i2c-0
Colibri iMX8X * i2c-17 N/A i2c-16
Colibri T20 i2c-0 i2c-1 i2c-4
Colibri T30 i2c-1 i2c-4 i2c-0
Colibri VF i2c-0 N/A N/A

*) the values may change, see the Colibri iMX8X section below for details.

Verdin

Module
(Proposed use)
I2C_1 / SODIMM_12/14
(Generic)
I2C_2_DSI / SODIMM_53/55
(DSI)
I2C_3_HDMI / SODIMM_57/59
(HDMI DDC)
I2C_4_CSI / SODIMM_93/95
(CSI2)
On-Module
Verdin iMX8MM i2c-3 i2c-1 N/A i2c-2 i2c-0

Get the Linux Index from the Controller Address

The default values from the tables above may change if you enable extra I2Cs, for example, to use a MIPI-CSI2 camera, an LVDS or MIPI-DSI display - or for any other reason you enable or disable I2Cs.

You can make sure that you are using the correct I2C by using the controller address to get the Linux index. The controller address does not change.

Example - Colibri iMX8X

See the addresses for Colibri iMX8X in the table below:

SODIMM_194/196
(Generic)
On-Module
5a810000.i2c 5a800000.i2c

You can use any of i2cdetect -l or ls -la /sys/class/i2c-dev to get the index once you know the address.

Examples below are provided for the Embedded Linux BSP with only 2 I2Cs enabled: the one from the Colibri standard and the on-module.

Using i2cdetect -l:

# i2cdetect -l
i2c-17  i2c         5a810000.i2c                        I2C adapter
i2c-16  i2c         5a800000.i2c                        I2C adapter

Using ls -la /sys/class/i2c-dev:

# ls -la /sys/class/i2c-dev
drwxr-xr-x    2 root     root             0 Jan 13 15:20 .
drwxr-xr-x   68 root     root             0 Jan 13 15:20 ..
lrwxrwxrwx    1 root     root             0 Jan 13 15:20 i2c-16 -> ../../devices/platform/5a800000.i2c/i2c-16/i2c-dev/i2c-16
lrwxrwxrwx    1 root     root             0 Jan 13 15:20 i2c-17 -> ../../devices/platform/5a810000.i2c/i2c-17/i2c-dev/i2c-17

I2C Tools

Most I2C devices are handled by kernel drivers. The device tree or platform data binds the I2C bus to such drivers. From userspace one accesses them then through the relevant subsystem rather than having to do low-level I2C access. E.g. for an RTC one would use /dev/rtcX or even a userspace program like hwclock.

The I2C Tools package provides tools for low-level access to I2C devices. As follows a few sample use cases:

Check the configured I2C busses

root@colibri-t20:~# ls -l /dev/i2c-*
crw------- 1 root root 89, 0 Jan 1 2000 /dev/i2c-0
crw------- 1 root root 89, 1 Jan 1 2000 /dev/i2c-1
crw------- 1 root root 89, 4 Jan 1 2000 /dev/i2c-4

Detect devices on i2c-0

root@colibri-t20:~# i2cdetect -y -r 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

UU denotes a device which is used by a kernel driver and thus is usually not touched. Depending on the I2C device it may not get discovered by i2cdetect.

Dump register content of an I2C device

root@colibri-t20:~# i2cdump -r 0-0xf 0 0x20 b
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0, address 0x20, mode byte
Probe range limited to 0x00-0x0f.
Continue? [Y/n] y
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 10 40 00 00 10 80 00 80 88 02 00 23 00 00 03 18 ?@..??.???.#..??

Read a single byte, change its value and verify it with an additional read

root@colibri-t20:~# i2cget 0 0x20 4 b
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will read from device file /dev/i2c-0, chip address 0x20, data address
0x04, using read byte data.
Continue? [Y/n] y
0x10
root@colibri-t20:~# i2cset 0 0x20 4 0x18 b
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will write to device file /dev/i2c-0, chip address 0x20, data address
0x04, data 0x18, mode byte.
Continue? [Y/n] y
root@colibri-t20:~# i2cget 0 0x20 4 b
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will read from device file /dev/i2c-0, chip address 0x20, data address
0x04, using read byte data.
Continue? [Y/n]
0x18