diff options
Diffstat (limited to 'board/nyan/battery.c')
-rw-r--r-- | board/nyan/battery.c | 209 |
1 files changed, 166 insertions, 43 deletions
diff --git a/board/nyan/battery.c b/board/nyan/battery.c index 8e46df4e59..7c0058c1d6 100644 --- a/board/nyan/battery.c +++ b/board/nyan/battery.c @@ -6,14 +6,103 @@ */ #include "battery.h" +#include "battery_smart.h" +#include "gpio.h" +#include "host_command.h" +#include "util.h" +#include "console.h" + +/* Console output macros */ +#define CPRINTF(format, args...) cprintf(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 battery_cut_off; + +struct battery_device { + char manuf[9]; + char device[9]; + int design_mv; + struct battery_info *battery_info; + int support_cut_off; +}; + +static struct battery_info info_2s = { + /* + * Design voltage + * max = 8.4V + * normal = 7.4V + * min = 6.0V + */ + .voltage_max = 8400, + .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_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, + } +}; + +#ifdef CONFIG_BATTERY_VENDOR_PARAMS /* - * Design capacity - * Battery capacity = 8200 mAh - * 1C = 8200 mA + * The following parameters are for 2S battery. + * There is no corresponding params for 3S battery. */ -#define DESIGN_CAPACITY 8200 - enum { TEMP_RANGE_10, TEMP_RANGE_23, @@ -47,57 +136,32 @@ static const int const current_limit[TEMP_RANGE_MAX][VOLT_RANGE_MAX] = { { 800, 1600, 800}, }; -static const struct battery_info info = { - /* - * Design voltage - * max = 8.4V - * normal = 7.4V - * min = 6.0V - */ - .voltage_max = 8400, - .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 inline void limit_value(int *val, int limit) { if (*val > limit) *val = limit; } -const struct battery_info *battery_get_info(void) -{ - return &info; -} - void battery_vendor_params(struct batt_params *batt) { 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 > info.voltage_max) - batt->desired_voltage = info.voltage_max; + 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 >= info.charging_max_c || - bat_temp_c < info.charging_min_c) { + 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; @@ -125,6 +189,65 @@ void battery_vendor_params(struct batt_params *batt) limit_value(desired_current, current_limit[temp_range][volt_range]); /* If battery wants current, give it at least the precharge current */ - if (*desired_current > 0 && *desired_current < info.precharge_current) - *desired_current = info.precharge_current; + if (*desired_current > 0 && + *desired_current < battery_info->precharge_current) + *desired_current = battery_info->precharge_current; +} +#endif /* CONFIG_BATTERY_VENDOR_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))) { + CPRINTF("[%T Failed to get MANUF name]\n"); + return NULL; + } + + if (battery_device_name(device, sizeof(device))) { + CPRINTF("[%T Failed to get DEVICE name]\n"); + return NULL; + } + if (battery_design_voltage((int *)&design_mv)) { + CPRINTF("[%T Failed to get DESIGN_VOLTAGE]\n"); + return NULL; + } + + 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)) { + CPRINTF("[%T battery Manuf:%s, Device=%s, design=%u]\n", + manuf, device, design_mv); + battery_cut_off = support_batteries[i].support_cut_off; + battery_info = support_batteries[i].battery_info; + return battery_info; + } + } + + return NULL; +} + +int battery_command_cut_off(struct host_cmd_handler_args *args) +{ + if (battery_cut_off) + return sb_write(SB_SHIP_MODE_ADDR, SB_SHIP_MODE_DATA); + else + return EC_RES_INVALID_COMMAND; +} +DECLARE_HOST_COMMAND(EC_CMD_BATTERY_CUT_OFF, battery_command_cut_off, + EC_VER_MASK(0)); + + +#ifdef CONFIG_BATTERY_CHECK_CONNECTED +/** + * Physical detection of battery connection. + */ +int battery_is_connected(void) +{ + return (gpio_get_level(GPIO_BAT_DETECT_L) == 0); } +#endif /* CONFIG_BATTERY_CHECK_CONNECTED */ |