summaryrefslogtreecommitdiff
path: root/driver/battery/smart.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/battery/smart.c')
-rw-r--r--driver/battery/smart.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/driver/battery/smart.c b/driver/battery/smart.c
index 81a74917a9..48177fd375 100644
--- a/driver/battery/smart.c
+++ b/driver/battery/smart.c
@@ -60,8 +60,7 @@ test_mockable int sb_write(int cmd, int param)
#endif
}
-int sb_read_string(int port, int slave_addr, int offset, uint8_t *data,
- int len)
+int sb_read_string(int offset, uint8_t *data, int len)
{
#ifdef CONFIG_BATTERY_CUT_OFF
/*
@@ -71,12 +70,44 @@ int sb_read_string(int port, int slave_addr, int offset, uint8_t *data,
return EC_RES_ACCESS_DENIED;
#endif
#ifdef CONFIG_SMBUS
- return smbus_read_string(port, slave_addr, offset, data, len);
+ return smbus_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ offset, data, len);
#else
- return i2c_read_string(port, slave_addr, offset, data, len);
+ return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ offset, data, len);
#endif
}
+int sb_read_mfgacc(int cmd, int block, uint8_t *data, int len)
+{
+ int rv;
+
+ /*
+ * First two bytes returned from read are command sent hence read
+ * doesn't yield anything if the length is less than 3 bytes.
+ */
+ if (len < 3)
+ return EC_ERROR_INVAL;
+
+ /* Send manufacturer access command */
+ rv = sb_write(SB_MANUFACTURER_ACCESS, cmd);
+ if (rv)
+ return rv;
+
+ /*
+ * Read data on the register block.
+ * First two bytes returned are command sent,
+ * rest are actual data LSB to MSB.
+ */
+ rv = sb_read_string(block, data, len);
+ if (rv)
+ return rv;
+ if ((data[0] | data[1] << 8) != cmd)
+ return EC_ERROR_UNKNOWN;
+
+ return EC_SUCCESS;
+}
+
int battery_get_mode(int *mode)
{
return sb_read(SB_BATTERY_MODE, mode);
@@ -237,22 +268,19 @@ test_mockable int battery_manufacture_date(int *year, int *month, int *day)
/* Read manufacturer name */
test_mockable int battery_manufacturer_name(char *dest, int size)
{
- return sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
- SB_MANUFACTURER_NAME, dest, size);
+ return sb_read_string(SB_MANUFACTURER_NAME, dest, size);
}
/* Read device name */
test_mockable int battery_device_name(char *dest, int size)
{
- return sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
- SB_DEVICE_NAME, dest, size);
+ return sb_read_string(SB_DEVICE_NAME, dest, size);
}
/* Read battery type/chemistry */
test_mockable int battery_device_chemistry(char *dest, int size)
{
- return sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
- SB_DEVICE_CHEMISTRY, dest, size);
+ return sb_read_string(SB_DEVICE_CHEMISTRY, dest, size);
}
void battery_get_params(struct batt_params *batt)
@@ -411,27 +439,14 @@ static int command_batt_mfg_access_read(int argc, char **argv)
if (argc > 3) {
len = strtoi(argv[3], &e, 0);
len += 2;
- if (*e || len < 1 || len > sizeof(data))
+ if (*e || len < 3 || len > sizeof(data))
return EC_ERROR_PARAM3;
}
- /* Send manufacturer access command */
- rv = sb_write(SB_MANUFACTURER_ACCESS, cmd);
+ rv = sb_read_mfgacc(cmd, block, data, len);
if (rv)
return rv;
- /*
- * Read data on the register block.
- * First two bytes returned are command sent,
- * rest are actual data LSB to MSB.
- */
- rv = sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
- block, data, len);
- if (rv)
- return rv;
- if (data[0] != (cmd & 0xff) || data[1] != (cmd >> 8 & 0xff))
- return EC_ERROR_UNKNOWN;
-
ccprintf("data[MSB->LSB]=0x");
do {
len--;
@@ -500,8 +515,7 @@ static int host_command_sb_read_block(struct host_cmd_handler_args *args)
(p->reg != SB_DEVICE_CHEMISTRY) &&
(p->reg != SB_MANUFACTURER_DATA))
return EC_RES_INVALID_PARAM;
- rv = sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR, p->reg,
- r->data, 32);
+ rv = sb_read_string(p->reg, r->data, 32);
if (rv)
return EC_RES_ERROR;