summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2020-10-14 13:58:40 -0600
committerCommit Bot <commit-bot@chromium.org>2020-10-21 21:24:14 +0000
commitb81af1233e23497ca8317f2669947398d0142e12 (patch)
treefb70584fedaa44810587cc11c888de7def9893dc
parent65d7595dfe16963f31fb057ca93ba2f7334ecb0a (diff)
downloadchrome-ec-b81af1233e23497ca8317f2669947398d0142e12.tar.gz
zephyr: add initial gpio shim
Add the gpioget and gpioset commands to zephyr build. This requires a minimum set of platform/ec gpio_ API functions. Add the minimum set of gpio_ functions. More can be added later depending on future uses BRANCH=none BUG=b:169935802 TEST=verify gpioget and gpioset console command work on volteer TEST=verify that posix-ec compiles without any named_gpios in DT Change-Id: Ie6f0b4505aa17c50c01b71fc4ea5b59393f39fce Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2488141 Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Commit-Queue: Jack Rosenthal <jrosenth@chromium.org>
-rw-r--r--include/gpio.h65
-rw-r--r--zephyr/CMakeLists.txt1
-rw-r--r--zephyr/shim/include/board.h9
-rw-r--r--zephyr/shim/include/gpio_signal.h29
-rw-r--r--zephyr/shim/src/CMakeLists.txt1
-rw-r--r--zephyr/shim/src/gpio.c130
-rw-r--r--zephyr/shim/src/util.c13
7 files changed, 232 insertions, 16 deletions
diff --git a/include/gpio.h b/include/gpio.h
index 92c851f91a..3fa091f4bd 100644
--- a/include/gpio.h
+++ b/include/gpio.h
@@ -11,24 +11,59 @@
#include "common.h"
#include "console.h"
-/* Flag definitions for gpio_info and gpio_alt_func */
+
+/*
+ * If compiling with Zephyr, include the GPIO_ definitions to deal with name
+ * conflicts
+ */
+#ifdef CONFIG_ZEPHYR
+#include <drivers/gpio.h>
+
+/* Validate that Zephyr's definition are the same for overlapping defines */
+#if GPIO_OPEN_DRAIN != (BIT(1) | BIT(2))
+#error GPIO_OPEN_DRAIN values are not the same!
+#elif GPIO_PULL_UP != BIT(4)
+#error GPIO_PULL_UP values are not the same!
+#elif GPIO_PULL_DOWN != BIT(5)
+#error GPIO_PULL_DOWN values are not the same!
+#elif GPIO_INPUT != BIT(8)
+#error GPIO_INPUT values are not the same!
+#elif GPIO_OUTPUT != BIT(9)
+#error GPIO_PULL_DOWN values are not the same!
+#endif
+
+/* Otherwise define overlapping GPIO_ flags ourselves */
+#else /* !CONFIG_ZEPHYR */
+#define GPIO_OPEN_DRAIN (BIT(1) | BIT(2)) /* Output type is open-drain */
+#define GPIO_PULL_UP BIT(4) /* Enable on-chip pullup */
+#define GPIO_PULL_DOWN BIT(5) /* Enable on-chip pulldown */
+#define GPIO_INPUT BIT(8) /* Input */
+#define GPIO_OUTPUT BIT(9) /* Output */
+#endif /* CONFIG_ZEPHYR */
+
+/*
+ * All flags supported by gpio_info expect GPIO_ANALOG
+ *
+ * Only 4 flags are supported by gpio_alt_func:
+ * GPIO_OPEN_DRAIN
+ * GPIO_PULL_UP
+ * GPIO_PULL_DOWN
+ * GPIO_PULL_ANALOG
+ */
#define GPIO_FLAG_NONE 0 /* No flag needed, default setting */
-/* The following are valid for both gpio_info and gpio_alt_func: */
-#define GPIO_OPEN_DRAIN BIT(0) /* Output type is open-drain */
-#define GPIO_PULL_UP BIT(1) /* Enable on-chip pullup */
-#define GPIO_PULL_DOWN BIT(2) /* Enable on-chip pulldown */
-/* The following are valid for gpio_alt_func only */
-#define GPIO_ANALOG BIT(3) /* Set pin to analog-mode */
-/* The following are valid for gpio_info only */
-#define GPIO_INPUT BIT(4) /* Input */
-#define GPIO_OUTPUT BIT(5) /* Output */
+#define GPIO_ANALOG BIT(0) /* Set pin to analog-mode */
+/* GPIO_OPEN_DRAIN BIT(1) | BIT(2) Output type is open-drain */
+#define GPIO_DEFAULT BIT(3) /* Don't set up on boot */
+/* GPIO_PULL_UP BIT(4) Enable on-chip pullup */
+/* GPIO_PULL_DOWN BIT(5) Enable on-chip pulldown */
#define GPIO_LOW BIT(6) /* If GPIO_OUTPUT, set level low */
#define GPIO_HIGH BIT(7) /* If GPIO_OUTPUT, set level high */
-#define GPIO_INT_F_RISING BIT(8) /* Interrupt on rising edge */
-#define GPIO_INT_F_FALLING BIT(9) /* Interrupt on falling edge */
-#define GPIO_INT_F_LOW BIT(11) /* Interrupt on low level */
-#define GPIO_INT_F_HIGH BIT(12) /* Interrupt on high level */
-#define GPIO_DEFAULT BIT(13) /* Don't set up on boot */
+/* GPIO_INPUT BIT(8) Input */
+/* GPIO_OUTPUT BIT(9) Output */
+#define GPIO_INT_F_RISING BIT(10) /* Interrupt on rising edge */
+#define GPIO_INT_F_FALLING BIT(11) /* Interrupt on falling edge */
+#define GPIO_INT_F_LOW BIT(12) /* Interrupt on low level */
+#define GPIO_INT_F_HIGH BIT(13) /* Interrupt on high level */
#define GPIO_INT_DSLEEP BIT(14) /* Interrupt in deep sleep */
#define GPIO_INT_SHARED BIT(15) /* Shared among multiple pins */
#define GPIO_SEL_1P8V BIT(16) /* Support 1.8v */
diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt
index 60eca34519..cac731a2bc 100644
--- a/zephyr/CMakeLists.txt
+++ b/zephyr/CMakeLists.txt
@@ -37,3 +37,4 @@ add_subdirectory_ifdef(CONFIG_PLATFORM_EC "shim/src")
# Shimmed modules
zephyr_sources_ifdef(CONFIG_PLATFORM_EC "${PLATFORM_EC}/common/base32.c")
zephyr_sources_ifdef(CONFIG_PLATFORM_EC_TIMER "${PLATFORM_EC}/common/timer.c")
+zephyr_sources_ifdef(CONFIG_SHELL "${PLATFORM_EC}/common/gpio_commands.c")
diff --git a/zephyr/shim/include/board.h b/zephyr/shim/include/board.h
index 01f9344a8a..62bb1b23e2 100644
--- a/zephyr/shim/include/board.h
+++ b/zephyr/shim/include/board.h
@@ -6,6 +6,13 @@
#ifndef __BOARD_H
#define __BOARD_H
-/* Intentionally empty. */
+#include <devicetree.h>
+
+/* Included shimed version of gpio signal. */
+#include <gpio_signal.h>
+/* Include board specific gpio mapping/aliases if named_pgios node exists */
+#if DT_NODE_EXISTS(DT_PATH(named_gpios))
+#include <gpio_map.h>
+#endif
#endif /* __BOARD_H */
diff --git a/zephyr/shim/include/gpio_signal.h b/zephyr/shim/include/gpio_signal.h
new file mode 100644
index 0000000000..698ef126bb
--- /dev/null
+++ b/zephyr/shim/include/gpio_signal.h
@@ -0,0 +1,29 @@
+/* Copyright 2020 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef __CROS_EC_GPIO_SIGNAL_H
+#define __CROS_EC_GPIO_SIGNAL_H
+
+#include <devicetree.h>
+
+#define GPIO_SIGNAL(id) _CONCAT(GPIO_, id)
+#define GPIO_SIGNAL_WITH_COMMA(id) GPIO_SIGNAL(id),
+enum gpio_signal {
+#if DT_NODE_EXISTS(DT_PATH(named_gpios))
+ DT_FOREACH_CHILD(DT_PATH(named_gpios), GPIO_SIGNAL_WITH_COMMA)
+#endif
+ GPIO_COUNT
+};
+#undef GPIO_SIGNAL_WITH_COMMA
+
+/** @brief Converts a node identifier under named gpios to enum
+ *
+ * Converts the specified node identifier name, which should be nested under
+ * the named_gpios node, into the correct enum gpio_signal that can be used
+ * with platform/ec gpio API
+ */
+#define NAMED_GPIO(name) GPIO_SIGNAL(DT_PATH(named_gpios, name))
+
+#endif /* __CROS_EC_GPIO_SIGNAL_H */
diff --git a/zephyr/shim/src/CMakeLists.txt b/zephyr/shim/src/CMakeLists.txt
index f87b114949..b56557deb9 100644
--- a/zephyr/shim/src/CMakeLists.txt
+++ b/zephyr/shim/src/CMakeLists.txt
@@ -4,4 +4,5 @@
zephyr_sources(console.c)
zephyr_sources(util.c)
+zephyr_sources(gpio.c)
zephyr_sources_ifdef(CONFIG_PLATFORM_EC_TIMER hwtimer.c)
diff --git a/zephyr/shim/src/gpio.c b/zephyr/shim/src/gpio.c
new file mode 100644
index 0000000000..96d982052c
--- /dev/null
+++ b/zephyr/shim/src/gpio.c
@@ -0,0 +1,130 @@
+/* Copyright 2020 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <device.h>
+#include <gpio.h>
+#include <init.h>
+#include <kernel.h>
+#include <logging/log.h>
+
+LOG_MODULE_REGISTER(gpio_shim, LOG_LEVEL_ERR);
+
+/*
+ * Static information about each GPIO that is configured in the named_gpios
+ * device tree node.
+ */
+struct gpio_config {
+ const char *name; /* GPIO net name */
+ const char *dev_name; /* Set at build time for lookup */
+ gpio_pin_t pin; /* Bit number of pin within device */
+ gpio_flags_t init_flags; /* From build time */
+};
+
+#define GPIO_CONFIG(id) \
+ { \
+ .name = DT_LABEL(id), \
+ .dev_name = DT_LABEL(DT_PHANDLE(id, gpios)), \
+ .pin = DT_GPIO_PIN(id, gpios), \
+ .init_flags = DT_GPIO_FLAGS(id, gpios), \
+ },
+static const struct gpio_config configs[] = {
+#if DT_NODE_EXISTS(DT_PATH(named_gpios))
+ DT_FOREACH_CHILD(DT_PATH(named_gpios), GPIO_CONFIG)
+#endif
+};
+
+/* Runtime information for each GPIO that is configured in named_gpios */
+struct gpio_data {
+ const struct device *dev; /* Set during in init function */
+};
+
+#define GPIO_DATA(id) { },
+static struct gpio_data data[] = {
+#if DT_NODE_EXISTS(DT_PATH(named_gpios))
+ DT_FOREACH_CHILD(DT_PATH(named_gpios), GPIO_DATA)
+#endif
+};
+
+
+int gpio_is_implemented(enum gpio_signal signal)
+{
+ /* All GPIOs listed in Device Tree are consider implemented */
+ return 1;
+}
+
+int gpio_get_level(enum gpio_signal signal)
+{
+ const int l = gpio_pin_get_raw(data[signal].dev, configs[signal].pin);
+
+ if (l < 0) {
+ LOG_ERR("Cannot read %s (%d)", configs[signal].name, l);
+ return 0;
+ }
+ return l;
+}
+
+const char *gpio_get_name(enum gpio_signal signal)
+{
+ return configs[signal].name;
+}
+
+void gpio_set_level(enum gpio_signal signal, int value)
+{
+ int rv;
+
+ if (value != 0) {
+ rv = gpio_port_set_bits_raw(data[signal].dev,
+ BIT(configs[signal].pin));
+ } else {
+ rv = gpio_port_clear_bits_raw(data[signal].dev,
+ BIT(configs[signal].pin));
+ }
+
+ if (rv < 0) {
+ LOG_ERR("Cannot write %s (%d)", configs[signal].name, rv);
+ }
+}
+
+static int convert_from_zephyr_flags(const gpio_flags_t zephyr)
+{
+ int ec_flags = 0;
+
+ /*
+ * Convert from Zephyr flags to EC flags. Note that a few flags have
+ * the same value in both builds environments (e.g. GPIO_OUTPUT)
+ */
+ if (zephyr | GPIO_OUTPUT) {
+ ec_flags |= GPIO_OUTPUT;
+ }
+
+ return ec_flags;
+}
+
+int gpio_get_default_flags(enum gpio_signal signal)
+{
+ return convert_from_zephyr_flags(configs[signal].init_flags);
+}
+
+static int init_gpios(const struct device *unused)
+{
+ ARG_UNUSED(unused);
+
+ for (size_t i = 0; i < ARRAY_SIZE(configs); ++i) {
+ data[i].dev = device_get_binding(configs[i].dev_name);
+
+ if (data[i].dev == NULL) {
+ LOG_ERR("Not found (%s)", configs[i].name);
+ }
+
+ const int rv = gpio_pin_configure(data[i].dev, configs[i].pin,
+ configs[i].init_flags);
+
+ if (rv < 0) {
+ LOG_ERR("Config failed %s (%d)", configs[i].name, rv);
+ }
+ }
+ return 0;
+}
+SYS_INIT(init_gpios, PRE_KERNEL_1, 50);
diff --git a/zephyr/shim/src/util.c b/zephyr/shim/src/util.c
index 998a0db01d..6cd6e0dc68 100644
--- a/zephyr/shim/src/util.c
+++ b/zephyr/shim/src/util.c
@@ -5,6 +5,7 @@
#include <common.h>
#include <stdlib.h>
+#include <ctype.h>
/* Int and Long are same size, just forward to existing Long implementation */
int strtoi(const char *nptr, char **endptr, int base)
@@ -12,3 +13,15 @@ int strtoi(const char *nptr, char **endptr, int base)
return strtol(nptr, endptr, base);
}
BUILD_ASSERT(sizeof(int) == sizeof(long));
+
+int strcasecmp(const char *s1, const char *s2)
+{
+ int diff;
+
+ do {
+ diff = tolower(*s1) - tolower(*s2);
+ if (diff)
+ return diff;
+ } while (*(s1++) && *(s2++));
+ return 0;
+}