内核驱动,使用GPIO overlay时是否总是需要pinctrl 属性?
Kernel driver, is pinctrl property always needed when using GPIO overlay?
我已经在 Unix Stackexchange 上问过这个问题,但它似乎是一个错误的地方来解决这类问题。 Ad rem:
我正在为 SPI 控制的显示器创建一个内核驱动程序,它旨在与 Raspberry PI 一起工作。除了 3 条 SPI 线外,显示器还有 3 条额外的控制线:BUSY、RST 和 DC。为了有可能控制这些线路,我的 DTS 必须包含额外的 GPIO 片段。
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
spidev@0 {
status = "disabled";
};
epd0: epd@0 {
compatible = "waveshare,epd";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&epd_pins>;
spi-max-frequency = <1000000>;
width = <128>;
height = <296>;
dc-gpios = <&gpio 16 0>;
reset-gpios = <&gpio 20 0>;
busy-gpios = <&gpio 21 0>;
status = "okay";
};
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
epd_pins: epd_pins {
brcm,pins = <16 20 21>; /* DC RST BUSY */
brcm,function = <1 1 0>; /* out out in */
};
};
};
DTS 工作得很好,我没想到会有任何问题。但是有一件事我不确定:
pinctrl-names = "default";
pinctrl-0 = <&epd_pins>;
我在其他带有 gpio
片段的 DT 中看到过类似的属性,但并非总是如此;有时是,有时不是。如果我注释掉这两行,似乎没有任何变化,我的驱动程序仍然可以正常工作。
我有两个问题:
- 这些
pinctrl
行的目的是什么?我知道 pin controller 子系统,但我在我的 DT 的上下文中严格要求。
- 为什么我需要声明
gpio
叠加层?无论如何,我直接从我的驱动程序代码中设置 IN 或 OUT 函数,我的 gpio 编号在 spi
overlay (dc-gpios
, reset-gpios
, busy-gpios
). 中定义
回答你的问题(假设你大致了解设备树中pinctrl线的功能)。
当您的设备被内核探测时,如果您的 dts 中有这些 pinctrl 行,那么内核会请求 pinctrl 子系统将 brcm,pins
下列出的引脚配置为它们各自的功能在 brcm,function
下定义。名为 default
的 pinctrl 状态要求由内核自动设置。您可以将其他状态定义为
pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi1_default>;
pinctrl-1 = <&spi1_sleep>;
对于其他状态,如睡眠或空闲,您必须在驱动程序通过分别调用函数 pinctrl_pm_select_sleep_state
或 pinctrl_pm_select_idle_state
更改电源管理状态时显式调用它们。如果在设备树中定义了相应的引脚状态,则只能调用这些函数,否则您可能必须手动调用 pinctrl api 进行配置。
在你的情况下没有必要,因为你说你在设备驱动程序中明确设置引脚模式和配置,那么在这种情况下,对于你的特定情况,你可能不需要这些行设备树。
我已经在 Unix Stackexchange 上问过这个问题,但它似乎是一个错误的地方来解决这类问题。 Ad rem:
我正在为 SPI 控制的显示器创建一个内核驱动程序,它旨在与 Raspberry PI 一起工作。除了 3 条 SPI 线外,显示器还有 3 条额外的控制线:BUSY、RST 和 DC。为了有可能控制这些线路,我的 DTS 必须包含额外的 GPIO 片段。
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
spidev@0 {
status = "disabled";
};
epd0: epd@0 {
compatible = "waveshare,epd";
reg = <0>;
pinctrl-names = "default";
pinctrl-0 = <&epd_pins>;
spi-max-frequency = <1000000>;
width = <128>;
height = <296>;
dc-gpios = <&gpio 16 0>;
reset-gpios = <&gpio 20 0>;
busy-gpios = <&gpio 21 0>;
status = "okay";
};
};
};
fragment@1 {
target = <&gpio>;
__overlay__ {
epd_pins: epd_pins {
brcm,pins = <16 20 21>; /* DC RST BUSY */
brcm,function = <1 1 0>; /* out out in */
};
};
};
DTS 工作得很好,我没想到会有任何问题。但是有一件事我不确定:
pinctrl-names = "default";
pinctrl-0 = <&epd_pins>;
我在其他带有 gpio
片段的 DT 中看到过类似的属性,但并非总是如此;有时是,有时不是。如果我注释掉这两行,似乎没有任何变化,我的驱动程序仍然可以正常工作。
我有两个问题:
- 这些
pinctrl
行的目的是什么?我知道 pin controller 子系统,但我在我的 DT 的上下文中严格要求。 - 为什么我需要声明
gpio
叠加层?无论如何,我直接从我的驱动程序代码中设置 IN 或 OUT 函数,我的 gpio 编号在spi
overlay (dc-gpios
,reset-gpios
,busy-gpios
). 中定义
回答你的问题(假设你大致了解设备树中pinctrl线的功能)。
当您的设备被内核探测时,如果您的 dts 中有这些 pinctrl 行,那么内核会请求 pinctrl 子系统将
brcm,pins
下列出的引脚配置为它们各自的功能在brcm,function
下定义。名为default
的 pinctrl 状态要求由内核自动设置。您可以将其他状态定义为pinctrl-names = "default", "sleep";
pinctrl-0 = <&spi1_default>;
pinctrl-1 = <&spi1_sleep>;
对于其他状态,如睡眠或空闲,您必须在驱动程序通过分别调用函数
pinctrl_pm_select_sleep_state
或pinctrl_pm_select_idle_state
更改电源管理状态时显式调用它们。如果在设备树中定义了相应的引脚状态,则只能调用这些函数,否则您可能必须手动调用 pinctrl api 进行配置。在你的情况下没有必要,因为你说你在设备驱动程序中明确设置引脚模式和配置,那么在这种情况下,对于你的特定情况,你可能不需要这些行设备树。