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.