summaryrefslogtreecommitdiff
path: root/common/peripheral_charger.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/peripheral_charger.c')
-rw-r--r--common/peripheral_charger.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/common/peripheral_charger.c b/common/peripheral_charger.c
index 5767315a78..caaf535976 100644
--- a/common/peripheral_charger.c
+++ b/common/peripheral_charger.c
@@ -68,6 +68,21 @@ static const char *_text_state(enum pchg_state state)
return state_names[state];
}
+static const char *_text_mode(enum pchg_mode mode)
+{
+ static const char *const mode_names[] = {
+ [PCHG_MODE_NORMAL] = "NORMAL",
+ [PCHG_MODE_DOWNLOAD] = "DOWNLOAD",
+ [PCHG_MODE_PASSTHRU] = "PASSTHRU",
+ };
+ BUILD_ASSERT(ARRAY_SIZE(mode_names) == PCHG_MODE_COUNT);
+
+ if (mode < 0 || mode >= PCHG_MODE_COUNT)
+ return "UNDEF";
+
+ return mode_names[mode];
+}
+
static const char *_text_event(enum pchg_event event)
{
/* TODO: Use "S%d" for normal build. */
@@ -140,10 +155,10 @@ static enum pchg_state pchg_reset(struct pchg *ctx)
} else if (rv != EC_SUCCESS_IN_PROGRESS) {
CPRINTS("ERR: Failed to reset to normal mode");
}
- } else {
+ } else if (ctx->mode == PCHG_MODE_DOWNLOAD) {
state = PCHG_STATE_DOWNLOAD;
pchg_queue_event(ctx, PCHG_EVENT_UPDATE_OPEN);
- }
+ } /* No-op for passthru mode */
return state;
}
@@ -442,11 +457,17 @@ static int pchg_run(struct pchg *ctx)
CPRINTS("P%d Run in STATE_%s for EVENT_%s", port,
_text_state(ctx->state), _text_event(ctx->event));
+ /*
+ * IRQ event is further translated to an actual event unless we're
+ * in passthru mode, where IRQ events will be passed to the host.
+ */
if (ctx->event == PCHG_EVENT_IRQ) {
- rv = ctx->cfg->drv->get_event(ctx);
- if (rv) {
- CPRINTS("ERR: Failed to get event (%d)", rv);
- return 0;
+ if (ctx->mode != PCHG_MODE_PASSTHRU) {
+ rv = ctx->cfg->drv->get_event(ctx);
+ if (rv) {
+ CPRINTS("ERR: Failed to get event (%d)", rv);
+ return 0;
+ }
}
CPRINTS(" EVENT_%s", _text_event(ctx->event));
}
@@ -747,6 +768,23 @@ static enum ec_status hc_pchg_update(struct host_cmd_handler_args *args)
ctx->update.crc32 = p->crc32;
pchg_queue_event(ctx, PCHG_EVENT_UPDATE_CLOSE);
break;
+
+ case EC_PCHG_UPDATE_CMD_RESET:
+ HCPRINTS("Resetting");
+
+ gpio_disable_interrupt(ctx->cfg->irq_pin);
+ _clear_port(ctx);
+ ctx->cfg->drv->reset(ctx);
+ gpio_enable_interrupt(ctx->cfg->irq_pin);
+ break;
+
+ case EC_PCHG_UPDATE_CMD_ENABLE_PASSTHRU:
+ HCPRINTS("Enabling passthru mode");
+ mutex_lock(&ctx->mtx);
+ ctx->mode = PCHG_MODE_PASSTHRU;
+ mutex_unlock(&ctx->mtx);
+ break;
+
default:
return EC_RES_INVALID_PARAM;
}
@@ -775,6 +813,7 @@ static int cc_pchg(int argc, const char **argv)
ccprintf("P%d STATE_%s EVENT_%s SOC=%d%%\n", port,
_text_state(ctx->state), _text_event(ctx->event),
ctx->battery_percent);
+ ccprintf("mode=%s\n", _text_mode(ctx->mode));
ccprintf("error=0x%x dropped=%u fw_version=0x%x\n", ctx->error,
ctx->dropped_event_count, ctx->fw_version);
return EC_SUCCESS;