问题
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