Introduction

This page provides information about the Cadence I2C driver which can be found on Xilinx Git and mainline as i2c-cadence.c
Zynq has two I2C hard IP. I2C can be used as a master with this linux driver.
There is support for repeated start with some limitations.

HW IP Features


Known issues and limitations

Important AR links

Kernel Configuration

The following config options need to be enabled:
CONFIG_I2C_CADENCE

It depends on I2C and ARCH_ZYNQ



Devicetree

Refer to Documentation/devicetree/bindings/i2c/i2c-cadence.txt for complete description.
Example
The following example shows adding an I2C node to the devicetree with the various interfaces connected to i2c on zynq zc702 board:

i2c0 {
    status = "okay";
    clock-frequency = <400000>;
    pinctrl-names = "default";
    pinctrl-0 = <&&pinctrl_i2c0_default>;
 
    i2cswitch@74 {
        compatible = "nxp,pca9548";
        #address-cells = <1>;
        #size-cells = <0>;
        reg = <0x74>;
 
        i2c@0 {
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <0>;
            si570: clock-generator@5d {
                #clock-cells = <0>;
                compatible = "silabs,si570";
                temperature-stability = <50>;
                reg = <0x5d>;
                factory-fout = <156250000>;
                clock-frequency = <148500000>;
            };
        };
 
        i2c@2 {
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <2>;
            eeprom@54 {
                compatible = "at,24c08";
                reg = <0x54>;
            };
        };
 
        i2c@3 {
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <3>;
            gpio@21 {
                compatible = "ti,tca6416";
                reg = <0x21>;
                gpio-controller;
                #gpio-cells = <2>;
            };
        };
 
        i2c@4 {
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <4>;
            rtc@51 {
                compatible = "nxp,pcf8563";
                reg = <0x51>;
            };
        };
 
        i2c@7 {
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <7>;
            hwmon@52 {
                compatible = "ti,ucd9248";
                reg = <52>;
            };
            hwmon@53 {
                compatible = "ti,ucd9248";
                reg = <53>;
            };
            hwmon@54 {
                compatible = "ti,ucd9248";
                reg = <54>;
            };
        };
    };
};
 
 

Test procedure


This section details i2c tests with various interfaces:
Eeprom Test helper script
Writes different patterns to the I2C EEPROM, reads back the contents of the EEPROM and performs data verification.
Inputs expected by the helper script (i2c_eeprom_helper.sh), in that order:
1. The EEPROM to test in the /sys filesystem, a full path
2. Offset from the start of the EEPROM
3. The number of bytes to read/write at the offset from the start of the EEPROM.

I2C eeprom helper script & test logs:



EEPROM Stress Test
The following test can be used for performing eeprom stress test:


Testing RTC
Read Date and Time from RTC

zynq> cat /sys/bus/i2c/devices/5-0051/rtc/rtc0/date
zynq> cat /sys/bus/i2c/devices/5-0051/rtc/rtc0/date

Testing UCD9248
TI's UCD9248 PWM controllers are commonly used on Xilinx platforms like the zc702.
The Linux driver for these controllers allows voltage and current monitoring through a sysfs interface exposed in /sys/bus/i2c/devices/*.
The driver is documented in Documentation/hwmon/ucd9200

zynq> cat /sys/bus/i2c/devices/8-0035/hwmon/hwmon1/in1_min
zynq> cat /sys/bus/i2c/devices/8-0035/hwmon/hwmon1/curr1_input

Testing I2C EEPROM
Basic test on zynq zc702 board:
1. Create BIN file using DD command

- dd if=/dev/urandom of=eeprom_in.bin bs=1 count=128 skip=0
128+0 records in
128+0 records out
128 bytes (128B) copied, 0.001327 seconds, 94.2KB/s

2. Write BIN file to EEPROM

- dd if=eeprom_in.bin of=/sys/bus/i2c/devices/0-0054/eeprom bs=1 count=128 skip=0
128+0 records in
128+0 records out
128 bytes (128B) copied, 2.539178 seconds, 50B/s

3. Read Data From EEPROM

- dd if=/sys/bus/i2c/devices/0-0054/eeprom of=eeprom_out.bin bs=1 count=128 skip=0
128+0 records in
128+0 records out
128 bytes (128B) copied, 0.065103 seconds, 1.9KB/s

Expected Output

Verify data using md5sum tools

- md5sum eeprom_in.bin eeprom_out.bin
e83e141e1d9f71b3f820652f502239d2 eeprom_in.bin
e83e141e1d9f71b3f820652f502239d2 eeprom_out.bin

Mainline Status

This driver is currently in sync with mainline kernel driver.

ChangeLog

2023.2

2023.1

Summary

Commits

9fdf6d9i2c: cadence: Support PEC for SMBus block read

58b9242i2c: cadence: Add standard bus recovery support

8bfd4eci2c: cadence: Fix regression with bus recovery

2022.2

Summary

Commits

42ab616i2c: cadence: Change large transfer count reset logic to be unconditional

2022.1

Summary

Commits

ed35515i2c: cadence: add IRQ check

b14b31fi2c: cadence: fix reference leak when pm_runtime_get_sync fails


Related Links
None