diff options
author | Edward Hill <ecgh@chromium.org> | 2020-03-17 20:37:39 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-03-20 18:14:18 +0000 |
commit | 1deb79863d965a2410515f633ff66646badd9a65 (patch) | |
tree | 7f0fe721561d920ec2a22509382643cd4db3e5b9 /common/ioexpander.c | |
parent | 9f17f26d0ac487ea4092809f23fe7c38cfb7e866 (diff) | |
download | chrome-ec-1deb79863d965a2410515f633ff66646badd9a65.tar.gz |
ioexpander: add IOEX_FLAGS_DISABLED
BUG=b:150349225
BRANCH=none
TEST=none
Signed-off-by: Edward Hill <ecgh@chromium.org>
Change-Id: Id264d633576ca79b288a435f95de7fda9ca201ad
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2108334
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Reviewed-by: Paul Ma <magf@bitland.corp-partner.google.com>
Tested-by: Paul Ma <magf@bitland.corp-partner.google.com>
Diffstat (limited to 'common/ioexpander.c')
-rw-r--r-- | common/ioexpander.c | 100 |
1 files changed, 65 insertions, 35 deletions
diff --git a/common/ioexpander.c b/common/ioexpander.c index de64bafc7e..f8c5f81360 100644 --- a/common/ioexpander.c +++ b/common/ioexpander.c @@ -40,9 +40,18 @@ int signal_is_ioex(int signal) static const struct ioex_info *ioex_get_signal_info(enum ioex_signal signal) { + const struct ioex_info *g; + ASSERT(signal_is_ioex(signal)); - return ioex_list + signal - IOEX_SIGNAL_START; + g = ioex_list + signal - IOEX_SIGNAL_START; + + if (ioex_config[g->ioex].flags & IOEX_FLAGS_DISABLED) { + CPRINTS("ioex %s disabled", g->name); + return NULL; + } + + return g; } static int ioex_is_valid_interrupt_signal(enum ioex_signal signal) @@ -50,6 +59,9 @@ static int ioex_is_valid_interrupt_signal(enum ioex_signal signal) const struct ioexpander_drv *drv; const struct ioex_info *g = ioex_get_signal_info(signal); + if (g == NULL) + return EC_ERROR_BUSY; + /* Fail if no interrupt handler */ if (signal - IOEX_SIGNAL_START >= ioex_ih_count) return EC_ERROR_PARAM1; @@ -94,22 +106,13 @@ int ioex_disable_interrupt(enum ioex_signal signal) return drv->enable_interrupt(g->ioex, g->port, g->mask, 0); } -int ioex_get_flags_by_mask(int ioex, int port, int mask, int *flags) -{ - return ioex_config[ioex].drv->get_flags_by_mask(ioex, port, mask, - flags); -} - -int ioex_set_flags_by_mask(int ioex, int port, int mask, int flags) -{ - return ioex_config[ioex].drv->set_flags_by_mask(ioex, port, mask, - flags); -} - int ioex_get_flags(enum ioex_signal signal, int *flags) { const struct ioex_info *g = ioex_get_signal_info(signal); + if (g == NULL) + return EC_ERROR_BUSY; + return ioex_config[g->ioex].drv->get_flags_by_mask(g->ioex, g->port, g->mask, flags); } @@ -118,6 +121,9 @@ int ioex_set_flags(enum ioex_signal signal, int flags) { const struct ioex_info *g = ioex_get_signal_info(signal); + if (g == NULL) + return EC_ERROR_BUSY; + return ioex_config[g->ioex].drv->set_flags_by_mask(g->ioex, g->port, g->mask, flags); } @@ -126,6 +132,9 @@ int ioex_get_level(enum ioex_signal signal, int *val) { const struct ioex_info *g = ioex_get_signal_info(signal); + if (g == NULL) + return EC_ERROR_BUSY; + return ioex_config[g->ioex].drv->get_level(g->ioex, g->port, g->mask, val); } @@ -134,65 +143,83 @@ int ioex_set_level(enum ioex_signal signal, int value) { const struct ioex_info *g = ioex_get_signal_info(signal); + if (g == NULL) + return EC_ERROR_BUSY; + return ioex_config[g->ioex].drv->set_level(g->ioex, g->port, g->mask, value); } int ioex_init(int ioex) { + const struct ioex_info *g = ioex_list; const struct ioexpander_drv *drv = ioex_config[ioex].drv; + int rv; + int i; - if (drv->init == NULL) - return EC_SUCCESS; - - return drv->init(ioex); -} + if (ioex_config[ioex].flags & IOEX_FLAGS_DISABLED) + return EC_ERROR_BUSY; -static void ioex_init_default(void) -{ - const struct ioex_info *g = ioex_list; - int i; + if (drv->init != NULL) { + rv = drv->init(ioex); + if (rv != EC_SUCCESS) + return rv; + } - for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; i++) - ioex_init(i); /* * Set all IO expander GPIOs to default flags according to the setting * in gpio.inc */ for (i = 0; i < IOEX_COUNT; i++, g++) { - if (g->mask && !(g->flags & GPIO_DEFAULT)) { - ioex_set_flags_by_mask(g->ioex, g->port, + if (g->ioex == ioex && g->mask && !(g->flags & GPIO_DEFAULT)) { + drv->set_flags_by_mask(g->ioex, g->port, g->mask, g->flags); } } + return EC_SUCCESS; +} + +static void ioex_init_default(void) +{ + int i; + + for (i = 0; i < CONFIG_IO_EXPANDER_PORT_COUNT; i++) + ioex_init(i); } DECLARE_HOOK(HOOK_INIT, ioex_init_default, HOOK_PRIO_INIT_I2C + 1); const char *ioex_get_name(enum ioex_signal signal) { - const struct ioex_info *g = ioex_get_signal_info(signal); + const struct ioex_info *g = ioex_list + signal - IOEX_SIGNAL_START; return g->name; } -static void print_ioex_info(int io) +static void print_ioex_info(enum ioex_signal signal) { int changed, v, val; int flags = 0; + const struct ioex_info *g = ioex_list + signal - IOEX_SIGNAL_START; - v = ioex_get_level(io, &val); + if (ioex_config[g->ioex].flags & IOEX_FLAGS_DISABLED) { + ccprintf(" DISABLED %s\n", ioex_get_name(signal)); + return; + } + + + v = ioex_get_level(signal, &val); if (v) { - ccprintf("Fail to get %s level\n", ioex_get_name(io)); + ccprintf("Fail to get %s level\n", ioex_get_name(signal)); return; } - v = ioex_get_flags(io, &flags); + v = ioex_get_flags(signal, &flags); if (v) { - ccprintf("Fail to get %s flags\n", ioex_get_name(io)); + ccprintf("Fail to get %s flags\n", ioex_get_name(signal)); return; } - changed = last_val_changed(io, val); + changed = last_val_changed(signal, val); ccprintf(" %d%c %s%s%s%s%s%s\n", val, (changed ? '*' : ' '), @@ -201,16 +228,19 @@ static void print_ioex_info(int io) (flags & GPIO_LOW ? "L " : ""), (flags & GPIO_HIGH ? "H " : ""), (flags & GPIO_OPEN_DRAIN ? "ODR " : ""), - ioex_get_name(io)); + ioex_get_name(signal)); /* Flush console to avoid truncating output */ cflush(); } -int ioex_get_default_flags(enum ioex_signal signal) +static int ioex_get_default_flags(enum ioex_signal signal) { const struct ioex_info *g = ioex_get_signal_info(signal); + if (g == NULL) + return 0; + return g->flags; } |