summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@chromium.org>2015-10-21 10:51:21 -0700
committerchrome-bot <chrome-bot@chromium.org>2015-10-27 11:52:34 -0700
commitcb4a76e8022c73fb0a0b50700912d86f41ea3dbb (patch)
tree0cfcc8ead036350e3ad994ee8229dac69a7f5b28
parent95e8bc2e0bed68b040d2b19d1dd62a4debcc1852 (diff)
downloadchrome-ec-cb4a76e8022c73fb0a0b50700912d86f41ea3dbb.tar.gz
i2c: get battery information from charge state
ARM systems currently use SBS kernel driver which talks to the battery through I2C passthu in the EC. Instead when asking for battery information try getting it from the charge state machine first, and then try the battery if charge state does not have the information. This reduces latency by cutting out the battery response time. BUG=chromium:484841 BRANCH=none TEST=check that power_supply_info works properly on Jerry Change-Id: If4da15ccabe412adc31fc94b189089ebb3e9265c Signed-off-by: Mary Ruthven <mruthven@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/307905 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--common/charge_state_v2.c48
-rw-r--r--common/i2c.c23
-rw-r--r--driver/battery/smart.c3
-rw-r--r--include/battery.h4
-rw-r--r--include/charge_state_v2.h15
-rw-r--r--include/config.h1
6 files changed, 90 insertions, 4 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 0d89d470ce..b01f537b20 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -917,6 +917,54 @@ int charge_prevent_power_on(void)
return prevent_power_on;
}
+#ifdef VIRTUAL_BATTERY_ADDR
+int virtual_battery_read(uint8_t batt_param, uint8_t *dest, int read_len)
+{
+ int val;
+
+ switch (batt_param) {
+ case SB_SERIAL_NUMBER:
+ val = strtoi(host_get_memmap(EC_MEMMAP_BATT_SERIAL), NULL, 16);
+ memcpy(dest, &val, read_len);
+ break;
+ case SB_VOLTAGE:
+ memcpy(dest, &curr.batt.voltage, read_len);
+ break;
+ case SB_RELATIVE_STATE_OF_CHARGE:
+ memcpy(dest, &curr.batt.state_of_charge, read_len);
+ break;
+ case SB_TEMPERATURE:
+ memcpy(dest, &curr.batt.temperature, read_len);
+ break;
+ case SB_CURRENT:
+ memcpy(dest, &curr.batt.current, read_len);
+ break;
+ case SB_FULL_CHARGE_CAPACITY:
+ memcpy(dest, &curr.batt.full_capacity, read_len);
+ break;
+ case SB_BATTERY_STATUS:
+ memcpy(dest, &curr.batt.status, read_len);
+ break;
+ case SB_CYCLE_COUNT:
+ memcpy(dest, (int *)host_get_memmap(EC_MEMMAP_BATT_CCNT),
+ read_len);
+ break;
+ case SB_DESIGN_CAPACITY:
+ memcpy(dest, (int *)host_get_memmap(EC_MEMMAP_BATT_DCAP),
+ read_len);
+ break;
+ case SB_DESIGN_VOLTAGE:
+ memcpy(dest, (int *)host_get_memmap(EC_MEMMAP_BATT_DVLT),
+ read_len);
+ break;
+ default:
+ return EC_ERROR_INVAL;
+ }
+ return EC_SUCCESS;
+
+}
+#endif
+
enum charge_state charge_get_state(void)
{
switch (curr.state) {
diff --git a/common/i2c.c b/common/i2c.c
index c3c8d50a9c..daf758aaa1 100644
--- a/common/i2c.c
+++ b/common/i2c.c
@@ -7,6 +7,7 @@
#include "battery.h"
#include "clock.h"
+#include "charge_state.h"
#include "console.h"
#include "host_command.h"
#include "gpio.h"
@@ -616,6 +617,9 @@ static int i2c_command_passthru(struct host_cmd_handler_args *args)
const uint8_t *out;
int in_len;
int ret;
+#if defined(VIRTUAL_BATTERY_ADDR) && defined(I2C_PORT_VIRTUAL_BATTERY)
+ uint8_t batt_param = 0;
+#endif
#ifdef CONFIG_I2C_PASSTHRU_RESTRICTED
if (system_is_locked())
@@ -648,7 +652,7 @@ static int i2c_command_passthru(struct host_cmd_handler_args *args)
unsigned int addr = (msg->addr_flags & EC_I2C_ADDR_MASK) << 1;
int xferflags = I2C_XFER_START;
int read_len = 0, write_len = 0;
- int rv;
+ int rv = 1;
if (msg->addr_flags & EC_I2C_FLAG_READ)
read_len = msg->len;
@@ -659,13 +663,26 @@ static int i2c_command_passthru(struct host_cmd_handler_args *args)
if (resp->num_msgs == params->num_msgs - 1)
xferflags |= I2C_XFER_STOP;
+#if defined(VIRTUAL_BATTERY_ADDR) && defined(I2C_PORT_VIRTUAL_BATTERY)
+ if (params->port == I2C_PORT_VIRTUAL_BATTERY &&
+ VIRTUAL_BATTERY_ADDR == addr) {
+ /* get batt param from write msg */
+ if (*out)
+ batt_param = *out;
+ rv = virtual_battery_read(batt_param,
+ &resp->data[in_len],
+ read_len);
+ }
+#endif
/* Transfer next message */
PTHRUPRINTF("i2c passthru xfer port=%x, addr=%x, out=%p, "
"write_len=%x, data=%p, read_len=%x, flags=%x",
params->port, addr, out, write_len,
&resp->data[in_len], read_len, xferflags);
- rv = i2c_xfer(params->port, addr, out, write_len,
- &resp->data[in_len], read_len, xferflags);
+ if (rv)
+ rv = i2c_xfer(params->port, addr, out, write_len,
+ &resp->data[in_len], read_len, xferflags);
+
if (rv) {
/* Driver will have sent a stop bit here */
if (rv == EC_ERROR_TIMEOUT)
diff --git a/driver/battery/smart.c b/driver/battery/smart.c
index 112af6abb0..212457866e 100644
--- a/driver/battery/smart.c
+++ b/driver/battery/smart.c
@@ -303,6 +303,9 @@ void battery_get_params(struct batt_params *batt)
if (battery_full_charge_capacity(&batt_new.full_capacity))
batt_new.flags |= BATT_FLAG_BAD_FULL_CAPACITY;
+ if (battery_status(&batt_new.status))
+ batt_new.flags |= BATT_FLAG_BAD_STATUS;
+
/* If any of those reads worked, the battery is responsive */
if ((batt_new.flags & BATT_FLAG_BAD_ANY) != BATT_FLAG_BAD_ANY)
batt_new.flags |= BATT_FLAG_RESPONSIVE;
diff --git a/include/battery.h b/include/battery.h
index 18c84a37d3..e79ddd3adf 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -65,6 +65,7 @@ struct batt_params {
int desired_current; /* Charging current desired by battery (mA) */
int remaining_capacity; /* Remaining capacity in mAh */
int full_capacity; /* Capacity in mAh (might change occasionally) */
+ int status; /* Battery status */
enum battery_present is_present; /* Is the battery physically present */
int flags; /* Flags */
};
@@ -86,8 +87,9 @@ struct batt_params {
#define BATT_FLAG_BAD_DESIRED_CURRENT 0x00000080
#define BATT_FLAG_BAD_REMAINING_CAPACITY 0x00000100
#define BATT_FLAG_BAD_FULL_CAPACITY 0x00000200
+#define BATT_FLAG_BAD_STATUS 0x00000400
/* All of the above BATT_FLAG_BAD_* bits */
-#define BATT_FLAG_BAD_ANY 0x000003fc
+#define BATT_FLAG_BAD_ANY 0x000007fc
/* Battery constants */
struct battery_info {
diff --git a/include/charge_state_v2.h b/include/charge_state_v2.h
index 37b88326c9..c5aedb7a94 100644
--- a/include/charge_state_v2.h
+++ b/include/charge_state_v2.h
@@ -4,12 +4,16 @@
*/
#include "battery.h"
+#include "battery_smart.h"
#include "charger.h"
#include "timer.h"
#ifndef __CROS_EC_CHARGE_STATE_V2_H
#define __CROS_EC_CHARGE_STATE_V2_H
+#if defined(CONFIG_I2C_VIRTUAL_BATTERY) && defined(CONFIG_BATTERY_SMART)
+#define VIRTUAL_BATTERY_ADDR BATTERY_ADDR
+#endif
/*
* The values exported by charge_get_state() and charge_get_flags() are used
* only to control the LEDs (with one not-quite-correct exception). For V2
@@ -68,5 +72,16 @@ enum ec_status charger_profile_override_set_param(uint32_t param,
*/
int charge_set_input_current_limit(int ma);
+
+/**
+ * Get value of battery parameter from charge state.
+ *
+ * @param batt_param battery parameter
+ * @param dest Destination buffer for data
+ * @param read_len Number of bytes to write to buffer
+ * @return EC_SUCCESS if successful, non-zero if error.
+ *
+ */
+int virtual_battery_read(uint8_t batt_param, uint8_t *dest, int read_len);
#endif /* __CROS_EC_CHARGE_STATE_V2_H */
diff --git a/include/config.h b/include/config.h
index 9bd278359c..26fced9a46 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1048,6 +1048,7 @@
#undef CONFIG_I2C_DEBUG_PASSTHRU
#undef CONFIG_I2C_PASSTHROUGH
#undef CONFIG_I2C_PASSTHRU_RESTRICTED
+#undef CONFIG_I2C_VIRTUAL_BATTERY
/* For EC that is only an I2C slave */
#undef CONFIG_I2C_SLAVE_ONLY