Controlling GPIO in Linux

This application note shows how to control STM32MP1 GPIOs in Linux.

1. Kernel sys Interface to GPIO is Deprecated

Starting with Linux kernel version 6.0, the /sys/class/gpio interface is removed from the kernel. The libgpiod3 library and utilities from the libgpiod-tools package should be used to configure and control processor's GPIOs from the user space.

2. Changes to the Kernel Configuration

No changes in the kernel configuration is required to control GPIOs from the user space in Linux.

It must be ensured though that the GPIO pin to be controlled from the user space is not assigned to any driver in Linux. The GPIO assignments for all the available pins can be found out using the gpioinfo utility in the Linux command line and from the /sys/kernel/debug/gpio file:

root@stm32mp15-som:~# gpioinfo gpiochip0 - 16 lines: line 0: "PA0" input line 1: "PA1" input consumer="kernel" line 2: "PA2" input consumer="kernel" line 10: "PD10" output consumer="regulators:sub_nrst-regulator" line 11: "PD11" output consumer="regulators:eth_reg" line 12: "PD12" input line 13: "PD13" output consumer="panel-backlight" line 14: "PD14" output consumer="regulators:usb-host-regulator" line 15: "PD15" input root@stm32mp15-som:~# cat /sys/kernel/debug/gpio gpiochip0: GPIOs 0-15, parent: platform/soc:pinctrl@50002000, GPIOA: gpio-0 (PA0 ) gpio-1 (PA1 ) gpio-2 (PA2 ) gpio-58 (PD10 |regulators:sub_nrst-) out hi gpio-59 (PD11 |regulators:eth_reg ) out hi gpio-60 (PD12 ) gpio-61 (PD13 |panel-backlight ) out hi gpio-62 (PD14 |regulators:usb-host-) out hi

3. Testing GPIO

For the User Push Button 1 the specific pin is MCO1 (PI11). The signal is pulled up when the button is not pressed and is driven low when the button is pressed. The gpioget command is used to print the state of a GPIO line. The command may be supplied with the active-low parameter if the requested signal is active low, as, for example, the line for the User Push Button 1. So, if the command is issued when the button is not pressed, the output should indicate that the line is not active:

root@stm32mp15-som:~# gpioget --active-low PI11 "PI11"=inactive

If the command issued with the button pressed, the output should indicate that the line is active:

root@stm32mp15-som:~# gpioget --active-low PI11 "PI11"=active

After the button is released, the line becomes inactive again:

For the User LED 1 the specific pin is A13. Now run the following shell command to turn the User LED 1 on and off at a 1Hz frequency:

4. Alternative Ways to Access GPIO

In Linux, you may access GPIOs using different approaches, not only the ones described in this application note above. Here are some external links that might be usefull if you decide to try an alternative approach.

ITo work with GPIOs from the user space, there are the following possibilities:

These drivers allow to use different GPIO-related mechanisms already implemented in Linux. For example, you may simply force a LED connected to GPIO output to blink with the specified frequency, or simply force input subsystem to generate a some-button-pressed event on changing GPIO input.

5. Controlling GPIO from Kernel

The following article describes accessing GPIOs from the kernel context:
GPIO in the kernel: an introduction [LWN.net]

As an example of a device driver that makes use of the kernel GPIO APIs, refer to the device driver for the Goodix touch-screen controller. The device driver configures and uses a GPIO input for interrupt.

The relevant device tree file is linux-stm32mp/arch/arm/boot/dts/stm32mp157a-som.dts. Refer specifically to the goodix_ts@14 node and the goodix,irq-gpio property.

The device driver itself is linux/drivers/input/touchscreen/goodix.c. Refer specifically to the goodix_get_gpio_config(), devm_request_threaded_irq(), gpiod_direction_output(), and gpiod_direction_input() functions.