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.
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 except for the following:
- i2c: cadence: Clear HOLD bit before xfer_size register rolls over
- i2c-cadence: Replace the value with enum
- i2c-cadence: Check the return value of pin-ctrl
- i2c: cadence: Handling Slave monitor mode
- i2c: cadence: Recover bus after controller reset
- i2c: cadence: Implement save restore
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
- Summary
- 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
- Summary
- 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
- Summary
- 2018.2
- None
- 2018.3
- None
- 2019.1
- Summary
- i2c: cadence: Fix typo in kernel-doc format
- i2c: cadence: Fix the driver in interrupt flurry case
- Commits
- 6e7f6d7 i2c: cadence: Fix typo in kernel-doc format
- 7376658 i2c: cadence: Fix the driver in interrupt flurry case
- Summary
- 2019.2
- None
- 2020.1
- Summary
- Revert "i2c: cadence: Fix the hold bit setting"
- Commits:
- Summary
- 2020.2
- Summary
- i2c-cadence: Replace the value with enum
- i2c-cadence: Check the return value of pin-ctrl
- i2c: cadence: Clear HOLD bit at correct time in Rx path
- i2c: cadence: Handle transfer_size rollover
- Commits
- Summary
Related Links
None