summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRong Chang <rongchang@chromium.org>2013-07-24 08:22:48 -0700
committerChromeBot <chrome-bot@google.com>2013-07-24 13:07:13 -0700
commit6c280b1b324d56416732ff532f0d8d69d2dbdfad (patch)
treeb31a23b435b8174eb4c187cd80c6280257e00528
parent7b95d397feab540fa35d47ce810628e03af34e4b (diff)
downloadchrome-ec-6c280b1b324d56416732ff532f0d8d69d2dbdfad.tar.gz
Move TPSChrome charging temperature range to battery pack
This change moves vendor specific temperature ranges to battery pack files or board setup files. And added a host test case to verify that does not change x86 smart battery charging state machine behavior. BUG=chrome-os-partner:21181 BRANCH=None TEST=manual build test: util/ecmakeall.sh hosttests: make hosttests && make runtests Change-Id: I48e76826b5555f64b78e3c063ce5f02416c72aa2 Signed-off-by: Rong Chang <rongchang@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/62978 Reviewed-by: Vic Yang <victoryang@chromium.org>
-rw-r--r--board/daisy/board.c11
-rw-r--r--board/host/board.h7
-rw-r--r--board/pit/board.c11
-rw-r--r--board/puppy/board.c11
-rw-r--r--board/snow/board.c11
-rw-r--r--board/spring/board.c11
-rw-r--r--common/battery_falco.c27
-rw-r--r--common/battery_link.c37
-rw-r--r--common/battery_peppy.c31
-rw-r--r--common/battery_slippy.c31
-rw-r--r--common/build.mk1
-rw-r--r--common/charge_state.c12
-rw-r--r--common/mock_charger.c43
-rw-r--r--common/mock_smart_battery_stub.c183
-rw-r--r--common/pmu_tps65090_charger.c30
-rw-r--r--common/smart_battery.c21
-rw-r--r--include/battery_pack.h17
-rw-r--r--include/charge_state.h2
-rw-r--r--include/smart_battery.h19
-rw-r--r--test/build.mk2
-rw-r--r--test/sbs_charging.c112
-rw-r--r--test/sbs_charging.tasklist19
-rw-r--r--test/test_config.mk1
23 files changed, 450 insertions, 200 deletions
diff --git a/board/daisy/board.c b/board/daisy/board.c
index d9a384983d..7a3a9bad66 100644
--- a/board/daisy/board.c
+++ b/board/daisy/board.c
@@ -4,6 +4,7 @@
*/
/* Daisy board-specific configuration */
+#include "battery_pack.h"
#include "common.h"
#include "gaia_power.h"
#include "gpio.h"
@@ -99,6 +100,16 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
GPIO_SIGNAL_NOT_IMPLEMENTED("WP_L"),
};
+/* Battery temperature ranges in degrees C */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .start_charging_min_c = 5,
+ .start_charging_max_c = 45,
+ .charging_min_c = 5,
+ .charging_max_c = 60,
+ .discharging_min_c = 0,
+ .discharging_max_c = 100,
+};
+
/* I2C ports */
const struct i2c_port_t i2c_ports[I2C_PORTS_USED] = {
{"0", 0, 100},
diff --git a/board/host/board.h b/board/host/board.h
index d962f3f285..a0d0d35cd7 100644
--- a/board/host/board.h
+++ b/board/host/board.h
@@ -17,6 +17,13 @@
#define CONFIG_TEMP_SENSOR
#undef CONFIG_WATCHDOG
+/* Host test config */
+#ifdef SMART_BATTERY_CHARGER
+#define CONFIG_CHARGER
+#define CONFIG_MOCK_BATTERY
+#define CONFIG_CHARGER_INPUT_CURRENT 4032
+#endif
+
/* Keyboard protocol */
#ifdef KB_8042
#define CONFIG_KEYBOARD_PROTOCOL_8042
diff --git a/board/pit/board.c b/board/pit/board.c
index 018fbbf0f8..c5167eb3a2 100644
--- a/board/pit/board.c
+++ b/board/pit/board.c
@@ -4,6 +4,7 @@
*/
/* Pit board-specific configuration */
+#include "battery_pack.h"
#include "common.h"
#include "extpower.h"
#include "gaia_power.h"
@@ -80,6 +81,16 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"KB_OUT12", GPIO_A, (1<<13), GPIO_KB_OUTPUT, NULL},
};
+/* Battery temperature ranges in degrees C */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 45,
+ .charging_min_c = 0,
+ .charging_max_c = 60,
+ .discharging_min_c = 0,
+ .discharging_max_c = 100,
+};
+
/* I2C ports */
const struct i2c_port_t i2c_ports[I2C_PORTS_USED] = {
{"host", I2C_PORT_HOST, 100},
diff --git a/board/puppy/board.c b/board/puppy/board.c
index 1d288d6848..607a94b7fc 100644
--- a/board/puppy/board.c
+++ b/board/puppy/board.c
@@ -4,6 +4,7 @@
*/
/* Puppy board-specific configuration */
+#include "battery_pack.h"
#include "common.h"
#include "extpower.h"
#include "gaia_power.h"
@@ -80,6 +81,16 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"KB_OUT12", GPIO_A, (1<<13), GPIO_KB_OUTPUT, NULL},
};
+/* Battery temperature ranges in degrees C */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .start_charging_min_c = 5,
+ .start_charging_max_c = 45,
+ .charging_min_c = 5,
+ .charging_max_c = 60,
+ .discharging_min_c = 0,
+ .discharging_max_c = 100,
+};
+
/* I2C ports */
const struct i2c_port_t i2c_ports[I2C_PORTS_USED] = {
{"host", I2C_PORT_HOST, 100},
diff --git a/board/snow/board.c b/board/snow/board.c
index 90bdba1847..7344db6aae 100644
--- a/board/snow/board.c
+++ b/board/snow/board.c
@@ -4,6 +4,7 @@
*/
/* Snow board-specific configuration */
+#include "battery_pack.h"
#include "board_config.h"
#include "chipset.h"
#include "common.h"
@@ -93,6 +94,16 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"KB_OUT12", GPIO_C, (1<<7), GPIO_KB_OUTPUT, NULL},
};
+/* Battery temperature ranges in degrees C */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .start_charging_min_c = 5,
+ .start_charging_max_c = 45,
+ .charging_min_c = 5,
+ .charging_max_c = 60,
+ .discharging_min_c = 0,
+ .discharging_max_c = 100,
+};
+
/* I2C ports */
const struct i2c_port_t i2c_ports[I2C_PORTS_USED] = {
{"host", I2C_PORT_HOST, 100},
diff --git a/board/spring/board.c b/board/spring/board.c
index 98ffe3882e..b22545c5d7 100644
--- a/board/spring/board.c
+++ b/board/spring/board.c
@@ -5,6 +5,7 @@
/* Spring board-specific configuration */
#include "adc.h"
+#include "battery_pack.h"
#include "board_config.h"
#include "chipset.h"
#include "common.h"
@@ -93,6 +94,16 @@ const struct gpio_info gpio_list[GPIO_COUNT] = {
{"ILIM", GPIO_B, (1<<4), GPIO_OUT_LOW, NULL},
};
+/* Battery temperature ranges in degrees C */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .start_charging_min_c = 5,
+ .start_charging_max_c = 45,
+ .charging_min_c = 5,
+ .charging_max_c = 60,
+ .discharging_min_c = 0,
+ .discharging_max_c = 100,
+};
+
/* ADC channels */
const struct adc_t adc_channels[ADC_CH_COUNT] = {
/*
diff --git a/common/battery_falco.c b/common/battery_falco.c
index c2430fa07e..9a493c19d6 100644
--- a/common/battery_falco.c
+++ b/common/battery_falco.c
@@ -12,18 +12,21 @@
#define SB_SHIP_MODE_DATA 0x0010
/* FIXME: We need REAL values for all this stuff */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .start_charging_min_c = 0,
+ .start_charging_max_c = 45,
+ .charging_min_c = 0,
+ .charging_max_c = 45,
+ .discharging_min_c = -10,
+ .discharging_max_c = 60,
+};
+
static const struct battery_info info = {
.voltage_max = 8400,
.voltage_normal = 7400,
.voltage_min = 6000,
- /* Operational temperature range */
- .temp_charge_min = CELSIUS_TO_DECI_KELVIN(0),
- .temp_charge_max = CELSIUS_TO_DECI_KELVIN(45),
- .temp_discharge_min = CELSIUS_TO_DECI_KELVIN(-10),
- .temp_discharge_max = CELSIUS_TO_DECI_KELVIN(60),
-
/* Pre-charge values. */
.precharge_current = 256, /* mA */
};
@@ -37,18 +40,6 @@ const struct battery_info *battery_get_info(void)
* called "smart". Do we really want to second-guess it? For now, let's not. */
void battery_vendor_params(struct batt_params *batt)
{
-#if 0
- /* Limit charging voltage */
- if (batt->desired_voltage > info.voltage_max)
- batt->desired_voltage = info.voltage_max;
-
- /* Don't charge if outside of allowable temperature range */
- if (batt->temperature >= info.temp_charge_max ||
- batt->temperature <= info.temp_charge_min) {
- batt->desired_voltage = 0;
- batt->desired_current = 0;
- }
-#endif
}
int battery_command_cut_off(struct host_cmd_handler_args *args)
diff --git a/common/battery_link.c b/common/battery_link.c
index c92f3dafd2..4e7e9c769b 100644
--- a/common/battery_link.c
+++ b/common/battery_link.c
@@ -47,6 +47,20 @@ static const int const current_limit[TEMP_RANGE_MAX][VOLT_RANGE_MAX] = {
{ 800, 1600, 800},
};
+const struct battery_temperature_ranges bat_temp_ranges = {
+ /*
+ * 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 const struct battery_info info = {
/*
* Design voltage
@@ -58,16 +72,6 @@ static const struct battery_info info = {
.voltage_normal = 7400,
.voltage_min = 6000,
- /*
- * Operational temperature range
- * 0 <= T_charge <= 50 deg C
- * -20 <= T_discharge <= 60 deg C
- */
- .temp_charge_min = CELSIUS_TO_DECI_KELVIN(0),
- .temp_charge_max = CELSIUS_TO_DECI_KELVIN(50),
- .temp_discharge_min = CELSIUS_TO_DECI_KELVIN(-20),
- .temp_discharge_max = CELSIUS_TO_DECI_KELVIN(60),
-
/* Pre-charge current: I <= 0.01C */
.precharge_current = 64, /* mA */
};
@@ -87,26 +91,27 @@ 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);
/* Limit charging voltage */
if (batt->desired_voltage > info.voltage_max)
batt->desired_voltage = info.voltage_max;
/* Don't charge if outside of allowable temperature range */
- if (batt->temperature >= info.temp_charge_max ||
- batt->temperature <= info.temp_charge_min) {
+ if (bat_temp_c >= bat_temp_ranges.charging_max_c ||
+ bat_temp_c < bat_temp_ranges.charging_min_c) {
batt->desired_voltage = 0;
batt->desired_current = 0;
return;
}
- if (batt->temperature <= CELSIUS_TO_DECI_KELVIN(10))
+ if (bat_temp_c <= 10)
temp_range = TEMP_RANGE_10;
- else if (batt->temperature <= CELSIUS_TO_DECI_KELVIN(23))
+ else if (bat_temp_c <= 23)
temp_range = TEMP_RANGE_23;
- else if (batt->temperature <= CELSIUS_TO_DECI_KELVIN(35))
+ else if (bat_temp_c <= 35)
temp_range = TEMP_RANGE_35;
- else if (batt->temperature <= CELSIUS_TO_DECI_KELVIN(45))
+ else if (bat_temp_c <= 45)
temp_range = TEMP_RANGE_45;
else
temp_range = TEMP_RANGE_50;
diff --git a/common/battery_peppy.c b/common/battery_peppy.c
index 086469c9a3..76d2d04395 100644
--- a/common/battery_peppy.c
+++ b/common/battery_peppy.c
@@ -14,22 +14,21 @@
#define SB_SHIP_MODE_DATA 0xc574
/* Values for 54Wh 3UPF656790-1-T1001 battery */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .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 const struct battery_info info = {
.voltage_max = 12600,
.voltage_normal = 11100, /* Average of max & min */
.voltage_min = 9000,
- /*
- * Operational temperature range
- * 0 <= T_charge <= 60 deg C
- * 0 <= T_discharge <= 50 deg C
- */
- .temp_charge_min = CELSIUS_TO_DECI_KELVIN(0),
- .temp_charge_max = CELSIUS_TO_DECI_KELVIN(60),
- .temp_discharge_min = CELSIUS_TO_DECI_KELVIN(0),
- .temp_discharge_max = CELSIUS_TO_DECI_KELVIN(50),
-
/* Pre-charge values. */
.precharge_current = 256, /* mA */
};
@@ -43,18 +42,6 @@ const struct battery_info *battery_get_info(void)
* called "smart". Do we really want to second-guess it? For now, let's not. */
void battery_vendor_params(struct batt_params *batt)
{
-#if 0
- /* Limit charging voltage */
- if (batt->desired_voltage > info.voltage_max)
- batt->desired_voltage = info.voltage_max;
-
- /* Don't charge if outside of allowable temperature range */
- if (batt->temperature >= info.temp_charge_max ||
- batt->temperature <= info.temp_charge_min) {
- batt->desired_voltage = 0;
- batt->desired_current = 0;
- }
-#endif
}
int battery_command_cut_off(struct host_cmd_handler_args *args)
diff --git a/common/battery_slippy.c b/common/battery_slippy.c
index 8d9648d26d..64d5c09d1e 100644
--- a/common/battery_slippy.c
+++ b/common/battery_slippy.c
@@ -9,22 +9,21 @@
#include "gpio.h"
/* FIXME: We need REAL values for all this stuff */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ .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 const struct battery_info info = {
.voltage_max = 16800,
.voltage_normal = 14800,
.voltage_min = 10800,
- /*
- * Operational temperature range
- * 0 <= T_charge <= 50 deg C
- * -20 <= T_discharge <= 60 deg C
- */
- .temp_charge_min = CELSIUS_TO_DECI_KELVIN(0),
- .temp_charge_max = CELSIUS_TO_DECI_KELVIN(50),
- .temp_discharge_min = CELSIUS_TO_DECI_KELVIN(-20),
- .temp_discharge_max = CELSIUS_TO_DECI_KELVIN(60),
-
/* Pre-charge values. */
.precharge_current = 256, /* mA */
};
@@ -38,18 +37,6 @@ const struct battery_info *battery_get_info(void)
* called "smart". Do we really want to second-guess it? For now, let's not. */
void battery_vendor_params(struct batt_params *batt)
{
-#if 0
- /* Limit charging voltage */
- if (batt->desired_voltage > info.voltage_max)
- batt->desired_voltage = info.voltage_max;
-
- /* Don't charge if outside of allowable temperature range */
- if (batt->temperature >= info.temp_charge_max ||
- batt->temperature <= info.temp_charge_min) {
- batt->desired_voltage = 0;
- batt->desired_current = 0;
- }
-#endif
}
/**
diff --git a/common/build.mk b/common/build.mk
index 6f8a0213e0..18644b8b96 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -46,6 +46,7 @@ common-$(CONFIG_LED_PEPPY)+=led_peppy.o
common-$(CONFIG_LED_SLIPPY)+=led_slippy.o
common-$(CONFIG_LID_SWITCH)+=lid_switch.o
common-$(CONFIG_LPC)+=port80.o
+common-$(CONFIG_MOCK_BATTERY)+=mock_smart_battery_stub.o mock_charger.o
common-$(CONFIG_ONEWIRE_LED)+=onewire_led.o
common-$(CONFIG_POWER_BUTTON)+=power_button.o
common-$(CONFIG_POWER_BUTTON_X86)+=power_button_x86.o
diff --git a/common/charge_state.c b/common/charge_state.c
index 8d605ec03e..49630ff7be 100644
--- a/common/charge_state.c
+++ b/common/charge_state.c
@@ -34,6 +34,13 @@
/* Timeout after AP battery shutdown warning before we kill the AP */
#define LOW_BATTERY_SHUTDOWN_TIMEOUT_US (30 * SECOND)
+#ifndef TASK_ID_CHARGER
+#define TASK_ID_CHARGER TASK_ID_INVALID
+#endif
+#ifndef TASK_ID_SWITCH
+#define TASK_ID_SWITCH TASK_ID_INVALID
+#endif
+
static const char * const state_name[] = POWER_STATE_NAME_TABLE;
static int state_machine_force_idle = 0;
@@ -483,6 +490,7 @@ static enum power_state state_charge(struct power_state_context *ctx)
static enum power_state state_discharge(struct power_state_context *ctx)
{
struct batt_params *batt = &ctx->curr.batt;
+ int8_t bat_temp_c = DECI_KELVIN_TO_CELSIUS(batt->temperature);
if (ctx->curr.ac)
return PWR_STATE_REINIT;
@@ -490,8 +498,8 @@ static enum power_state state_discharge(struct power_state_context *ctx)
return PWR_STATE_ERROR;
/* Handle overtemp in discharging state by powering off host */
- if ((batt->temperature > ctx->battery->temp_discharge_max ||
- batt->temperature < ctx->battery->temp_discharge_min) &&
+ if ((bat_temp_c >= bat_temp_ranges.discharging_max_c ||
+ bat_temp_c < bat_temp_ranges.discharging_min_c) &&
chipset_in_state(CHIPSET_STATE_ON)) {
CPRINTF("[%T charge force shutdown due to battery temp]\n");
chipset_force_shutdown();
diff --git a/common/mock_charger.c b/common/mock_charger.c
index d1d9659ad8..47b2a96079 100644
--- a/common/mock_charger.c
+++ b/common/mock_charger.c
@@ -78,7 +78,6 @@ int charger_set_current(int current)
return EC_SUCCESS;
}
-
int charger_get_voltage(int *voltage)
{
*voltage = mock_voltage;
@@ -94,6 +93,48 @@ int charger_set_voltage(int voltage)
}
+int charger_get_option(int *option)
+{
+ return EC_SUCCESS;
+}
+
+
+int charger_set_option(int option)
+{
+ return EC_SUCCESS;
+}
+
+
+int charger_manufacturer_id(int *id)
+{
+ return EC_SUCCESS;
+}
+
+
+int charger_device_id(int *id)
+{
+ return EC_SUCCESS;
+}
+
+
+int charger_get_input_current(int *input_current)
+{
+ return EC_SUCCESS;
+}
+
+
+int charger_set_input_current(int input_current)
+{
+ return EC_SUCCESS;
+}
+
+
+int charger_closest_current(int current)
+{
+ return current;
+}
+
+
int charger_post_init(void)
{
mock_current = CONFIG_CHARGER_INPUT_CURRENT;
diff --git a/common/mock_smart_battery_stub.c b/common/mock_smart_battery_stub.c
index 49b44859c9..0cf7b70e78 100644
--- a/common/mock_smart_battery_stub.c
+++ b/common/mock_smart_battery_stub.c
@@ -1,105 +1,124 @@
+/* Copyright (c) 2013 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.
+ *
+ * Smart battery driver.
+ */
+
+#include "battery_pack.h"
+#include "common.h"
#include "console.h"
#include "smart_battery.h"
#include "smart_battery_stub.h"
#include "uart.h"
#include "util.h"
-static int mock_temperature = 2981;
-static int mock_desire_voltage = 7000;
-static int mock_desire_current = 3000;
-static int mock_voltage = 6000;
-static int mock_current = 3000;
+static uint16_t mock_smart_battery[SB_MANUFACTURER_DATA + 1];
int sb_read(int cmd, int *param)
{
- switch (cmd)
- {
- case SB_TEMPERATURE:
- *param = mock_temperature;
- break;
- case SB_VOLTAGE:
- *param = mock_voltage;
- break;
- case SB_CURRENT:
- *param = mock_current;
- break;
- case SB_RELATIVE_STATE_OF_CHARGE:
- case SB_ABSOLUTE_STATE_OF_CHARGE:
- *param = 70; /* 70% charged */
- break;
- case SB_REMAINING_CAPACITY:
- *param = 7000; /* 7000 mAh */
- break;
- case SB_FULL_CHARGE_CAPACITY:
- case SB_DESIGN_CAPACITY:
- *param = 10000; /* 10000 mAh */
- break;
- case SB_AVERAGE_TIME_TO_EMPTY:
- case SB_RUN_TIME_TO_EMPTY:
- *param = 60; /* 60 min to empty */
- break;
- case SB_AVERAGE_TIME_TO_FULL:
- *param = 30; /* 30 min to full */
- break;
- case SB_CHARGING_CURRENT:
- *param = mock_desire_current;
- break;
- case SB_CHARGING_VOLTAGE:
- *param = mock_desire_voltage;
- break;
- case SB_CYCLE_COUNT:
- *param = 10;
- break;
- case SB_DESIGN_VOLTAGE:
- *param = 7400; /* 7.4 V */
- break;
- case SB_SERIAL_NUMBER:
- *param = 112233;
- break;
- default:
- *param = 0;
- break;
- }
+ if (cmd >= ARRAY_SIZE(mock_smart_battery))
+ return EC_ERROR_UNIMPLEMENTED;
+ if (cmd < 0 || param == NULL)
+ return EC_ERROR_INVAL;
+ *param = mock_smart_battery[cmd];
+ return EC_SUCCESS;
+}
+int sb_write(int cmd, int param)
+{
+ if (cmd >= ARRAY_SIZE(mock_smart_battery))
+ return EC_ERROR_UNIMPLEMENTED;
+ if (cmd < 0)
+ return EC_ERROR_INVAL;
+ mock_smart_battery[cmd] = param;
return EC_SUCCESS;
}
+int battery_manufacturer_name(char *manufacturer_name, int buf_size)
+{
+ return EC_SUCCESS;
+}
-int sb_write(int cmd, int param)
+int battery_device_name(char *device_name, int buf_size)
{
- uart_printf("sb_write: cmd = %d, param = %d\n", cmd, param);
return EC_SUCCESS;
}
+int battery_device_chemistry(char *device_chemistry, int buf_size)
+{
+ return EC_SUCCESS;
+}
+
+int battery_current(int *current)
+{
+ int rv, d;
+
+ rv = sb_read(SB_CURRENT, &d);
+ if (rv)
+ return rv;
+
+ *current = (int16_t)d;
+ return EC_SUCCESS;
+}
+
+int battery_average_current(int *current)
+{
+ int rv, d;
+
+ rv = sb_read(SB_AVERAGE_CURRENT, &d);
+ if (rv)
+ return rv;
-static int command_sb_mock(int argc, char **argv)
+ *current = (int16_t)d;
+ return EC_SUCCESS;
+}
+
+int battery_time_at_rate(int rate, int *minutes)
{
- char *e;
- int v;
-
- if (argc < 3)
- return EC_ERROR_PARAM_COUNT;
-
- v = strtoi(argv[2], &e, 0);
- if (*e)
- return EC_ERROR_PARAM2;
-
- if (!strcasecmp(argv[1], "temperature"))
- mock_temperature = v;
- else if (!strcasecmp(argv[1], "desire_voltage"))
- mock_desire_voltage = v;
- else if (!strcasecmp(argv[1], "desire_current"))
- mock_desire_current = v;
- else if (!strcasecmp(argv[1], "voltage"))
- mock_voltage = v;
- else if (!strcasecmp(argv[1], "current"))
- mock_current = v;
- else
- return EC_ERROR_PARAM1;
+ return EC_SUCCESS;
+}
+int battery_manufacturer_date(int *year, int *month, int *day)
+{
return EC_SUCCESS;
}
-DECLARE_CONSOLE_COMMAND(sbmock, command_sb_mock,
- "name value",
- "Mock smart battery attribute",
- NULL);
+
+/* Fake battery */
+const struct battery_temperature_ranges bat_temp_ranges = {
+ /*
+ * 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 const struct battery_info bat_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 */
+};
+
+const struct battery_info *battery_get_info(void)
+{
+ return &bat_info;
+}
+
+void battery_vendor_params(struct batt_params *batt)
+{
+}
diff --git a/common/pmu_tps65090_charger.c b/common/pmu_tps65090_charger.c
index 36fb0d1989..d91a52b83b 100644
--- a/common/pmu_tps65090_charger.c
+++ b/common/pmu_tps65090_charger.c
@@ -5,6 +5,7 @@
* TI TPS65090 PMU charging task.
*/
+#include "battery_pack.h"
#include "clock.h"
#include "chipset.h"
#include "common.h"
@@ -58,31 +59,30 @@ static void enable_charging(int enable)
gpio_set_level(GPIO_CHARGER_EN, enable);
}
-/*
- * TODO(rongchang): move battery vendor specific functions to battery pack
- * module
- */
-static int battery_temperature_celsius(int t)
+static int battery_temperature_celsius(int deci_k)
{
- return (t - 2731) / 10;
+ return (deci_k - 2731) / 10;
}
-static int battery_start_charging_range(int t)
+static int battery_start_charging_range(int deci_k)
{
- t = battery_temperature_celsius(t);
- return (t >= 5 && t < 45);
+ int8_t temp_c = battery_temperature_celsius(deci_k);
+ return (temp_c >= bat_temp_ranges.start_charging_min_c &&
+ temp_c < bat_temp_ranges.start_charging_max_c);
}
-static int battery_charging_range(int t)
+static int battery_charging_range(int deci_k)
{
- t = battery_temperature_celsius(t);
- return (t >= 5 && t < 60);
+ int8_t temp_c = battery_temperature_celsius(deci_k);
+ return (temp_c >= bat_temp_ranges.charging_min_c &&
+ temp_c < bat_temp_ranges.charging_max_c);
}
-static int battery_discharging_range(int t)
+static int battery_discharging_range(int deci_k)
{
- t = battery_temperature_celsius(t);
- return (t >= 0 && t < 100);
+ int8_t temp_c = battery_temperature_celsius(deci_k);
+ return (temp_c >= bat_temp_ranges.discharging_min_c &&
+ temp_c < bat_temp_ranges.discharging_max_c);
}
/*
diff --git a/common/smart_battery.c b/common/smart_battery.c
index e0bc9c5e46..536959bd82 100644
--- a/common/smart_battery.c
+++ b/common/smart_battery.c
@@ -106,6 +106,27 @@ int battery_manufacturer_date(int *year, int *month, int *day)
return EC_SUCCESS;
}
+/* Read manufacturer name */
+int battery_manufacturer_name(char *manufacturer_name, int buf_size)
+{
+ return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ SB_MANUFACTURER_NAME, manufacturer_name, buf_size);
+}
+
+/* Read device name */
+int battery_device_name(char *device_name, int buf_size)
+{
+ return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ SB_DEVICE_NAME, device_name, buf_size);
+}
+
+/* Read battery type/chemistry */
+int battery_device_chemistry(char *device_chemistry, int buf_size)
+{
+ return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ SB_DEVICE_CHEMISTRY, device_chemistry, buf_size);
+}
+
/*****************************************************************************/
/* Console commands */
diff --git a/include/battery_pack.h b/include/battery_pack.h
index 0367ee8406..5e023db471 100644
--- a/include/battery_pack.h
+++ b/include/battery_pack.h
@@ -10,6 +10,7 @@
#include "common.h"
#define CELSIUS_TO_DECI_KELVIN(temp_c) ((temp_c) * 10 + 2731)
+#define DECI_KELVIN_TO_CELSIUS(temp_dk) ((temp_dk - 2731) / 10)
/* Battery parameters */
struct batt_params {
@@ -21,17 +22,23 @@ struct batt_params {
int desired_current; /* Charging current desired by battery (mA) */
};
+/* Working temperature ranges in degrees C */
+struct battery_temperature_ranges {
+ int8_t start_charging_min_c;
+ int8_t start_charging_max_c;
+ int8_t charging_min_c;
+ int8_t charging_max_c;
+ int8_t discharging_min_c;
+ int8_t discharging_max_c;
+};
+extern const struct battery_temperature_ranges bat_temp_ranges;
+
/* Battery constants */
struct battery_info {
/* Design voltage in mV */
int voltage_max;
int voltage_normal;
int voltage_min;
- /* Working temperature range in 0.1 K increments */
- int temp_charge_min;
- int temp_charge_max;
- int temp_discharge_min;
- int temp_discharge_max;
/* Pre-charge current in mA */
int precharge_current;
};
diff --git a/include/charge_state.h b/include/charge_state.h
index bd8f576b55..d2dd4aa052 100644
--- a/include/charge_state.h
+++ b/include/charge_state.h
@@ -149,7 +149,7 @@ int charge_get_percent(void);
/**
* Return non-zero if discharging and battery so low we should shut down.
*/
-#ifdef HAS_TASK_CHARGER
+#ifdef CONFIG_CHARGER
int charge_want_shutdown(void);
#else
static inline int charge_want_shutdown(void) { return 0; }
diff --git a/include/smart_battery.h b/include/smart_battery.h
index 1db6203692..ef65cd9d0d 100644
--- a/include/smart_battery.h
+++ b/include/smart_battery.h
@@ -213,26 +213,13 @@ static inline int battery_serial_number(int *serial)
{ return sb_read(SB_SERIAL_NUMBER, serial); }
/* Read manufacturer name */
-static inline int battery_manufacturer_name(char *manufacturer_name,
- int buf_size)
-{
- return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
- SB_MANUFACTURER_NAME, manufacturer_name, buf_size);
-}
+int battery_manufacturer_name(char *manufacturer_name, int buf_size);
/* Read device name */
-static inline int battery_device_name(char *device_name, int buf_size)
-{
- return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
- SB_DEVICE_NAME, device_name, buf_size);
-}
+int battery_device_name(char *device_name, int buf_size);
/* Read battery type/chemistry */
-static inline int battery_device_chemistry(char *device_chemistry, int buf_size)
-{
- return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
- SB_DEVICE_CHEMISTRY, device_chemistry, buf_size);
-}
+int battery_device_chemistry(char *device_chemistry, int buf_size);
/* Read battery discharging current
* unit: mA
diff --git a/test/build.mk b/test/build.mk
index 3e09caa0fb..e2212fa71a 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -31,6 +31,7 @@ test-list-$(BOARD_bolt)=
# Emulator tests
test-list-host=mutex pingpong utils kb_scan kb_mkbp lid_sw power_button hooks
test-list-host+=thermal flash queue kb_8042 extpwr_gpio console_edit system
+test-list-host+=sbs_charging
console_edit-y=console_edit.o
extpwr_gpio-y=extpwr_gpio.o
@@ -46,6 +47,7 @@ pingpong-y=pingpong.o
power_button-y=power_button.o
powerdemo-y=powerdemo.o
queue-y=queue.o
+sbs_charging-y=sbs_charging.o
stress-y=stress.o
system-y=system.o
thermal-y=thermal.o
diff --git a/test/sbs_charging.c b/test/sbs_charging.c
new file mode 100644
index 0000000000..ef2337997e
--- /dev/null
+++ b/test/sbs_charging.c
@@ -0,0 +1,112 @@
+/* Copyright (c) 2013 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.
+ *
+ * Test lid switch.
+ */
+
+#include "battery_pack.h"
+#include "charge_state.h"
+#include "chipset.h"
+#include "common.h"
+#include "smart_battery.h"
+#include "task.h"
+#include "test_util.h"
+#include "util.h"
+
+#define WAIT_CHARGER_TASK 500
+
+static int mock_ac_present = 1;
+static int mock_chipset_state = CHIPSET_STATE_ON;
+static int is_shutdown;
+
+/* Mock GPIOs */
+int gpio_get_level(enum gpio_signal signal)
+{
+ if (signal == GPIO_AC_PRESENT)
+ return mock_ac_present;
+ return 0;
+}
+
+void chipset_force_shutdown(void)
+{
+ is_shutdown = 1;
+}
+
+int chipset_in_state(int state_mask)
+{
+ return state_mask & mock_chipset_state;
+}
+
+/* Setup init condition */
+static void test_setup(void)
+{
+ const struct battery_info *bat_info = battery_get_info();
+
+ /* 50% of charge */
+ sb_write(SB_RELATIVE_STATE_OF_CHARGE, 50);
+ sb_write(SB_ABSOLUTE_STATE_OF_CHARGE, 50);
+ /* 25 degree Celsius */
+ sb_write(SB_TEMPERATURE, 250 + 2731);
+ /* Normal voltage */
+ sb_write(SB_VOLTAGE, bat_info->voltage_normal);
+ sb_write(SB_CHARGING_VOLTAGE, bat_info->voltage_max);
+ sb_write(SB_CHARGING_CURRENT, 4000);
+ /* Discharging at 100mAh */
+ sb_write(SB_CURRENT, -100);
+ /* Unplug AC */
+ mock_ac_present = 0;
+}
+
+static int wait_charging_state(void)
+{
+ enum power_state state;
+ task_wake(TASK_ID_CHARGER);
+ msleep(WAIT_CHARGER_TASK);
+ state = charge_get_state();
+ ccprintf("[CHARGING TEST] state = %d\n", state);
+ return state;
+}
+
+static int test_charge_state(void)
+{
+ enum power_state state;
+
+ state = wait_charging_state();
+ /* Plug AC, charging at 1000mAh */
+ ccprintf("[CHARGING TEST] AC on\n");
+ mock_ac_present = 1;
+ sb_write(SB_CURRENT, 1000);
+ state = wait_charging_state();
+ TEST_ASSERT(state == PWR_STATE_CHARGE);
+
+ /* Unplug AC, discharging at 1000mAh */
+ ccprintf("[CHARGING TEST] AC off\n");
+ mock_ac_present = 0;
+ sb_write(SB_CURRENT, -1000);
+ state = wait_charging_state();
+ TEST_ASSERT(state == PWR_STATE_DISCHARGE);
+
+ /* Discharging overtemp */
+ ccprintf("[CHARGING TEST] AC off, batt temp = 90 C\n");
+ mock_ac_present = 0;
+ sb_write(SB_CURRENT, -1000);
+
+ state = wait_charging_state();
+ TEST_ASSERT(state == PWR_STATE_DISCHARGE);
+ sb_write(SB_TEMPERATURE, CELSIUS_TO_DECI_KELVIN(90));
+ state = wait_charging_state();
+ TEST_ASSERT(is_shutdown);
+ TEST_ASSERT(state == PWR_STATE_DISCHARGE);
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_setup();
+
+ RUN_TEST(test_charge_state);
+
+ test_print_result();
+}
diff --git a/test/sbs_charging.tasklist b/test/sbs_charging.tasklist
new file mode 100644
index 0000000000..6ca1e65553
--- /dev/null
+++ b/test/sbs_charging.tasklist
@@ -0,0 +1,19 @@
+/* Copyright (c) 2013 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.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_TEST(n, r, d, s) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_TEST_TASK_LIST \
+ TASK_TEST(CHARGER, charger_task, NULL, TASK_STACK_SIZE) \
+ TASK_TEST(CHIPSET, chipset_task, NULL, TASK_STACK_SIZE)
diff --git a/test/test_config.mk b/test/test_config.mk
index 968519fa22..9837c0fe01 100644
--- a/test/test_config.mk
+++ b/test/test_config.mk
@@ -7,3 +7,4 @@
#
CFLAGS-kb_8042=-DKB_8042
+CFLAGS-sbs_charging=-DSMART_BATTERY_CHARGER