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