summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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