diff options
Diffstat (limited to 'driver/battery/smart.c')
-rw-r--r-- | driver/battery/smart.c | 68 |
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; |