diff options
-rw-r--r-- | board/veyron/battery.c | 299 |
1 files changed, 20 insertions, 279 deletions
diff --git a/board/veyron/battery.c b/board/veyron/battery.c index cbce0ce014..02b491443f 100644 --- a/board/veyron/battery.c +++ b/board/veyron/battery.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -7,307 +7,48 @@ #include "battery.h" #include "battery_smart.h" +#include "console.h" #include "gpio.h" #include "host_command.h" #include "util.h" -#include "console.h" - -/* Console output macros */ -#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args) - -/* These 2 defines are for cut_off command for 3S battery */ -#define SB_SHIP_MODE_ADDR 0x3a -#define SB_SHIP_MODE_DATA 0xc574 - -static struct battery_info *battery_info; -static int support_cut_off; - -struct battery_device { - char manuf[9]; - char device[9]; - int design_mv; - struct battery_info *battery_info; - int support_cut_off; -}; - -/* - * Used for the case that battery cannot be detected, such as the pre-charge - * case. In this case, we need to provide the battery with the enough voltage - * (usually the highest voltage among batteries, but the smallest precharge - * current). This should be as conservative as possible. - */ -static struct battery_info info_precharge = { - .voltage_max = 8600, /* the max voltage among batteries */ - .voltage_normal = 7600, - .voltage_min = 6000, +/* Shutdown mode parameter to write to manufacturer access register */ +#define SB_SHUTDOWN_DATA 0x0010 - /* Pre-charge values. */ - .precharge_current = 256, /* mA, the min current among batteries */ - - .start_charging_min_c = 0, - .start_charging_max_c = 50, - .charging_min_c = 0, - .charging_max_c = 60, - .discharging_min_c = 0, - .discharging_max_c = 75, -}; - -static struct battery_info info_2s = { - /* - * Design voltage - * max = 8.4V - * normal = 7.4V - * min = 6.0V - */ - .voltage_max = 8400, +static const struct battery_info info = { + .voltage_max = 8400, /* mV */ .voltage_normal = 7400, .voltage_min = 6000, - - /* Pre-charge current: I <= 0.01C */ - .precharge_current = 64, /* mA */ - - /* - * Operational temperature range - * 0 <= T_charge <= 50 deg C - * -20 <= T_discharge <= 60 deg C - */ - .start_charging_min_c = 0, - .start_charging_max_c = 50, - .charging_min_c = 0, - .charging_max_c = 50, - .discharging_min_c = -20, - .discharging_max_c = 60, -}; - -static struct battery_info info_3s = { - - .voltage_max = 12600, - .voltage_normal = 11100, /* Average of max & min */ - .voltage_min = 9000, - - /* Pre-charge values. */ - .precharge_current = 392, /* mA */ - - .start_charging_min_c = 0, - .start_charging_max_c = 60, - .charging_min_c = 0, - .charging_max_c = 60, - .discharging_min_c = 0, - .discharging_max_c = 50, -}; - -static struct battery_info info_3s_LGC = { - - .voltage_max = 12900, - .voltage_normal = 11400, /* Average of max & min */ - .voltage_min = 9000, - - /* Pre-charge values. */ - .precharge_current = 256, /* mA */ - - .start_charging_min_c = 0, - .start_charging_max_c = 50, - .charging_min_c = 0, - .charging_max_c = 60, - .discharging_min_c = 0, - .discharging_max_c = 75, -}; - -static struct battery_info info_4s_LGC = { - - .voltage_max = 17200, - .voltage_normal = 15200, /* Average of max & min */ - .voltage_min = 12000, - - /* Pre-charge values. */ .precharge_current = 256, /* mA */ - .start_charging_min_c = 0, - .start_charging_max_c = 50, + .start_charging_max_c = 45, .charging_min_c = 0, - .charging_max_c = 60, + .charging_max_c = 45, .discharging_min_c = 0, - .discharging_max_c = 75, -}; - -static struct battery_device support_batteries[] = { - { - .manuf = "NVT", - .device = "ARROW", - .design_mv = 7400, - .battery_info = &info_2s, - .support_cut_off = 0, - }, - { - .manuf = "SANYO", - .device = "AP13J3K", - .design_mv = 11250, - .battery_info = &info_3s, - .support_cut_off = 1, - }, - { - .manuf = "SONYCorp", - .device = "AP13J4K", - .design_mv = 11400, - .battery_info = &info_3s, - .support_cut_off = 1, - }, - { - .manuf = "LGC", - .device = "AC14B8K", - .design_mv = 15200, - .battery_info = &info_4s_LGC, - .support_cut_off = 1, - }, - { - .manuf = "LGC", - .device = "AC14B18J", - .design_mv = 11400, - .battery_info = &info_3s_LGC, - .support_cut_off = 1, - }, -}; - -#ifdef CONFIG_BATTERY_OVERRIDE_PARAMS -/* - * The following parameters are for 2S battery. - * There is no corresponding params for 3S battery. - */ -enum { - TEMP_RANGE_10, - TEMP_RANGE_23, - TEMP_RANGE_35, - TEMP_RANGE_45, - TEMP_RANGE_50, - TEMP_RANGE_MAX -}; - -enum { - VOLT_RANGE_7200, - VOLT_RANGE_8000, - VOLT_RANGE_8400, - VOLT_RANGE_MAX -}; - -/* - * Vendor provided charging method - * temp : < 7.2V, 7.2V ~ 8.0V, 8.0V ~ 8.4V - * - 0 ~ 10 : 0.8A 1.6A 0.8A - * - 10 ~ 23 : 1.6A 4.0A 1.6A - * - 23 ~ 35 : 4.0A 4.0A 4.0A - * - 35 ~ 45 : 1.6A 4.0A 1.6A - * - 45 ~ 50 : 0.8A 1.6A 0.8A - */ -static const int const current_limit[TEMP_RANGE_MAX][VOLT_RANGE_MAX] = { - { 800, 1600, 800}, - {1600, 4000, 1600}, - {4000, 4000, 4000}, - {1600, 4000, 1600}, - { 800, 1600, 800}, + .discharging_max_c = 60, }; -static inline void limit_value(int *val, int limit) +const struct battery_info *battery_get_info(void) { - if (*val > limit) - *val = limit; + return &info; } -void battery_override_params(struct batt_params *batt) +static int cutoff(void) { - int *desired_current = &batt->desired_current; - int temp_range, volt_range; - int bat_temp_c = DECI_KELVIN_TO_CELSIUS(batt->temperature); - - if (battery_info == NULL) - return; - - /* Return if the battery is not a 2S battery */ - if (battery_info->voltage_max != info_2s.voltage_max) - return; - - /* Limit charging voltage */ - if (batt->desired_voltage > battery_info->voltage_max) - batt->desired_voltage = battery_info->voltage_max; - - /* Don't charge if outside of allowable temperature range */ - if (bat_temp_c >= battery_info->charging_max_c || - bat_temp_c < battery_info->charging_min_c) { - batt->desired_voltage = 0; - batt->desired_current = 0; - batt->flags &= ~BATT_FLAG_WANT_CHARGE; - return; - } - - if (bat_temp_c <= 10) - temp_range = TEMP_RANGE_10; - else if (bat_temp_c <= 23) - temp_range = TEMP_RANGE_23; - else if (bat_temp_c <= 35) - temp_range = TEMP_RANGE_35; - else if (bat_temp_c <= 45) - temp_range = TEMP_RANGE_45; - else - temp_range = TEMP_RANGE_50; + int rv; - if (batt->voltage < 7200) - volt_range = VOLT_RANGE_7200; - else if (batt->voltage < 8000) - volt_range = VOLT_RANGE_8000; - else - volt_range = VOLT_RANGE_8400; + /* Ship mode command must be sent twice to take effect */ + rv = sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA); - limit_value(desired_current, current_limit[temp_range][volt_range]); + if (rv != EC_SUCCESS) + return rv; - /* If battery wants current, give it at least the precharge current */ - if (*desired_current > 0 && - *desired_current < battery_info->precharge_current) - *desired_current = battery_info->precharge_current; + return sb_write(SB_MANUFACTURER_ACCESS, SB_SHUTDOWN_DATA); } -#endif /* CONFIG_BATTERY_OVERRIDE_PARAMS */ -const struct battery_info *battery_get_info(void) -{ - int i; - char manuf[9]; - char device[9]; - int design_mv; - - if (battery_manufacturer_name(manuf, sizeof(manuf))) { - CPRINTS("Failed to get MANUF name"); - return &info_precharge; - } - - if (battery_device_name(device, sizeof(device))) { - CPRINTS("Failed to get DEVICE name"); - return &info_precharge; - } - if (battery_design_voltage((int *)&design_mv)) { - CPRINTS("Failed to get DESIGN_VOLTAGE"); - return &info_precharge; - } - - for (i = 0; i < ARRAY_SIZE(support_batteries); ++i) { - if ((strcasecmp(support_batteries[i].manuf, manuf) == 0) && - (strcasecmp(support_batteries[i].device, device) == 0) && - (support_batteries[i].design_mv == design_mv)) { - CPRINTS("battery Manuf:%s, Device=%s, design=%u", - manuf, device, design_mv); - support_cut_off = support_batteries[i].support_cut_off; - battery_info = support_batteries[i].battery_info; - return battery_info; - } - } - - CPRINTS("un-recognized battery Manuf:%s, Device:%s", - manuf, device); - return &info_precharge; -} int board_cut_off_battery(void) { - if (support_cut_off) - return sb_write(SB_SHIP_MODE_ADDR, SB_SHIP_MODE_DATA); - else - return EC_RES_INVALID_COMMAND; + return cutoff(); } + |