Part 9: I2C, SPI, and GPIO Drivers

I2C and SPI are the most common buses for connecting sensors, displays, and peripherals in embedded systems. This part covers writing drivers for devices on these buses.

Bus Overview

flowchart TB
    subgraph I2C["I2C Bus"]
        direction LR
        I2C_CTRL[I2C Controller]
        I2C_D1[Device 0x48]
        I2C_D2[Device 0x50]
        I2C_CTRL --- I2C_D1
        I2C_CTRL --- I2C_D2
    end

    subgraph SPI["SPI Bus"]
        direction LR
        SPI_CTRL[SPI Controller]
        SPI_D1[Device CS0]
        SPI_D2[Device CS1]
        SPI_CTRL --- SPI_D1
        SPI_CTRL --- SPI_D2
    end

    subgraph GPIO["GPIO"]
        direction LR
        GPIO_CTRL[GPIO Controller]
        GPIO_P1[Pin 0]
        GPIO_P2[Pin 1]
        GPIO_CTRL --- GPIO_P1
        GPIO_CTRL --- GPIO_P2
    end

    CPU[CPU/SoC]
    CPU --> I2C
    CPU --> SPI
    CPU --> GPIO

    style I2C fill:#738f99,stroke:#0277bd
    style SPI fill:#8f8a73,stroke:#f9a825
    style GPIO fill:#7a8f73,stroke:#2e7d32

Chapter Contents

Chapter Topic Key Concepts
9.1 I2C Subsystem Bus architecture, adapters, clients
9.2 I2C Client Driver i2c_driver, probe/remove
9.3 I2C with Regmap regmap abstraction for I2C
9.4 SPI Subsystem Bus architecture, transfers
9.5 SPI Driver spi_driver, SPI messaging
9.6 GPIO Consumer API gpiod_get, set/get values
9.7 GPIO Provider gpio_chip implementation
9.8 Pin Control Pin muxing, pin configuration

I2C vs SPI Comparison

Feature I2C SPI
Wires 2 (SDA, SCL) 4+ (MOSI, MISO, CLK, CS)
Addressing 7-bit address Chip select lines
Speed Up to 3.4 MHz Up to 100+ MHz
Topology Multi-master, multi-slave Single master, multi-slave
Complexity Higher protocol Simple
Use case Sensors, EEPROMs Flash, displays, high-speed

I2C Architecture

flowchart TB
    subgraph UserSpace["User Space"]
        APP[Application]
    end

    subgraph Kernel["Kernel"]
        I2CCORE[I2C Core]
        I2CDEV[i2c-dev]
        I2CADAPTER[I2C Adapter Driver]
        I2CCLIENT[I2C Client Driver]
    end

    subgraph Hardware
        CTRL[I2C Controller]
        DEV[I2C Device]
    end

    APP -->|"/dev/i2c-N"| I2CDEV
    I2CDEV --> I2CCORE
    I2CCLIENT --> I2CCORE
    I2CCORE --> I2CADAPTER
    I2CADAPTER --> CTRL
    CTRL -->|"I2C Bus"| DEV

SPI Architecture

flowchart TB
    subgraph UserSpace["User Space"]
        APP[Application]
    end

    subgraph Kernel["Kernel"]
        SPICORE[SPI Core]
        SPIDEV[spidev]
        SPICTRL[SPI Controller Driver]
        SPICLIENT[SPI Device Driver]
    end

    subgraph Hardware
        CTRL[SPI Controller]
        DEV[SPI Device]
    end

    APP -->|"/dev/spidevN.M"| SPIDEV
    SPIDEV --> SPICORE
    SPICLIENT --> SPICORE
    SPICORE --> SPICTRL
    SPICTRL --> CTRL
    CTRL -->|"SPI Bus"| DEV

Key Data Structures

I2C

/* I2C client (device) */
struct i2c_client {
    unsigned short addr;        /* 7-bit I2C address */
    char name[I2C_NAME_SIZE];   /* Device name */
    struct i2c_adapter *adapter; /* Parent adapter */
    struct device dev;          /* Device structure */
};

/* I2C driver */
struct i2c_driver {
    int (*probe)(struct i2c_client *client);
    void (*remove)(struct i2c_client *client);
    struct device_driver driver;
    const struct i2c_device_id *id_table;
};

SPI

/* SPI device */
struct spi_device {
    struct device dev;
    struct spi_controller *controller;
    u32 max_speed_hz;
    u8 chip_select;
    u8 bits_per_word;
    u32 mode;  /* SPI_MODE_0..3, SPI_CS_HIGH, etc. */
};

/* SPI driver */
struct spi_driver {
    int (*probe)(struct spi_device *spi);
    void (*remove)(struct spi_device *spi);
    struct device_driver driver;
    const struct spi_device_id *id_table;
};

Examples

This part includes working examples:

  • i2c-sensor: I2C temperature sensor driver
  • spi-device: SPI device driver with regmap
  • gpio-driver: GPIO controller (gpio_chip)

Prerequisites

Before starting this part, ensure you understand:

  • Platform drivers (Part 6)
  • Managed resources (devm_*) - used extensively in these drivers
  • Device Tree (Part 8)
  • Interrupt handling (Part 7)

Further Reading

Next

Start with I2C Subsystem to understand I2C bus architecture.


Table of contents


Back to top

Linux Driver Development Guide is a community resource for learning kernel driver development. Not affiliated with the Linux Foundation. Content provided for educational purposes.

This site uses Just the Docs, a documentation theme for Jekyll.