设备树中的struct rockchip_pin_group 和struct rockchip_pmx_func 一组组物理引脚的集合和描述一个逻辑功能

1.概要

目的:确认两个结构体的关系。

rockchip_pin_group谁对引脚的定义。

rockchip_pmx_func是对功能的定义,一个功能有一组引脚共同构成。

2.内容

在瑞芯微RK3588的pinctrl驱动中,struct rockchip_pin_group 和 struct rockchip_pmx_func 是核心数据结构,用于描述引脚复用(Pinmux)和功能配置。以下是它们的详细解析:


1. struct rockchip_pin_group

作用
表示一组物理引脚的集合,通常对应某个外设功能(如SPI、I2C)的引脚配置。

关键成员

struct rockchip_pin_group {
    const char *name;               // 引脚组名称(如 "spi0_sck")
    const unsigned int *pins;       // 引脚编号数组(如 GPIO0_A0, GPIO0_A1)
    const unsigned int num_pins;    // 引脚数量
    const unsigned int *funcs;      // 每个引脚对应的复用功能索引
    const unsigned int *drive;      // 驱动强度配置(可选)
    const unsigned int *pull;       // 上拉/下拉配置(可选)
    const unsigned int *schmitt;    // 施密特触发器配置(可选)
};

示例
定义SPI0的SCK引脚组:

static const unsigned int spi0_sck_pins[] = { RK_PD0 };
static const unsigned int spi0_sck_funcs[] = { RK_FUNC_SPI0 };

struct rockchip_pin_group spi0_sck_group = {
    .name = "spi0_sck",
    .pins = spi0_sck_pins,
    .num_pins = ARRAY_SIZE(spi0_sck_pins),
    .funcs = spi0_sck_funcs,
};

2. struct rockchip_pmx_func

作用
描述一个逻辑功能(如SPI0),包含该功能所需的引脚组及配置。

关键成员

struct rockchip_pmx_func {
    const char *name;               // 功能名称(如 "spi0")
    const char * const *groups;     // 关联的引脚组数组(如 "spi0_sck", "spi0_mosi")
    const unsigned int num_groups;  // 引脚组数量
    const unsigned int *ctrl;       // 额外控制配置(如时钟使能)
};

示例
定义SPI0功能:

static const char * const spi0_groups[] = {
    "spi0_sck",
    "spi0_mosi",
    "spi0_miso",
    "spi0_cs0",
};

struct rockchip_pmx_func spi0_func = {
    .name = "spi0",
    .groups = spi0_groups,
    .num_groups = ARRAY_SIZE(spi0_groups),
};

3. 两者关系

  • 功能与引脚组的绑定
    一个功能(pmx_func)由多个引脚组(pin_group)组成。例如,SPI0功能需要SCK、MOSI、MISO、CS等引脚组。

  • 配置流程

    1. 在设备树(DTS)中定义引脚组和功能:

      pinctrl_spi0: spi0@0 {
          rockchip,pins = <
              RK_PD0 RK_FUNC_SPI0 &pcfg_pull_none,
              RK_PD1 RK_FUNC_SPI0 &pcfg_pull_none,
              /* ... */
          >;
          rockchip,function = "spi0";
      };
    2. 驱动解析DTS,填充rockchip_pin_grouprockchip_pmx_func结构体。
    3. 当外设(如SPI控制器)请求pinctrl_select_state()时,系统根据功能名称找到对应的pmx_func,并配置所有关联的pin_group

4. 高级配置

  • 电气参数
    通过drivepullschmitt等成员可配置引脚的驱动强度、上拉/下拉电阻、施密特触发器等。

  • 动态切换
    支持运行时切换功能(如从UART切换到GPIO),通过pinctrl_lookup_state()pinctrl_select_state()实现。


