aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpio
diff options
context:
space:
mode:
authorPatrick Delaunay2020-01-13 11:35:07 +0100
committerTom Rini2020-04-16 23:06:54 -0400
commit477ca57b9a53120a14bdca356612fce15211345d (patch)
tree8ede882b3395eda2e70c38d8b4ad1b1772e6bc7b /drivers/gpio
parent695e5fd5469ab052126c4cb30c4d26e6058de067 (diff)
gpio: add support of new GPIO direction flag
This commit manages the new dir flags that can be used in gpio specifiers to indicate the pull-up or pull-down resistor configuration for output gpio (GPIO_PULL_UP, GPIO_PULL_DOWN) or the Open Drain/Open Source configuration for input gpio (GPIO_OPEN_DRAIN, GPIO_OPEN_SOURCE). These flags are already supported in Linux kernel in gpio lib. This patch only parse and save the direction flags in GPIO descriptor (desc->flags), it prepares the introduction of new ops to manage them. The GPIO uclass supports new GPIO flags from device-tree (GPIO_XXX define in include/dt-bindings/gpio/gpio.h) and translate them in the dir flags (GPIOD_XXX): - GPIO_PULL_UP => GPIOD_PULL_UP - GPIO_PULL_DOWN => GPIOD_PULL_DOWN - GPIO_OPEN_DRAIN => GPIOD_OPEN_DRAIN - GPIO_OPEN_SOURCE => GPIOD_OPEN_SOURCE This patch also adds protection in the check_dir_flags function for new invalid configuration of the dir flags. Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-uclass.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 9550e45e6cd..25263994d24 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -145,6 +145,24 @@ int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
if (args->args[1] & GPIO_ACTIVE_LOW)
desc->flags |= GPIOD_ACTIVE_LOW;
+ /*
+ * need to test 2 bits for gpio output binding:
+ * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
+ * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
+ */
+ if (args->args[1] & GPIO_SINGLE_ENDED) {
+ if (args->args[1] & GPIO_LINE_OPEN_DRAIN)
+ desc->flags |= GPIOD_OPEN_DRAIN;
+ else
+ desc->flags |= GPIOD_OPEN_SOURCE;
+ }
+
+ if (args->args[1] & GPIO_PULL_UP)
+ desc->flags |= GPIOD_PULL_UP;
+
+ if (args->args[1] & GPIO_PULL_DOWN)
+ desc->flags |= GPIOD_PULL_DOWN;
+
return 0;
}
@@ -521,6 +539,18 @@ static int check_dir_flags(ulong flags)
return -EINVAL;
}
+ if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
+ log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
+ __func__, flags);
+ return -EINVAL;
+ }
+
+ if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
+ log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
+ __func__, flags);
+ return -EINVAL;
+ }
+
return 0;
}