- Published on
How to Write a Raspberry Pi GPIO Driver: Ultimate Guide for Pi 3/4/5 (2025)
- Authors
- Name
- Amarnath B R
- @digitallyamar
How to Write a Raspberry Pi GPIO Driver
Introduction
As a Linux kernel developer consultant with over 20 years of experience in Android Board Support Package (BSP) development for several OEM smartphone companies like Samsung, Motorola, LG, and Sony Ericsson, I've tackled complex driver challenges, including authoring the CAIF network driver for ST-Ericsson's ARM platforms pushed to upstream Linux Kernel source. General Purpose Input/Output (GPIO) drivers are critical for controlling hardware like LEDs, sensors, and buttons on Raspberry Pi, a staple in embedded systems and IoT projects. Whether you're building a smart home device or debugging a kernel module, mastering GPIO drivers is essential.
This guide provides a comprehensive, step-by-step tutorial on writing a Raspberry Pi GPIO driver for Pi 3, 4, and 5, with a focus on the Pi 5's RP1 chip. Unlike outdated tutorials stuck on older Pi models or fragmented forum posts, this article covers modern Raspberry Pi OS (2025), kernel 6.6, and advanced debugging techniques. You'll get working code, a device tree overlay, and a free GPIO debug script. Let's dive in!
Explore my OV5647 camera driver guide for more embedded insights or try my ICCID Validator for IoT projects.
What is a Raspberry Pi GPIO Driver?
GPIO drivers allow software to interact with Raspberry Pi's general-purpose pins, enabling control of external devices like LEDs or sensors. As someone who's written network drivers like CAIF for ARM platforms, I can attest that GPIO drivers share similar principles: precise register manipulation and kernel integration. Here's a quick overview:
-
GPIO Purpose: GPIO pins handle input (e.g., button presses) or output (e.g., LED toggling). Drivers run in kernel space for performance, unlike user-space tools like sysfs.
-
Raspberry Pi Models:
- Pi 3/4: Use BCM2711 SoC with direct GPIO access via registers.
- Pi 5: Introduces the RP1 chip, a southbridge managing GPIO over a PCI bus, requiring updated driver techniques.
-
APIs: Modern kernels use the gpiod library (gpiod_set_value, gpio_request_one) for robust GPIO control, replacing older gpio APIs.
Model | GPIO Pins | Access Methods | Kernel API |
---|---|---|---|
Pi 3 | 26 | BCM2711 (direct) | gpiod/sysfs |
Pi 4 | 26 | BCM2711 (direct) | gpiod/sysfs |
Pi 5 | 26 | RP1 (PCI bus) | gpiod/pinctrl |
This guide builds a driver for all models, with Pi 5-specific tweaks to address the RP1 chip, a gap in many tutorials.
Need a Raspberry Pi 5 to start? Grab one here.
Setting Up Your Raspberry Pi GPIO Driver Environment
To write a GPIO driver, you need a proper development environment. Many guides, like those from 2018, reference outdated tools or Pi 3 setups. This section uses Raspberry Pi OS (Bookworm, 2025) and kernel 6.6, compatible with Pi 3, 4, and 5.
Prerequisites
- Hardware: Raspberry Pi 3/4/5, LED, 220Ω resistor, breadboard, jumper wires.
- Software: Raspberry Pi OS (Bookworm, 2025), GCC 12.x, kernel headers.
- Setup Steps:
- Install Dependencies
sudo apt update sudo apt install build-essential raspberrypi-kernel-headers git
- Clone Kernel Source:
git clone --depth=1 -b rpi-6.6.y https://github.com/raspberrypi/linux
- Set Cross-Compiler (Pi 5, ARM64):
export CROSS_COMPILE=aarch64-linux-gnu- export ARCH=arm64
- Configure Kernel
make bcm2711_defconfig
- Install Dependencies
- Pi 5 Note: The RP1 chip requires PCI bus awareness for GPIO access, unlike BCM2711’s direct mapping. We'll cover this in the device tree section.
Get a breadboard kit for testing here.
Writing a Raspberry Pi GPIO Driver: Step-by-Step Code
Let us write a kernel module to control an LED on GPIO 21, compatible with Pi 3/4/5. This driver uses the modern gpiod API, improving on older gpio methods in older tutorials found on the internet.
Driver Code
Below is a complete C driver to toggle an LED on GPIO 21, with error handling for robustness.
#include <linux/module.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
static struct gpio_desc *led_gpio;
static int __init gpio_driver_init(void) {
int ret;
led_gpio = gpiod_get(NULL, "gpio21", GPIOD_OUT_LOW);
if (IS_ERR(led_gpio)) {
printk(KERN_ERR "GPIO request failed: %ld\n", PTR_ERR(led_gpio));
return PTR_ERR(led_gpio);
}
gpiod_set_value(led_gpio, 1); // Turn LED on
printk(KERN_INFO "GPIO Driver Loaded for Raspberry Pi\n");
return 0;
}
static void __exit gpio_driver_exit(void) {
gpiod_set_value(led_gpio, 0); // Turn LED off
gpiod_put(led_gpio);
printk(KERN_INFO "GPIO Driver Unloaded\n");
}
module_init(gpio_driver_init);
module_exit(gpio_driver_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Amarnath B R <digitallyamar@gmail.com>");
MODULE_DESCRIPTION("Raspberry Pi GPIO Driver for LED Control");
Explanation
- API Choice: Uses gpiod_get for modern GPIO handling, avoiding deprecated gpio_request (seen in older tutorials).
- Error Handling: Checks for EBUSY or EINVAL errors, critical for Pi 5’s RP1 chip.
Device Tree Overlay (Pi 5)
For Pi 5, configure the RP1 chip's GPIO via a device tree overlay:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2712";
fragment@0 {
target = <&gpio>;
__overlay__ {
led_gpio: led_gpio {
brcm,pins = <21>;
brcm,function = <1>; // Output
brcm,pull = <2>; // Pull-up
};
};
};
};
- Save: As led-gpio.dts.
- Compile: dtc -@ -I dts -O dtb -o led-gpio.dtbo led-gpio.dts.
- Apply: Copy to /boot/overlays/ and add dtoverlay=led-gpio to /boot/config.txt.
Compilation and Loading
1. Compile:
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
2. Load:
sudo insmod gpio_driver.ko
3. Verify: Check dmesg for "GPIO Driver Loaded."
Debugging Your Raspberry Pi GPIO Driver
Debugging is critical, as errors like EBUSY or kernel panics are common. Unlike fragmented forum posts or other blog's basic dmesg tips, this section offers advanced techniques.
Common Issues and Fixes
Error | Cause | Fix |
---|---|---|
EBUSY | GPIO in use | Check /sys/kernel/debug/gpio, free via echo 21 > /sys/class/gpio/unexport |
EINVAL | Invalid pin | Verify RP1 pin mapping for Pi 5 (GPIO 0-27) |
Kernel Panic | Bad register access | Use device tree overlay, disable /dev/mem direct access |
Debugging Steps
- Check GPIO Status:
Output example: gpiochip4: GPIOs 0-27, parent: platform/soc, gpio: GPIO 21 (led_gpio | output | active).
cat /sys/kernel/debug/gpio
- Monitor Logs:
sudo dmesg | grep GPIO
- Test via Sysfs (Fallback):
echo 21 > /sys/class/gpio/export echo out > /sys/class/gpio/gpio21/direction echo 1 > /sys/class/gpio/gpio21/value
- Advanced: Use gdb for kernel debugging or pinctrl for Pi 5:
pinctrl set 21 op pu
My CAIF driver work on ST-Ericsson ARM platforms taught me to prioritize dmesg parsing for driver issues, a technique that applies here.
Need expert BSP debugging? Contact me for consulting (digitallyamar@gmail.com) ($50-100/hour)
GPIO Drivers on Raspberry Pi 5: Handling the RP1 Chip
The Raspberry Pi 5's RP1 chip, a southbridge managing GPIO via PCI, introduces unique challenges absent in Pi 3/4 (BCM2711 direct access). Many tutorials ignore this.
- RP1 Overview: Handles GPIO, I2C, and UART via PCI bus, requiring updated device tree and pinctrl configurations.
- Challenges:
- Pin mapping differs (e.g., GPIO 21 on RP1 vs. BCM2711).
- PCI driver integration needed for kernel modules.
- Solutions:
- Use device tree overlay (above) to map GPIO 21.
- Verify pin functions: pinctrl get 21 (output, pull-up).
- Update kernel config: Enable CONFIG_PINCTRL_RP1=y.
This ensures compatibility, unlike outdated guides stuck on older models.
Get a Raspberry Pi 5 here to experiment with RP1.
Frequently Asked Questions About Raspberry Pi GPIO Drivers
Q1: Why does gpio_request fail on Raspberry Pi 5? A: Common causes include EBUSY (GPIO in use) or incorrect RP1 pin mapping. Check /sys/kernel/debug/gpio and free pins via sysfs.
Q2: How to toggle GPIO pins without a kernel driver? A: Use sysfs: echo 21 > /sys/class/gpio/export; echo out > /sys/class/gpio/gpio21/direction; echo 1 > /sys/class/gpio/gpio21/value.
Q3: What’s the difference between sysfs and gpiod APIs? A: Sysfs (/sys/class/gpio) is user-space, slower, and simpler; gpiod is kernel-space, faster, and supports advanced features like interrupts.
Conclusion
This guide equips you to write a Raspberry Pi GPIO driver for Pi 3, 4, and 5, with modern kernel 6.6 code, Pi 5 RP1 chip support, and advanced debugging tips. Unlike fragmented forum posts or outdated tutorials, it consolidates 20+ years of my BSP expertise, including my CAIF driver work, into a practical tutorial.
Resources:
- Need help with Raspberry Pi BSPs or drivers? Contact me for consulting (digitallyamar@gmail.com) ($50-100/hour).
Share your GPIO challenges in the comments below!
A typical Linux kernel driver compilation demo video.