mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-11 02:15:14 +00:00
usb_pd: Add host command to limit external charger voltage / current
PD charger voltage + current can now be limited with EC_CMD_EXTERNAL_POWER_LIMIT. The limit is automatically cleared when the AP transitions out of S0 into S3 / suspend. BUG=chrome-os-partner:43285 TEST=Manual on Samus w/ zinger. - Plug zinger, verify charging at 20V/3A. - `ectool extpwrlimit 3000 12000 --dev=1`, verify charging at 12V/3A - `ectool extpwrlimit 1000 5000 --dev=1`, verify charging at 5V/1A - Plug zinger into other port, verify still charging at 5V/1A - `powerd_dbus_suspend`, verify charging at 20V/3A - `chglim 2000 12000`, verify charging at 12V/2A - `ectool extpwrlimit 0xffff 0xffff --dev=1`, verify charging at 20V/3A - `chglim 1000 20000`, verify charging at 20V/1A - `chglim`, verify charging at 20V/3A BRANCH=ryu Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: I6cd5377be91b3df75f99cb414fd3fa5a463b56cb Reviewed-on: https://chromium-review.googlesource.com/293954 Reviewed-by: Todd Broch <tbroch@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
6f8637a6df
commit
ad8ce3f806
@@ -22,6 +22,7 @@
|
||||
/* Optional features */
|
||||
#undef CONFIG_CMD_HASH
|
||||
#define CONFIG_CHARGE_MANAGER
|
||||
#define CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT
|
||||
#define CONFIG_CHARGE_RAMP_HW
|
||||
#define CONFIG_FORCE_CONSOLE_RESUME
|
||||
#define CONFIG_STM_HWTIMER32
|
||||
|
||||
@@ -855,3 +855,76 @@ DECLARE_CONSOLE_COMMAND(chgoverride, command_charge_port_override,
|
||||
"[port | -1 | -2]",
|
||||
"Force charging from a given port (-1 = off, -2 = disable charging)",
|
||||
NULL);
|
||||
|
||||
#ifdef CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT
|
||||
static void charge_manager_set_external_power_limit(int current_lim,
|
||||
int voltage_lim)
|
||||
{
|
||||
int port;
|
||||
|
||||
if (current_lim == EC_POWER_LIMIT_NONE)
|
||||
current_lim = CHARGE_CEIL_NONE;
|
||||
if (voltage_lim == EC_POWER_LIMIT_NONE)
|
||||
voltage_lim = PD_MAX_VOLTAGE_MV;
|
||||
|
||||
for (port = 0; port < CONFIG_USB_PD_PORT_COUNT; ++port) {
|
||||
charge_manager_set_ceil(port, CEIL_REQUESTOR_HOST, current_lim);
|
||||
pd_set_external_voltage_limit(port, voltage_lim);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On transition out of S0, disable all external power limits, in case AP
|
||||
* failed to clear them.
|
||||
*/
|
||||
static void charge_manager_external_power_limit_off(void)
|
||||
{
|
||||
charge_manager_set_external_power_limit(EC_POWER_LIMIT_NONE,
|
||||
EC_POWER_LIMIT_NONE);
|
||||
}
|
||||
DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, charge_manager_external_power_limit_off,
|
||||
HOOK_PRIO_DEFAULT);
|
||||
|
||||
static int hc_external_power_limit(struct host_cmd_handler_args *args)
|
||||
{
|
||||
const struct ec_params_external_power_limit_v1 *p = args->params;
|
||||
|
||||
charge_manager_set_external_power_limit(p->current_lim,
|
||||
p->voltage_lim);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_EXTERNAL_POWER_LIMIT,
|
||||
hc_external_power_limit,
|
||||
EC_VER_MASK(1));
|
||||
|
||||
static int command_external_power_limit(int argc, char **argv)
|
||||
{
|
||||
int max_current;
|
||||
int max_voltage;
|
||||
char *e;
|
||||
|
||||
if (argc >= 2) {
|
||||
max_current = strtoi(argv[1], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM1;
|
||||
} else
|
||||
max_current = EC_POWER_LIMIT_NONE;
|
||||
|
||||
if (argc >= 3) {
|
||||
max_voltage = strtoi(argv[2], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM1;
|
||||
} else
|
||||
max_voltage = EC_POWER_LIMIT_NONE;
|
||||
|
||||
charge_manager_set_external_power_limit(max_current, max_voltage);
|
||||
ccprintf("max req: %dmA %dmV\n", max_current, max_voltage);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(chglim, command_external_power_limit,
|
||||
"[max_current (mA)] [max_voltage (mV)]",
|
||||
"Set max charger current / voltage",
|
||||
NULL);
|
||||
#endif /* CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT */
|
||||
|
||||
@@ -34,7 +34,7 @@ static int rw_flash_changed = 1;
|
||||
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
/* Cap on the max voltage requested as a sink (in millivolts) */
|
||||
static unsigned max_request_mv = -1; /* no cap */
|
||||
static unsigned max_request_mv = PD_MAX_VOLTAGE_MV; /* no cap */
|
||||
|
||||
/**
|
||||
* Find PDO index that offers the most amount of power and stays within
|
||||
@@ -53,10 +53,6 @@ static int pd_find_pdo_index(int cnt, uint32_t *src_caps, int max_mv)
|
||||
int cur_mv;
|
||||
#endif
|
||||
|
||||
/* max_mv of -1 represents max limit */
|
||||
if (max_mv == -1)
|
||||
max_mv = PD_MAX_VOLTAGE_MV;
|
||||
|
||||
/* max voltage is always limited by this boards max request */
|
||||
max_mv = MIN(max_mv, PD_MAX_VOLTAGE_MV);
|
||||
|
||||
@@ -155,7 +151,7 @@ void pd_process_source_cap(int port, int cnt, uint32_t *src_caps)
|
||||
int pdo_index;
|
||||
|
||||
/* Get max power info that we could request */
|
||||
pdo_index = pd_find_pdo_index(cnt, src_caps, -1);
|
||||
pdo_index = pd_find_pdo_index(cnt, src_caps, PD_MAX_VOLTAGE_MV);
|
||||
if (pdo_index < 0)
|
||||
pdo_index = 0;
|
||||
pd_extract_pdo_power(src_caps[pdo_index], &ma, &mv);
|
||||
|
||||
@@ -2725,6 +2725,19 @@ void pd_request_source_voltage(int port, int mv)
|
||||
|
||||
task_wake(PD_PORT_TO_TASK_ID(port));
|
||||
}
|
||||
|
||||
void pd_set_external_voltage_limit(int port, int mv)
|
||||
{
|
||||
pd_set_max_voltage(mv);
|
||||
|
||||
if (pd[port].task_state == PD_STATE_SNK_READY ||
|
||||
pd[port].task_state == PD_STATE_SNK_TRANSITION) {
|
||||
/* Set flag to send new power request in pd_task */
|
||||
pd[port].new_power_request = 1;
|
||||
task_wake(PD_PORT_TO_TASK_ID(port));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USB_PD_DUAL_ROLE */
|
||||
|
||||
static int command_pd(int argc, char **argv)
|
||||
|
||||
@@ -247,6 +247,9 @@
|
||||
/* Compile charge manager */
|
||||
#undef CONFIG_CHARGE_MANAGER
|
||||
|
||||
/* Handle the external power limit host command in charge manager */
|
||||
#undef CONFIG_CHARGE_MANAGER_EXTERNAL_POWER_LIMIT
|
||||
|
||||
/* Compile input current ramping support */
|
||||
#undef CONFIG_CHARGE_RAMP
|
||||
|
||||
|
||||
@@ -2842,14 +2842,18 @@ struct ec_params_current_limit {
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Set maximum external power current.
|
||||
* Set maximum external voltage / current.
|
||||
*/
|
||||
#define EC_CMD_EXT_POWER_CURRENT_LIMIT 0xa2
|
||||
#define EC_CMD_EXTERNAL_POWER_LIMIT 0xa2
|
||||
|
||||
struct ec_params_ext_power_current_limit {
|
||||
uint32_t limit; /* in mA */
|
||||
/* Command v0 is used only on Spring and is obsolete + unsupported */
|
||||
struct ec_params_external_power_limit_v1 {
|
||||
uint16_t current_lim; /* in mA, or EC_POWER_LIMIT_NONE to clear limit */
|
||||
uint16_t voltage_lim; /* in mV, or EC_POWER_LIMIT_NONE to clear limit */
|
||||
} __packed;
|
||||
|
||||
#define EC_POWER_LIMIT_NONE 0xffff
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Smart battery pass-through */
|
||||
|
||||
|
||||
@@ -946,6 +946,15 @@ int pd_set_power_supply_ready(int port);
|
||||
*/
|
||||
void pd_request_source_voltage(int port, int mv);
|
||||
|
||||
/**
|
||||
* Set a voltage limit from the PD source.
|
||||
*
|
||||
* If the source is currently active, it triggers a new negotiation.
|
||||
* @param port USB-C port number
|
||||
* @param mv limit voltage in millivolts.
|
||||
*/
|
||||
void pd_set_external_voltage_limit(int port, int mv);
|
||||
|
||||
/**
|
||||
* Set the PD input current limit.
|
||||
*
|
||||
|
||||
@@ -43,8 +43,6 @@ static struct option long_opts[] = {
|
||||
|
||||
const char help_str[] =
|
||||
"Commands:\n"
|
||||
" extpwrcurrentlimit\n"
|
||||
" Set the maximum external power current\n"
|
||||
" autofanctrl <on>\n"
|
||||
" Turn on automatic fan speed control.\n"
|
||||
" backlight <enabled>\n"
|
||||
@@ -93,6 +91,8 @@ const char help_str[] =
|
||||
" Sets the SMI mask for EC host events\n"
|
||||
" eventsetwakemask <mask>\n"
|
||||
" Sets the wake mask for EC host events\n"
|
||||
" extpwrlimit\n"
|
||||
" Set the maximum external power limit\n"
|
||||
" fanduty <percent>\n"
|
||||
" Forces the fan PWM to a constant duty cycle\n"
|
||||
" flasherase <offset> <size>\n"
|
||||
@@ -4829,26 +4829,34 @@ int cmd_lcd_backlight(int argc, char *argv[])
|
||||
}
|
||||
|
||||
|
||||
int cmd_ext_power_current_limit(int argc, char *argv[])
|
||||
int cmd_ext_power_limit(int argc, char *argv[])
|
||||
{
|
||||
struct ec_params_ext_power_current_limit p;
|
||||
int rv;
|
||||
/* Version 1 is used, no support for obsolete version 0 */
|
||||
struct ec_params_external_power_limit_v1 p;
|
||||
char *e;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <max_current_mA>\n", argv[0]);
|
||||
if (argc != 3) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s <max_current_mA> <max_voltage_mV>\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p.limit = strtol(argv[1], &e, 0);
|
||||
p.current_lim = strtol(argv[1], &e, 0);
|
||||
if (e && *e) {
|
||||
fprintf(stderr, "Bad value.\n");
|
||||
fprintf(stderr, "Bad param1.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = ec_command(EC_CMD_EXT_POWER_CURRENT_LIMIT, 0, &p, sizeof(p),
|
||||
NULL, 0);
|
||||
return rv;
|
||||
p.voltage_lim = strtol(argv[2], &e, 0);
|
||||
if (e && *e) {
|
||||
fprintf(stderr, "Bad param2.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send version 1 of command */
|
||||
return ec_command(EC_CMD_EXTERNAL_POWER_LIMIT, 1, &p, sizeof(p),
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -6315,7 +6323,6 @@ int cmd_pd_write_log(int argc, char *argv[])
|
||||
|
||||
/* NULL-terminated list of commands */
|
||||
const struct command commands[] = {
|
||||
{"extpwrcurrentlimit", cmd_ext_power_current_limit},
|
||||
{"autofanctrl", cmd_thermal_auto_fan_ctrl},
|
||||
{"backlight", cmd_lcd_backlight},
|
||||
{"battery", cmd_battery},
|
||||
@@ -6340,6 +6347,7 @@ const struct command commands[] = {
|
||||
{"eventsetscimask", cmd_host_event_set_sci_mask},
|
||||
{"eventsetsmimask", cmd_host_event_set_smi_mask},
|
||||
{"eventsetwakemask", cmd_host_event_set_wake_mask},
|
||||
{"extpwrlimit", cmd_ext_power_limit},
|
||||
{"fanduty", cmd_fanduty},
|
||||
{"flasherase", cmd_flash_erase},
|
||||
{"flashprotect", cmd_flash_protect},
|
||||
|
||||
Reference in New Issue
Block a user