summaryrefslogtreecommitdiff
path: root/common/ioexpander.c
diff options
context:
space:
mode:
authorEdward Hill <ecgh@chromium.org>2020-03-17 20:37:39 -0600
committerCommit Bot <commit-bot@chromium.org>2020-03-20 18:14:18 +0000
commit1deb79863d965a2410515f633ff66646badd9a65 (patch)
tree7f0fe721561d920ec2a22509382643cd4db3e5b9 /common/ioexpander.c
parent9f17f26d0ac487ea4092809f23fe7c38cfb7e866 (diff)
downloadchrome-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.c100
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;
}