Cadence I2C Driver

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

  • Master mode
  • Support 16 bytes FIFO
  • Programmable normal and fast bus data rates
  • Interrupt support
  • Repeated start support using HOLD bit
  • FIFO control using HOLD bit
  • Slave monitoring support in Master mode.


Known issues and limitations

  • Repeated start after a read transfer is not supported by this controller. A warning is given when this condition is detected by the driver.
  • The following are the controller errata:
  • Missing glitch filter.
  • I2C Master Generates Invalid Read Transactions
  • Missing I2C Master Completion Interrupt.
  • Timing requirement violations
    • I2C - Standard Mode running faster than 90 kHz violates tHD; STA timing requirement.
    • I2C - Fast Mode running faster than 384kHz violates tLOW; STA timing requirement.
    • I2C - Fast Mode running faster than 384 kHz violates tBUF; STA timing requirement.
  • I2C Missing Arbitration On Repeated Start.
  • Multi-master configuration works only if all the participating masters are operating at the same frequency.

Important AR links

  • Zynq-7000 AP SoC, I2C - Missing Glitch Filter Implementation in Zynq PS I2C Controller AR# 61861
  • Zynq-7000 AP SoC, I2C - I2C Master Generates Invalid Read Transactions AR# 61664
  • Zynq-7000 AP SoC, I2C - Missing I2C Master Completion Interrupt AR# 61665
  • Zynq-7000 AP SoC, I2C - I2C Missing Arbitration on Repeated Start AR# 60695
  • Zynq-7000 AP SoC, I2C - Standard Mode running faster than 90 kHz violates tHD; STA timing requirement AR# 59366
  • Zynq-7000 AP SoC, I2C - Fast Mode running faster than 384kHz violates tLOW; STA timing requirement AR# 60693
  • Zynq-7000 AP SoC, I2C - Fast Mode running faster than 384 kHz violates tBUF; STA timing requirement AR# 60694

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

2024.1

Summary

  • Remove unused CDNS_I2C_DATA_INTR_DEPTH define
  • Remove irq field from driver state struct
  • Remove redundant expression in if clause
  • Remove always false ternary operator
  • Remove unnecessary register reads
  • Allow to specify the FIFO depth