From 5c808ee56c44be4c665de6a85f5feb5cd5753f9d Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Fri, 7 Feb 2014 10:45:05 -0800 Subject: [PATCH] Support DPTF charger current limiting This enables the AP to limit charging current via ACPI. BUG=chrome-os-partner:23971 BRANCH=rambi TEST=manual drain battery down to <90%, then plug into AC (charger commands at EC console, iotools at root shell) iotools io_write8 0x66 0x81 iotools io_write8 0x62 0x08 iotools io_write8 0x62 3 charger -> dptf limit 192, I_batt=192 charger dptf 320 charger -> dptf limit 320, I_batt=320 iotools io_write8 0x66 0x80 iotools io_write8 0x62 0x08 iotools io_read8 0x62 -> 0x05 iotools io_write8 0x66 0x81 iotools io_write8 0x62 0x08 iotools io_write8 0x62 0xff charger -> dptf disabled, I_batt=(something > 192) iotools io_write8 0x66 0x80 iotools io_write8 0x62 0x08 iotools io_read8 0x62 -> 0xff Change-Id: Iace2ebbbc018143c0154310d7acd02d16a6b7339 Signed-off-by: Randall Spangler Reviewed-on: https://chromium-review.googlesource.com/185411 Reviewed-by: Bill Richardson --- common/acpi.c | 19 +++++++++++++++++++ common/charger.c | 33 ++++++++++++++++++++++++++++++++- include/dptf.h | 28 +++++++++++++++++++++++----- include/ec_commands.h | 8 ++++++++ 4 files changed, 82 insertions(+), 6 deletions(-) diff --git a/common/acpi.c b/common/acpi.c index 69cf3bc837..eed20fdbe0 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -75,6 +75,15 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) case EC_ACPI_MEM_TEMP_ID: result = dptf_query_next_sensor_event(); break; +#endif +#ifdef CONFIG_CHARGER + case EC_ACPI_MEM_CHARGING_LIMIT: + result = dptf_get_charging_current_limit(); + if (result >= 0) + result /= EC_ACPI_MEM_CHARGING_LIMIT_STEP_MA; + else + result = EC_ACPI_MEM_CHARGING_LIMIT_DISABLED; + break; #endif default: CPRINTF("[%T ACPI read 0x%02x (ignored)]\n", acpi_addr); @@ -123,6 +132,16 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) idx, enable); break; } +#endif +#ifdef CONFIG_CHARGER + case EC_ACPI_MEM_CHARGING_LIMIT: + if (data == EC_ACPI_MEM_CHARGING_LIMIT_DISABLED) { + dptf_set_charging_current_limit(-1); + } else { + data *= EC_ACPI_MEM_CHARGING_LIMIT_STEP_MA; + dptf_set_charging_current_limit(data); + } + break; #endif default: CPRINTF("[%T ACPI write 0x%02x = 0x%02x (ignored)]\n", diff --git a/common/charger.c b/common/charger.c index ebac3896c1..3780b2b5a1 100644 --- a/common/charger.c +++ b/common/charger.c @@ -8,6 +8,7 @@ #include "charger.h" #include "common.h" #include "console.h" +#include "dptf.h" #include "host_command.h" #include "printf.h" #include "util.h" @@ -16,6 +17,19 @@ #define CPUTS(outstr) cputs(CC_CHARGER, outstr) #define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args) +/* DPTF current limit, -1 = none */ +static int dptf_limit_ma = -1; + +void dptf_set_charging_current_limit(int ma) +{ + dptf_limit_ma = ma >= 0 ? ma : -1; +} + +int dptf_get_charging_current_limit(void) +{ + return dptf_limit_ma; +} + int charger_closest_voltage(int voltage) { const struct charger_info *info = charger_get_info(); @@ -39,6 +53,10 @@ int charger_closest_current(int current) { const struct charger_info * const info = charger_get_info(); + /* Apply DPTF limit if necessary */ + if (dptf_limit_ma >= 0 && current > dptf_limit_ma) + current = dptf_limit_ma; + /* * If the requested current is non-zero but below our minimum, * return the minimum. See crosbug.com/p/8662. @@ -112,6 +130,13 @@ static int print_info(void) info->input_current_min, info->input_current_max, info->input_current_step); + /* dptf current limit */ + print_item_name("I_dptf:"); + if (dptf_limit_ma >= 0) + ccprintf("%5d\n", dptf_limit_ma); + else + ccputs("disabled\n"); + return EC_SUCCESS; } @@ -138,11 +163,17 @@ static int command_charger(int argc, char **argv) if (*e) return EC_ERROR_PARAM2; return charger_set_voltage(d); + } else if (strcasecmp(argv[1], "dptf") == 0) { + d = strtoi(argv[2], &e, 0); + if (*e) + return EC_ERROR_PARAM2; + dptf_limit_ma = d; + return EC_SUCCESS; } else return EC_ERROR_PARAM1; } DECLARE_CONSOLE_COMMAND(charger, command_charger, - "[input | current | voltage] [newval]", + "[input | current | voltage | dptf] [newval]", "Get or set charger param(s)", NULL); diff --git a/include/dptf.h b/include/dptf.h index f611acb361..6797806e18 100644 --- a/include/dptf.h +++ b/include/dptf.h @@ -8,26 +8,44 @@ #ifndef __CROS_EC_DPTF_H #define __CROS_EC_DPTF_H -/* 0-100% sets fixed duty cycle, out of range means let the EC drive */ +/** + * Set fan duty target. + * + * 0-100% sets fixed duty cycle, out of range means let the EC drive. + */ void dptf_set_fan_duty_target(int pct); -/* 0-100% if in duty mode. -1 if not */ +/** + * Return 0-100% if in duty mode. -1 if not. + */ int dptf_get_fan_duty_target(void); /* Thermal thresholds may be set for each temp sensor. */ #define DPTF_THRESHOLDS_PER_SENSOR 2 #define DPTF_THRESHOLD_HYSTERESIS 2 -/* Set/enable the thresholds */ +/** + * Set/enable the thresholds. + */ void dptf_set_temp_threshold(int sensor_id, /* zero-based sensor index */ int temp, /* in degrees K */ int idx, /* which threshold (0 or 1) */ int enable); /* true = on, false = off */ -/* +/** * Return the ID of a temp sensor that has crossed its threshold since the last - time we asked. -1 means none. + * time we asked. -1 means none. */ int dptf_query_next_sensor_event(void); +/** + * Set charging current limit, in mA. -1 means no limit. + */ +void dptf_set_charging_current_limit(int ma); + +/** + * Get charging current limit, in mA, or -1 if not DPTF-limiting. + */ +int dptf_get_charging_current_limit(void); + #endif /* __CROS_EC_DPTF_H */ diff --git a/include/ec_commands.h b/include/ec_commands.h index e4652bed89..3d557eb6d4 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -1971,6 +1971,14 @@ struct ec_params_reboot_ec { * write 0x1 to [0x07] -- disable threshold 1 */ +/* DPTF battery charging current limit */ +#define EC_ACPI_MEM_CHARGING_LIMIT 0x08 + +/* Charging limit is specified in 64 mA steps */ +#define EC_ACPI_MEM_CHARGING_LIMIT_STEP_MA 64 +/* Value to disable DPTF battery charging limit */ +#define EC_ACPI_MEM_CHARGING_LIMIT_DISABLED 0xff + /* Current version of ACPI memory address space */ #define EC_ACPI_MEM_VERSION_CURRENT 1