summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhuohao Lee <zhuohao@chromium.org>2019-01-19 17:03:10 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-02-11 03:06:45 +0000
commit64725769a67d68e48594fbe8c0668cc645542f1c (patch)
tree6ab2b6b4fa5e4d95566ff54c1edb2bbe1f43aa81
parentdafb9c633f0f974f56595f9caa930757813727a4 (diff)
downloadchrome-ec-64725769a67d68e48594fbe8c0668cc645542f1c.tar.gz
usb_port_power_smart: turn on/off charging mode during system suspend
This patch adds a feature to allow the userspace program turns on/off the usb type-a charging mode during system suspend. BUG=b:121438672 BRANCH=firmware-rammus-11275 TEST=make -j buildall ectool usbchargemode 0 0x2 0, CDP works in S0 and S0ix ectool usbchargemode 0 0x2 1, CDP works in S0 but not in S0ix Change-Id: Icb8ab1b3f1beb671fbd02f441bf40284ba74e097 Signed-off-by: Zhuohao Lee <zhuohao@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1424040 Reviewed-by: Jett Rink <jettrink@chromium.org> (cherry picked from commit 9670696203029efa87b0871073e149b7ba8619c2) Reviewed-on: https://chromium-review.googlesource.com/c/1460291
-rw-r--r--common/acpi.c3
-rw-r--r--common/usb_port_power_dumb.c6
-rw-r--r--common/usb_port_power_smart.c69
-rw-r--r--include/ec_commands.h3
-rw-r--r--include/usb_charge.h15
-rw-r--r--util/ectool.c17
6 files changed, 86 insertions, 27 deletions
diff --git a/common/acpi.c b/common/acpi.c
index da6795acd9..1355b6c636 100644
--- a/common/acpi.c
+++ b/common/acpi.c
@@ -358,7 +358,8 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
if (mode_field & 1)
mode = USB_CHARGE_MODE_ENABLED;
- if (usb_charge_set_mode(i, mode)) {
+ if (usb_charge_set_mode(i, mode,
+ USB_ALLOW_SUSPEND_CHARGE)) {
CPRINTS("ERROR: could not set charge "
"mode of USB port p%d to %d",
i, mode);
diff --git a/common/usb_port_power_dumb.c b/common/usb_port_power_dumb.c
index a37fb84c3f..ea6904c97f 100644
--- a/common/usb_port_power_dumb.c
+++ b/common/usb_port_power_dumb.c
@@ -47,7 +47,8 @@ static void usb_port_all_ports_off(void)
/*****************************************************************************/
/* Host commands */
-int usb_charge_set_mode(int port_id, enum usb_charge_mode mode)
+int usb_charge_set_mode(int port_id, enum usb_charge_mode mode,
+ enum usb_suspend_charge inhibit_charge)
{
CPRINTS("USB port p%d %d", port_id, mode);
@@ -72,7 +73,8 @@ static int usb_port_command_set_mode(struct host_cmd_handler_args *args)
{
const struct ec_params_usb_charge_set_mode *p = args->params;
- if (usb_charge_set_mode(p->usb_port_id, p->mode) != EC_SUCCESS)
+ if (usb_charge_set_mode(p->usb_port_id, p->mode,
+ p->inhibit_charge) != EC_SUCCESS)
return EC_RES_ERROR;
return EC_RES_SUCCESS;
diff --git a/common/usb_port_power_smart.c b/common/usb_port_power_smart.c
index 0d1b18d820..8da655f331 100644
--- a/common/usb_port_power_smart.c
+++ b/common/usb_port_power_smart.c
@@ -25,7 +25,10 @@
#define CONFIG_USB_PORT_POWER_SMART_DEFAULT_MODE USB_CHARGE_MODE_SDP2
#endif
-static uint8_t charge_mode[CONFIG_USB_PORT_POWER_SMART_PORT_COUNT];
+static struct {
+ uint8_t mode:7;
+ uint8_t inhibit_charging_in_suspend:1;
+} charge_mode[CONFIG_USB_PORT_POWER_SMART_PORT_COUNT];
/* GPIOs to enable/disable USB ports. Board specific. */
extern const int usb_port_enable[CONFIG_USB_PORT_POWER_SMART_PORT_COUNT];
@@ -91,12 +94,13 @@ static void usb_charge_all_ports_ctrl(enum usb_charge_mode mode)
int i;
for (i = 0; i < CONFIG_USB_PORT_POWER_SMART_PORT_COUNT; i++)
- usb_charge_set_mode(i, mode);
+ usb_charge_set_mode(i, mode, USB_ALLOW_SUSPEND_CHARGE);
}
-int usb_charge_set_mode(int port_id, enum usb_charge_mode mode)
+int usb_charge_set_mode(int port_id, enum usb_charge_mode mode,
+ enum usb_suspend_charge inhibit_charge)
{
- CPRINTS("USB charge p%d m%d", port_id, mode);
+ CPRINTS("USB charge p%d m%d i%d", port_id, mode, inhibit_charge);
if (port_id >= CONFIG_USB_PORT_POWER_SMART_PORT_COUNT)
return EC_ERROR_INVAL;
@@ -125,7 +129,8 @@ int usb_charge_set_mode(int port_id, enum usb_charge_mode mode)
return EC_ERROR_UNKNOWN;
}
- charge_mode[port_id] = mode;
+ charge_mode[port_id].mode = mode;
+ charge_mode[port_id].inhibit_charging_in_suspend = inhibit_charge;
return EC_SUCCESS;
}
@@ -136,17 +141,18 @@ int usb_charge_set_mode(int port_id, enum usb_charge_mode mode)
static int command_set_mode(int argc, char **argv)
{
int port_id = -1;
- int mode = -1;
+ int mode = -1, inhibit_charge = 0;
char *e;
int i;
if (argc == 1) {
for (i = 0; i < CONFIG_USB_PORT_POWER_SMART_PORT_COUNT; i++)
- ccprintf("Port %d: %d\n", i, charge_mode[i]);
+ ccprintf("Port %d: %d,%d\n", i, charge_mode[i].mode,
+ charge_mode[i].inhibit_charging_in_suspend);
return EC_SUCCESS;
}
- if (argc != 3)
+ if (argc != 3 && argc != 4)
return EC_ERROR_PARAM_COUNT;
port_id = strtoi(argv[1], &e, 0);
@@ -158,17 +164,26 @@ static int command_set_mode(int argc, char **argv)
if (*e || mode < 0 || mode >= USB_CHARGE_MODE_COUNT)
return EC_ERROR_PARAM2;
- return usb_charge_set_mode(port_id, mode);
+ if (argc == 4) {
+ inhibit_charge = strtoi(argv[3], &e, 0);
+ if (*e || (inhibit_charge != 0 && inhibit_charge != 1))
+ return EC_ERROR_PARAM3;
+ }
+
+ return usb_charge_set_mode(port_id, mode, inhibit_charge);
}
DECLARE_CONSOLE_COMMAND(usbchargemode, command_set_mode,
- "[<port> <0 | 1 | 2 | 3>]",
+ "[<port> <0 | 1 | 2 | 3> [<0 | 1>]]",
"Set USB charge mode");
/*
* Modes:
- * 0=Disabled.
- * 1=Standard downstream port.
- * 2=Charging downstream port, BC 1.2.
- * 3=Dedicated charging port, BC 1.2.
+ * 0 = Disabled.
+ * 1 = Standard downstream port.
+ * 2 = Charging downstream port, BC 1.2.
+ * 3 = Dedicated charging port, BC 1.2.
+ * Inhibit Charge:
+ * 0 = Enable charging during system suspend
+ * 1 = Disable charging during system suspend
*/
/*****************************************************************************/
@@ -178,7 +193,8 @@ static int usb_charge_command_set_mode(struct host_cmd_handler_args *args)
{
const struct ec_params_usb_charge_set_mode *p = args->params;
- if (usb_charge_set_mode(p->usb_port_id, p->mode) != EC_SUCCESS)
+ if (usb_charge_set_mode(p->usb_port_id, p->mode,
+ p->inhibit_charge) != EC_SUCCESS)
return EC_RES_ERROR;
return EC_RES_SUCCESS;
@@ -212,17 +228,36 @@ static void usb_charge_init(void)
}
for (i = 0; i < CONFIG_USB_PORT_POWER_SMART_PORT_COUNT; i++)
- usb_charge_set_mode(i, prev[i]);
+ usb_charge_set_mode(i, prev[i], USB_ALLOW_SUSPEND_CHARGE);
}
DECLARE_HOOK(HOOK_INIT, usb_charge_init, HOOK_PRIO_DEFAULT);
static void usb_charge_resume(void)
{
+ int i;
+
/* Turn on USB ports on as we go into S0 from S3 or S5. */
- usb_charge_all_ports_ctrl(CONFIG_USB_PORT_POWER_SMART_DEFAULT_MODE);
+ for (i = 0; i < CONFIG_USB_PORT_POWER_SMART_PORT_COUNT; i++)
+ usb_charge_set_mode(i,
+ CONFIG_USB_PORT_POWER_SMART_DEFAULT_MODE,
+ charge_mode[i].inhibit_charging_in_suspend);
}
DECLARE_HOOK(HOOK_CHIPSET_RESUME, usb_charge_resume, HOOK_PRIO_DEFAULT);
+static void usb_charge_suspend(void)
+{
+ int i;
+
+ /*
+ * Inhibit charging during suspend if the inhibit_charging_in_suspend
+ * is set to 1.
+ */
+ for (i = 0; i < CONFIG_USB_PORT_POWER_SMART_PORT_COUNT; i++)
+ if (charge_mode[i].inhibit_charging_in_suspend)
+ usb_charge_set_enabled(i, 0 /* disabled */);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, usb_charge_suspend, HOOK_PRIO_DEFAULT);
+
static void usb_charge_shutdown(void)
{
/* Turn on USB ports off as we go back to S5. */
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 76bf97f1c0..ca0660e5f5 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -2799,7 +2799,8 @@ struct ec_params_config_power_button {
struct ec_params_usb_charge_set_mode {
uint8_t usb_port_id;
- uint8_t mode;
+ uint8_t mode:7;
+ uint8_t inhibit_charge:1;
} __ec_align1;
/*****************************************************************************/
diff --git a/include/usb_charge.h b/include/usb_charge.h
index 1de3372434..6dfb8bd98b 100644
--- a/include/usb_charge.h
+++ b/include/usb_charge.h
@@ -30,14 +30,23 @@ enum usb_charge_mode {
USB_CHARGE_MODE_COUNT
};
+enum usb_suspend_charge {
+ /* Enable charging in suspend */
+ USB_ALLOW_SUSPEND_CHARGE,
+ /* Disable charging in suspend */
+ USB_DISALLOW_SUSPEND_CHARGE
+};
+
/**
* Set USB charge mode for the port.
*
- * @param usb_port_id Port to set.
- * @param mode New mode for port.
+ * @param usb_port_id Port to set.
+ * @param mode New mode for port.
+ * @param inhibit_charge Inhibit charging during system suspend.
* @return EC_SUCCESS, or non-zero if error.
*/
-int usb_charge_set_mode(int usb_port_id, enum usb_charge_mode mode);
+int usb_charge_set_mode(int usb_port_id, enum usb_charge_mode mode,
+ enum usb_suspend_charge inhibit_charge);
#ifdef HAS_TASK_USB_CHG_P0
#define USB_CHG_EVENT_BC12 TASK_EVENT_CUSTOM(1)
diff --git a/util/ectool.c b/util/ectool.c
index b691500c2b..63833eb6da 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -4918,9 +4918,10 @@ int cmd_usb_charge_set_mode(int argc, char *argv[])
char *e;
int rv;
- if (argc != 3) {
+ if (argc != 3 && argc != 4) {
fprintf(stderr,
- "Usage: %s <port_id> <mode_id>\n", argv[0]);
+ "Usage: %s <port_id> <mode_id> <inhibit_charge>\n",
+ argv[0]);
return -1;
}
p.usb_port_id = strtol(argv[1], &e, 0);
@@ -4933,8 +4934,18 @@ int cmd_usb_charge_set_mode(int argc, char *argv[])
fprintf(stderr, "Bad mode ID.\n");
return -1;
}
+ p.inhibit_charge = 0;
+ if (argc == 4) {
+ p.inhibit_charge = strtol(argv[3], &e, 0);
+ if ((e && *e) || (p.inhibit_charge != 0 &&
+ p.inhibit_charge != 1)) {
+ fprintf(stderr, "Bad value\n");
+ return -1;
+ }
+ }
- printf("Setting port %d to mode %d...\n", p.usb_port_id, p.mode);
+ printf("Setting port %d to mode %d inhibit_charge %d...\n",
+ p.usb_port_id, p.mode, p.inhibit_charge);
rv = ec_command(EC_CMD_USB_CHARGE_SET_MODE, 0,
&p, sizeof(p), NULL, 0);