SPI Device Driver Basics – free linux device driver tutorial

SPI Device Driver Basics – free linux device driver tutorial
SPI Device Driver Basics – free linux device driver tutorial — Chapter 8, Part 1

If you have already gone through our free I2C client driver lectures, you already know how a two-wire bus like I2C works. This lecture starts a brand-new chapter on the SPI device driver linux kernel subsystem — the bus you will meet on nearly every flash chip, ADC, DAC, display controller, and sensor that needs high-speed, low-latency data transfer. By the end of this article you will understand SPI wiring, signal names, chip select behaviour, and how the bus physically moves data, so the driver code in Part 2 makes complete sense.

spi device driver linux kernel
free linux kernel development course
free embedded linux course
free linux device drivers course
MOSI MISO SCK CS

What You Will Learn

  • What SPI is and why it is used instead of I2C or UART in many embedded designs
  • The four signal lines of an SPI bus and their common naming variations
  • How a single SPI master talks to multiple slave chips using chip select
  • The difference between half-duplex and full-duplex data transfer on SPI
  • Where the spi device driver linux kernel subsystem fits in the overall kernel driver model
  • Real hardware examples that use SPI in production embedded systems

Prerequisites

Before starting this lecture, you should be comfortable with:

  • Basic Linux kernel module concepts (module_init, module_exit)
  • Character device driver basics (file_operations, probe/remove pattern)
  • Our earlier free linux device drivers course lectures on I2C client drivers, since SPI reuses the same bus/driver/device matching philosophy
  • A Linux host or single-board computer (Raspberry Pi, BeagleBone, or similar) with an accessible SPI header, running kernel 6.x

What Is SPI?

Serial Peripheral Interface, or SPI, is a synchronous serial communication protocol used to connect a microcontroller or SoC (the master) to one or more peripheral chips (the slaves) such as serial flash memory, analog-to-digital converters, digital-to-analog converters, TFT displays, and various sensors. Unlike I2C, which uses only two shared wires, SPI dedicates separate wires for sending and receiving data, which lets it reach clock speeds well beyond what I2C can offer — commonly tens of megahertz, and in some designs even higher, with the exact ceiling set by the specific controller and board layout rather than the protocol itself.

Because the clock is generated entirely by the master, SPI slaves never need their own clock source, which keeps peripheral chips simple and cheap. This is one of the main reasons SPI shows up so often in cost-sensitive embedded designs.

The Four SPI Signal Lines

A standard SPI bus uses four signal lines. Depending on the chip vendor and datasheet, these lines are known by several different names, which can confuse beginners the first time they read a schematic. The table below maps every common alias back to its standard SPI function.

Standard Name Common Aliases Direction Purpose
MOSI SIMO, SDI, DI, SDA Master → Slave Carries data written by the master to the slave
MISO SOMI, SDO, DO, SDA Slave → Master Carries data returned by the slave to the master
SCK CLK, SCL Master → Slave Clock signal that times every bit transferred
CS SS, CSx, EN, ENB Master → Slave Chip select — tells one specific slave to listen

The chip select (CS) line deserves special attention. It is almost always active low, meaning the slave only pays attention to the bus while CS is pulled down to logic 0. The master is fully responsible for driving CS, and it must never talk to more than one slave at a time on a shared bus.

SPI Bus Topology: One Master, Many Slaves

A single SPI controller can address several independent slave chips by giving each one its own dedicated chip select line, while the clock, MOSI, and MISO lines are shared across every device on the bus. The diagram below shows this fan-out relationship using plain HTML boxes.

SPI Master To Multiple Slave Devices
SPI Master
SCK / MOSI / MISO
CS0, CS1, CS2
Slave 0 (Flash chip)
selected by CS0
Slave 1 (ADC)
selected by CS1
Slave 2 (Display)
selected by CS2

Every slave shares the same SCK, MOSI, and MISO wires, but each has its own private chip select line running back to the master. The master activates exactly one CS line at a time, so only that slave drives the MISO line and listens on MOSI. This is what allows one controller to manage multiple SPI peripherals safely on shared wiring, which is directly reflected later in how a spi device driver linux kernel module is registered against a specific chip select index.

Half-Duplex vs Full-Duplex Transfer

SPI is a full-duplex protocol by design: the master can clock data out on MOSI at exactly the same time it clocks data in on MISO, in a single continuous transfer. Many real device drivers only use this in a half-duplex style anyway, for example writing a register address on MOSI first and then reading the register value back on MISO in a second phase, because that is how most peripheral chips are designed to respond. Both patterns are supported by the same underlying kernel transfer API, which we cover in detail in Part 2 of this chapter.

