summaryrefslogtreecommitdiff
path: root/common/peripheral_charger.c
diff options
context:
space:
mode:
authorJack Rosenthal <jrosenth@chromium.org>2021-11-04 12:11:58 -0600
committerCommit Bot <commit-bot@chromium.org>2021-11-05 04:22:34 +0000
commit252457d4b21f46889eebad61d4c0a65331919cec (patch)
tree01856c4d31d710b20e85a74c8d7b5836e35c3b98 /common/peripheral_charger.c
parent08f5a1e6fc2c9467230444ac9b582dcf4d9f0068 (diff)
downloadchrome-ec-stabilize-14388.62.B-ish.tar.gz
In the interest of making long-term branch maintenance incur as little technical debt on us as possible, we should not maintain any files on the branch we are not actually using. This has the added effect of making it extremely clear when merging CLs from the main branch when changes have the possibility to affect us. The follow-on CL adds a convenience script to actually pull updates from the main branch and generate a CL for the update. BUG=b:204206272 BRANCH=ish TEST=make BOARD=arcada_ish && make BOARD=drallion_ish Signed-off-by: Jack Rosenthal <jrosenth@chromium.org> Change-Id: I17e4694c38219b5a0823e0a3e55a28d1348f4b18 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3262038 Reviewed-by: Jett Rink <jettrink@chromium.org> Reviewed-by: Tom Hughes <tomhughes@chromium.org>
Diffstat (limited to 'common/peripheral_charger.c')
-rw-r--r--common/peripheral_charger.c740
1 files changed, 0 insertions, 740 deletions
diff --git a/common/peripheral_charger.c b/common/peripheral_charger.c
deleted file mode 100644
index 0a597ad6bd..0000000000
--- a/common/peripheral_charger.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "atomic.h"
-#include "chipset.h"
-#include "common.h"
-#include "device_event.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "mkbp_event.h"
-#include "peripheral_charger.h"
-#include "queue.h"
-#include "stdbool.h"
-#include "task.h"
-#include "timer.h"
-#include "util.h"
-
-/* Peripheral Charge Manager */
-
-#define CPRINTS(fmt, args...) cprints(CC_PCHG, "PCHG: " fmt, ##args)
-
-/* Currently only used for FW update. */
-static uint32_t pchg_host_events;
-
-static void pchg_queue_event(struct pchg *ctx, enum pchg_event event)
-{
- mutex_lock(&ctx->mtx);
- if (queue_add_unit(&ctx->events, &event) == 0) {
- ctx->dropped_event_count++;
- CPRINTS("ERR: Queue is full");
- }
- mutex_unlock(&ctx->mtx);
-}
-
-static void _send_host_event(const struct pchg *ctx, uint32_t event)
-{
- int port = PCHG_CTX_TO_PORT(ctx);
-
- atomic_or(&pchg_host_events, event | port << EC_MKBP_PCHG_PORT_SHIFT);
- mkbp_send_event(EC_MKBP_EVENT_PCHG);
-}
-
-static const char *_text_state(enum pchg_state state)
-{
- /* TODO: Use "S%d" for normal build. */
- static const char * const state_names[] = EC_PCHG_STATE_TEXT;
- BUILD_ASSERT(ARRAY_SIZE(state_names) == PCHG_STATE_COUNT);
-
- if (state >= sizeof(state_names))
- return "UNDEF";
-
- return state_names[state];
-}
-
-static const char *_text_event(enum pchg_event event)
-{
- /* TODO: Use "S%d" for normal build. */
- static const char * const event_names[] = {
- [PCHG_EVENT_NONE] = "NONE",
- [PCHG_EVENT_IRQ] = "IRQ",
- [PCHG_EVENT_RESET] = "RESET",
- [PCHG_EVENT_INITIALIZED] = "INITIALIZED",
- [PCHG_EVENT_ENABLED] = "ENABLED",
- [PCHG_EVENT_DISABLED] = "DISABLED",
- [PCHG_EVENT_DEVICE_DETECTED] = "DEVICE_DETECTED",
- [PCHG_EVENT_DEVICE_CONNECTED] = "DEVICE_CONNECTED",
- [PCHG_EVENT_DEVICE_LOST] = "DEVICE_LOST",
- [PCHG_EVENT_CHARGE_STARTED] = "CHARGE_STARTED",
- [PCHG_EVENT_CHARGE_UPDATE] = "CHARGE_UPDATE",
- [PCHG_EVENT_CHARGE_ENDED] = "CHARGE_ENDED",
- [PCHG_EVENT_CHARGE_STOPPED] = "CHARGE_STOPPED",
- [PCHG_EVENT_UPDATE_OPENED] = "UPDATE_OPENED",
- [PCHG_EVENT_UPDATE_CLOSED] = "UPDATE_CLOSED",
- [PCHG_EVENT_UPDATE_WRITTEN] = "UPDATE_WRITTEN",
- [PCHG_EVENT_IN_NORMAL] = "IN_NORMAL",
- [PCHG_EVENT_CHARGE_ERROR] = "CHARGE_ERROR",
- [PCHG_EVENT_UPDATE_ERROR] = "UPDATE_ERROR",
- [PCHG_EVENT_OTHER_ERROR] = "OTHER_ERROR",
- [PCHG_EVENT_ENABLE] = "ENABLE",
- [PCHG_EVENT_DISABLE] = "DISABLE",
- [PCHG_EVENT_UPDATE_OPEN] = "UPDATE_OPEN",
- [PCHG_EVENT_UPDATE_WRITE] = "UPDATE_WRITE",
- [PCHG_EVENT_UPDATE_CLOSE] = "UPDATE_CLOSE",
- };
- BUILD_ASSERT(ARRAY_SIZE(event_names) == PCHG_EVENT_COUNT);
-
- if (event >= sizeof(event_names))
- return "UNDEF";
-
- return event_names[event];
-}
-
-static void _clear_port(struct pchg *ctx)
-{
- mutex_lock(&ctx->mtx);
- queue_init(&ctx->events);
- mutex_unlock(&ctx->mtx);
- atomic_clear(&ctx->irq);
- ctx->battery_percent = 0;
- ctx->error = 0;
- ctx->update.data_ready = 0;
-}
-
-static enum pchg_state pchg_reset(struct pchg *ctx)
-{
- enum pchg_state state = PCHG_STATE_RESET;
- int rv;
-
- /*
- * In case we get asynchronous reset, clear port though it's redundant
- * for a synchronous reset.
- */
- _clear_port(ctx);
-
- if (ctx->mode == PCHG_MODE_NORMAL) {
- rv = ctx->cfg->drv->init(ctx);
- if (rv == EC_SUCCESS) {
- state = PCHG_STATE_INITIALIZED;
- pchg_queue_event(ctx, PCHG_EVENT_ENABLE);
- } else if (rv != EC_SUCCESS_IN_PROGRESS) {
- CPRINTS("ERR: Failed to reset to normal mode");
- }
- } else {
- state = PCHG_STATE_DOWNLOAD;
- pchg_queue_event(ctx, PCHG_EVENT_UPDATE_OPEN);
- }
-
- return state;
-}
-
-static void pchg_state_reset(struct pchg *ctx)
-{
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_IN_NORMAL:
- ctx->state = PCHG_STATE_INITIALIZED;
- pchg_queue_event(ctx, PCHG_EVENT_ENABLE);
- break;
- default:
- break;
- }
-}
-
-static void pchg_state_initialized(struct pchg *ctx)
-{
- int rv;
-
- if (ctx->event == PCHG_EVENT_ENABLE)
- ctx->error &= ~PCHG_ERROR_HOST;
-
- /* Spin in INITIALIZED until error condition is cleared. */
- if (ctx->error)
- return;
-
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_ENABLE:
- rv = ctx->cfg->drv->enable(ctx, true);
- if (rv == EC_SUCCESS)
- ctx->state = PCHG_STATE_ENABLED;
- else if (rv != EC_SUCCESS_IN_PROGRESS)
- CPRINTS("ERR: Failed to enable");
- break;
- case PCHG_EVENT_ENABLED:
- ctx->state = PCHG_STATE_ENABLED;
- break;
- default:
- break;
- }
-}
-
-static void pchg_state_enabled(struct pchg *ctx)
-{
- int rv;
-
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_DISABLE:
- ctx->error |= PCHG_ERROR_HOST;
- rv = ctx->cfg->drv->enable(ctx, false);
- if (rv == EC_SUCCESS)
- ctx->state = PCHG_STATE_INITIALIZED;
- else if (rv != EC_SUCCESS_IN_PROGRESS)
- CPRINTS("ERR: Failed to disable");
- break;
- case PCHG_EVENT_DISABLED:
- ctx->state = PCHG_STATE_INITIALIZED;
- break;
- case PCHG_EVENT_DEVICE_DETECTED:
- ctx->state = PCHG_STATE_DETECTED;
- break;
- case PCHG_EVENT_DEVICE_CONNECTED:
- /*
- * Proactively query SOC in case charging info won't be sent
- * because device is already charged.
- */
- ctx->cfg->drv->get_soc(ctx);
- ctx->state = PCHG_STATE_CONNECTED;
- break;
- default:
- break;
- }
-}
-
-static void pchg_state_detected(struct pchg *ctx)
-{
- int rv;
-
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_DISABLE:
- ctx->error |= PCHG_ERROR_HOST;
- rv = ctx->cfg->drv->enable(ctx, false);
- if (rv == EC_SUCCESS)
- ctx->state = PCHG_STATE_INITIALIZED;
- else if (rv != EC_SUCCESS_IN_PROGRESS)
- CPRINTS("ERR: Failed to disable");
- break;
- case PCHG_EVENT_DISABLED:
- ctx->state = PCHG_STATE_INITIALIZED;
- break;
- case PCHG_EVENT_DEVICE_CONNECTED:
- /*
- * Proactively query SOC in case charging info won't be sent
- * because device is already charged.
- */
- ctx->cfg->drv->get_soc(ctx);
- ctx->state = PCHG_STATE_CONNECTED;
- break;
- case PCHG_EVENT_DEVICE_LOST:
- ctx->battery_percent = 0;
- ctx->state = PCHG_STATE_ENABLED;
- break;
- default:
- break;
- }
-}
-
-static void pchg_state_connected(struct pchg *ctx)
-{
- int rv;
-
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_DISABLE:
- ctx->error |= PCHG_ERROR_HOST;
- rv = ctx->cfg->drv->enable(ctx, false);
- if (rv == EC_SUCCESS)
- ctx->state = PCHG_STATE_INITIALIZED;
- else if (rv != EC_SUCCESS_IN_PROGRESS)
- CPRINTS("ERR: Failed to disable");
- break;
- case PCHG_EVENT_DISABLED:
- ctx->state = PCHG_STATE_INITIALIZED;
- break;
- case PCHG_EVENT_CHARGE_STARTED:
- ctx->state = PCHG_STATE_CHARGING;
- break;
- case PCHG_EVENT_DEVICE_LOST:
- ctx->battery_percent = 0;
- ctx->state = PCHG_STATE_ENABLED;
- break;
- case PCHG_EVENT_CHARGE_ERROR:
- ctx->state = PCHG_STATE_INITIALIZED;
- break;
- default:
- break;
- }
-}
-
-static void pchg_state_charging(struct pchg *ctx)
-{
- int rv;
-
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_DISABLE:
- ctx->error |= PCHG_ERROR_HOST;
- rv = ctx->cfg->drv->enable(ctx, false);
- if (rv == EC_SUCCESS)
- ctx->state = PCHG_STATE_INITIALIZED;
- else if (rv != EC_SUCCESS_IN_PROGRESS)
- CPRINTS("ERR: Failed to disable");
- break;
- case PCHG_EVENT_DISABLED:
- ctx->state = PCHG_STATE_INITIALIZED;
- break;
- case PCHG_EVENT_CHARGE_UPDATE:
- break;
- case PCHG_EVENT_DEVICE_LOST:
- ctx->battery_percent = 0;
- ctx->state = PCHG_STATE_ENABLED;
- break;
- case PCHG_EVENT_CHARGE_ERROR:
- ctx->state = PCHG_STATE_INITIALIZED;
- break;
- case PCHG_EVENT_CHARGE_ENDED:
- case PCHG_EVENT_CHARGE_STOPPED:
- ctx->state = PCHG_STATE_CONNECTED;
- break;
- default:
- break;
- }
-}
-
-static void pchg_state_download(struct pchg *ctx)
-{
- int rv;
-
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_UPDATE_OPEN:
- rv = ctx->cfg->drv->update_open(ctx);
- if (rv == EC_SUCCESS) {
- ctx->state = PCHG_STATE_DOWNLOADING;
- } else if (rv != EC_SUCCESS_IN_PROGRESS) {
- _send_host_event(ctx, EC_MKBP_PCHG_UPDATE_ERROR);
- CPRINTS("ERR: Failed to open");
- }
- break;
- case PCHG_EVENT_UPDATE_OPENED:
- ctx->state = PCHG_STATE_DOWNLOADING;
- _send_host_event(ctx, EC_MKBP_PCHG_UPDATE_OPENED);
- break;
- case PCHG_EVENT_UPDATE_ERROR:
- _send_host_event(ctx, EC_MKBP_PCHG_UPDATE_ERROR);
- break;
- default:
- break;
- }
-}
-
-static void pchg_state_downloading(struct pchg *ctx)
-{
- int rv;
-
- switch (ctx->event) {
- case PCHG_EVENT_RESET:
- ctx->state = pchg_reset(ctx);
- break;
- case PCHG_EVENT_UPDATE_WRITE:
- if (ctx->update.data_ready == 0)
- break;
- rv = ctx->cfg->drv->update_write(ctx);
- if (rv != EC_SUCCESS && rv != EC_SUCCESS_IN_PROGRESS) {
- _send_host_event(ctx, EC_MKBP_PCHG_UPDATE_ERROR);
- CPRINTS("ERR: Failed to write");
- }
- break;
- case PCHG_EVENT_UPDATE_WRITTEN:
- ctx->update.data_ready = 0;
- _send_host_event(ctx, EC_MKBP_PCHG_WRITE_COMPLETE);
- break;
- case PCHG_EVENT_UPDATE_CLOSE:
- rv = ctx->cfg->drv->update_close(ctx);
- if (rv == EC_SUCCESS) {
- ctx->state = PCHG_STATE_DOWNLOAD;
- } else if (rv != EC_SUCCESS_IN_PROGRESS) {
- _send_host_event(ctx, EC_MKBP_PCHG_UPDATE_ERROR);
- CPRINTS("ERR: Failed to close");
- }
- break;
- case PCHG_EVENT_UPDATE_CLOSED:
- ctx->state = PCHG_STATE_DOWNLOAD;
- _send_host_event(ctx, EC_MKBP_PCHG_UPDATE_CLOSED);
- break;
- case PCHG_EVENT_UPDATE_ERROR:
- CPRINTS("ERR: Failed to update");
- _send_host_event(ctx, EC_MKBP_PCHG_UPDATE_ERROR);
- break;
- default:
- break;
- }
-}
-
-static int pchg_run(struct pchg *ctx)
-{
- enum pchg_state previous_state = ctx->state;
- uint8_t previous_battery = ctx->battery_percent;
- int port = PCHG_CTX_TO_PORT(ctx);
- int rv;
-
- mutex_lock(&ctx->mtx);
- if (!queue_remove_unit(&ctx->events, &ctx->event)) {
- mutex_unlock(&ctx->mtx);
- CPRINTS("P%d No event in queue", port);
- return 0;
- }
- mutex_unlock(&ctx->mtx);
-
- CPRINTS("P%d Run in STATE_%s for EVENT_%s", port,
- _text_state(ctx->state), _text_event(ctx->event));
-
- 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;
- }
- CPRINTS(" EVENT_%s", _text_event(ctx->event));
- }
-
- if (ctx->event == PCHG_EVENT_NONE)
- return 0;
-
- switch (ctx->state) {
- case PCHG_STATE_RESET:
- pchg_state_reset(ctx);
- break;
- case PCHG_STATE_INITIALIZED:
- pchg_state_initialized(ctx);
- break;
- case PCHG_STATE_ENABLED:
- pchg_state_enabled(ctx);
- break;
- case PCHG_STATE_DETECTED:
- pchg_state_detected(ctx);
- break;
- case PCHG_STATE_CONNECTED:
- pchg_state_connected(ctx);
- break;
- case PCHG_STATE_CHARGING:
- pchg_state_charging(ctx);
- break;
- case PCHG_STATE_DOWNLOAD:
- pchg_state_download(ctx);
- break;
- case PCHG_STATE_DOWNLOADING:
- pchg_state_downloading(ctx);
- break;
- default:
- CPRINTS("ERR: Unknown state (%d)", ctx->state);
- return 0;
- }
-
- if (previous_state != ctx->state)
- CPRINTS("->STATE_%s", _text_state(ctx->state));
-
- if (ctx->battery_percent != previous_battery)
- CPRINTS("Battery %u%%", ctx->battery_percent);
-
- /*
- * Notify the host of
- * - [S0] Charge update with SoC change and all other events.
- * - [S3/S0IX] Device attach or detach (for wake-up)
- * - [S5/G3] No events.
- */
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
- return 0;
-
- if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND))
- return (ctx->event == PCHG_EVENT_DEVICE_DETECTED)
- || (ctx->event == PCHG_EVENT_DEVICE_LOST);
-
- if (ctx->event == PCHG_EVENT_CHARGE_UPDATE)
- return ctx->battery_percent != previous_battery;
-
- return ctx->event != PCHG_EVENT_NONE;
-}
-
-void pchg_irq(enum gpio_signal signal)
-{
- struct pchg *ctx;
- int i;
-
- for (i = 0; i < pchg_count; i++) {
- ctx = &pchgs[i];
- if (signal == ctx->cfg->irq_pin) {
- ctx->irq = 1;
- task_wake(TASK_ID_PCHG);
- return;
- }
- }
-}
-
-
-static void pchg_suspend_complete(void)
-{
- CPRINTS("%s", __func__);
- device_enable_event(EC_DEVICE_EVENT_WLC);
-}
-DECLARE_HOOK(HOOK_CHIPSET_SUSPEND_COMPLETE, pchg_suspend_complete,
- HOOK_PRIO_DEFAULT);
-
-static void pchg_startup(void)
-{
- struct pchg *ctx;
- int p;
-
- CPRINTS("%s", __func__);
-
- for (p = 0; p < pchg_count; p++) {
- ctx = &pchgs[p];
- _clear_port(ctx);
- ctx->mode = PCHG_MODE_NORMAL;
- ctx->cfg->drv->reset(ctx);
- gpio_enable_interrupt(ctx->cfg->irq_pin);
- }
-
- task_wake(TASK_ID_PCHG);
-}
-DECLARE_HOOK(HOOK_CHIPSET_STARTUP, pchg_startup, HOOK_PRIO_DEFAULT);
-
-static void pchg_shutdown(void)
-{
- struct pchg *ctx;
- int p;
-
- CPRINTS("%s", __func__);
-
- for (p = 0; p < pchg_count; p++) {
- ctx = &pchgs[0];
- gpio_disable_interrupt(ctx->cfg->irq_pin);
- }
-}
-DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pchg_shutdown, HOOK_PRIO_DEFAULT);
-
-void pchg_task(void *u)
-{
- struct pchg *ctx;
- int p;
-
- if (chipset_in_state(CHIPSET_STATE_ON))
- /* We are here after power-on (because of late sysjump). */
- pchg_startup();
-
- while (true) {
- /* Process pending events for all ports. */
- int rv = 0;
-
- for (p = 0; p < pchg_count; p++) {
- ctx = &pchgs[p];
- do {
- if (atomic_clear(&ctx->irq))
- pchg_queue_event(ctx, PCHG_EVENT_IRQ);
- rv |= pchg_run(ctx);
- } while (queue_count(&ctx->events));
- }
-
- /* Send one host event for all ports. */
- if (rv)
- device_set_single_event(EC_DEVICE_EVENT_WLC);
-
- task_wait_event(-1);
- }
-}
-
-static enum ec_status hc_pchg_count(struct host_cmd_handler_args *args)
-{
- struct ec_response_pchg_count *r = args->response;
-
- r->port_count = pchg_count;
- args->response_size = sizeof(*r);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_PCHG_COUNT, hc_pchg_count, EC_VER_MASK(0));
-
-#define HCPRINTS(fmt, args...) cprints(CC_PCHG, "HC:PCHG: " fmt, ##args)
-
-static enum ec_status hc_pchg(struct host_cmd_handler_args *args)
-{
- const struct ec_params_pchg *p = args->params;
- struct ec_response_pchg *r = args->response;
- int port = p->port;
- struct pchg *ctx;
-
- if (port >= pchg_count)
- return EC_RES_INVALID_PARAM;
-
- ctx = &pchgs[port];
-
- if (ctx->state == PCHG_STATE_CONNECTED
- && ctx->battery_percent >= ctx->cfg->full_percent)
- r->state = PCHG_STATE_FULL;
- else
- r->state = ctx->state;
-
- r->battery_percentage = ctx->battery_percent;
- r->error = ctx->error;
- r->fw_version = ctx->fw_version;
- r->dropped_event_count = ctx->dropped_event_count;
-
- args->response_size = sizeof(*r);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_PCHG, hc_pchg, EC_VER_MASK(1));
-
-int pchg_get_next_event(uint8_t *out)
-{
- uint32_t events = atomic_clear(&pchg_host_events);
-
- memcpy(out, &events, sizeof(events));
-
- return sizeof(events);
-}
-DECLARE_EVENT_SOURCE(EC_MKBP_EVENT_PCHG, pchg_get_next_event);
-
-static enum ec_status hc_pchg_update(struct host_cmd_handler_args *args)
-{
- const struct ec_params_pchg_update *p = args->params;
- struct ec_response_pchg_update *r = args->response;
- int port = p->port;
- struct pchg *ctx;
-
- if (port >= pchg_count)
- return EC_RES_INVALID_PARAM;
-
- ctx = &pchgs[port];
-
- switch (p->cmd) {
- case EC_PCHG_UPDATE_CMD_RESET_TO_NORMAL:
- HCPRINTS("Resetting to normal mode");
-
- gpio_disable_interrupt(ctx->cfg->irq_pin);
- _clear_port(ctx);
- ctx->mode = PCHG_MODE_NORMAL;
- ctx->cfg->drv->reset(ctx);
- gpio_enable_interrupt(ctx->cfg->irq_pin);
- break;
-
- case EC_PCHG_UPDATE_CMD_OPEN:
- HCPRINTS("Resetting to download mode");
-
- gpio_disable_interrupt(ctx->cfg->irq_pin);
- _clear_port(ctx);
- ctx->mode = PCHG_MODE_DOWNLOAD;
- ctx->cfg->drv->reset(ctx);
- gpio_enable_interrupt(ctx->cfg->irq_pin);
-
- ctx->update.version = p->version;
- r->block_size = ctx->cfg->block_size;
- args->response_size = sizeof(*r);
- break;
-
- case EC_PCHG_UPDATE_CMD_WRITE:
- if (ctx->state != PCHG_STATE_DOWNLOADING)
- return EC_RES_ERROR;
- if (p->size > sizeof(ctx->update.data))
- return EC_RES_OVERFLOW;
- if (ctx->update.data_ready)
- return EC_RES_BUSY;
-
- HCPRINTS("Writing %u bytes to 0x%x", p->size, p->addr);
- ctx->update.addr = p->addr;
- ctx->update.size = p->size;
- memcpy(ctx->update.data, p->data, p->size);
- pchg_queue_event(ctx, PCHG_EVENT_UPDATE_WRITE);
- ctx->update.data_ready = 1;
- break;
-
- case EC_PCHG_UPDATE_CMD_CLOSE:
- if (ctx->state != PCHG_STATE_DOWNLOADING)
- return EC_RES_ERROR;
- if (ctx->update.data_ready)
- return EC_RES_BUSY;
-
- HCPRINTS("Closing update session (crc=0x%x)", p->crc32);
- ctx->update.crc32 = p->crc32;
- pchg_queue_event(ctx, PCHG_EVENT_UPDATE_CLOSE);
- break;
- default:
- return EC_RES_INVALID_PARAM;
- }
-
- task_wake(TASK_ID_PCHG);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_PCHG_UPDATE, hc_pchg_update, EC_VER_MASK(0));
-
-static int cc_pchg(int argc, char **argv)
-{
- int port;
- char *end;
- struct pchg *ctx;
-
- if (argc < 2 || 4 < argc)
- return EC_ERROR_PARAM_COUNT;
-
- port = strtoi(argv[1], &end, 0);
- if (*end || port < 0 || port >= pchg_count)
- return EC_ERROR_PARAM1;
- ctx = &pchgs[port];
-
- if (argc == 2) {
- ccprintf("P%d STATE_%s EVENT_%s SOC=%d%%\n",
- port, _text_state(ctx->state), _text_event(ctx->event),
- ctx->battery_percent);
- ccprintf("error=0x%x dropped=%u fw_version=0x%x\n",
- ctx->error, ctx->dropped_event_count, ctx->fw_version);
- return EC_SUCCESS;
- }
-
- if (!strcasecmp(argv[2], "reset")) {
- if (argc == 3)
- ctx->mode = PCHG_MODE_NORMAL;
- else if (!strcasecmp(argv[3], "download"))
- ctx->mode = PCHG_MODE_DOWNLOAD;
- else
- return EC_ERROR_PARAM3;
- gpio_disable_interrupt(ctx->cfg->irq_pin);
- _clear_port(ctx);
- ctx->cfg->drv->reset(ctx);
- gpio_enable_interrupt(ctx->cfg->irq_pin);
- } else if (!strcasecmp(argv[2], "enable")) {
- pchg_queue_event(ctx, PCHG_EVENT_ENABLE);
- } else if (!strcasecmp(argv[2], "disable")) {
- pchg_queue_event(ctx, PCHG_EVENT_DISABLE);
- } else {
- return EC_ERROR_PARAM2;
- }
-
- task_wake(TASK_ID_PCHG);
-
- return EC_SUCCESS;
-}
-DECLARE_CONSOLE_COMMAND(pchg, cc_pchg,
- "\n\t<port>"
- "\n\t<port> reset [download]"
- "\n\t<port> enable"
- "\n\t<port> disable",
- "Control peripheral chargers");