Skip to content

Day77 - GPIO Consumer Driver and gpiod APIs

Objective

Learn how Linux GPIO consumer drivers acquire GPIO resources from Device Tree and access GPIO lines through the gpiod API.

Topics covered:

  • GPIO consumer driver architecture
  • Device Tree GPIO lookup
  • devm_gpiod_get()
  • devm_gpiod_get_optional()
  • gpiod_direction_input()
  • gpiod_direction_output()
  • gpiod_get_value()
  • gpiod_set_value()
  • GPIO consumer driver probe/remove flow

Lab1 - Raspberry Pi GPIO Consumer Investigation

Goal

Investigate how real Linux drivers consume GPIO resources from Device Tree.


Discover GPIO Properties

Search Device Tree GPIO properties:

find /sys/firmware/devicetree/base -name "*gpios"

Example:

bluetooth/shutdown-gpios
ethernet/phy-reset-gpios
led-act/gpios

Inspect GPIO Specifiers

Example:

hexdump -C shutdown-gpios

Result:

00 00 00 1b
00 00 00 1d
00 00 00 00

Meaning:

<phandle offset flags>

Verify GPIO Flags

Examples:

Property Flags
shutdown-gpios 0
phy-reset-gpios 1
led-act gpios 1

Verified:

flags = 0
    → GPIO_ACTIVE_HIGH

flags = 1
    → GPIO_ACTIVE_LOW

Inspect GPIO Consumer Ownership

Check:

cat /sys/kernel/debug/gpio

Examples:

gpio-562 (BT_ON      |shutdown )
gpio-601 (ETH_RST_N  |phy-reset)
gpio-521 (2712_STAT_LED |ACT)

Verified:

Device Tree Property
        ↓
GPIO Consumer
        ↓
gpio_desc
        ↓
debugfs ownership

Lab2 - GPIO Consumer API Simulation

Goal

Simulate Linux GPIO consumer APIs.


Added Device Tree Lookup Layer

Implemented:

demo_gpio_dt_register_chip()
demo_gpio_dt_unregister_chip()

demo_gpio_dt_find_chip()

demo_of_get_gpio()

Lookup flow:

reset-gpios
        ↓
gpio_property
        ↓
controller_name
        ↓
gpio_chip
        ↓
gpio_dt_spec

Added Consumer API Layer

Implemented:

devm_gpiod_get()
devm_gpiod_get_optional()

gpiod_direction_input()
gpiod_direction_output()

gpiod_get_value()
gpiod_set_value()

Architecture:

Consumer Driver
        ↓
gpiod API
        ↓
gpio_desc
        ↓
gpio_chip
        ↓
GPIO Controller

Test Result

Initial:

DIR = 0x00000000
IN  = 0x00000000
OUT = 0x00000000

Reset GPIO:

[RESET GPIO active-low logical 1]

DIR = 0x00000080
OUT = 0x00000000
[RESET GPIO active-low logical 0]

DIR = 0x00000080
OUT = 0x00000080

Enable GPIO:

[ENABLE GPIO active-high logical 1]

DIR = 0x000000a0
OUT = 0x000000a0
[ENABLE GPIO active-high logical 0]

DIR = 0x000000a0
OUT = 0x00000080

Verified:

logical value
        ↓
active-low translation
        ↓
physical value

Optional GPIO Test

dummy =
    devm_gpiod_get_optional(
        &dev,
        "dummy");

Output:

dummy = (nil)

Verified:

missing property
        ↓
optional GPIO
        ↓
NULL

Lab3 - GPIO Consumer Driver Simulation

Goal

Simulate a Linux GPIO consumer driver.


Driver Private Data

struct demo_device {
    struct gpio_desc *reset_gpio;
    struct gpio_desc *enable_gpio;
};

Probe Flow

Implemented:

demo_probe()

Flow:

allocate private data
        ↓
request GPIOs
        ↓
configure directions
        ↓
set initial state
        ↓
device ready

Remove Flow

Implemented:

demo_remove()

Flow:

disable device
        ↓
assert reset
        ↓
release GPIOs
        ↓
free private data

Test Result

Initial:

DIR = 0x00000000
IN  = 0x00000000
OUT = 0x00000000

Probe:

[INFO] probe done

DIR = 0x000000a0
IN  = 0x00000000
OUT = 0x000000a0

Meaning:

reset released
enable asserted
device ready

Remove:

[INFO] remove start
[INFO] remove exit

DIR = 0x000000a0
IN  = 0x00000000
OUT = 0x00000000

Meaning:

device disabled
reset asserted
GPIO resources released

Key Takeaways

Linux GPIO consumer drivers operate on GPIO descriptors rather than GPIO controller hardware.

The complete access path is:

Device Tree
        ↓
devm_gpiod_get()
        ↓
gpio_desc
        ↓
gpiod_set_value()
        ↓
gpio_chip
        ↓
GPIO Controller

This is the standard GPIO usage model used by Linux platform drivers.