SPI is the “Serial Peripheral Interface”, widely used with embedded systems because it is a simple and efficient interface: basically a multiplexed shift register. Its three signal wires hold a clock (SCK, often in the range of 1-20 MHz), a “Master Out, Slave In” (MOSI) data line, and a “Master In, Slave Out” (MISO) data line. SPI is a full duplex protocol; for each bit shifted out the MOSI line (one per clock) another is shifted in on the MISO line. Those bits are assembled into words of various sizes on the way to and from system memory. An additional chipselect line is usually active-low (nCS); four signals are normally used for each peripheral, plus sometimes an interrupt.
The SPI bus facilities listed here provide a generalized interface to declare SPI busses and devices, manage them according to the standard Linux driver model, and perform input/output operations. At this time, only “master” side interfaces are supported, where Linux talks to SPI peripherals and does not implement such a peripheral itself. (Interfaces to support implementing SPI slaves would necessarily look different.)
The programming interface is structured around two kinds of driver, and two kinds of device. A “Controller Driver” abstracts the controller hardware, which may be as simple as a set of GPIO pins or as complex as a pair of FIFOs connected to dual DMA engines on the other side of the SPI shift register (maximizing throughput). Such drivers bridge between whatever bus they sit on (often the platform bus) and SPI, and expose the SPI side of their device as a struct spi_master. SPI devices are children of that master, represented as a struct spi_device and manufactured from struct spi_board_info descriptors which are usually provided by board-specific initialization code. A struct spi_driver is called a “Protocol Driver”, and is bound to a spi_device using normal driver model calls.
The I/O model is a set of queued messages. Protocol drivers submit one or more struct spi_message objects, which are processed and completed asynchronously. (There are synchronous wrappers, however.) Messages are built from one or more struct spi_transfer objects, each of which wraps a full duplex SPI transfer. A variety of protocol tweaking options are needed, because different chips adopt very different policies for how they use the bits transferred with SPI.
statistics for spi transfers
Definition
struct spi_statistics {
spinlock_t lock;
unsigned long messages;
unsigned long transfers;
unsigned long errors;
unsigned long timedout;
unsigned long spi_sync;
unsigned long spi_sync_immediate;
unsigned long spi_async;
unsigned long long bytes;
unsigned long long bytes_rx;
unsigned long long bytes_tx;
#define SPI_STATISTICS_HISTO_SIZE 17
unsigned long transfer_bytes_histo[SPI_STATISTICS_HISTO_SIZE];
unsigned long transfers_split_maxsize;
};
Members
Master side proxy for an SPI slave device
Definition
struct spi_device {
struct device dev;
struct spi_master * master;
u32 max_speed_hz;
u8 chip_select;
u8 bits_per_word;
u16 mode;
#define SPI_CPHA 0x01
#define SPI_CPOL 0x02
#define SPI_MODE_0 (0|0)
#define SPI_MODE_1 (0|SPI_CPHA)
#define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
#define SPI_CS_HIGH 0x04
#define SPI_LSB_FIRST 0x08
#define SPI_3WIRE 0x10
#define SPI_LOOP 0x20
#define SPI_NO_CS 0x40
#define SPI_READY 0x80
#define SPI_TX_DUAL 0x100
#define SPI_TX_QUAD 0x200
#define SPI_RX_DUAL 0x400
#define SPI_RX_QUAD 0x800
int irq;
void * controller_state;
void * controller_data;
char modalias[SPI_NAME_SIZE];
int cs_gpio;
struct spi_statistics statistics;
};
Members
Description
A spi_device is used to interchange data between an SPI slave (usually a discrete chip) and CPU memory.
In dev, the platform_data is used to hold information about this device that’s meaningful to the device’s protocol driver, but not to its controller. One example might be an identifier for a chip variant with slightly different functionality; another might be information about how this particular board wires the chip’s pins.
Host side “protocol” driver
Definition
struct spi_driver {
const struct spi_device_id * id_table;
int (* probe) (struct spi_device *spi);
int (* remove) (struct spi_device *spi);
void (* shutdown) (struct spi_device *spi);
struct device_driver driver;
};
Members
Description
This represents the kind of device driver that uses SPI messages to interact with the hardware at the other end of a SPI link. It’s called a “protocol” driver because it works through messages rather than talking directly to SPI hardware (which is what the underlying SPI controller driver does to pass those messages). These protocols are defined in the specification for the device(s) supported by the driver.
As a rule, those device protocols represent the lowest level interface supported by a driver, and it will support upper level interfaces too. Examples of such upper levels include frameworks like MTD, networking, MMC, RTC, filesystem character device nodes, and hardware monitoring.
reverse effect of spi_register_driver
Parameters
Context
can sleep
Helper macro for registering a SPI driver
Parameters
Description
Helper macro for SPI drivers which do not do anything special in module init/exit. This eliminates a lot of boilerplate. Each module may only use this macro once, and calling it replaces module_init() and module_exit()
interface to SPI master controller
Definition
struct spi_master {
struct device dev;
struct list_head list;
s16 bus_num;
u16 num_chipselect;
u16 dma_alignment;
u16 mode_bits;
u32 bits_per_word_mask;
#define SPI_BPW_MASK(bits) BIT((bits) - 1)
#define SPI_BIT_MASK(bits) (((bits) == 32) ? ~0U : (BIT(bits) - 1))
#define SPI_BPW_RANGE_MASK(min# max) (SPI_BIT_MASK(max) - SPI_BIT_MASK(min - 1))
u32 min_speed_hz;
u32 max_speed_hz;
u16 flags;
#define SPI_MASTER_HALF_DUPLEX BIT(0)
#define SPI_MASTER_NO_RX BIT(1)
#define SPI_MASTER_NO_TX BIT(2)
#define SPI_MASTER_MUST_RX BIT(3)
#define SPI_MASTER_MUST_TX BIT(4)
#define SPI_MASTER_GPIO_SS BIT(5)
size_t (* max_transfer_size) (struct spi_device *spi);
size_t (* max_message_size) (struct spi_device *spi);
struct mutex io_mutex;
spinlock_t bus_lock_spinlock;
struct mutex bus_lock_mutex;
bool bus_lock_flag;
int (* setup) (struct spi_device *spi);
int (* transfer) (struct spi_device *spi,struct spi_message *mesg);
void (* cleanup) (struct spi_device *spi);
bool (* can_dma) (struct spi_master *master,struct spi_device *spi,struct spi_transfer *xfer);
bool queued;
struct kthread_worker kworker;
struct task_struct * kworker_task;
struct kthread_work pump_messages;
spinlock_t queue_lock;
struct list_head queue;
struct spi_message * cur_msg;
bool idling;
bool busy;
bool running;
bool rt;
bool auto_runtime_pm;
bool cur_msg_prepared;
bool cur_msg_mapped;
struct completion xfer_completion;
size_t max_dma_len;
int (* prepare_transfer_hardware) (struct spi_master *master);
int (* transfer_one_message) (struct spi_master *master,struct spi_message *mesg);
int (* unprepare_transfer_hardware) (struct spi_master *master);
int (* prepare_message) (struct spi_master *master,struct spi_message *message);
int (* unprepare_message) (struct spi_master *master,struct spi_message *message);
int (* spi_flash_read) (struct spi_device *spi,struct spi_flash_read_message *msg);
bool (* flash_read_supported) (struct spi_device *spi);
void (* set_cs) (struct spi_device *spi, bool enable);
int (* transfer_one) (struct spi_master *master, struct spi_device *spi,struct spi_transfer *transfer);
void (* handle_err) (struct spi_master *master,struct spi_message *message);
int * cs_gpios;
struct spi_statistics statistics;
struct dma_chan * dma_tx;
struct dma_chan * dma_rx;
void * dummy_rx;
void * dummy_tx;
int (* fw_translate_cs) (struct spi_master *master, unsigned cs);
};
Members
transfer a single spi_transfer. - return 0 if the transfer is finished, - return 1 if the transfer is still in progress. When
the driver is finished with this transfer it must call spi_finalize_current_transfer() so the subsystem can issue the next transfer. Note: transfer_one and transfer_one_message are mutually exclusive; when both are set, the generic subsystem does not call your transfer_one callback.
Description
Each SPI master controller can communicate with one or more spi_device children. These make a small bus, sharing MOSI, MISO and SCK signals but not chip select signals. Each device may be configured to use a different clock rate, since those shared signals are ignored unless the chip is selected.
The driver for an SPI controller manages access to those devices through a queue of spi_message transactions, copying data between CPU memory and an SPI slave device. For each such message it queues, it calls the message’s completion function when the transaction completes.
spi resource management structure
Definition
struct spi_res {
struct list_head entry;
spi_res_release_t release;
unsigned long long data[];
};
Members
Description
this is based on ideas from devres, but focused on life-cycle management during spi_message processing
a read/write buffer pair
Definition
struct spi_transfer {
const void * tx_buf;
void * rx_buf;
unsigned len;
dma_addr_t tx_dma;
dma_addr_t rx_dma;
struct sg_table tx_sg;
struct sg_table rx_sg;
unsigned cs_change:1;
unsigned tx_nbits:3;
unsigned rx_nbits:3;
#define SPI_NBITS_SINGLE 0x01
#define SPI_NBITS_DUAL 0x02
#define SPI_NBITS_QUAD 0x04
u8 bits_per_word;
u16 delay_usecs;
u32 speed_hz;
struct list_head transfer_list;
};
Members
Description
SPI transfers always write the same number of bytes as they read. Protocol drivers should always provide rx_buf and/or tx_buf. In some cases, they may also want to provide DMA addresses for the data being transferred; that may reduce overhead, when the underlying driver uses dma.
If the transmit buffer is null, zeroes will be shifted out while filling rx_buf. If the receive buffer is null, the data shifted in will be discarded. Only “len” bytes shift out (or in). It’s an error to try to shift out a partial word. (For example, by shifting out three bytes with word size of sixteen or twenty bits; the former uses two bytes per word, the latter uses four bytes.)
In-memory data values are always in native CPU byte order, translated from the wire byte order (big-endian except with SPI_LSB_FIRST). So for example when bits_per_word is sixteen, buffers are 2N bytes long (len = 2N) and hold N sixteen bit words in CPU byte order.
When the word size of the SPI transfer is not a power-of-two multiple of eight bits, those in-memory words include extra bits. In-memory words are always seen by protocol drivers as right-justified, so the undefined (rx) or unused (tx) bits are always the most significant bits.
All SPI transfers start with the relevant chipselect active. Normally it stays selected until after the last transfer in a message. Drivers can affect the chipselect signal using cs_change.
(i) If the transfer isn’t the last one in the message, this flag is used to make the chipselect briefly go inactive in the middle of the message. Toggling chipselect in this way may be needed to terminate a chip command, letting a single spi_message perform all of group of chip transactions together.
(ii) When the transfer is the last one in the message, the chip may stay selected until the next transfer. On multi-device SPI busses with nothing blocking messages going to other devices, this is just a performance hint; starting a message to another device deselects this one. But in other cases, this can be used to ensure correctness. Some devices need protocol transactions to be built from a series of spi_message submissions, where the content of one message is determined by the results of previous messages and where the whole transaction ends when the chipselect goes intactive.
When SPI can transfer in 1x,2x or 4x. It can get this transfer information from device through tx_nbits and rx_nbits. In Bi-direction, these two should both be set. User can set transfer mode with SPI_NBITS_SINGLE(1x) SPI_NBITS_DUAL(2x) and SPI_NBITS_QUAD(4x) to support these three transfer.
The code that submits an spi_message (and its spi_transfers) to the lower layers is responsible for managing its memory. Zero-initialize every field you don’t set up explicitly, to insulate against future API updates. After you submit a message and its transfers, ignore them until its completion callback.
one multi-segment SPI transaction
Definition
struct spi_message {
struct list_head transfers;
struct spi_device * spi;
unsigned is_dma_mapped:1;
void (* complete) (void *context);
void * context;
unsigned frame_length;
unsigned actual_length;
int status;
struct list_head queue;
void * state;
struct list_head resources;
};
Members
Description
A spi_message is used to execute an atomic sequence of data transfers, each represented by a struct spi_transfer. The sequence is “atomic” in the sense that no other spi_message may use that SPI bus until that sequence completes. On some systems, many such sequences can execute as as single programmed DMA transfer. On all systems, these messages are queued, and might complete after transactions to other devices. Messages sent to a given spi_device are always executed in FIFO order.
The code that submits an spi_message (and its spi_transfers) to the lower layers is responsible for managing its memory. Zero-initialize every field you don’t set up explicitly, to insulate against future API updates. After you submit a message and its transfers, ignore them until its completion callback.
Initialize spi_message and append transfers
Parameters
Description
This function initializes the given spi_message and adds each spi_transfer in the given array to the message.
structure describing the spi_transfer replacements that have occurred so that they can get reverted
Definition
struct spi_replaced_transfers {
spi_replaced_release_t release;
void * extradata;
struct list_head replaced_transfers;
struct list_head * replaced_after;
size_t inserted;
struct spi_transfer inserted_transfers[];
};
Members
note
that extradata will point to inserted_transfers**[**inserted] if some extra allocation is requested, so alignment will be the same as for spi_transfers
synchronous SPI data transfer
Parameters
Context
can sleep
Description
Does a synchronous SPI data transfer of the given spi_transfer array.
For more specific semantics see spi_sync().
Return
Return: zero on success, else a negative error code.
SPI synchronous write
Parameters
Context
can sleep
Description
This function writes the buffer buf. Callable only from contexts that can sleep.
Return
zero on success, else a negative error code.
SPI synchronous read
Parameters
Context
can sleep
Description
This function reads the buffer buf. Callable only from contexts that can sleep.
Return
zero on success, else a negative error code.
SPI synchronous 8 bit write followed by 8 bit read
Parameters
Context
can sleep
Description
Callable only from contexts that can sleep.
Return
the (unsigned) eight bit number returned by the device, or else a negative error code.
SPI synchronous 8 bit write followed by 16 bit read
Parameters
Context
can sleep
Description
The number is returned in wire-order, which is at least sometimes big-endian.
Callable only from contexts that can sleep.
Return
the (unsigned) sixteen bit number returned by the device, or else a negative error code.
SPI synchronous 8 bit write followed by 16 bit big-endian read
Parameters
Context
can sleep
Description
This function is similar to spi_w8r16, with the exception that it will convert the read 16 bit data word from big-endian to native endianness.
Callable only from contexts that can sleep.
Return
the (unsigned) sixteen bit number returned by the device in cpu endianness, or else a negative error code.
flash specific information for spi-masters that provide accelerated flash read interfaces
Definition
struct spi_flash_read_message {
void * buf;
loff_t from;
size_t len;
size_t retlen;
u8 read_opcode;
u8 addr_width;
u8 dummy_bytes;
u8 opcode_nbits;
u8 addr_nbits;
u8 data_nbits;
struct sg_table rx_sg;
bool cur_msg_mapped;
};
Members
board-specific template for a SPI device
Definition
struct spi_board_info {
char modalias[SPI_NAME_SIZE];
const void * platform_data;
void * controller_data;
int irq;
u32 max_speed_hz;
u16 bus_num;
u16 chip_select;
u16 mode;
};
Members
Description
When adding new SPI devices to the device tree, these structures serve as a partial device template. They hold information which can’t always be determined by drivers. Information that probe() can establish (such as the default transfer wordsize) is not included here.
These structures are used in two places. Their primary role is to be stored in tables of board-specific device descriptors, which are declared early in board initialization and then used (much later) to populate a controller’s device tree after the that controller’s driver initializes. A secondary (and atypical) role is as a parameter to spi_new_device() call, which happens after those controller drivers are active in some dynamic board configuration models.
register SPI devices for a given board
Parameters
Context
can sleep
Description
Board-specific early init code calls this (probably during arch_initcall) with segments of the SPI device table. Any device nodes are created later, after the relevant parent SPI controller (bus_num) is defined. We keep this table of devices forever, so that reloading a controller driver will not make Linux forget about these hard-wired devices.
Other code can also call this, e.g. a particular add-on board might provide SPI devices through its expansion connector, so code initializing that board would naturally declare its SPI devices.
The board info passed can safely be __initdata ... but be careful of any embedded pointers (platform_data, etc), they’re copied as-is.
Return
zero on success, else a negative error code.
register a SPI driver
Parameters
Context
can sleep
Return
zero on success, else a negative error code.
Allocate a new SPI device
Parameters
Context
can sleep
Description
Allows a driver to allocate and initialize a spi_device without registering it immediately. This allows a driver to directly fill the spi_device with device parameters before calling spi_add_device() on it.
Caller is responsible to call spi_add_device() on the returned spi_device structure to add it to the SPI master. If the caller needs to discard the spi_device without adding it, then it should call spi_dev_put() on it.
Return
a pointer to the new device, or NULL.
Add spi_device allocated with spi_alloc_device
Parameters
Description
Companion function to spi_alloc_device. Devices allocated with spi_alloc_device can be added onto the spi bus with this function.
Return
0 on success; negative errno on failure
instantiate one new SPI device
Parameters
Context
can sleep
Description
On typical mainboards, this is purely internal; and it’s not needed after board init creates the hard-wired devices. Some development platforms may not be able to use spi_register_board_info though, and this is exported so that for example a USB or parport based adapter driver could add devices (which it would learn about out-of-band).
Return
the new device, or NULL.
unregister a single SPI device
Parameters
Description
Start making the passed SPI device vanish. Normally this would be handled by spi_unregister_master().
report completion of a transfer
Parameters
Description
Called by SPI drivers using the core transfer_one_message() implementation to notify it that the current interrupt driven transfer has finished and the next one may be scheduled.
called by driver to check for queued messages
Parameters
Description
If there are more messages in the queue, the next message is returned from this call.
Return
the next message in the queue, else NULL if the queue is empty.
the current message is complete
Parameters
Description
Called by the driver to notify the core that the message in the front of the queue is complete and can be removed from the queue.
allocate SPI master controller
Parameters
Context
can sleep
Description
This call is used only by SPI master controller drivers, which are the only ones directly touching chip registers. It’s how they allocate an spi_master structure, prior to calling spi_register_master().
This must be called from context that can sleep.
The caller is responsible for assigning the bus number and initializing the master’s methods before calling spi_register_master(); and (after errors adding the device) calling spi_master_put() to prevent a memory leak.
Return
the SPI master structure on success, else NULL.
register SPI master controller
Parameters
Context
can sleep
Description
SPI master controllers connect to their drivers using some non-SPI bus, such as the platform bus. The final stage of probe() in that code includes calling spi_register_master() to hook up to this SPI bus glue.
SPI controllers use board specific (often SOC specific) bus numbers, and board-specific addressing for SPI devices combines those numbers with chip select numbers. Since SPI does not directly support dynamic device identification, boards need configuration tables telling which chip is at which address.
This must be called from context that can sleep. It returns zero on success, else a negative error code (dropping the master’s refcount). After a successful return, the caller is responsible for calling spi_unregister_master().
Return
zero on success, else a negative error code.
register managed SPI master controller
Parameters
Context
can sleep
Description
Register a SPI device as with spi_register_master() which will automatically be unregister
Return
zero on success, else a negative error code.
unregister SPI master controller
Parameters
Context
can sleep
Description
This call is used only by SPI master controller drivers, which are the only ones directly touching chip registers.
This must be called from context that can sleep.
look up master associated with bus_num
Parameters
Context
can sleep
Description
This call may be used with devices that are registered after arch init time. It returns a refcounted pointer to the relevant spi_master (which the caller must release), or NULL if there is no such master registered.
Return
the SPI master structure on success, else NULL.
allocate a spi resource that is life-cycle managed during the processing of a spi_message while using spi_transfer_one
Parameters
Return
the pointer to the allocated data
This may get enhanced in the future to allocate from a memory pool of the spi_device or spi_master to avoid repeated allocations.
free an spi resource
Parameters
add a spi_res to the spi_message
Parameters
release all spi resources for this message
Parameters
replace transfers with several transfers and register change with spi_message.resources
Parameters
Return
split spi transfers into multiple transfers when an individual transfer exceeds a certain size
Parameters
Return
status of transformation
setup SPI mode and clock rate
Parameters
Context
can sleep, and no requests are queued to the device
Description
SPI protocol drivers may need to update the transfer mode if the device doesn’t work with its default. They may likewise need to update clock rates or word sizes from initial values. This function changes those settings, and must be called from a context that can sleep. Except for SPI_CS_HIGH, which takes effect immediately, the changes take effect the next time the device is selected and data is transferred to or from it. When this function returns, the spi device is deselected.
Note that this call will fail if the protocol driver specifies an option that the underlying controller or its driver does not support. For example, not all hardware supports wire transfers using nine bit words, LSB-first wire encoding, or active-high chipselects.
Return
zero on success, else a negative error code.
asynchronous SPI transfer
Parameters
Context
any (irqs may be blocked, etc)
Description
This call may be used in_irq and other contexts which can’t sleep, as well as from task contexts which can sleep.
The completion callback is invoked in a context which can’t sleep. Before that invocation, the value of message->status is undefined. When the callback is issued, message->status holds either zero (to indicate complete success) or a negative error code. After that callback returns, the driver which issued the transfer request may deallocate the associated memory; it’s no longer in use by any SPI core or controller driver code.
Note that although all messages to a spi_device are handled in FIFO order, messages may go to different devices in other orders. Some device might be higher priority, or have various “hard” access time requirements, for example.
On detection of any fault during the transfer, processing of the entire message is aborted, and the device is deselected. Until returning from the associated message completion callback, no other spi_message queued to that device will be processed. (This rule applies equally to all the synchronous transfer calls, which are wrappers around this core asynchronous primitive.)
Return
zero on success, else a negative error code.
version of spi_async with exclusive bus usage
Parameters
Context
any (irqs may be blocked, etc)
Description
This call may be used in_irq and other contexts which can’t sleep, as well as from task contexts which can sleep.
The completion callback is invoked in a context which can’t sleep. Before that invocation, the value of message->status is undefined. When the callback is issued, message->status holds either zero (to indicate complete success) or a negative error code. After that callback returns, the driver which issued the transfer request may deallocate the associated memory; it’s no longer in use by any SPI core or controller driver code.
Note that although all messages to a spi_device are handled in FIFO order, messages may go to different devices in other orders. Some device might be higher priority, or have various “hard” access time requirements, for example.
On detection of any fault during the transfer, processing of the entire message is aborted, and the device is deselected. Until returning from the associated message completion callback, no other spi_message queued to that device will be processed. (This rule applies equally to all the synchronous transfer calls, which are wrappers around this core asynchronous primitive.)
Return
zero on success, else a negative error code.
blocking/synchronous SPI data transfers
Parameters
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleep is non-interruptible, and has no timeout. Low-overhead controller drivers may DMA directly into and out of the message buffers.
Note that the SPI device’s chip select is active during the message, and then is normally disabled between messages. Drivers for some frequently-used devices may want to minimize costs of selecting a chip, by leaving it selected in anticipation that the next message will go to the same chip. (That may increase power usage.)
Also, the caller is guaranteeing that the memory associated with the message will not be freed before this call returns.
Return
zero on success, else a negative error code.
version of spi_sync with exclusive bus usage
Parameters
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleep is non-interruptible, and has no timeout. Low-overhead controller drivers may DMA directly into and out of the message buffers.
This call should be used by drivers that require exclusive access to the SPI bus. It has to be preceded by a spi_bus_lock call. The SPI bus must be released by a spi_bus_unlock call when the exclusive access is over.
Return
zero on success, else a negative error code.
obtain a lock for exclusive SPI bus usage
Parameters
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleep is non-interruptible, and has no timeout.
This call should be used by drivers that require exclusive access to the SPI bus. The SPI bus must be released by a spi_bus_unlock call when the exclusive access is over. Data transfer must be done by spi_sync_locked and spi_async_locked calls when the SPI bus lock is held.
Return
always zero.
release the lock for exclusive SPI bus usage
Parameters
Context
can sleep
Description
This call may only be used from a context that may sleep. The sleep is non-interruptible, and has no timeout.
This call releases an SPI bus lock previously obtained by an spi_bus_lock call.
Return
always zero.
SPI synchronous write followed by read
Parameters
Context
can sleep
Description
This performs a half duplex MicroWire style transaction with the device, sending txbuf and then reading rxbuf. The return value is zero for success, else a negative errno status code. This call may only be used from a context that may sleep.
Parameters to this routine are always copied using a small buffer; portable code should never use this for more than 32 bytes. Performance-sensitive or bulk transfer code should instead use spi_{async,sync}() calls with dma-safe buffers.
Return
zero on success, else a negative error code.