2009-12-04

Linux 2.6 SPI Framework Analysis

1. Files

Linux only implements the SPI controller side. The SPI framework and related SPI master driver files normally go to the "drivers/spi" subfolder under Linux kernel source tree.

spi.c:
The main file implements the SPI framework, including the SPI master and SPI device related function calls.

include/linux/spi/spi.h:
Header file for spi.c and some inline functions.

spidev.c:
Implements a general char device driver for SPI device. This driver can do read/write/ioctl on the SPI device.

include/linux/spi/spidev.h:
Header file for spidev.c.

spi_bitbang.c/spi_gpio.c:
A library implementing a SPI master with GPIOs using bitbang.

spi_xxxx.c
Board related SPI master and SPI device implementation.

2. SPI Framework

Linux has two level SPI devices: SPI master and SPI device.

SPI master is SPI bus controller, and it really handles the hardware. struct spi_master specifies the details of SPI master. Its driver operates the hardware to transfer and/or receive data to/from the SPI device. Under each SPI master (or SPI bus), there could be more than 1 SPI devices.

SPI device is the presentation of the SPI slave in kernel. struct spi_device specifies the details of SPI device. In order to communicate with the SPI slave device, there must be one SPI device existing in the kernel.

Normally, platform data for SPI master and device are statically defined in board specific file. To make it work, SPI master driver and SPI device driver need to be implemented.

2.1. SPI Master Driver

SPI master driver should be registered with probe() function. When SPI master device is found, the probe() function will be called.

The probe() function will initialize the SPI hardware based on the platform data of SPI master. It will allocate struct spi_master and register it to the system. The it will scan the platform data to find the SPI devices connected to this SPI bus.

scan_boardinfo() scans the platform data, and call spi_new_device() to create SPI device data structure, and set up struct spi_device based on the platform information. Then it calls the master's setup() method to further initialize, link the struct spi_device with struct spi_master, and add the SPI device to the system.

To this point, the SPI master and SPI device are created and added to the system. But it still can't communicate with the SPI device as no specific driver is installed yet.

2.2. SPI Device Driver

SPI device needs a driver to work. A general char device driver is implemented in Linux to support basic read()/write()/ioctl() methods. To link up the SPI device with this driver, just need to define the modalias of struct spi_board_info to "spidev".

If a driver is available for SPI device, its probe() method will be called when the SPI device is created and added to the system.

2.3. SPI Data Transfer

The user application needs a SPI device to access the data transfer service from SPI. Read/write/ioctl can be used for data transfer. The SPI device driver utlizes the SPI framework structures to communicate with SPI master driver. The struct spi_message is used to schedule a message to the SPI master's queue. Each message might includes a list of struct spi_transfer.

The SPI master's transfer function will be called by the SPI device driver to start the transfer. The SPI device driver normally needs to wait the SPI master finishs the transfer before return to the user application.

The SPI master driver needs to implement a mechanism to send the data on the SPI bus using the SPI device specified settings. It's the SPI master driver's responsibilities to operate the hardware to send out the data. Normally, the SPI master needs to implement:

  - a message queue: to hold the messages from the SPI device driver

  - a workqueue and workqueue thread: to pump the messages from the message queue and start transfer

  - a tasklet and tasklet handler: to send the data on the hardware

  - a interrupt handler: to handle the interrupts during the transfer

While the SPI master transfering the data, the SPI device driver normally implement a completion to wait the SPI master finishes the transfer.

3. Data Structure Example

This data structure example is taken from ST Cartesio MSP SPI Driver. Click the picture to view a big one.



No comments:

Post a Comment