[openwrt/openwrt] linux/named-gpio-export: add support for OPEN_DRAIN and OPEN_SOURCE flag

LEDE Commits lede-commits at lists.infradead.org
Tue Aug 15 07:08:19 PDT 2023


hauke pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/0af88d2512b94bb0e3d81058beaa220448e46119

commit 0af88d2512b94bb0e3d81058beaa220448e46119
Author: Martin Schiller <ms at dev.tdt.de>
AuthorDate: Fri Aug 4 12:59:03 2023 +0200

    linux/named-gpio-export: add support for OPEN_DRAIN and OPEN_SOURCE flag
    
    This change makes it possible to use the GPIO_OPEN_DRAIN /
    GPIO_OPEN_SOURCE Flags when exporting GPIOs via dts.
    
    We need to emulate the open-source or open-drain functionalities for the
    initial value, because the used functions (gpiod_direction_output_raw)
    do not take this into account.
    
    Signed-off-by: Martin Schiller <ms at dev.tdt.de>
---
 .../800-GPIO-add-named-gpio-exports.patch          | 38 +++++++++++++++++++---
 .../hack-6.1/800-GPIO-add-named-gpio-exports.patch | 38 +++++++++++++++++++---
 2 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch
index 0a2c82cacb..f27b7ef9de 100644
--- a/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch
+++ b/target/linux/generic/hack-5.15/800-GPIO-add-named-gpio-exports.patch
@@ -15,7 +15,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
  
  #include "gpiolib.h"
  #include "gpiolib-of.h"
-@@ -1059,3 +1061,72 @@ void of_gpio_dev_init(struct gpio_chip *
+@@ -1059,3 +1061,100 @@ void of_gpio_dev_init(struct gpio_chip *
  	else
  		gc->of_node = gdev->dev.of_node;
  }
@@ -47,6 +47,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +			max_gpio = of_gpio_count(cnp);
 +
 +		for (i = 0; i < max_gpio; i++) {
++			struct gpio_desc *desc;
 +			unsigned flags = 0;
 +			enum of_gpio_flags of_flags;
 +
@@ -54,17 +55,44 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +			if (!gpio_is_valid(gpio))
 +				return gpio;
 +
-+			if (of_flags == OF_GPIO_ACTIVE_LOW)
++			if (of_flags & OF_GPIO_ACTIVE_LOW)
 +				flags |= GPIOF_ACTIVE_LOW;
 +
-+			if (!of_property_read_u32(cnp, "gpio-export,output", &val))
-+				flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-+			else
++			if (!of_property_read_u32(cnp, "gpio-export,output", &val)) {
++				if (of_flags & OF_GPIO_SINGLE_ENDED) {
++					/*
++					 * As gpiod_direction_output_raw() is used, we
++					 * need to emulate open drain or open source here.
++					 */
++					if (of_flags & OF_GPIO_OPEN_DRAIN) {
++						flags |= GPIOF_OPEN_DRAIN;
++						flags |= val ? GPIOF_IN : GPIOF_OUT_INIT_LOW;
++					} else {
++						flags |= GPIOF_OPEN_SOURCE;
++						flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_IN;
++					}
++				} else {
++					flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++				}
++			} else {
 +				flags |= GPIOF_IN;
++			}
 +
 +			if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
 +				continue;
 +
++			/*
++			 * When emulating open-source or open-drain functionalities by not
++			 * actively driving the line (setting mode to input) we still need to
++			 * set the IS_OUT flag or otherwise we won't be able to set the line
++			 * value anymore.
++			 */
++			if ((flags & GPIOF_IN) &&
++			    ((flags & GPIOF_OPEN_DRAIN) || (flags & GPIOF_OPEN_SOURCE))) {
++				desc = gpio_to_desc(gpio);
++				set_bit(FLAG_IS_OUT, &desc->flags);
++			}
++
 +			dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
 +			gpio_export_with_name(gpio, dmc, name);
 +			nb++;
diff --git a/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch b/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch
index 658d9c3806..ba5351275d 100644
--- a/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch
+++ b/target/linux/generic/hack-6.1/800-GPIO-add-named-gpio-exports.patch
@@ -15,7 +15,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
  
  #include "gpiolib.h"
  #include "gpiolib-of.h"
-@@ -1030,3 +1032,72 @@ void of_gpio_dev_init(struct gpio_chip *
+@@ -1030,3 +1032,100 @@ void of_gpio_dev_init(struct gpio_chip *
  	else
  		gc->of_node = gdev->dev.of_node;
  }
@@ -47,6 +47,7 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +			max_gpio = of_gpio_count(cnp);
 +
 +		for (i = 0; i < max_gpio; i++) {
++			struct gpio_desc *desc;
 +			unsigned flags = 0;
 +			enum of_gpio_flags of_flags;
 +
@@ -54,17 +55,44 @@ Signed-off-by: John Crispin <blogic at openwrt.org>
 +			if (!gpio_is_valid(gpio))
 +				return gpio;
 +
-+			if (of_flags == OF_GPIO_ACTIVE_LOW)
++			if (of_flags & OF_GPIO_ACTIVE_LOW)
 +				flags |= GPIOF_ACTIVE_LOW;
 +
-+			if (!of_property_read_u32(cnp, "gpio-export,output", &val))
-+				flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
-+			else
++			if (!of_property_read_u32(cnp, "gpio-export,output", &val)) {
++				if (of_flags & OF_GPIO_SINGLE_ENDED) {
++					/*
++					 * As gpiod_direction_output_raw() is used, we
++					 * need to emulate open drain or open source here.
++					 */
++					if (of_flags & OF_GPIO_OPEN_DRAIN) {
++						flags |= GPIOF_OPEN_DRAIN;
++						flags |= val ? GPIOF_IN : GPIOF_OUT_INIT_LOW;
++					} else {
++						flags |= GPIOF_OPEN_SOURCE;
++						flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_IN;
++					}
++				} else {
++					flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
++				}
++			} else {
 +				flags |= GPIOF_IN;
++			}
 +
 +			if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
 +				continue;
 +
++			/*
++			 * When emulating open-source or open-drain functionalities by not
++			 * actively driving the line (setting mode to input) we still need to
++			 * set the IS_OUT flag or otherwise we won't be able to set the line
++			 * value anymore.
++			 */
++			if ((flags & GPIOF_IN) &&
++			    ((flags & GPIOF_OPEN_DRAIN) || (flags & GPIOF_OPEN_SOURCE))) {
++				desc = gpio_to_desc(gpio);
++				set_bit(FLAG_IS_OUT, &desc->flags);
++			}
++
 +			dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
 +			gpio_export_with_name(gpio, dmc, name);
 +			nb++;




More information about the lede-commits mailing list