Transfer Style What Happens Typical Use Case
Full-duplex Data flows on MOSI and MISO simultaneously, bit for bit, on every clock edge Audio codecs, high-speed ADC streaming
Half-duplex The master writes a command or address first, then a separate phase reads the response Serial flash memory, register-based sensors

Real-World Use Cases For SPI

  • Serial NOR/NAND flash chips — firmware and bootloader storage on almost every embedded board
  • ADC and DAC chips — high-speed analog sampling and generation
  • TFT and e-paper displays — frame buffer data pushed to the panel controller
  • SD cards in SPI mode — a fallback transfer mode supported by most SD controllers
  • Sensor chips — accelerometers, gyroscopes, and pressure sensors that need faster sampling than I2C allows

Common Mistakes When Working With SPI Hardware

Mistake Why It Breaks Things Fix
Wiring MOSI/MISO reversed between master and slave No data movement, or garbage received Always cross MOSI-out to MOSI-in on the slave; never join both MOSI pins directly
Sharing one CS line across multiple slaves Bus contention — several chips answer on MISO at once Give every slave its own dedicated CS line
Wrong SPI mode (CPOL/CPHA) for the target chip Bits sampled at the wrong clock edge, silent corrupted reads Check the datasheet’s timing diagram and match SPI_MODE_0 through SPI_MODE_3 exactly (covered in Part 2)
Clock speed set above the chip’s rated maximum Intermittent read/write failures under load Start conservative and raise max_speed_hz gradually while testing

Best Practices For SPI Hardware Design

  • Keep SPI traces short, especially at higher clock speeds, to avoid signal reflection issues
  • Always add a pull-up or pull-down on CS lines during boot so no slave is accidentally selected before the driver initializes
  • Document which chip select index maps to which physical device in your board’s device tree comments
  • Use logic analyzers when bringing up new SPI hardware — SPI’s clocked nature makes it very easy to decode compared to asynchronous buses

Summary And Key Takeaways

  • SPI uses four dedicated lines — MOSI, MISO, SCK, and CS — with the master always generating the clock
  • Multiple slaves share the same data and clock lines but each need their own private chip select
  • SPI natively supports full-duplex transfer, though many drivers use it in a half-duplex request/response pattern
  • Getting SPI mode (CPOL/CPHA) wrong is the single most common bring-up bug — Part 2 explains this in full detail
  • This foundation prepares you for Part 2, where we cover the spi device driver linux kernel data structures, modern driver registration, and a working example driver

Frequently Asked Questions

What is the maximum speed an SPI bus can run at?

There is no protocol-level speed ceiling — SPI’s maximum clock rate depends entirely on the specific controller, the slave chip’s rated maximum, and board trace quality. Many embedded controllers comfortably support tens of megahertz, and some specialized controllers go much higher.

Is SPI faster than I2C?

Yes, in almost every practical case. SPI’s dedicated MOSI/MISO lines and higher achievable clock rates generally give it far more throughput than I2C, which shares a single data line and typically runs at lower speeds.

Can SPI support more than one master on the same bus?

Standard SPI is single-master by design. Some newer or vendor-specific extensions add multi-master arbitration, but the Linux spi device driver linux kernel subsystem assumes one master (the SPI controller) per bus.

Why is chip select usually active low?

Active-low chip select lets a pull-up resistor keep every slave deselected by default during power-up or reset, which prevents accidental bus contention before the master driver has finished initializing.

Do all SPI slaves need both MOSI and MISO connected?

No. Some devices are write-only (they never send data back, so MISO can be left unconnected) and some are read-only in a similar way. The driver only needs to set up the transfer buffers the hardware actually uses.

What is the difference between SPI and SPI NOR flash?

SPI is the bus protocol itself. SPI NOR flash is a specific category of storage chip that happens to use the SPI bus as its communication interface — one is the transport, the other is a device that rides on top of it.

Where do I learn the actual SPI driver code?

Part 2 of this chapter walks through the spi_device and spi_driver kernel structures, modern probe/remove registration, SPI modes, and a complete original example driver, as part of our free linux kernel development course.

Continue To SPI Driver Architecture

Ready to see the kernel-side data structures and write your first SPI driver? Move on to Part 2 of this free embedded systems course.

Leave a Reply

Your email address will not be published. Required fields are marked *