Linux GPIO号如何获得其值?

时间:2019-04-05 09:37:05

标签: linux-kernel linux-device-driver gpio

我试图了解Linux GPIO数字如何获得其值。 例如GPIO mapping for Joule

我尝试阅读Pinctrl子系统上的linux文档,还查看了Intel Joule中使用的GPIO驱动程序的代码: https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/intel/pinctrl-broxton.c

但是,这种方式看起来非常特定于平台。我正在寻找一些通用行业标准。请帮忙,或引导我读一些好文章。

1 个答案:

答案 0 :(得分:2)

首先,必须获得全局系统GPIO编号(GSGN)与相对于特定GPIO控制器的区别。早在GPIO描述符时代之前,就已经使用GSGN。在切换到描述符方案之后,编号方案从(半)静态GSGN移到了动态GSGN,因此对用户来说毫无意义。取而代之的是使用了该引脚的标签(如果有)或一对带有数字相对的GPIO控制器手柄。这由资源提供者(例如ACPI和设备树)决定。如果由于某种原因,用户希望获得一对控制器和相对编号,则libgpiod库和工具可以实现这一点。

因此,到焦耳GPIO编号方案的链接确实很脆弱,用户不应该知道GSGN。有几种方法可以获取正在运行的系统上的控制器和相对编号。但是通常它们都与驱动程序和ACPI表相关,并且不需要任何用户参与。

示例:

请考虑引脚UART_1_TXD(由于某种原因,该引脚在该文档中的命名错误,应为LPSS_UART1_TXD)。根据 pinctrl-broxton.c ,这是GPIO控制器上具有ACPI _HID INT34D1 和_UID 1 的引脚43。

列出所有枚举的GPIO控制器(可选步骤):

# gpiodetect 
gpiochip0 [INT34D1:00] (83 lines)
gpiochip1 [INT34D1:01] (72 lines)
gpiochip2 [INT34D1:02] (42 lines)
gpiochip3 [INT34D1:03] (31 lines)
gpiochip4 [INT34D1:04] (20 lines)

使用_UID 1 查找一个:

# grep -w 1 /sys/bus/acpi/devices/INT34D1\:0*/uid
/sys/bus/acpi/devices/INT34D1:00/uid:1

# gpiodetect | grep -w INT34D1:00
gpiochip0 [INT34D1:00] (83 lines)

因此,有趣的对是:gpiochip0 43

在实际的资源提供程序中,它看起来像这样(摘自meta-acpi项目):

...
*   pin name           pin number   led
*   -----------------------------------------
*   ISH_GPIO_0_LS      35           heartbeat
*   ISH_GPIO_1_LS      33           sd-card
*   ISH_GPIO_2_LS      31           wifi
*   ISH_GPIO_3_LS      29           led-3
...
            GpioIo (
...
                "\\_SB.GPO2",               // GPIO controller
                0)                          // Must be 0
            {
                22,                         // ISH_GPIO_0_LS
                23,                         // ISH_GPIO_1_LS
                24,                         // ISH_GPIO_2_LS
                25                          // ISH_GPIO_3_LS
            }
...

在这里您看到通过完整路径(即 \ _ SB.GPO2 )对 Device 对象的引用。

您可能会在meta-acpi项目中找到更多示例。

如果有任何奇怪的情况,用户确实想要一个无意义的数字,可以这样:

# mount -t debugfs none /sys/kernel/debug/

# cat /sys/kernel/debug/pinctrl/INT34D1\:00/gpio-ranges 
GPIO ranges handled:
0: INT34D1:00 GPIOS [429 - 460] PINS [0 - 31]
32: INT34D1:00 GPIOS [461 - 492] PINS [32 - 63]
64: INT34D1:00 GPIOS [493 - 511] PINS [64 - 82]

# echo $((43-32+461))
472

有关GPIO库和子系统的更多详细信息,请参见gpio.txt