5. 调试建议

  • 检查DTS配置
    确保引脚组和功能名称与驱动代码一致。

  • 查看pinctrl日志
    启用CONFIG_DEBUG_PINCTRL,通过dmesg查看引脚配置过程。

  • 硬件手册
    参考《RK3588 TRM》的GPIO和Pinmux章节,确认引脚复用编号和电气参数。

通过这两个结构体,RK3588的pinctrl驱动实现了灵活的引脚复用管理,支持外设动态配置和硬件抽象。

3.关联链接

4.关联知识 

1.解析设备树

pinctrl_spi0: spi0@0 {
    rockchip,pins = <
        RK_PD0 RK_FUNC_SPI0 &pcfg_pull_none,
        RK_PD1 RK_FUNC_SPI0 &pcfg_pull_none,
        /* ... */
    >;
    rockchip,function = "spi0";
};

在瑞芯微RK3588的pinctrl驱动中,解析用户提供的设备树节点 pinctrl_spi0 后,生成的 struct rockchip_pin_group 和 struct rockchip_pmx_func 结构体如下:


1. struct rockchip_pin_group 解析

设备树中的 rockchip,pins 数组每个条目对应一个引脚组。假设条目为:

rockchip,pins = <
    RK_PD0 RK_FUNC_SPI0 &pcfg_pull_none,
    RK_PD1 RK_FUNC_SPI0 &pcfg_pull_none,
    RK_PD2 RK_FUNC_SPI0 &pcfg_pull_none,
    RK_PD3 RK_FUNC_SPI0 &pcfg_pull_none
>;
生成的引脚组:

每个条目生成一个 rockchip_pin_group,名称自动生成(如 spi0_pd0spi0_pd1 等):

/* 引脚组 1: PD0 */
static const unsigned int spi0_pd0_pins[] = { RK_PD0 };
static const unsigned int spi0_pd0_funcs[] = { RK_FUNC_SPI0 };
static const unsigned int spi0_pd0_pull[] = { PULL_NONE };

struct rockchip_pin_group spi0_pd0_group = {
    .name   = "spi0_pd0",
    .pins   = spi0_pd0_pins,
    .num_pins = 1,
    .funcs  = spi0_pd0_funcs,
    .pull   = spi0_pd0_pull,
};

/* 引脚组 2: PD1 */
static const unsigned int spi0_pd1_pins[] = { RK_PD1 };
static const unsigned int spi0_pd1_funcs[] = { RK_FUNC_SPI0 };
static const unsigned int spi0_pd1_pull[] = { PULL_NONE };

struct rockchip_pin_group spi0_pd1_group = {
    .name   = "spi0_pd1",
    .pins   = spi0_pd1_pins,
    .num_pins = 1,
    .funcs  = spi0_pd1_funcs,
    .pull   = spi0_pd1_pull,
};

/* 后续引脚组(PD2, PD3)结构类似,名称依次为 spi0_pd2, spi0_pd3 */

2. struct rockchip_pmx_func 解析

设备树中的 rockchip,function = "spi0" 关联到功能名称,生成的 pmx_func 结构体如下:

/* 定义所有引脚组名称 */
static const char * const spi0_groups[] = {
    "spi0_pd0",  /* 对应 PD0 */
    "spi0_pd1",  /* 对应 PD1 */
    "spi0_pd2",  /* 对应 PD2 */
    "spi0_pd3",  /* 对应 PD3 */
};

/* 生成功能结构体 */
struct rockchip_pmx_func spi0_func = {
    .name      = "spi0",
    .groups    = spi0_groups,
    .num_groups = ARRAY_SIZE(spi0_groups),
};

3. 关键解析逻辑

  1. 引脚组生成
    • 每个 rockchip,pins 条目生成一个 rockchip_pin_group
    • 组名自动生成(如 功能名_引脚名,如 spi0_pd0)。
    • 引脚编号、功能、电气参数(如上拉)从设备树解析。
  2. 功能关联
    • rockchip,function 属性匹配 pmx_func 的 name
    • 所有关联的引脚组名称存入 pmx_func.groups 数组。

