gpio: search for gpio label if gpio is not found through bank name
authorHeiko Schocher <hs@denx.de>
Fri, 22 May 2020 09:08:59 +0000 (11:08 +0200)
committerTom Rini <trini@konsulko.com>
Tue, 7 Jul 2020 22:23:37 +0000 (18:23 -0400)
dm_gpio_lookup_name() searches for a gpio through
the bank name. But we have also gpio labels, and it
makes sense to search for a gpio also in the labels
we have defined, if no gpio is found through the
bank name definition.

This is useful for example if you have a wp pin on
different gpios on different board versions.

If dm_gpio_lookup_name() searches also for the gpio labels,
you can give the gpio an unique label name and search
for this label, and do not need to differ between
board revisions.

Signed-off-by: Heiko Schocher <hs@denx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
[trini: Don't enable by default]
Signed-off-by: Tom Rini <trini@konsulko.com>
drivers/gpio/Kconfig
drivers/gpio/gpio-uclass.c
test/dm/gpio.c

index af608b7..0e8ad95 100644 (file)
@@ -46,6 +46,26 @@ config GPIO_HOG
          is a mechanism providing automatic GPIO request and config-
          uration as part of the gpio-controller's driver probe function.
 
+config DM_GPIO_LOOKUP_LABEL
+       bool "Enable searching for gpio labelnames"
+       depends on DM_GPIO
+       help
+         This option enables searching for gpio names in
+         the defined gpio labels, if the search for the
+         gpio bank name failed. This makes sense if you use
+         different gpios on different hardware versions
+         for the same functionality in board code.
+
+config SPL_DM_GPIO_LOOKUP_LABEL
+       bool "Enable searching for gpio labelnames"
+       depends on DM_GPIO && SPL_DM && SPL_GPIO_SUPPORT
+       help
+         This option enables searching for gpio names in
+         the defined gpio labels, if the search for the
+         gpio bank name failed. This makes sense if you use
+         different gpios on different hardware versions
+         for the same functionality in board code.
+
 config ALTERA_PIO
        bool "Altera PIO driver"
        depends on DM_GPIO
index f016532..ab17fa8 100644 (file)
@@ -68,6 +68,45 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
        return ret ? ret : -ENOENT;
 }
 
+#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
+/**
+ * dm_gpio_lookup_label() - look for name in gpio device
+ *
+ * search in uc_priv, if there is a gpio with labelname same
+ * as name.
+ *
+ * @name:      name which is searched
+ * @uc_priv:   gpio_dev_priv pointer.
+ * @offset:    gpio offset within the device
+ * @return:    0 if found, -ENOENT if not.
+ */
+static int dm_gpio_lookup_label(const char *name,
+                               struct gpio_dev_priv *uc_priv, ulong *offset)
+{
+       int len;
+       int i;
+
+       *offset = -1;
+       len = strlen(name);
+       for (i = 0; i < uc_priv->gpio_count; i++) {
+               if (!uc_priv->name[i])
+                       continue;
+               if (!strncmp(name, uc_priv->name[i], len)) {
+                       *offset = i;
+                       return 0;
+               }
+       }
+       return -ENOENT;
+}
+#else
+static int
+dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
+                    ulong *offset)
+{
+       return -ENOENT;
+}
+#endif
+
 int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
 {
        struct gpio_dev_priv *uc_priv = NULL;
@@ -96,6 +135,13 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
                        if (!strict_strtoul(name + len, 10, &offset))
                                break;
                }
+
+               /*
+                * if we did not found a gpio through its bank
+                * name, we search for a valid gpio label.
+                */
+               if (!dm_gpio_lookup_label(name, uc_priv, &offset))
+                       break;
        }
 
        if (!dev)
index ecba566..fcee1fe 100644 (file)
@@ -132,6 +132,15 @@ static int dm_test_gpio(struct unit_test_state *uts)
        ut_assertok(dm_gpio_set_value(desc, 0));
        ut_asserteq(0, dm_gpio_get_value(desc));
 
+       /* Check if lookup for labels work */
+       ut_assertok(gpio_lookup_name("hog_input_active_low", &dev, &offset,
+                                    &gpio));
+       ut_asserteq_str(dev->name, "base-gpios");
+       ut_asserteq(0, offset);
+       ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 0, gpio);
+       ut_assert(gpio_lookup_name("hog_not_exist", &dev, &offset,
+                                  &gpio));
+
        return 0;
 }
 DM_TEST(dm_test_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);