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
2025.1
None
2024.2
Summary
Add system suspend and resume PM support
remove printout on handled timeouts
Relocate cdns_i2c_runtime_suspend and cdns_i2c_runtime to facilitate atomic mode
Split cdns_i2c_master_xfer for Atomic Mode
Add atomic transfer support for controller version 1.4
Commits
6d0b17b - i2c: cadence: Add system suspend and resume PM support
70a81b4 - i2c: cadence: remove printout on handled timeouts
2afb02c - i2c: cadence: Relocate cdns_i2c_runtime_suspend and cdns_i2c_runtime to facilitate atomic mode
9c9b15c - i2c: cadence: Split cdns_i2c_master_xfer for Atomic Mode
5f3a1d1 - i2c: cadence: Add atomic transfer support for controller version 1.4
2024.1
Summary
Remove unused CDNS_I2C_DATA_INTR_DEPTH define
Remove
irq
field from driver state structRemove redundant expression in if clause
Remove always false ternary operator
Remove unnecessary register reads
Allow to specify the FIFO depth
Detect maximum transfer size
Add reset controller support
Fix runtime PM leak on error path
Convert to platform remove callback returning void
Fix the kernel-doc warnings
Commits
72f94ff - i2c: cadence: Remove unused CDNS_I2C_DATA_INTR_DEPTH define
2264997 - i2c: cadence: Remove irq
field from driver state struct
a4a1a78 - i2c: cadence: Remove redundant expression in if clause
e9d373c - i2c: cadence: Remove always false ternary operator
ff0cf7b - i2c: cadence: Remove unnecessary register reads
a069fcd - i2c: cadence: Allow to specify the FIFO depth
ba06487 - i2c: cadence: Detect maximum transfer size
0cbc9a2 - i2c: cadence: Add reset controller support
ae1664f - i2c: cadence: cdns_i2c_master_xfer(): Fix runtime PM leak on error path
e190a0c - i2c: Convert to platform remove callback returning void
637f33a - i2c: cadence: Fix the kernel-doc warnings
2023.2
None
2023.1
Summary
Support PEC for SMBus block read
Add standard bus recovery support
Fix regression with bus recovery
Commits
9fdf6d9 - i2c: cadence: Support PEC for SMBus block read
58b9242 - i2c: cadence: Add standard bus recovery support
8bfd4ec - i2c: cadence: Fix regression with bus recovery
2022.2
Summary
Change large transfer count reset logic to be unconditional
Commits
42ab616 - i2c: cadence: Change large transfer count reset logic to be unconditional
2022.1
Summary
Add IRQ check
Fix reference leak when pm_runtime_get_sync fails
Commits
ed35515 - i2c: cadence: add IRQ check
b14b31f - i2c: cadence: fix reference leak when pm_runtime_get_sync fails
Related Links
None
© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy