Accessing I2C Devices in Linux on i.MXRT1170
The Linux kernel provides a device driver for the I2C controller of the NXP i.MXRT1170, enabled in the kernel with the CONFIG_I2C_IMX_LPI2C build-time option. Another kernel configuration option that you will require is CONFIG_I2C_CHARDEV. This option enables the kernel API that allows accessing I2C devices from user-space application code. Both these kernel configuration options are enabled by default in the rootfs project.
The i.MXRT1170 includes six I2C bus controllers. The parameters of each bus controller (interrupt request numbers, clocks, etc.) are specified in the lpi2c* child nodes properties in the soc node in the linux/arch/arm/boot/dts/nxp/imx/imxrt1170.dtsi file:
soc {
...
lpi2c2: i2c@40108000 {
compatible = "fsl,imx7ulp-lpi2c";
reg = <0x40108000 0x4000>;
interrupts = <33>;
clocks = <&clks IMXRT1170_CLK_LPI2C2>;
#address-cells = <1>;
#size-cells = <0>;
status = "disabled";
};
...
};Assignment of the I2C signals to specific pins is described in the pinctrl_lpi2c* child nodes of the pinctrl node:
&pinctrl {
pinctrl_lpi2c2: lpi2cgrp {
fsl,pins = <
IOMUXC_GPIO_EMC_B2_00_LPI2C2_SCL (IMX_PAD_SION | \
MXRT1170_PAD_DSE | \
MXRT1170_PAD_PUE | \
MXRT1170_PAD_PUS | \
MXRT1170_PAD_SRE)
IOMUXC_GPIO_EMC_B2_01_LPI2C2_SDA (IMX_PAD_SION | \
MXRT1170_PAD_DSE | \
MXRT1170_PAD_PUE | \
MXRT1170_PAD_PUS | \
MXRT1170_PAD_SRE)
>;
};
...
};Finally, the rootfs.dts.IMXRT117X_NXPEVK (rootfs.dts.MAAXBOARD_RT for the MaaXBoard-RT board) file defines the I2C interface reference, with additional properties which enable the appropriate I2C bus controller, and connect it to the pins specified:
&i2c2 {
pinctrl-0 = <&pinctrl_lpi2c2>;
pinctrl-names = "default";
i2c-scl-rising-time-ns = <185>;
i2c-scl-falling-time-ns = <20>;
status = "okay";
...
};The Emcraft uClinux distribution includes the Linux run-time tools that can be used to access I2C devices from user space. The following lines in the rootfs.initramfs file add these tools to the target file system:
file /usr/sbin/i2cdump ${INSTALL_ROOT}/A2F/root/usr/sbin/i2cdump 755 0 0
file /usr/sbin/i2cdetect ${INSTALL_ROOT}/A2F/root/usr/sbin/i2cdetect 755 0 0
file /usr/sbin/i2cget ${INSTALL_ROOT}/A2F/root/usr/sbin/i2cget 755 0 0
file /usr/sbin/i2cset ${INSTALL_ROOT}/A2F/root/usr/sbin/i2cset 755 0 0The functionality described above is enabled by default in the rootfs project. So, just run the rootfs.uImage binary on your target and observe the kernel messages about the I2C bus being enabled:
[ 2.031271] i2c i2c-1: LPI2C adapter registeredRun the Linux I2C tools to examine I2C devices on your target. For instance, the following command scans the I2C1 bus interface and reports any devices it detects on the bus:
/ # i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- 04 -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- 1a -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- 42 -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- UU -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --Refer to the documentation available from the Internet for detailed manuals on the Linux I2C tools, for instance: http://www.lm-sensors.org/wiki/i2cToolsDocumentation. Sometimes your I2C device is already supported in the Linux kernel, and you want to utilize it in some standard way. To provide such access to the I2C device you need:
Enable the appropriate I2C device driver in your Linux kernel configuration;
Add information about your I2C device into the appropriate i2c node reference in the
rootfs.kernel.IMXRT117X_NXPEVKfile.
As an example, let's test the EEPROM installed on the ANT7-M24LR-A board connected to the J1: Pi-HAT compatible 40-pin header of the MaaXBoard-RT board. This EEPROM is connected to the I2C3 bus with address 0x53.
The Linux kernel provides a device driver for I2C EEPROMs, enabled in the kernel with the CONFIG_EEPROM_AT24 build-time option. The specific EEPROM device is described in the rootfs.dts.MAAXBOARD_RT file:
&i2c3 {
...
eeprom@53 {
compatible = "atmel,24c64";
reg = <0x53>;
};
};Validate access to the EEPROM device via the standard interfaces defined by the kernel drivers:
/ # echo "Some text written to EEPROM" > /sys/bus/i2c/devices/0-0053/eeprom
/ # head -n1 /sys/bus/i2c/devices/0-0053/eeprom
Some text written to EEPROM