summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/samus/extpower.c17
-rw-r--r--common/charge_manager.c3
-rw-r--r--common/pd_log.c32
-rw-r--r--include/charge_manager.h2
-rw-r--r--include/ec_commands.h14
-rw-r--r--util/ectool.c37
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},