summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2015-09-28 08:07:43 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-10-06 22:57:08 -0700
commit9669eeede24a9bae19cc000213265632a63e5d80 (patch)
tree08ad4e0e85fe1a0b2ebc1b9bb55f18e515376e2f /driver
parentf7022544bffac0964300405eb878b114d14128ae (diff)
downloadchrome-ec-9669eeede24a9bae19cc000213265632a63e5d80.tar.gz
charge_state_v2: fix battfake command race condition
This moves battfake console command to the battery driver. This fixes a race condition with using the 'battfake' command where charge_state_v2 could return the real battery percentage even when a faked percentage is specified, if a higher priority task uses the battery state of charge in between when the battery is read, and when the fake state of charge overwrites the battery parameter. BUG=chrome-os-partner:45878 BRANCH=none TEST=use tap for battery with a faked state of charge. the tap for battery queries the battery percentage a lot, so without this CL, the tap sequence often temporarily jumps to different percentages and colors. with this CL, the tap sequence works great. Change-Id: I3ae0866d1ff7bb8d0c51355cd6b958310766f19e Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/302711 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'driver')
-rw-r--r--driver/battery/bq27541.c31
-rw-r--r--driver/battery/smart.c35
2 files changed, 64 insertions, 2 deletions
diff --git a/driver/battery/bq27541.c b/driver/battery/bq27541.c
index 2f7e1b2678..ae9f024cc2 100644
--- a/driver/battery/bq27541.c
+++ b/driver/battery/bq27541.c
@@ -46,6 +46,7 @@
#define REG_PROTECTOR 0x6d
static int battery_type_id;
+static int fake_state_of_charge = -1;
static int bq27541_read(int offset, int *data)
{
@@ -236,9 +237,12 @@ void battery_get_params(struct batt_params *batt)
if (bq27541_read(REG_TEMPERATURE, &batt->temperature))
batt->flags |= BATT_FLAG_BAD_TEMPERATURE;
- if (bq27541_read8(REG_STATE_OF_CHARGE, &batt->state_of_charge))
+ if (bq27541_read8(REG_STATE_OF_CHARGE, &v) && fake_state_of_charge < 0)
batt->flags |= BATT_FLAG_BAD_STATE_OF_CHARGE;
+ batt->state_of_charge = fake_state_of_charge >= 0 ?
+ fake_state_of_charge : v;
+
if (bq27541_read(REG_VOLTAGE, &batt->voltage))
batt->flags |= BATT_FLAG_BAD_VOLTAGE;
@@ -327,3 +331,28 @@ enum battery_disconnect_state battery_get_disconnect_state(void)
return BATTERY_NOT_DISCONNECTED;
}
#endif /* CONFIG_BATTERY_REVIVE_DISCONNECT */
+
+static int command_battfake(int argc, char **argv)
+{
+ char *e;
+ int v;
+
+ if (argc == 2) {
+ v = strtoi(argv[1], &e, 0);
+ if (*e || v < -1 || v > 100)
+ return EC_ERROR_PARAM1;
+
+ fake_state_of_charge = v;
+ }
+
+ if (fake_state_of_charge >= 0)
+ ccprintf("Fake batt %d%%\n",
+ fake_state_of_charge);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(battfake, command_battfake,
+ "percent (-1 = use real level)",
+ "Set fake battery level",
+ NULL);
+
diff --git a/driver/battery/smart.c b/driver/battery/smart.c
index 0c63e0fec1..112af6abb0 100644
--- a/driver/battery/smart.c
+++ b/driver/battery/smart.c
@@ -21,6 +21,8 @@
#define BATTERY_WAIT_TIMEOUT (2800*MSEC)
#define BATTERY_NO_RESPONSE_TIMEOUT (1000*MSEC)
+static int fake_state_of_charge = -1;
+
test_mockable int sbc_read(int cmd, int *param)
{
return i2c_read16(I2C_PORT_CHARGER, CHARGER_ADDR, cmd, param);
@@ -272,9 +274,14 @@ void battery_get_params(struct batt_params *batt)
if (sb_read(SB_TEMPERATURE, &batt_new.temperature))
batt_new.flags |= BATT_FLAG_BAD_TEMPERATURE;
- if (sb_read(SB_RELATIVE_STATE_OF_CHARGE, &batt_new.state_of_charge))
+ if (sb_read(SB_RELATIVE_STATE_OF_CHARGE, &batt_new.state_of_charge)
+ && fake_state_of_charge < 0)
batt_new.flags |= BATT_FLAG_BAD_STATE_OF_CHARGE;
+ /* If soc is faked, override with faked data */
+ if (fake_state_of_charge >= 0)
+ batt_new.state_of_charge = fake_state_of_charge;
+
if (sb_read(SB_VOLTAGE, &batt_new.voltage))
batt_new.flags |= BATT_FLAG_BAD_VOLTAGE;
@@ -378,6 +385,32 @@ int battery_wait_for_stable(void)
return EC_ERROR_TIMEOUT;
}
+#ifndef CONFIG_CHARGER_V1
+static int command_battfake(int argc, char **argv)
+{
+ char *e;
+ int v;
+
+ if (argc == 2) {
+ v = strtoi(argv[1], &e, 0);
+ if (*e || v < -1 || v > 100)
+ return EC_ERROR_PARAM1;
+
+ fake_state_of_charge = v;
+ }
+
+ if (fake_state_of_charge >= 0)
+ ccprintf("Fake batt %d%%\n",
+ fake_state_of_charge);
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(battfake, command_battfake,
+ "percent (-1 = use real level)",
+ "Set fake battery level",
+ NULL);
+#endif
+
/*****************************************************************************/
/* Smart battery pass-through
*/