diff options
-rw-r--r-- | board/samus/extpower.c | 17 | ||||
-rw-r--r-- | common/charge_manager.c | 3 | ||||
-rw-r--r-- | common/pd_log.c | 32 | ||||
-rw-r--r-- | include/charge_manager.h | 2 | ||||
-rw-r--r-- | include/ec_commands.h | 14 | ||||
-rw-r--r-- | util/ectool.c | 37 |
6 files changed, 103 insertions, 2 deletions
diff --git a/board/samus/extpower.c b/board/samus/extpower.c index 79eb941d18..19f4a5d5ff 100644 --- a/board/samus/extpower.c +++ b/board/samus/extpower.c @@ -245,6 +245,22 @@ static int get_boostin_voltage(void) return ret; } +/* + * Send command to PD to write a custom persistent log entry indicating that + * charging was wedged. Returns pd_host_command success status. + */ +static int log_charge_wedged(void) +{ + static struct ec_params_pd_write_log_entry log_args; + + log_args.type = PD_EVENT_MCU_BOARD_CUSTOM; + log_args.port = 0; + + return pd_host_command(EC_CMD_PD_WRITE_LOG_ENTRY, 0, + &log_args, + sizeof(struct ec_params_pd_write_log_entry), + NULL, 0); +} /* Time interval between checking if charge circuit is wedged */ #define CHARGE_WEDGE_CHECK_INTERVAL (2*SECOND) @@ -320,6 +336,7 @@ static void check_charge_wedged(void) host_command_pd_send_status(PD_CHARGE_NONE); charger_disable(1); charge_circuit_state = CHARGE_CIRCUIT_WEDGED; + log_charge_wedged(); CPRINTS("Charge wedged! PROCHOT %02x, Stalled: %d", prochot_status, charge_stalled_count); diff --git a/common/charge_manager.c b/common/charge_manager.c index 35a570d2e6..bf93724cbd 100644 --- a/common/charge_manager.c +++ b/common/charge_manager.c @@ -199,6 +199,9 @@ void charge_manager_save_log(int port) uint16_t flags = 0; struct ec_response_usb_pd_power_info pinfo; + if (port < 0 || port >= PD_PORT_COUNT) + return; + save_log[port] = 0; charge_manager_fill_power_info(port, &pinfo); diff --git a/common/pd_log.c b/common/pd_log.c index fa9b8c3bf5..96d55f9330 100644 --- a/common/pd_log.c +++ b/common/pd_log.c @@ -3,6 +3,7 @@ * found in the LICENSE file. */ +#include "charge_manager.h" #include "console.h" #include "hooks.h" #include "host_command.h" @@ -194,6 +195,37 @@ dequeue_retry: DECLARE_HOST_COMMAND(EC_CMD_PD_GET_LOG_ENTRY, hc_pd_get_log_entry, EC_VER_MASK(0)); + +static int hc_pd_write_log_entry(struct host_cmd_handler_args *args) +{ + const struct ec_params_pd_write_log_entry *p = args->params; + uint8_t type = p->type; + uint8_t port = p->port; + + if (type < PD_EVENT_MCU_BASE || type >= PD_EVENT_ACC_BASE) + return EC_RES_INVALID_PARAM; + if (port > 0 && port >= PD_PORT_COUNT) + return EC_RES_INVALID_PARAM; + + switch (type) { + /* Charge event: Log data for all ports */ + case PD_EVENT_MCU_CHARGE: + charge_manager_save_log(port); + break; + + /* Other events: no extra data, just log event type + port */ + case PD_EVENT_MCU_CONNECT: + case PD_EVENT_MCU_BOARD_CUSTOM: + default: + pd_log_event(type, PD_LOG_PORT_SIZE(port, 0), 0, NULL); + break; + } + + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_PD_WRITE_LOG_ENTRY, + hc_pd_write_log_entry, + EC_VER_MASK(0)); #else /* !HAS_TASK_HOSTCMD */ /* we are a PD accessory, send back the events as a VDM (VDO_CMD_GET_LOG) */ int pd_vdm_get_log_entry(uint32_t *payload) diff --git a/include/charge_manager.h b/include/charge_manager.h index d761f131fc..6654542667 100644 --- a/include/charge_manager.h +++ b/include/charge_manager.h @@ -6,6 +6,8 @@ #ifndef __CHARGE_MANAGER_H #define __CHARGE_MANAGER_H +#include "common.h" + /* Charge port that indicates no active port */ #define CHARGE_SUPPLIER_NONE -1 #define CHARGE_PORT_NONE -1 diff --git a/include/ec_commands.h b/include/ec_commands.h index 304cb9acda..edf9f4fa6b 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -2888,8 +2888,10 @@ struct ec_response_pd_log { /* PD event log : entry types */ /* PD MCU events */ #define PD_EVENT_MCU_BASE 0x00 -#define PD_EVENT_MCU_CHARGE (PD_EVENT_MCU_BASE+0) -#define PD_EVENT_MCU_CONNECT (PD_EVENT_MCU_BASE+1) +#define PD_EVENT_MCU_CHARGE (PD_EVENT_MCU_BASE+0) +#define PD_EVENT_MCU_CONNECT (PD_EVENT_MCU_BASE+1) +/* Reserved for custom board event */ +#define PD_EVENT_MCU_BOARD_CUSTOM (PD_EVENT_MCU_BASE+2) /* PD generic accessory events */ #define PD_EVENT_ACC_BASE 0x20 #define PD_EVENT_ACC_RW_FAIL (PD_EVENT_ACC_BASE+0) @@ -2978,6 +2980,14 @@ struct ec_params_usb_pd_set_mode_request { uint8_t port; /* port */ } __packed; +/* Ask the PD MCU to record a log of a requested type */ +#define EC_CMD_PD_WRITE_LOG_ENTRY 0x117 + +struct ec_params_pd_write_log_entry { + uint8_t type; /* event type : see PD_EVENT_xx above */ + uint8_t port; /* port#, or 0 for events unrelated to a given port */ +} __packed; + #endif /* !__ACPI__ */ /*****************************************************************************/ diff --git a/util/ectool.c b/util/ectool.c index 251e604b84..ed4787706f 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -141,6 +141,8 @@ const char help_str[] = " Whether or not the AP should pause in S5 on shutdown\n" " pdlog\n" " Prints the PD event log entries\n" + " pdwritelog <type> <port>\n" + " Writes a PD event log of the given <type>\n" " pdgetmode <port>\n" " Get All USB-PD alternate SVIDs and modes on <port>\n" " pdsetmode <port> <svid> <opos>\n" @@ -5469,6 +5471,10 @@ int cmd_pd_log(int argc, char *argv[]) >> CHARGE_FLAGS_TYPE_SHIFT; pinfo.max_power = 0; print_pd_power_info(&pinfo); + } else if (u.r.type == PD_EVENT_MCU_CONNECT) { + printf("New connection\n"); + } else if (u.r.type == PD_EVENT_MCU_BOARD_CUSTOM) { + printf("Board-custom event\n"); } else if (u.r.type == PD_EVENT_ACC_RW_FAIL) { printf("RW signature check failed\n"); } else if (u.r.type == PD_EVENT_PS_FAULT) { @@ -5503,6 +5509,36 @@ int cmd_pd_log(int argc, char *argv[]) return 0; } +int cmd_pd_write_log(int argc, char *argv[]) +{ + struct ec_params_pd_write_log_entry p; + char *e; + + if (argc < 3) { + fprintf(stderr, "Usage: %s <log_type> <port>\n", + argv[0]); + return -1; + } + + if (!strcasecmp(argv[1], "charge")) + p.type = PD_EVENT_MCU_CHARGE; + else { + p.type = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad log_type parameter.\n"); + return -1; + } + } + + p.port = strtol(argv[2], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad port parameter.\n"); + return -1; + } + + return ec_command(EC_CMD_PD_WRITE_LOG_ENTRY, 0, &p, sizeof(p), NULL, 0); +} + /* NULL-terminated list of commands */ const struct command commands[] = { {"extpwrcurrentlimit", cmd_ext_power_current_limit}, @@ -5559,6 +5595,7 @@ const struct command commands[] = { {"pdsetmode", cmd_pd_set_amode}, {"port80read", cmd_port80_read}, {"pdlog", cmd_pd_log}, + {"pdwritelog", cmd_pd_write_log}, {"powerinfo", cmd_power_info}, {"protoinfo", cmd_proto_info}, {"pstoreinfo", cmd_pstore_info}, |