Linux驱动开发—设备树描述引脚复用 Pinmux 与Pinctrl

书接上回:Linux驱动开发—设备树基本概念,语法详解-CSDN博客

Pinmux 概念

Pinmux,或 Pin Multiplexer,是一种在电子电路设计中使用的技术,用于在一个芯片上多路复用(共享)引脚的功能。通过 pinmux,可以将一个引脚配置为多种功能,例如 GPIO(通用输入输出)、UART(通用异步收发传输器)、I2C(集成电路间总线)、SPI(串行外设接口)等。这样可以在有限的引脚资源下实现更多的功能,增加芯片的灵活性和可扩展性。pinmux 广泛应用于嵌入式系统设计、微控制器、系统级芯片(SoC)等领域,特别是在需要实现多种外设功能且引脚资源有限的情况下。

这样设计的优点:

  1. 节省引脚资源:通过共享引脚的方式,减少了芯片对引脚数量的需求。
  2. 灵活性高:可以根据实际应用需求灵活配置引脚功能。
  3. 成本降低:减少了对外部引脚扩展的需求,从而降低了硬件成本。

例如,一个 MCU(微控制单元)可能有一个引脚可以配置为 GPIO 或 UART 的 TX 引脚。通过设置 pinmux 配置寄存器,可以选择这个引脚的具体功能。

Pinctrl 概念

Pinctrl(Pin Control)是与 pinmux 密切相关的概念,但更为广泛。Pinctrl 是一个综合的引脚管理框架,涵盖了引脚的多路复用、配置和实时控制。通过 pinctrl,设计人员可以灵活地配置和管理芯片引脚,提高系统的功能性和可靠性。它不仅包括引脚的多路复用,还涵盖了对引脚电气特性的配置和控制。Pinctrl 通常涉及以下几个方面:

多路复用(Pin Multiplexing)

这是 pinmux 的主要功能,即选择一个引脚的具体功能,例如将一个引脚配置为 UART、I2C、SPI 或 GPIO。

引脚配置(Pin Configuration)

配置引脚的电气特性,包括:

  • 上拉或下拉电阻:通过内部上拉或下拉电阻来确定引脚的默认状态。
  • 驱动强度:控制引脚输出的电流能力。
  • 输入/输出模式:设置引脚为输入模式、输出模式或高阻态。
  • 中断配置:设置引脚中断的触发方式,例如上升沿、下降沿或电平触发。

引脚控制(Pin Control)

这是指对引脚的实时控制和管理,例如使能或禁用特定引脚的功能,或者在运行时动态改变引脚的配置。

Pinctrl 在软件中的实现

在操作系统层面,如 Linux,pinctrl 通常由一个专用的子系统管理。设备树(Device Tree)文件中定义了引脚的多路复用和配置,内核引导时会根据这些配置初始化引脚。典型的设备树片段简单示例:

pinctrl {
    uart0_pins: uart0 {
        pins = "PA0", "PA1";
        function = "uart";
        bias-pull-up;
        drive-strength = <4>;
    };
};

使用场景

  • 嵌入式系统:在嵌入式设备中,通过 pinctrl 管理引脚的多路复用和配置,实现外设功能。
  • SoC(系统级芯片):在复杂的 SoC 设计中,pinctrl 用于配置和管理多个子系统的引脚。
  • 低功耗设计:通过配置引脚的低功耗模式,减少系统的整体功耗。

使用设备树描述引脚复用

理论上描述示例

假设我们有一个 UART 接口,需要配置其引脚:

&uart0 {
    pinctrl-names = "default";
    pinctrl-0 = <&uart0_pins>;
    status = "okay";
};
pinctrl {
    uart0_pins: uart0_pins {
        pins = "PA0", "PA1";  // 引脚名称
        function = "uart";    // 引脚功能
        bias-pull-up;         // 上拉电阻
        drive-strength = <4>; // 驱动强度
    };
};

引脚组通常在特定设备节点中引用,以便在设备初始化时进行配置。

&uart0 {
    pinctrl-names = "default";
    pinctrl-0 = <&uart0_pins>;
    status = "okay";
};

引脚端:固定的语法: pinctrl 名字和 pinctrl 引脚

在这个例子中,&uart0 节点引用了 uart0_pins 引脚组,并将其命名为 default 配置。系统启动时,UART0 的引脚将根据 uart0_pins 引脚组的定义进行配置。

配置端:不同Soc 厂商可能不一样,没有通用标准

pinctrl {
    uart0_pins: uart0_pins {
        pins = "PA0", "PA1";  // 引脚名称
        function = "uart";    // 引脚功能
        bias-pull-up;         // 上拉电阻
        drive-strength = <4>; // 驱动强度
    };
};

常见属性:

  • pins:定义引脚组中的具体引脚。
  • function:定义引脚的功能,例如 UART、I2C、SPI 等。
  • bias-disable:禁用上拉或下拉电阻。
  • bias-pull-up:启用上拉电阻。
  • bias-pull-down:启用下拉电阻。
  • drive-strength:设置引脚的驱动强度,通常以 mA 为单位。
  • slew-rate:设置引脚的转换速率,影响信号的上升和下降时间。
  • input-enable:启用输入功能。
  • output-enable:启用输出功能。

实际上NXP示例

将NXP源码中dtb翻译出来主要的源码,截取部分引脚复用示例;

