Skip to content

Day75 - GPIO Controller Architecture

Objective

Understand how Linux GPIO controllers are implemented on top of MMIO register blocks and how GPIO abstractions are built through gpio_chip.


Lab 1 - Raspberry Pi GPIO Controller Inspection

Goal

Inspect real GPIO controllers on Raspberry Pi 5.

Device Tree Investigation

Identify GPIO controller nodes:

find /proc/device-tree/soc@107c000000 -name gpio-controller -print

Result:

/proc/device-tree/soc@107c000000/gpio@7d508500/gpio-controller
/proc/device-tree/soc@107c000000/gpio@7d517c00/gpio-controller

GPIO Controller Information

hexdump -Cv reg

Controller 1:

compatible = brcm,brcmstb-gpio
reg        = <0x7d508500 0x40>

Controller 2:

compatible = brcm,brcmstb-gpio
reg        = <0x7d517c00 0x40>

GPIO Debug Information

cat /sys/kernel/debug/gpio

Observed:

  • BCM2712 internal GPIO controllers
  • RP1 GPIO controller
  • GPIO consumer ownership
  • GPIO line naming

Key Observations

Device Tree
platform device
platform driver
gpiochip
GPIO lines

Lab 2 - GPIO Controller Register Simulation

Goal

Simulate a GPIO controller register block.

Register Layout

Offset
--------------------------------
0x00 DIR
0x04 IN
0x08 OUT
0x0C SET
0x10 CLR
--------------------------------

Controller Model

struct gpio_controller {
    uint32_t dir;
    uint32_t in;
    uint32_t out;
};

Implemented APIs

gpio_direction_input()
gpio_direction_output()

gpio_get_value()
gpio_set_value()

gpio_simulate_input()

Test Sequence

GPIO5
    output high

GPIO5
    output low

GPIO7
    input high

Result

DIR = 0x00000020
IN  = 0x00000080
OUT = 0x00000000

Register Interpretation

GPIO5
    direction = output

GPIO7
    direction = input

GPIO7
    input level = high

Lab 3 - gpio_chip Abstraction Simulation

Goal

Build a simplified Linux gpio_chip abstraction.

Architecture

main
gpio_chip
gpio_controller
register model

gpio_chip Structure

struct gpio_chip {
    void *priv;

    gpio_direction_input_t direction_input;
    gpio_direction_output_t direction_output;

    gpio_get_t get;
    gpio_set_t set;
};

Callback Wrappers

chip_direction_input()
chip_direction_output()

chip_get()
chip_set()

Initialization

gpio_chip_init()

Test Flow

main
gpio_chip_set()
chip->set()
gpio_set_value()
register update

Result

[GPIO5 output high via gpio_chip]
DIR = 0x00000020
OUT = 0x00000020

[GPIO5 output low via gpio_chip]
DIR = 0x00000020
OUT = 0x00000000

[GPIO7 input high via gpio_chip]
GPIO7 value = 1
IN = 0x00000080

Conclusion

A GPIO controller is fundamentally a MMIO register block.

Linux introduces gpio_chip as a callback-based abstraction layer to separate generic GPIO operations from hardware-specific register implementations.

The overall model becomes:

gpiolib
gpio_chip
GPIO controller driver
MMIO registers