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:
-
I2C1 connects internally to the power management IC (PMIC), the on-module Micro Controller Assist (MCA), and the Atmel Cryptochip at the following addresses:
Interface Address (7-bit) PMIC
0x08
Cryptochip
0x60
MCA
0x7e
-
I2C2, I2C3, and I2C4 are available for peripherals to use (multiplexed with other functionality).
On the ConnectCore 6UL SBC Express:
-
I2C2 is available on the expansion connector and on Grove connector J10.
On the ConnectCore 6UL SBC Pro:
-
I2C1 is available on a connector, which you can use to connect additional devices.
The following table lists the three devices on board the ConnectCore 6UL SBC Pro I2C1 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:
-
Touch controller at address 0x14, available on AUO 10" LCD display. See https://www.digi.com/products/models/cc-acc-lcdw-10 for details on the AUO 10" LCD kit available from Digi.
-
OmniVision ov5640 CSI camera at address 0x3C, (not included in the kit).
The 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:
-
IMX I2C interface (CONFIG_I2C_IMX)
This kernel configuration option is enabled as built-in on the default ConnectCore 6UL kernel configuration file.
Kernel driver
The driver for the I2C interface is located at:
File | Description |
---|---|
i.MX I2C controller driver |
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 CPU, system-on-module, and carrier board device tree files.
Example: I2C1
Define the bus
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
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
&i2c1 {
[...]
goodix_touch: gt911@14 {
compatible = "goodix,gt9271";
reg = <0x14>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_goodix_touch>;
interrupt-parent = <&gpio5>;
interrupts = <2 IRQ_TYPE_EDGE_RISING>;
irq-gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>;
reset-gpios = <&mca_ioexp_gpio 29 GPIO_ACTIVE_HIGH>;
skip-firmware-request;
reload-fw-on-resume;
};
[...]
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-0 i2c 21a0000.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 6UL platform.
Go to GitHub to see the application instructions and source code.
See I2C API for more information about the I2C APIx.