diff options
-rw-r--r-- | common/charge_state_v2.c | 48 | ||||
-rw-r--r-- | common/i2c.c | 23 | ||||
-rw-r--r-- | driver/battery/smart.c | 3 | ||||
-rw-r--r-- | include/battery.h | 4 | ||||
-rw-r--r-- | include/charge_state_v2.h | 15 | ||||
-rw-r--r-- | include/config.h | 1 |
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 |