on 2020-05-28 02:12 AM
Background
Two frameworks are available to configure and control a given pin: pinctrl and GPIOLib. They are selected according to pin usage:
· pinctrl is used mainly when a pin is controlled by an internal peripheral. Pinctrl handles the pin configuration and allows assigning a specific feature to a pin. The Pinctrl overview article provides an overview of the pinctrl framework.
· GPIOLib is used when a pin (generic GPIO) needs to be controlled dynamically at runtime (GPIO). GPIOLib is used to control a pin by software. The GPIOLib overview article provides an overview of the GPIOLib framework.
Today GPIO dynamic reconfiguration of pinctrl with GPIO Sysfs (/sys/class/gpio/gpioxx) is deprecated, alternative now is GPIOlib
Answer
For this the user has to add a GPIO property in node of the existing device driver (or create a st,dummy device driver as in example below) to initialize and control the “generic GPIO” with the GPIOLib bending.
-> https://wiki.st.com/stm32mpu/wiki/GPIO_device_tree_configuration
Ex: with "foo" device driver that initializes a GPIO with internal Pull-up enabled,
in foo device driver code :
gpiod_get(&pdev->dev, "function", GPIOD_OUT);
Device tree :
foo_device {
...
function-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH| GPIO_PULL_UP>;
...
};
Examples GPIO Lib usage :
https://wiki.st.com/stm32mpu/wiki/How_to_control_a_GPIO_in_userspace
https://wiki.st.com/stm32mpu/wiki/How_to_control_a_GPIO_in_kernel_space
In OpenSTLinux Ecosystem <2.0.0 it is not possible to use as above GPIOLib to get initialized a GPIO with an internal pull-up/pull-down with flags GPIO_PULL_UP or GPIO_PULL_DOWN).
Instead we use pinctrl bindings and pintcrl with strict mode disabled (strict mode is to forbid the configuration of a pin at 2 different places (to avoid dual allocation).
At probe a dummy driver will initialize the GPIO with the bias (internal pull up/down) and GPIOLib will allow to change the GPIO output state to high or low
Find an example done on DK2 board with GPIOA14
workspace/sources/linux-stm32mp/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
soc {
pinctrl: pin-controller@50002000 {
keyleds_pins_a: keyleds_pins_a-0 {
pins {
pinmux = <STM32_PINMUX('A', 14, GPIO)>;
bias-pull-up;
drive-push-pull;
slew-rate = <0>;
};
};
workspace/sources/linux-stm32mp/arch/arm/boot/dts/stm32mp157a-dk1.dts
/ {
ledpa4 {
compatible = "st,dummy";
pinctrl-names = "default";
pinctrl-0 = <&keyleds_pins_a>;
status = "okay";
};
B Create dumy driver
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
static int gpio_init_probe(struct platform_device *pdev)
{
printk(KERN_INFO "GPIO example init\n");
return(0);
}
static int gpio_exit_remove(struct platform_device *pdev)
{
printk(KERN_INFO "GPIO example exit\n");
return(0);
}
/* this structure does the matching with the device tree */
/* if it does not match the compatible field of DT, nothing happens */
static struct of_device_id dummy_match[] = {
{.compatible = "st,dummy"},
{/* end node */}
};
static struct platform_driver dummy_driver = {
.probe = gpio_init_probe,
.remove = gpio_exit_remove,
.driver = {
.name = "dummy_driver",
.owner = THIS_MODULE,
.of_match_table = dummy_match,
}
};
module_platform_driver(dummy_driver);
MODULE_AUTHOR("STMicroelectronics");
MODULE_DESCRIPTION("Gpio example with pinctrl config");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:dummy_driver");
***
after boot
***
COMMAND : more /sys/kernel/debug/pinctrl/soc\:pin-controller@50002000/pin
pin 14 (PA14): input - high - floating
COMMAND : gpioinfo gpiochip0
line 14: unnamed unused input active-high
***
activation led via GPIOlib :
COMMAND : gpioset gpiochip0 14=0 the greend led is ON on the board
***
pin 14 (PA14): output - low - push pull - floating - low speed
Reg: : MODE -OD(or ID) - OTYPE - PUPD - OSPEED
line 14: unnamed unused output active-high
****
probe : modprobe dummy_device
****
pin 14 (PA14): input - high - pull up
line 14: unnamed unused output active-high
***
activation led via GPIOlib :
COMMAND : gpioset gpiochip0 14=0 the greend led is ON on the board
***
pin 14 (PA14): output - low - push pull - pull up - low speed
line 14: unnamed unused output active-high
(To disable strict mode:
workspace/sources/linux-stm32mp/drivers/pinctrl/stm32/pinctrl-stm32.c
static const struct pinmux_ops stm32_pmx_ops = {
.get_functions_count = stm32_pmx_get_funcs_cnt,
.get_function_name = stm32_pmx_get_func_name,
.get_function_groups = stm32_pmx_get_func_groups,
.set_mux = stm32_pmx_set_mux,
.gpio_set_direction = stm32_pmx_gpio_set_direction,
/* PATCH GPIOLib */
.strict = false,
/* .strict = true,*/
};
)