DTS中如何配置设备相关的pinctrl

本文详细解析了嵌入式Linux环境下DTS中pinctrl子系统的配置方法,重点介绍了如何定义和管理设备驱动中的pin功能,包括pin的选择、配置及驱动程序的引用。通过实例展示了Freescale IOMUX的pin配置过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进行嵌入式Linux驱动开发时,不可避免的会涉及到DTS相关的编写工作,而其中,最为重要的一项工作就是pinctrl相关的配置,这包括pins的功能选择(作为普通IO,还是作为外围控制器的pins)以及pins的配置(pull-up/pull-down、驱动能力、三态等)。
内核中的pinctrl子系统抽象了不同SoC中关于pins的管理方式,Linux内核之pinctrl子系统对于pinctrl子系统进行了简要的概述,如果想要了解pinctrl子系统,可以参考这篇博文。

本文主要讲解对于一个具体的设备驱动,如何在DTS中基于pinctrl实现关于pins的管理,这包括:

  • 如何定义pin功能
  • 驱动程序如何引用pin

如何定义pin功能

利用内核文档

市面上存在很多的SoC,一般情况下,不同的SoC在DTS中关于pin的管理方式会有一些不同。SoC厂商在发布时,会编写相关的pinctrl驱动程序,同时,会在内核目录Documentation/devicetree/bindings/pinctrl下,编写相关的配置说明,比如,fsl,imx-pinctrl.txt
里面说明了 Freescale IOMUX Controller (IOMUXC) for I.MX相关的配置说明;rockchipi, pinctrl.txt里面说面了Rockchip Pinmux Controller相关的配置说明。

所以,当我们拿到一块电路板时,首先,需要确定其使用的SoC,然后,去Documentation/devicetree/bindings/pinctrl目录下,找到关于该款SoC相关的pinctrl的配置说明。这里需要注意的时,某个厂商的SoC一般遵循相同的pinctrl配置方式,所以,在未找到具体SoC的
pinctrl使用说明时,可以直接查看这个SoC厂商的说明文档,比如,我们如果使用的是s3c6410,可以看到该目录下,没有s3c6410相关的说明,但是,我们可以找到samsung-pinctrl.txt,参照这个文档,同样可以在DTS中配置pinctrl。

pin配置举例

下面拿一个例子,说明一下如何在DTS中定义pin的功能。

Freescale IOMUX

关于Freescale SoC的pinctrl配置,主要完成一下两项内容:

  • 确定SoC的pinctrl控制器的兼容性: compatible: “fsl,-iomuxc”,关于SoC的IOMUX的兼容性,需要到fsl,-pinctrl.txt中获得。
  • 配置具体的pins: fsl,pins/</>,该字段定义了pin的功能,其一般定义一组pins的功能,这一组pins服务于同一function,比如spi控制器。每个配置项包括6字段分别是:前5个字段分别是<mux_reg conf_reg input_reg mux_val input_val>,可以到/arch/arm/boot/dts的imx*-pinfunc.h中找到他们的定义,
    比如,imx6ul-pinfunc.h定义imx6ul这款SoC的所有pins。6个字段是pin的配置参数,比如:pull-up/pull-down等。

下面是sd卡所用到的pin的功能配置定义:

usdhc@219c000 { /* uSDHC4 */
    non-removable;
    vmmc-supply = <&reg_3p3v>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_usdhc4_1>;
};         
           
