diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2022-10-06 15:27:38 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-10-26 16:17:38 +0000 |
commit | dfd2865721bd6d151d76b8beac53e5cc0d1e9164 (patch) | |
tree | affecc9c2275490d603326c09cbacfe6cd4375bf /common/peripheral_charger.c | |
parent | eff5ae0db72fb8c656f67ed5b2849f07125074e1 (diff) | |
download | chrome-ec-dfd2865721bd6d151d76b8beac53e5cc0d1e9164.tar.gz |
PCHG: Add pass-through mode
In pass-through (passthru in short) mode, EC stops handling PCHG events
but reports IRQs to the host. This mode allows the host to directly
communicate with a chip using I2C pass-through, for example.
A host sends EC_CMD_PCHG_UPDATE with EC_PCHG_UPDATE_CMD_ENABLE_PASSTHRU
sub-command or EC_PCHG_UPDATE_CMD_RESET_TO_NORMAL sub-command to enter
or exit the mode.
BUG=b:245764044
BRANCH=None
TEST=Redrix
Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Change-Id: I16fe3f6ccd4a78bf3417fe3c0e86b5428a954acd
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3938411
Reviewed-by: caveh jalali <caveh@chromium.org>
Diffstat (limited to 'common/peripheral_charger.c')
-rw-r--r-- | common/peripheral_charger.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/common/peripheral_charger.c b/common/peripheral_charger.c index 80ad205cdc..08cc7f3223 100644 --- a/common/peripheral_charger.c +++ b/common/peripheral_charger.c @@ -55,6 +55,21 @@ struct pchg_policy_t pchg_policy_suspend = { .err_mask = 0, }; +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. */ @@ -206,10 +221,10 @@ static enum pchg_state pchg_reset(struct pchg *ctx) ctx->error |= PCHG_ERROR_MASK(PCHG_ERROR_COMMUNICATION); 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; } @@ -526,11 +541,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)); } @@ -831,6 +852,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; } @@ -859,6 +897,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; |