Cadence I2C Linux driver for Zynq and Zynq Ultrascale+ MPSoC

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. I2C slave support is yet to be added in the 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.

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

i2c_kconfig.png

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 zc702:
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 fro 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
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 except for the following:
  • Recover bus after controller reset
  • Fix pin controller failure
  • Fix the i2c Bus Recovery issue.
  • Added slave support
  • Fix wording in i2c-cadence driver
  • Re-order the interrupt enable sequence in the i2c send and receive path
  • Fixed repeated start not holding the bus long enough
  • Remove pm_runtime_disable

ChangeLog


  • 2016.3
    • None
  • 2016.4
    • None
  • 2017.1
    • Summary
  • i2c: cadence: Recover bus after controller reset
  • i2c: cadence: Fix pin controller failure
  • I2c: Fix the i2c Bus Recovery issue.
  • i2c: cadence: Added slave support
  • i2c: cadence: Fix wording in i2c-cadence driver

  • Commits
    • 0b4e260 i2c: cadence: Recover bus after controller reset
    • b6811d3 i2c: cadence: Fix pin controller failure
    • 5639be4 I2c: Fix the i2c Bus Recovery issue.
    • f2290d9 i2c: cadence: Added slave support
    • 2c3fd0a i2c: cadence: Fix wording in i2c-cadence driver

  • 2017.2
    • None
  • 2017.3
    • Summary
      • i2c: Re-order the interrupt enable sequence in the i2c send and receive path
      • i2c: cadence: Fixed repeated start not holding the bus long enough
      • i2c: cadence: Remove pm_runtime_disable
    • Commits
      • 1692844 i2c: Re-order the interrupt enable sequence in the i2c send and receive path
      • 9e90cc1 i2c: cadence: Fixed repeated start not holding the bus long enough
      • 4293372 i2c: cadence: Remove pm_runtime_disable
  • 2017.4
    • None
  • 2018.1
    • Summary
      • i2c: use dev_get_drvdata() to get private data in suspend/resume hooks
      • i2c: cadence: Fixed repeated start not holding the bus long enough
    • Commits
      • 9242e72 i2c: use dev_get_drvdata() to get private data in suspend/resume hooks
      • 9e90cc1 i2c: cadence: Fixed repeated start not holding the bus long enough
  • 2018.2
    • None



Related Links