4. 实际应用场景

当外设(如SPI控制器)请求配置 pinctrl_spi0 状态时:

  1. 驱动通过 rockchip,function = "spi0" 找到 spi0_func
  2. 遍历 spi0_func.groups 中的所有引脚组(如 spi0_pd0spi0_pd1)。
  3. 对每个引脚组调用 pinctrl_set_mux() 和 pinctrl_set_bias(),完成引脚复用和电气配置。

5. 验证方法

  • 查看DTS映射
    确保设备树中的引脚编号(如 RK_PD0)和功能(RK_FUNC_SPI0)与硬件手册一致。

  • 调试日志
    启用 CONFIG_DEBUG_PINCTRL,通过 dmesg 观察引脚配置过程,例如:

    pinctrl: group spi0_pd0 set to func SPI0
    pinctrl: group spi0_pd1 set to func SPI0
  • 代码检查
    在驱动源码中搜索 spi0_func 和 spi0_pd0_group,确认结构体定义与解析逻辑一致。


通过这种方式,RK3588的pinctrl驱动实现了引脚复用的灵活配置,支持外设动态切换功能(如从UART切换到SPI)。

6.关系分析

2.rockchip,pins中的rockchip和pins是表示两个东西,还是一个东西就叫rockchip,pins 

在设备树(DTS)语法中,rockchip,pins 是一个复合属性名,由两部分组成:

  1. rockchip:厂商前缀(Vendor Prefix),表示这是瑞芯微(Rockchip)自定义的属性。
  2. pins:属性名称(Property Name),表示该属性用于描述引脚(Pin)配置。

具体解析

  • 语法规则
    设备树属性名通常采用 厂商前缀, 属性名 的格式(如 rockchip,functionfsl,pinctrl),目的是避免不同厂商的属性命名冲突。

  • rockchip,pins 的作用
    该属性定义了一组引脚的复用(Pinmux)和电气配置(如上拉/下拉、驱动强度等)。每个条目(Entry)的格式为:

    <引脚编号> <功能选择> <电气配置1> <电气配置2> ...

示例解析

以您的代码为例:

rockchip,pins = <
    RK_PD0 RK_FUNC_SPI0 &pcfg_pull_none,
    RK_PD1 RK_FUNC_SPI0 &pcfg_pull_none,
    RK_PD2 RK_FUNC_SPI0 &pcfg_pull_none,
    RK_PD3 RK_FUNC_SPI0 &pcfg_pull_none
>;
每个条目的含义:
  1. RK_PD0
    引脚编号(Pin Number),表示物理引脚(如 GPIO0 的第 0 号引脚)。

  2. RK_FUNC_SPI0
    功能选择(Function Select),表示将引脚配置为 SPI0 的某个信号(如 SCK、MOSI 等)。

  3. &pcfg_pull_none
    电气配置(Electrical Configuration),此处表示禁用上拉/下拉电阻(Pull-Up/Pull-Down)。


驱动解析逻辑

