diff options
author | Michał Barnaś <mb@semihalf.com> | 2022-02-17 16:27:22 +0100 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2022-03-21 13:28:33 +0000 |
commit | 88970330f8610c5cd26ea88f8a7b0ddc7da83565 (patch) | |
tree | 8e77cc3748f1afbf17cb22aa21c3d78c1e9f3fe6 /zephyr/shim | |
parent | f9ee774c60a3d7775b9941fb3fb2c19d6a14fbcb (diff) | |
download | chrome-ec-88970330f8610c5cd26ea88f8a7b0ddc7da83565.tar.gz |
zephyr: remove the named-ioexes and move ioex logic to gpio
This commit removes the named-ioexes node in device tree and moves
the io expanders logic to gpio one.
The ioex_* functions are now a wrappers to gpio_* ones.
BRANCH=main
BUG=b:216644442
TEST=zmake testall
Change-Id: I61b341a1b968ce376b0420ff05b50f910c75a168
Signed-off-by: Michał Barnaś <mb@semihalf.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3471601
Reviewed-by: Jeremy Bettis <jbettis@chromium.org>
Diffstat (limited to 'zephyr/shim')
-rw-r--r-- | zephyr/shim/include/zephyr_gpio_signal.h | 26 | ||||
-rw-r--r-- | zephyr/shim/src/ioex.c | 325 |
2 files changed, 7 insertions, 344 deletions
diff --git a/zephyr/shim/include/zephyr_gpio_signal.h b/zephyr/shim/include/zephyr_gpio_signal.h index 6522224456..265a7cdf9c 100644 --- a/zephyr/shim/include/zephyr_gpio_signal.h +++ b/zephyr/shim/include/zephyr_gpio_signal.h @@ -49,6 +49,10 @@ enum gpio_signal { #endif GPIO_COUNT, GPIO_LIMIT = 0x0FFF, + + IOEX_SIGNAL_START = GPIO_LIMIT + 1, + IOEX_SIGNAL_END = IOEX_SIGNAL_START, + IOEX_LIMIT = 0x1FFF, }; #undef GPIO_SIGNAL_WITH_COMMA @@ -123,28 +127,6 @@ DT_FOREACH_CHILD(DT_PATH(named_gpios), GPIO_DT_PTR_DECL) #endif /* DT_NODE_EXISTS(DT_PATH(named_gpios)) */ -/* - * Define enums for IO expanders and signals - */ -#define IOEX_SIGNAL(id) DT_STRING_UPPER_TOKEN(id, enum_name) -#define IOEX_SIGNAL_WITH_COMMA(id) \ - COND_CODE_1(DT_NODE_HAS_PROP(id, enum_name), (IOEX_SIGNAL(id), ), ()) -enum ioex_signal { - IOEX_SIGNAL_START = GPIO_LIMIT + 1, - /* Used to ensure that the first IOEX signal is same as start */ - __IOEX_PLACEHOLDER = GPIO_LIMIT, -#if DT_NODE_EXISTS(DT_PATH(named_ioexes)) - DT_FOREACH_CHILD(DT_PATH(named_ioexes), IOEX_SIGNAL_WITH_COMMA) -#endif - IOEX_SIGNAL_END, - IOEX_LIMIT = 0x1FFF, -}; -BUILD_ASSERT(IOEX_SIGNAL_END < IOEX_LIMIT); - -#undef IOEX_SIGNAL_WITH_COMMA -#undef IOEX_SIGNAL - -#define IOEX_COUNT (IOEX_SIGNAL_END - IOEX_SIGNAL_START) #define IOEXPANDER_ID_EXPAND(id) ioex_chip_##id #define IOEXPANDER_ID(id) IOEXPANDER_ID_EXPAND(id) diff --git a/zephyr/shim/src/ioex.c b/zephyr/shim/src/ioex.c index 57027f9241..c3bad885b0 100644 --- a/zephyr/shim/src/ioex.c +++ b/zephyr/shim/src/ioex.c @@ -3,279 +3,26 @@ * found in the LICENSE file. */ -#include <device.h> -#include <devicetree.h> #include <init.h> #include <kernel.h> #include <logging/log.h> - +#include "common.h" #ifdef __REQUIRE_ZEPHYR_GPIOS__ #undef __REQUIRE_ZEPHYR_GPIOS__ #endif -#include "gpio.h" -#include "gpio/gpio.h" -#include "i2c.h" #include "ioexpander.h" -#include "system.h" -#include "util.h" - -#if DT_NODE_EXISTS(DT_PATH(named_ioexes)) LOG_MODULE_REGISTER(ioex_shim, LOG_LEVEL_ERR); -struct ioex_gpio_config { - /* IOEX signal name */ - const char *name; - /* Device pointer to GPIO driver */ - const struct device *dev; - /* Bit number of the pin on the IOEX port */ - gpio_pin_t pin; - /* From DTS, excludes interrupts flags */ - gpio_flags_t init_flags; - /* - * Index of CrOS IO expander chip - * If IO expander uses CrOS EC driver, this value will be one - * of the possible from enum ioexpander_id - * otherwise, if using the Zephyr GPIO driver, this will be -1 - */ - int cros_drv_index; - /* Port of IO expander. Valid only if ioex field is not -1 */ - int port; -}; - -#ifdef CONFIG_PLATFORM_EC_IOEX_CROS_DRV -#define IOEX_IS_CROS_DRV(config) (config->cros_drv_index >= 0) -#else +#ifndef CONFIG_PLATFORM_EC_IOEX_CROS_DRV /* * If no legacy cros-ec IOEX drivers are used, we need a stub * symbol for ioex_config[]. Set the IOEX_IS_CROS_DRV to constant 0 * which will cause all these checks to compile out. */ -#define IOEX_IS_CROS_DRV(config) 0 struct ioexpander_config_t ioex_config[0]; #endif -struct ioex_int_config { - const enum ioex_signal signal; - const gpio_flags_t flags; - - void (*const handler)(enum gpio_signal); - struct gpio_callback callback; -}; - -/* Check IOEX interrupts flags */ -#define IOEX_INT(sig, f, cb) \ - BUILD_ASSERT(VALID_GPIO_INTERRUPT_FLAG(f), \ - STRINGIFY(sig) " is not using Zephyr interrupt flags"); -#ifdef EC_CROS_IOEX_INTERRUPTS -EC_CROS_IOEX_INTERRUPTS -#endif -#undef IOEX_INT - -/* Declare handlers */ -#ifdef EC_CROS_IOEX_INTERRUPTS -#define IOEX_INT(arg_signal, arg_flags, arg_handler) \ - void arg_handler(enum gpio_signal); -EC_CROS_IOEX_INTERRUPTS -#undef IOEX_INT -#endif /* EC_CROS_IOEX_INTERRUPTS */ - -#define IOEX_INT(arg_signal, arg_flags, arg_handler) \ -{ \ - .signal = arg_signal, \ - .flags = arg_flags, \ - .handler = arg_handler, \ -}, - -struct ioex_int_config ioex_int_configs[] = { -#ifdef EC_CROS_IOEX_INTERRUPTS - EC_CROS_IOEX_INTERRUPTS -#endif -}; -#undef IOEX_INT - -#define CHIP_FROM_GPIO(id) DT_PARENT(DT_GPIO_CTLR(id, gpios)) - -#define IOEX_GPIO_CONFIG(id) \ - { \ - .name = DT_LABEL(id), \ - .dev = DEVICE_DT_GET(DT_PHANDLE(id, gpios)), \ - .pin = DT_GPIO_PIN(id, gpios), \ - .init_flags = DT_GPIO_FLAGS(id, gpios), \ - .cros_drv_index = \ - COND_CODE_1(DT_NODE_HAS_COMPAT(CHIP_FROM_GPIO(id), \ - cros_ioex_chip), \ - (IOEXPANDER_ID(CHIP_FROM_GPIO(id)), ), \ - (-1,)) \ - .port = DT_REG_ADDR(DT_GPIO_CTLR(id, gpios)) \ - }, - -#define IOEX_INIT_FLAGS(id) 0, - -static const struct ioex_gpio_config ioex_gpio_configs[] = { - DT_FOREACH_CHILD(DT_PATH(named_ioexes), IOEX_GPIO_CONFIG) -}; - -static gpio_flags_t ioex_signals_flags[] = { - DT_FOREACH_CHILD(DT_PATH(named_ioexes), IOEX_INIT_FLAGS) -}; -BUILD_ASSERT(ARRAY_SIZE(ioex_signals_flags) == IOEX_COUNT); - -int signal_is_ioex(int signal) -{ - return ((signal >= IOEX_SIGNAL_START) && (signal < IOEX_SIGNAL_END)); -} - -static struct ioex_int_config *get_interrupt_from_signal( - enum ioex_signal signal) -{ - for (size_t i = 0; i < ARRAY_SIZE(ioex_int_configs); i++) { - if (ioex_int_configs[i].signal == signal) - return &ioex_int_configs[i]; - } - - LOG_ERR("No interrupt defined for GPIO %s", - ioex_gpio_configs[signal - IOEX_SIGNAL_START].name); - - return NULL; -} - -static const struct ioex_gpio_config *ioex_get_signal_info( - enum ioex_signal signal) -{ - const struct ioex_gpio_config *g; - - ASSERT(signal_is_ioex(signal)); - - g = ioex_gpio_configs + signal - IOEX_SIGNAL_START; - - if (IOEX_IS_CROS_DRV(g) && - !(ioex_config[g->cros_drv_index].flags & IOEX_FLAGS_INITIALIZED)) { - LOG_ERR("ioex %s disabled", g->name); - return NULL; - } - - return g; -} - -int ioex_enable_interrupt(enum ioex_signal signal) -{ - struct ioex_int_config *cfg = get_interrupt_from_signal(signal); - int offset = (signal - IOEX_SIGNAL_START); - int res; - - if (!cfg) - return EC_ERROR_PARAM1; - - res = gpio_pin_interrupt_configure(ioex_gpio_configs[offset].dev, - ioex_gpio_configs[offset].pin, - (cfg->flags | GPIO_INT_ENABLE) - & ~GPIO_INT_DISABLE); - - if (res) - LOG_ERR("Can't enable interrupt on %s", - ioex_gpio_configs[offset].name); - - return res; -} - -int ioex_disable_interrupt(enum ioex_signal signal) -{ - struct ioex_int_config *cfg = get_interrupt_from_signal(signal); - int offset = (signal - IOEX_SIGNAL_START); - int res; - - if (!cfg) - return EC_ERROR_PARAM1; - - res = gpio_pin_interrupt_configure(ioex_gpio_configs[offset].dev, - ioex_gpio_configs[offset].pin, - GPIO_INT_DISABLE); - - if (res) - LOG_ERR("Can't disable interrupt on %s", - ioex_gpio_configs[offset].name); - - return res; -} - -int ioex_get_flags(enum ioex_signal signal, int *flags) -{ - if (!signal_is_ioex(signal)) - return EC_ERROR_INVAL; - - *flags = convert_from_zephyr_flags( - ioex_signals_flags[signal - IOEX_SIGNAL_START]); - - return EC_SUCCESS; -} - -int ioex_set_flags(enum ioex_signal signal, int flags) -{ - const struct ioex_gpio_config *g = ioex_get_signal_info(signal); - - if (g == NULL) - return EC_ERROR_INVAL; - - if (gpio_pin_configure(g->dev, - g->pin, - convert_to_zephyr_flags(flags)) < 0) { - return EC_ERROR_UNKNOWN; - } - - ioex_signals_flags[signal - IOEX_SIGNAL_START] = - convert_to_zephyr_flags(flags); - - return EC_SUCCESS; -} - -int ioex_get_level(enum ioex_signal signal, int *val) -{ - const struct ioex_gpio_config *g = ioex_get_signal_info(signal); - int res; - - if (g == NULL) - return EC_ERROR_INVAL; - - res = gpio_pin_get_raw(g->dev, g->pin); - if (res < 0) - return EC_ERROR_UNKNOWN; - - *val = res; - - return EC_SUCCESS; -} - -int ioex_set_level(enum ioex_signal signal, int value) -{ - const struct ioex_gpio_config *g = ioex_get_signal_info(signal); - int res; - - if (g == NULL) - return EC_ERROR_INVAL; - - res = gpio_pin_set_raw(g->dev, g->pin, value); - if (res) - return EC_ERROR_UNKNOWN; - - return EC_SUCCESS; -} - -int ioex_get_port(int ioex, int port, int *val) -{ - return EC_ERROR_UNIMPLEMENTED; -} - -static void ioex_isr(const struct device *port, - struct gpio_callback *cb, - gpio_port_pins_t pins) -{ - struct ioex_int_config *cfg = - CONTAINER_OF(cb, struct ioex_int_config, callback); - - cfg->handler(cfg->signal); -} - int ioex_init(int ioex) { if (!IS_ENABLED(CONFIG_PLATFORM_EC_IOEX_CROS_DRV)) @@ -298,6 +45,7 @@ int ioex_init(int ioex) return EC_SUCCESS; } +#ifdef CONFIG_PLATFORM_EC_IOEX_CROS_DRV static int ioex_init_default(const struct device *unused) { int ret; @@ -316,74 +64,7 @@ static int ioex_init_default(const struct device *unused) LOG_ERR("Can't initialize ioex %d", i); } - /* - * Set all IO expander GPIOs to default flags according to the setting - * in device tree - */ - for (i = 0; i < IOEX_COUNT; i++) { - const struct ioex_gpio_config *g = - ioex_get_signal_info(IOEX_SIGNAL_START + i); - int flags; - - if (!g) - continue; - - flags = g->init_flags; - /* Late-sysJump should not set the output levels */ - if (system_jumped_late()) - flags &= ~(GPIO_LOW | GPIO_HIGH); - - ret = gpio_pin_configure(g->dev, g->pin, flags); - if (ret) - LOG_ERR("Can't configure %s", g->name); - - ioex_signals_flags[i] = g->init_flags; - } - - /* Init interrupts */ - for (i = 0; i < ARRAY_SIZE(ioex_int_configs); i++) { - int offset = ioex_int_configs[i].signal - IOEX_SIGNAL_START; - - gpio_init_callback(&ioex_int_configs[i].callback, - ioex_isr, - BIT(ioex_gpio_configs[offset].pin)); - ret = gpio_add_callback(ioex_gpio_configs[offset].dev, - &ioex_int_configs[i].callback); - if (ret) - LOG_ERR("Can't add callback to %s", - ioex_gpio_configs[offset].name); - } - return 0; } SYS_INIT(ioex_init_default, POST_KERNEL, CONFIG_PLATFORM_EC_IOEX_INIT_PRIORITY); - -const char *ioex_get_name(enum ioex_signal signal) -{ - const struct ioex_gpio_config *g = ioex_get_signal_info(signal); - - if (g == NULL) - return NULL; - - return g->name; -} - -int ioex_get_ioex_flags(enum ioex_signal signal, int *val) -{ - const struct ioex_gpio_config *g = ioex_get_signal_info(signal); - - if (g == NULL) - return EC_ERROR_INVAL; - - if (!IOEX_IS_CROS_DRV(g)) { - /* Zephyr gpio drivers are initialized by internal subsystem */ - *val = IOEX_FLAGS_INITIALIZED; - return EC_SUCCESS; - } - - *val = ioex_config[g->cros_drv_index].flags; - - return EC_SUCCESS; -} - #endif |