iomuxc@20e0000 {
    compatible = "fsl,imx6q-iomuxc";
    reg = <0x020e0000 0x4000>;
           
    /* shared pinctrl settings */
    usdhc4 {
        pinctrl_usdhc4_1: usdhc4grp-1 {
            fsl,pins = <
                MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
                MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
                MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
                MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
                MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
                MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
                MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059                                                                                                                                                                                                                                    
                MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
                MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
                MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
            >;
    };  
    ....
};       
  • iomuxc的兼容性为"fsl,imx6q-iomuxc";
  • 节点pinctrl_usdhc4_1定义了设备uSDHC4所使用的pins功能。

驱动程序如何使用pins

对于普通的设备,如何定义其使用到的pin呢?上面关于Freescale IOMUX的举例,说明了uSDHC4这个设备如何定义pins的功能。文档pinctrl-bindings.txt中说明了一般情况下如何在DTS中定义一个设备驱动的pins功能。

如果一个设备使用到某些pins,那么,在其DTS节点中至少包含下面两项内容:

  • pinctrl-names:定义设备不同的工作状态,一般包括下面几个:default、init、sleep、idle。其中,sleep、idle用于系统的电源管理,以达到控制系统功耗的目的。
  • pinctrl-0:定义了一个phandles的列表,每个phandle指向一个pinctrl的节点。该配置项定义了该设备的一种工作状态,其对应于pinctrl-names中首个工作状态。

下面举例说明一下:
deviceA {
pinctrl-names = “defalut”, “idle”;
pinctrl-0 = <&state_0_node_a>;
pinctrl-1 = <&state_1_node_a &state_1_node_b>;
};

deviceA节点,定义了"default","idle"两种工作状态,所以,下面依次定义了pinctrl-0和pinctrl-1两个pins列表,分别对应于上面两个状态。

上面内容,说明了一个设备如何在DTS中配置其所用到的pins,后面文章还具体分析pinctrl子系统在DTS中的配置方式。

关注公众号“奔跑的码仔”获取更多优质资源

### 设备树中 pinctrl 的功能与作用 #### 什么是 pinctrl? `pinctrl` 是 Linux 内核中的一个子系统,用于管理 SoC(System on Chip)上的 GPIO 和其他外设的引脚复用功能。它允许硬件资源通过软件动态配置,从而实现灵活的设备初始化和运行时调整。 #### `pinctrl` 的主要功能 1. **引脚复用 (Pin Multiplexing)** 大多数现代 SoC 提供多种外设接口(如 I2C、SPI、UART 等)。为了节省物理引脚数量,SoC 上的一个引脚可以被分配给不同的功能模块。`pinctrl` 子系统负责指定某个引脚的具体用途[^1]。 2. **引脚配置 (Pin Configuration)** 不同的功能可能需要特定的电气特性,比如驱动强度、上下拉电阻、电压等级等。`pinctrl` 可以在设备树中定义这些参数并应用到对应的引脚上[^2]。 3. **状态切换 (State Switching)** 在某些情况下,同一个引脚可能会有不同的工作模式。例如,在启动阶段使用 UART 进行调试,而在正常运行时将其释放为 GPIO 使用。`pinctrl` 支持定义多个状态,并根据需求动态切换[^3]。 4. **简化硬件抽象层** 通过将引脚配置集中到设备树中,减少了内核代码对具体硬件细节的依赖,提高了可移植性和维护性[^4]。 --- #### 实际应用场景解析 - 假设有一个按键连接到了 GPIO 引脚上,则可以在设备树中这样定义: ```dts gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio_keys>; key0 { label = "key0"; gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; }; }; ``` - `pinctrl-0 = <&pinctrl_gpio_keys>;` 表明此节点会引用名为 `pinctrl_gpio_keys` 的引脚控制组。 - 此处的 `pinctrl_gpio_keys` 定义了按键所使用的 GPIO 引脚及其相关属性(如方向、电平触发方式等)。 - 如果需要支持多态操作,可以通过定义不同状态来满足需求: ```dts &uart1 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart1_default_pins>; pinctrl-1 = <&uart1_sleep_pins>; }; ``` - 当进入休眠模式时,系统自动切换至 `uart1_sleep_pins` 所描述的状态,降低功耗或改变信号行为。 --- #### 技术背景补充 - 芯片内部存在一个内存映射区域,用来存储寄存器值以控制各外围模块的行为。`pinctrl` 就是通过对这些寄存器编程完成实际的任务。 - 设备树文件通常包含 `.dts` 后缀名,经过编译工具处理后生成二进制形式的 `.dtb` 文件加载到目标板卡中执行。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值