How do Linux GPIO numbers get their values?

喜欢而已 提交于 2020-06-28 18:09:28

问题


I am trying to understand how the Linux GPIO numbers get their values. e.g. GPIO mapping for Joule.

I tried reading linux documentation on Pinctrl Subsystem and also looked at the code of GPIO driver being used in Intel Joule : https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/intel/pinctrl-broxton.c

However going this way looks very platform-specific. I am looking for some generic industry standard. Please help or please direct me to some good article.


回答1:


First of all, one has to get the difference between Global System GPIO number (GSGN) and relative to the certain GPIO controller. Earlier, before the era of GPIO descriptors, the GSGN had been used. After switching to the descriptor scheme the numbering scheme moves from (semi-)static GSGN to dynamic one and thus makes nonsense to the user. Instead the label of the pin, if any, or a pair of GPIO controller handle with a number relative to it became in use. This is being dictated by the resource providers, such as ACPI and Device Tree. If, by some reason, user wants to get the pair of the controller and relative number, the libgpiod library and tools gives the possibility to achieve this.

So, the link to Joule GPIO numbering scheme is really fragile, users are not suppose to know the GSGN. There are ways how to get the controller and relative number on a running system. But usually it's all related to the driver and ACPI tables and doesn't require any user involvement.

Example:

Take into consideration the pin UART_1_TXD (by some reason it's named in that document wrongly, should be LPSS_UART1_TXD). According to pinctrl-broxton.c this is pin 43 on a GPIO controller with ACPI _HID INT34D1 and _UID 1.

List all enumerated GPIO controllers (optional step):

# 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)

Find one with _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)

So, the interesting pair is: gpiochip0 43.

In the actual resource provider it will look like this (taken from meta-acpi project):

...
*   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
            }
...

Here you see the reference to the Device object thru a full path, i.e. \_SB.GPO2.

You may find more examples in meta-acpi project.

If by any weird case user really wants a non-sense number, this is the way:

# 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

More details about GPIO library and subsystem can be found in gpio.txt.



来源:https://stackoverflow.com/questions/55532410/how-do-linux-gpio-numbers-get-their-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!