Skip to content

Linux gpiolib and GPIO Descriptor

Overview

Modern Linux GPIO drivers use the GPIO descriptor model rather than the legacy GPIO number model.

The GPIO subsystem is implemented by gpiolib.

gpiolib provides a hardware-independent abstraction layer between GPIO consumers and GPIO controller drivers.


Architecture

Consumer Driver
     gpiolib
    gpio_desc
    gpio_chip
GPIO Controller Driver
MMIO Registers

GPIO Controller Layer

GPIO controller drivers expose GPIO operations through a gpio_chip structure.

Typical callbacks:

struct gpio_chip {
    int (*direction_input)(...);

    int (*direction_output)(...);

    int (*get)(...);

    void (*set)(...);
};

Responsibilities:

  • Configure GPIO direction
  • Read GPIO state
  • Write GPIO state
  • Access GPIO controller registers

GPIO Descriptor Layer

A GPIO descriptor represents a single GPIO line.

Conceptually:

gpio_desc
one GPIO line

A descriptor contains metadata describing how a GPIO line should be accessed.

Typical information:

GPIO controller
GPIO offset
Consumer ownership
Active-low flag
Direction state

Why GPIO Descriptors Exist

Legacy GPIO APIs use GPIO numbers.

Example:

gpio_set_value(23, 1);

Problems:

Which GPIO controller owns GPIO23?

Is GPIO23 active-low?

Is GPIO23 already in use?

Who owns GPIO23?

The GPIO descriptor model solves these issues.

Example:

gpiod_set_value(desc, 1);

The descriptor already contains all required GPIO metadata.


GPIO Consumer Model

A GPIO consumer is a driver that uses a GPIO line.

Examples:

LED Driver
Reset Driver
Power Enable Driver
WiFi Driver
Ethernet Driver
Button Driver

Consumer drivers should not access GPIO controller hardware directly.

Instead:

Consumer
gpio_desc
gpiolib

Active-Low Translation

Device Tree can define GPIO polarity.

Example:

reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>;

Meaning:

logical high
physical low

logical low
physical high

Consumer drivers always operate on logical values.

Example:

gpiod_set_value(desc, 1);

gpiolib performs polarity translation before invoking gpio_chip callbacks.

Flow:

logical value
active-low translation
physical value
gpio_chip->set()

GPIO Ownership

A GPIO line may be owned by a consumer.

Example:

GPIO5
LED Driver

While owned:

Other consumers
Request rejected

Ownership prevents multiple drivers from controlling the same GPIO line simultaneously.


Device Tree GPIO Binding

GPIO resources are typically described in Device Tree.

Example:

led-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;

reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>;

Components:

&gpio
    GPIO controller

5 / 7
    GPIO line offset

GPIO_ACTIVE_HIGH
GPIO_ACTIVE_LOW
    GPIO flags

GPIO Lookup Flow

The GPIO lookup process converts a Device Tree property into a GPIO descriptor.

Conceptually:

reset-gpios
Device Tree lookup
gpio_dt_spec
devm_gpiod_get()
gpio_desc

GPIO Descriptor Access Flow

Typical GPIO write flow:

gpiod_set_value()
gpio_desc
active-low translation
gpio_chip->set()
GPIO Controller Register

Typical GPIO read flow:

gpiod_get_value()
gpio_chip->get()
physical value
active-low translation
logical value

Relationship Between gpio_desc and gpio_chip

gpio_desc
One GPIO Line

gpio_chip
One GPIO Controller

Example:

gpio_chip
 ├── GPIO0
 ├── GPIO1
 ├── GPIO2
 ├── GPIO3
 └── GPIO4

Each GPIO line is represented by its own descriptor.


Legacy GPIO Number Model

Legacy API:

gpio_direction_output();
gpio_set_value();
gpio_get_value();

Modern API:

gpiod_direction_output();
gpiod_set_value();
gpiod_get_value();

The descriptor API is preferred for new Linux drivers.


Summary

gpiolib provides the abstraction layer between GPIO consumers and GPIO controller drivers.

gpio_chip represents a GPIO controller.

gpio_desc represents a GPIO line.

GPIO consumers operate through GPIO descriptors rather than GPIO numbers.

Consumer
gpio_desc
gpiolib
gpio_chip
GPIO Controller