diff options
-rw-r--r-- | include/ec_commands.h | 47 | ||||
-rw-r--r-- | util/ectool.c | 69 |
2 files changed, 116 insertions, 0 deletions
diff --git a/include/ec_commands.h b/include/ec_commands.h index 841d10dae7..c8ae9740a1 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -6312,6 +6312,53 @@ struct ec_response_regulator_get_voltage { uint32_t voltage_mv; } __ec_align4; +/** + * Get the number of peripheral charge ports + */ +#define EC_CMD_PCHG_COUNT 0x0134 + +#define EC_PCHG_MAX_PORTS 8 + +struct ec_response_pchg_count { + uint8_t port_count; +} __ec_align1; + +/** + * Get the status of a peripheral charge port + */ +#define EC_CMD_PCHG 0x0135 + +struct ec_params_pchg { + uint8_t port; +} __ec_align1; + +struct ec_response_pchg { + uint32_t error; /* enum pchg_error */ + uint8_t state; /* enum pchg_state state */ + uint8_t battery_percentage; +} __ec_align2; + +enum pchg_state { + /* Charger is reset and not initialized. */ + PCHG_STATE_RESET = 0, + /* Charger is initialized or disabled. */ + PCHG_STATE_INITIALIZED, + /* Charger is enabled and ready to detect a device. */ + PCHG_STATE_ENABLED, + /* Device is detected in proximity. */ + PCHG_STATE_DETECTED, + /* Device is being charged. */ + PCHG_STATE_CHARGING, +}; + +#define EC_PCHG_STATE_TEXT { \ + [PCHG_STATE_RESET] = "RESET", \ + [PCHG_STATE_INITIALIZED] = "INITIALIZED", \ + [PCHG_STATE_ENABLED] = "ENABLED", \ + [PCHG_STATE_DETECTED] = "DETECTED", \ + [PCHG_STATE_CHARGING] = "CHARGING", \ + } + /*****************************************************************************/ /* The command range 0x200-0x2FF is reserved for Rotor. */ diff --git a/util/ectool.c b/util/ectool.c index af9870dcf1..bd2d0e5c73 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -208,6 +208,8 @@ const char help_str[] = " Prints saved panic info\n" " pause_in_s5 [on|off]\n" " Whether or not the AP should pause in S5 on shutdown\n" + " pchg [<port>]\n" + " Get peripheral charge port count and status\n" " pdcontrol [suspend|resume|reset|disable|on]\n" " Controls the PD chip\n" " pdchipinfo <port>\n" @@ -9145,6 +9147,72 @@ int cmd_charge_port_override(int argc, char *argv[]) return 0; } +static void cmd_pchg_help(char *cmd) +{ + fprintf(stderr, + " Usage1: %s\n" + " Usage2: %s <port>\n" + "\n" + " Usage1 prints the number of ports.\n" + " Usage2 prints the status of a port.\n", + cmd, cmd); +} + +int cmd_pchg(int argc, char *argv[]) +{ + int port, port_count; + char *e; + int rv; + struct ec_response_pchg_count *rsp_count = ec_inbuf; + static const char * const pchg_state_text[] = EC_PCHG_STATE_TEXT; + + rv = ec_command(EC_CMD_PCHG_COUNT, 0, NULL, 0, ec_inbuf, ec_max_insize); + if (rv < 0) { + fprintf(stderr, "Failed to get port count: %d\n", rv); + return rv; + } + port_count = rsp_count->port_count; + + if (argc == 1) { + /* Usage1 */ + printf("%d\n", port_count); + return 0; + } + + port = strtol(argv[1], &e, 0); + if ((e && *e) || port >= port_count) { + fprintf(stderr, "Bad port index\n"); + return -1; + } + + if (argc < 3) { + /* Usage2 */ + struct ec_params_pchg *p = ec_outbuf; + struct ec_response_pchg *r = ec_inbuf; + + p->port = port; + rv = ec_command(EC_CMD_PCHG, 0, ec_outbuf, sizeof(*p), + ec_inbuf, ec_max_insize); + if (rv < 0) { + fprintf(stderr, "Error code: %d\n", rv); + return rv; + } + + printf("State: %s (%d)\n", + r->state < sizeof(pchg_state_text) ? + pchg_state_text[r->state] : "UNDEF", + r->state); + printf("Battery: %d%%\n", r->battery_percentage); + printf("Flags: 0x%x\n", r->error); + return 0; + } + + fprintf(stderr, "Invalid parameter count\n\n"); + cmd_pchg_help(argv[0]); + + return -1; +} + int cmd_pd_log(int argc, char *argv[]) { union { @@ -9776,6 +9844,7 @@ const struct command commands[] = { {"nextevent", cmd_next_event}, {"panicinfo", cmd_panic_info}, {"pause_in_s5", cmd_s5}, + {"pchg", cmd_pchg}, {"pdgetmode", cmd_pd_get_amode}, {"pdsetmode", cmd_pd_set_amode}, {"port80read", cmd_port80_read}, |