[Linux外设驱动详解]8. GPIO子系统

8. GPIO子系统

8.1 概述

GPIO(General Purpose Input/Output,通用输入输出)是嵌入式系统中最基础、最常用的外设接口之一。Linux 内核通过 GPIO 子系统为驱动开发者提供了一套统一的 API,屏蔽了不同 SoC 硬件实现的差异。

什么是 GPIO?

  • 简单来说,GPIO 就是芯片引脚的软件控制能力
  • 每个引脚可以独立配置为输入或输出模式
  • 输出模式下可以控制引脚电平(高/低)
  • 输入模式下可以读取引脚电平状态

为什么需要 GPIO 子系统?

┌─────────────────────────────────────────────────────────────┐
│                        驱动开发者                            │
│  只需调用 gpiod_set_value() 等统一 API                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                      GPIO 子系统 (gpiolib)                   │
│  提供抽象层,统一管理所有 GPIO 控制器                        │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    GPIO Controller 驱动                      │
│  Rockchip GPIO  │  NXP GPIO  │  TI GPIO  │  ...             │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                      硬件 (SoC GPIO)                         │
└─────────────────────────────────────────────────────────────┘

8.2 GPIOLIB 架构

8.2.1 核心数据结构

1. struct gpio_desc - GPIO 描述符
/* kernel/drivers/gpio/gpiolib.h */
struct gpio_desc {
   
   
    struct gpio_device *gdev;      // 所属的 GPIO 设备
    unsigned long flags;           // 状态标志位
    const char *label;             // 使用者标签
    const char *name;              // GPIO 名称
    // ... 其他字段
};

flags 标志位说明:

标志位 宏定义 说明
0 FLAG_REQUESTED GPIO 已被请求占用
1 FLAG_IS_OUT 方向为输出
6 FLAG_ACTIVE_LOW 低电平有效
7 FLAG_OPEN_DRAIN 开漏输出模式
8 FLAG_OPEN_SOURCE 开源输出模式
9 FLAG_USED_AS_IRQ 被用作中断
13 FLAG_PULL_UP 上拉使能
14 FLAG_PULL_DOWN 下拉使能
2. struct gpio_chip - GPIO 控制器
/* kernel/include/linux/gpio/driver.h */
struct gpio_chip {
   
   
    const char *label;             // 功能名称
    struct gpio_device *gpiodev;   // 内部状态
    struct device *parent;         // 父设备
    struct module *owner;

    int base;                      // GPIO 编号基数
    u16 ngpio;                     // GPIO 数量

    // 方向控制
    int (*get_direction)(struct gpio_chip *gc, unsigned int offset);
    int (*direction_input)(struct gpio_chip *gc, unsigned int offset);
    int (*direction_output)(struct gpio_chip *gc, unsigned int offset, int value);

    // 数据读写
    int (*get)(struct gpio_chip *gc, unsigned int offset);
    void (*set)(struct gpio_chip *gc, unsigned int offset, int value);

    // 配置
    int (*set_config)(struct gpio_chip *gc, unsigned int offset, unsigned long config);

    // 中断相关
    int (*to_irq)(struct gpio_chip *gc, unsigned int offset);

    // 请求/释放
    int (*request)(struct gpio_chip *gc, unsigned int offset);
    void (*free)(struct gpio_chip *gc, unsigned int offset);
};
3. struct gpio_device - GPIO 设备
/* kernel/drivers/gpio/gpiolib.h */
struct gpio_device {
   
   
    int id;                        // 设备 ID
    struct device dev;             // 设备模型
    struct cdev chrdev;            // 字符设备
    struct gpio_chip *chip;        // 指向 gpio_chip
    struct gpio_desc *descs;       // GPIO 描述符数组
    int base;                      // 全局编号基数
    u16 ngpio;                     // GPIO 数量
    const char *label;             // 描述性名称
    struct list_head list;         // 链入全局 gpio_devices 链表
};

8.2.2 架构层次图

┌─────────────────────────────────────────────────────────────────────┐
│                         Consumer API 层                              │
│  gpiod_get() / gpiod_set_value() / gpiod_get_value()                │
└─────────────────────────────────────────────────────────────────────┘
                                   │
                                   │ 操作 gpio_desc
                                   ▼
┌─────────────────────────────────────────────────────────────────────┐
│                       GPIOLIB 核心层                                 │
│  - GPIO 描述符管理                                                   │
│  - 权限检查                                                          │
│  - 统一编号空间                                                      │
│  - 与设备树/ACPI 交互                                                │
└─────────────────────────────────────────────────────────────────────┘
                                   │
                                   │ 调用 gpio_chip ops
                                   ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     GPIO Controller 驱动层                           │
│  gpio-rockchip.c  │  gpio-pl061.c  │  gpio-tegra.c  │  ...          │
│  实现 gpio_chip 回调函数                                             │
└─────────────────────────────────────────────────────────────────────┘
                                   │
                                   │ 读写寄存器
                                   ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         硬件寄存器                                   │
└─────────────────────────────────────────────────────────────────────┘

8.2.3 注册流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JustaUncle

一杯咖啡,换我肝到天亮!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值