Linux I2C Driver

The LogiCORE™ IP AXI IIC Bus Interface connects to the AMBA® AXI specification and provides a low-speed, two-wire,serial bus interface to a large number of popular devices. This product specification defines the architecture,hardware (signal) interface, software (register) interface, and parameterization options for the AXI IIC Bus Interface module.


Table of Contents


HW IP Features

  • Compliant to industry standard I2C protocol
  • Register access through AXI4-Lite interface
  • Master or slave operation
  • Multi-master operation
  • Software selectable acknowledge bit
  • Arbitration lost interrupt with automatic mode switching from master to slave
  • Calling address identification interrupt with automatic mode switching from master to slave
  • START and STOP signal generation and detection
  • Repeated START signal generation •
  • Acknowledge bit generation and detection
  • Bus busy detection •
  • Fast-Mode Plus 1 MHz, Fast Mode 400 kHz, or Standard Mode 100 kHz operation
  • 7-bit or 10-bit addressing • General call enable or disable
  • Transmit and receive FIFOs – 16 bytes deep
  • Throttling
  • General purpose output, 1-bit to 8 bits wide
  • Dynamic Start and Stop generation

Known Issues and limitations

  • No slave mode support as of now.
  • No bus recovery. This is because the controller does not give the status of the scl / sda pins and therefore getting the status may be difficult.
  • Receive data length maximum up to 255 bytes.

Kernel Configuration

I2C is not enabled in the current default kernel configuration. The following steps may be used to enable the driver in the kernel configuration

Devicetree

https://github.com/Xilinx/linux-xlnx/blob/master/Documentation/devicetree/bindings/i2c/i2c-xiic.txt

Test procedure

I2C EEPROM From A User Space Application

The following example reads and writes through the I2C EEPROM on the KC705 board. This example can be downloaded at the following link.



This assumes the /dev/i2c device file was created by the user or using udev.

NOTE: The EEPROM higher level driver referenced below cannot be built into the kernel for this example to work. An error that indicates the application cannot set the I2C address will occur if this is the case.

Using An I2C EEPROM Driver As A Higher Layer

I2C EEPROM Driver Kernel Configuration

There are higher layer drivers that allow the I2C driver to be used to access other devices such as the I2C serial EEPROM on the ML507 board. The following steps may be used to enable the driver in the kernel configuration.

  1. From the device drivers menu, select Misc devices
  2. Select EEPROM Support
  3. Select I2C EEPROMs from most vendors
Adding An I2C EEPROM To The Device Tree

The following example shows adding the I2C EEPROM for the ML507 to it's device tree. The value of 0x050 is the I2C address of the EEPROM.

The device-tree generator for the EDK does not create this device on the I2C bus.

Expected Output


The following kernel output (or similar) shows the EEPROM driver was started.

Device Tree Probing 'i2c'
81600000.i2c #0 at 0x81600000 mapped to 0xD1020000, irq=20
at24 0-0050: 1024 byte 24c08 EEPROM (writable)



SysFS Interface.
The EEPROM driver allows the contents of the EEPROM to be seen in the sys file system at /sys/bus/i2c/devices/0-0050/eeprom.
The file,eeporm, is a file that can be read and written from user space.
If the sys file system is not mounted (no /sys dir), then the following commands will create and mount it.

bash > mkdir /sys/
bash > mount -t sysfs sysfs sys

The following shell commands can view the contents of the eeprom by 1st capturing it and then displaying the file as binary data.

bash> more /sys/bus/i2c/devices/0-0050/eeprom > eeprom.txt | od -x

code
Using An Aardvark I2C/SPI Activity Board For I2C EEPROM Testing

TotalPhase, the company that sells the Aardvark I2C test equipment, also sells a small board that we can use for our own testing, independent of the Aardvark. The board has an I2C EEPROM and an SPI EEPROM on it such that it can be connected to an FPGA board pretty easy.

http://www.totalphase.com/products/activity_board/
http://www.totalphase.com/download/pdf/activity-board-v1.00.pdf
http://www.totalphase.com/products/split_cable/

The point of this exercise is to have a standard test for the I2C that can be used across all boards.

See the following page, I2C With The Aardvark Board, for more information on how to do it.

Mainline Status

  • This driver is currently in sync with mainline kernel except for the following:
    Standard mode feature and bug fixes (8), coverity fixes (2), Smbus block read feature (1) as detailed below:
    • i2c: xiic: Remove interrupt enable/disable in Rx path
    • i2c: xiic: Switch to Xiic standard mode for i2c-read
    • i2c-xiic: Fix the type check for xiic_wakeup
    • i2c-xiic: return value of xiic_reinit
    • i2c: xiic: Add smbus_block_read functionality
    • i2c: xiic: Use 'nmsgs' variable instead of repeated_start
    • i2c: xiic: Add wait for FIFO empty in send_tx
    • i2c: xiic: Fix Rx and Tx paths in standard mode repeated start
    • i2c: xiic: Correct the datatype for rx_watermark
    • i2c: xiic: Add standard mode support for > 255 byte read transfers
    • i2c: xiic: Fix Tx Interrupt path for grouped messages

Change Log

  • 2016.3
  •  
    • None
  • 2016.4
    • None
  • 2017.1
    • None
  • 2017.2
    • None
  • 2017.3
    • None
  • 2017.4
    • None
  • 2018.1
    • Summary:
      • i2c: xiic: defer the probe if clock is not found
    • Commits:
      • d8aad33 i2c: xiic: defer the probe if clock is not found

  • 2018.2
    • None
  • 2018.3
    • Summary
      i2c: xiic: Make the start and the byte count write atomic
      i2c: xiic: Fix the clocking across bind unbind
    • Commits
      • ae7304c i2c: xiic: Make the start and the byte count write atomic
      • fc008f848 i2c: xiic: Fix the clocking across bind unbind
  • 2019.1
    • Summary:
      • i2c: xiic: Add timeout to the rx fifo wait loop
    • Commits:
      • b74ba1c14 i2c: xiic: Add timeout to the rx fifo wait loop