iomuxc {
		compatible = "fsl,imx8qm-iomuxc";
		pinctrl-names = "default";
		pinctrl-0 = <0x0e>;
		imx8qm-mek {
			hoggrp {
				fsl,pins = <0x73 0x00 0x600004c 0xb2 0x03 0x600004c 0x27 0x03 0x600004c 0x0f 0x03 0x600004c 0x9e 0x03 0x21 0x6f 0x03 0x21 0x6e 0x03 0x21 0x10 0x03 0x21 0x66 0x03 0x21 0x05 0x03 0x21 0x4b 0x03 0x21 0x4c 0x03 0x21 0x4e 0x03 0x21 0x4f 0x03 0x21 0xb3 0x03 0x21 0x5e 0x03 0x21>;
				linux,phandle = <0x0e>;
				phandle = <0x0e>;
			};

			uart_cm41grp {
				fsl,pins = <0x0b 0x01 0x6000020 0x0c 0x01 0x6000020>;
				linux,phandle = <0xde>;
				phandle = <0xde>;
			};

			esai0grp {
				fsl,pins = <0x68 0x00 0xc6000040 0x69 0x00 0xc6000040 0x6a 0x00 0xc6000040 0x6b 0x00 0xc6000040 0x6c 0x00 0xc6000040 0x6d 0x00 0xc6000040 0x70 0x00 0xc6000040>;
				linux,phandle = <0x137>;
				phandle = <0x137>;
			};

			fec1grp {
				fsl,pins = <0xff 0x00 0x14a0 0xa6 0x00 0x6000020 0xa5 0x00 0x6000020 0xf4 0x00 0x61 0xf3 0x00 0x61 0xf5 0x00 0x61 0xf6 0x00 0x61 0xf7 0x00 0x61 0xf8 0x00 0x61 0xf9 0x00 0x61 0xfa 0x00 0x61 0xfb 0x00 0x61 0xfc 0x00 0x61 0xfd 0x00 0x61 0xfe 0x00 0x61>;
				linux,phandle = <0x124>;
				phandle = <0x124>;
			};
		};
	};

同样分为两部分:

定义引脚端: 配置的引脚为<0x0e>,具体的含义需要查询数据手册

		compatible = "fsl,imx8qm-iomuxc";
		pinctrl-names = "default";
		pinctrl-0 = <0x0e>;

定义配置端:以串口UART为例

			uart_cm41grp {
				fsl,pins = <0x0b 0x01 0x6000020 0x0c 0x01 0x6000020>;
				linux,phandle = <0xde>;
				phandle = <0xde>;
			};

NXP中,一般定义为fsl,pins属性,具体解析如下:

引脚编号 (pin number):指定具体的物理引脚。

模式/功能 (mux mode):指定引脚的复用模式,使得一个引脚可以有多个功能。

电气属性 (electrical properties):配置引脚的电气特性,比如上拉/下拉电阻、驱动强度等。

第一组数据:0x0b 0x01 0x6000020

  • 引脚编号 (0x0b):这是引脚编号。
  • 模式 (0x01):这是引脚的复用模式,使得该引脚用于某个特定的功能。
  • 电气属性 (0x6000020):这是引脚的电气属性,通常包含配置如上拉/下拉电阻、驱动强度等。 具体属性需要查询数据手册

第二组数据:0x0c 0x01 0x6000020

  • 引脚编号 (0x0c):这是引脚编号。
  • 模式 (0x01):这是引脚的复用模式,使得该引脚用于某个特定的功能。
  • 电气属性 (0x6000020):这是引脚的电气属性。具体属性需要查询数据手册

实际上RK示例

以RK3588 设备树源码为例

gpio-keys {
	compatible = "gpio-keys";
	autorepeat;

	pinctrl-names = "default";
	pinctrl-0 = <&pwr_key>;

	power {
		gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>;
		linux,code = <KEY_POWER>;
		label = "GPIO Key Power";
		debounce-interval = <100>;
		wakeup-source;
	};
};
&pinctrl {
	pinctrl-names = "default";
	pinctrl-0 = <&rtc_32k>;

	buttons {
		pwr_key: pwr-key {
			rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>;
		};
	};

	usb {
		usb_drv: usb-drv {
			rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
		};
	};

	sdio-pwrseq {
		wifi_enable_h: wifi-enable-h {
			rockchip,pins = <0 RK_PA2 0 &pcfg_pull_none>;
		};
	};
};

定义引脚端: 配置的引脚为<&pwr_key>,具体的含义需要查询数据手册

		pinctrl-names = "default";
		pinctrl-0 = <&pwr_key>;

定义配置端 :复用电源按键

	buttons {
		pwr_key: pwr-key {
			rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>;
		};
	};

rockchip,pins = <0 RK_PA2 0 &pcfg_pull_none>;具体解析如下:

通过将 pwr_key 引脚配置为 rockchip,pins = <0 RK_PA6 0 &pcfg_pull_up>,明确了 PA6 引脚的电气属性和复用模式。这使得 pwr_key 可以在 gpio-keys 节点中被引用,并正确配置为电源按键。这个配置表明,PA6 引脚设置为上拉模式(pcfg_pull_up),并且默认工作在 GPIO 模式(复用模式为 0)。这种配置确保了按键按下时能被正确识别,并且有适当的电气特性来防止误触发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Trump. yang

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值