Skip to content

Day 77 - GPIO Consumer Driver and gpiod APIs

Goal

Understand how a Linux platform driver acquires GPIO resources from Device Tree and controls GPIO lines through the gpiod consumer API.

Build a complete GPIO consumer path from Device Tree property lookup to GPIO controller access.


Topics

GPIO Consumer Driver Architecture

Linux GPIO drivers are divided into two roles:

GPIO Controller Driver
        ↓
    gpio_chip
        ↓
      gpiolib
        ↓
    gpio_desc
        ↓
GPIO Consumer Driver

The GPIO controller driver registers GPIO lines to gpiolib.

Consumer drivers request GPIO resources through Device Tree and operate GPIOs through the GPIO descriptor API.


Device Tree GPIO Consumer Binding

A consumer driver requests GPIO resources using Device Tree properties.

Example:

reset-gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;

Property naming convention:

Consumer ID Device Tree Property
reset reset-gpios
enable enable-gpios
shutdown shutdown-gpios
phy-reset phy-reset-gpios

Consumer drivers use:

devm_gpiod_get(dev, "reset");
devm_gpiod_get(dev, "enable");

to acquire GPIO descriptors.


GPIO Consumer APIs

Common GPIO consumer APIs:

devm_gpiod_get()
devm_gpiod_get_optional()

gpiod_direction_input()
gpiod_direction_output()

gpiod_get_value()
gpiod_set_value()

The consumer driver does not directly access GPIO controller hardware.

Instead:

Consumer Driver
        ↓
gpio_desc
        ↓
gpio_chip
        ↓
GPIO Controller

Optional GPIO Resources

Some GPIO resources may be optional.

Example:

enable_gpio =
    devm_gpiod_get_optional(dev, "enable");

If the corresponding Device Tree property does not exist:

enable-gpios

the API returns:

NULL

instead of reporting a fatal error.


GPIO Consumer Driver Probe Flow

Typical Linux probe flow:

probe()
    ↓
allocate private data
    ↓
request GPIO resources
    ↓
configure GPIO direction
    ↓
set initial GPIO state
    ↓
device ready

Example:

reset_gpio =
    devm_gpiod_get(dev, "reset");

enable_gpio =
    devm_gpiod_get_optional(dev, "enable");

gpiod_direction_output(reset_gpio, 1);
gpiod_direction_output(enable_gpio, 1);

gpiod_set_value(reset_gpio, 0);