diff options
Diffstat (limited to 'common/peripheral_charger.c')
-rw-r--r-- | common/peripheral_charger.c | 740 |
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"); |