在瑞芯微的 pinctrl 驱动中,rockchip,pins 属性会被解析为:

  1. 引脚组(struct rockchip_pin_group
    每个条目生成一个引脚组,包含引脚编号、功能选择和电气配置。

  2. 功能(struct rockchip_pmx_func
    所有引脚组通过 rockchip,function 属性关联到一个逻辑功能(如 "spi0")。


总结

  • rockchip,pins 是一个整体属性名,由厂商前缀 rockchip 和属性名 pins 组成。
  • 每个条目定义了一个引脚的复用和电气配置,驱动会将其解析为 rockchip_pin_group 结构体。
  • 所有引脚组通过 rockchip,function 属性绑定到一个逻辑功能(如 "spi0"),生成 rockchip_pmx_func 结构体。

3.rockchip_pmx_func中的groups和rockchip_pin_group是什么关系

在瑞芯微RK3588的pinctrl驱动中,struct rockchip_pmx_func 的 groups 成员与 struct rockchip_pin_group 的关系是功能与引脚组的绑定关系,具体如下:


1. 核心关系

  • rockchip_pmx_func.groups 是一个字符串数组,存储了该功能(如SPI0)依赖的所有引脚组的名称(如 "spi0_sck""spi0_mosi")。
  • rockchip_pin_group 是具体的引脚配置实例,每个实例对应一个物理引脚或一组引脚的复用和电气参数。

驱动通过 groups 中的名称找到对应的 rockchip_pin_group 实例,完成功能配置。


2. 示例解析

假设设备树中定义了一个SPI0功能:

pinctrl_spi0: spi0@0 {
    rockchip,pins = <
        RK_PD0 RK_FUNC_SPI0 &pcfg_pull_none,  /* 引脚组1: SCK */
        RK_PD1 RK_FUNC_SPI0 &pcfg_pull_none,  /* 引脚组2: MOSI */
        RK_PD2 RK_FUNC_SPI0 &pcfg_pull_none,  /* 引脚组3: MISO */
        RK_PD3 RK_FUNC_SPI0 &pcfg_pull_none   /* 引脚组4: CS0 */
    >;
    rockchip,function = "spi0";
};
生成的 rockchip_pmx_func

/* 定义所有引脚组名称 */
static const char * const spi0_groups[] = {
    "spi0_sck",  /* 对应 SCK 引脚组 */
    "spi0_mosi", /* 对应 MOSI 引脚组 */
    "spi0_miso", /* 对应 MISO 引脚组 */
    "spi0_cs0",  /* 对应 CS0 引脚组 */
};

/* 生成功能结构体 */
struct rockchip_pmx_func spi0_func = {
    .name      = "spi0",
    .groups    = spi0_groups,      /* 绑定引脚组名称 */
    .num_groups = ARRAY_SIZE(spi0_groups),
};
生成的 rockchip_pin_group 示例(以SCK为例):

struct rockchip_pin_group spi0_sck_group = {
    .name   = "spi0_sck",          /* 与 groups 中的名称匹配 */
    .pins   = &rk_pd0,             /* 物理引脚 PD0 */
    .funcs  = &rk_func_spi0,       /* 复用功能 SPI0 */
    .pull   = &pull_none,          /* 电气配置:无上拉 */
};

3. 配置流程

当外设(如SPI控制器)请求配置 pinctrl_spi0 状态时:

  1. 驱动通过 rockchip,function = "spi0" 找到 spi0_func
  2. 遍历 spi0_func.groups 中的每个引脚组名称(如 "spi0_sck")。
  3. 根据名称找到对应的 rockchip_pin_group 实例(如 spi0_sck_group)。
  4. 对每个引脚组调用底层函数(如 rockchip_pin_config()),配置引脚复用和电气参数。

4. 设计意义

  • 模块化
    将功能(如SPI0)与引脚组解耦,便于复用引脚组配置(如多个功能共享同一引脚组)。
  • 可扩展性
    新增功能只需定义新的 rockchip_pmx_func 并关联现有引脚组,无需修改底层驱动。
  • 动态配置
    支持运行时切换功能(如从UART切换到GPIO),通过替换 groups 数组实现。

5. 验证方法

  • 设备树检查
    确保 rockchip,function 名称与 rockchip_pmx_func.name 一致,且 rockchip,pins 条目生成的引脚组名称存在于 groups 数组中。

  • 驱动调试
    启用 CONFIG_DEBUG_PINCTRL,观察日志中引脚组和功能的绑定关系:

    pinctrl: func spi0 requires groups: spi0_sck, spi0_mosi, spi0_miso, spi0_cs0
    pinctrl: group spi0_sck configured for func SPI0

通过这种设计,RK3588的pinctrl驱动实现了引脚复用的高度灵活性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值