cancel
Showing results for 
Search instead for 
Did you mean: 

FAQ: STM32MP1 How to get initialized a 'generic GPIO' (to control a LED) with a pull-up/pull down ?

How to configure and drive at run time a  "generic" GPIO a standalone GPIO (not connected to peripheral) ?
How to configure an internal pull-up for LED for example.
 

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,*/

};

)

Version history
Last update:
‎2020-05-28 02:12 AM