From 13c74da5ade0b98c9c024bf72e0c78c5155a8d08 Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Tue, 2 Apr 2013 15:52:31 +0800 Subject: [PATCH] spring: Add host command to limit external power current This is useful for debugging and the factory. BUG=chrome-os-partner:18530 TEST=On spring, check we can set PWM duty cycle and can go back to automatic control. BRANCH=spring Change-Id: I3da75f0a356cc0f21d748bf135e3b95fbd9c465b Signed-off-by: Vic Yang Reviewed-on: https://gerrit.chromium.org/gerrit/47105 Reviewed-by: Vincent Palatin --- board/spring/usb_charging.c | 39 +++++++++++++++++++++++++++++++++++-- include/ec_commands.h | 11 ++++++++++- util/ectool.c | 26 +++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/board/spring/usb_charging.c b/board/spring/usb_charging.c index 752d67c1bf..e46153fa32 100644 --- a/board/spring/usb_charging.c +++ b/board/spring/usb_charging.c @@ -10,13 +10,15 @@ #include "chipset.h" #include "clock.h" #include "console.h" -#include "hooks.h" #include "gpio.h" +#include "hooks.h" +#include "host_command.h" #include "keyboard_protocol.h" #include "pmu_tpschrome.h" #include "registers.h" #include "smart_battery.h" #include "stm32_adc.h" +#include "system.h" #include "task.h" #include "timer.h" #include "tsu6721.h" @@ -64,9 +66,17 @@ #define DELAY_USB_DP_DN_MS 20 #define DELAY_ID_MUX_MS 30 +/* + * Mapping from PWM duty to current: + * Current = A + B * PWM_Duty + */ +#define PWM_MAPPING_A 3012 +#define PWM_MAPPING_B (-29) + static int current_dev_type = TSU6721_TYPE_NONE; static int nominal_pwm_duty; static int current_pwm_duty; +static int user_pwm_duty = -1; static int pending_tsu6721_reset; @@ -292,6 +302,13 @@ static void board_pwm_tweak(void) vbus = adc_read_channel(ADC_CH_USB_VBUS_SNS); if (battery_current(¤t)) return; + + if (user_pwm_duty >= 0) { + if (current_pwm_duty != user_pwm_duty) + board_pwm_duty_cycle(user_pwm_duty); + return; + } + /* * If VBUS voltage is too low: * - If battery is discharging, throttling more is going to draw @@ -556,7 +573,7 @@ int board_get_usb_dev_type(void) int board_get_usb_current_limit(void) { /* Approximate value by PWM duty cycle */ - return 3012 - 29 * current_pwm_duty; + return PWM_MAPPING_A + PWM_MAPPING_B * current_pwm_duty; } /* @@ -639,3 +656,21 @@ DECLARE_CONSOLE_COMMAND(limitmode, command_current_limit_mode, "[normal | aggressive]", "Set current limit mode", NULL); + +/*****************************************************************************/ +/* Host commands */ + +static int ext_power_command_current_limit(struct host_cmd_handler_args *args) +{ + const struct ec_params_ext_power_current_limit *p = args->params; + + if (system_is_locked()) + return EC_RES_ACCESS_DENIED; + + user_pwm_duty = ((int)(p->limit) - PWM_MAPPING_A) / PWM_MAPPING_B; + + return EC_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_EXT_POWER_CURRENT_LIMIT, + ext_power_command_current_limit, + EC_VER_MASK(0)); diff --git a/include/ec_commands.h b/include/ec_commands.h index 17e35a1355..caa0bcd3ee 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -1273,7 +1273,16 @@ struct ec_response_power_info { #define EC_CMD_CHARGE_CURRENT_LIMIT 0xa1 struct ec_params_current_limit { - uint32_t limit; + uint32_t limit; /* in mA */ +} __packed; + +/* + * Set maximum external power current. + */ +#define EC_CMD_EXT_POWER_CURRENT_LIMIT 0xa2 + +struct ec_params_ext_power_current_limit { + uint32_t limit; /* in mA */ } __packed; /*****************************************************************************/ diff --git a/util/ectool.c b/util/ectool.c index 0332ea6c45..09166b4ae3 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -28,6 +28,8 @@ static inline int MIN(int a, int b) { return a < b ? a : b; } const char help_str[] = "Commands:\n" + " extpwrcurrentlimit\n" + " Set the maximum external power current\n" " autofanctrl \n" " Turn on automatic fan speed control.\n" " backlight \n" @@ -2024,6 +2026,29 @@ int cmd_lcd_backlight(int argc, char *argv[]) } +int cmd_ext_power_current_limit(int argc, char *argv[]) +{ + struct ec_params_ext_power_current_limit p; + int rv; + char *e; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return -1; + } + + p.limit = strtol(argv[1], &e, 0); + if (e && *e) { + fprintf(stderr, "Bad value.\n"); + return -1; + } + + rv = ec_command(EC_CMD_EXT_POWER_CURRENT_LIMIT, 0, &p, sizeof(p), + NULL, 0); + return rv; +} + + int cmd_charge_current_limit(int argc, char *argv[]) { struct ec_params_current_limit p; @@ -2730,6 +2755,7 @@ struct command { /* 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},