Skip to content

Commit c4b12a2

Browse files
committed
power: supply: sbs-battery: simplify read_read_string_data
The SBS battery implements SMBus block reads. Currently the driver "emulates" this by doing an I2C byte read for the length followed by an I2C block read. The I2C subsystem actually provides a proper API for doing SMBus block reads, which can and should be used instead. The current implementation does not properly handle packet error checking (PEC). This change requires, that I2C bus drivers support I2C_M_RECV_LEN or directly provide the SMBus API to access device manufacturer and model name. Reviewed-by: Emil Velikov <[email protected]> Signed-off-by: Sebastian Reichel <[email protected]>
1 parent d6f5632 commit c4b12a2

File tree

1 file changed

+12
-53
lines changed

1 file changed

+12
-53
lines changed

drivers/power/supply/sbs-battery.c

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -202,66 +202,32 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
202202
char *values)
203203
{
204204
struct sbs_info *chip = i2c_get_clientdata(client);
205-
s32 ret = 0, block_length = 0;
206-
int retries_length, retries_block;
207-
u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
208-
209-
retries_length = chip->i2c_retry_count;
210-
retries_block = chip->i2c_retry_count;
205+
int retries = chip->i2c_retry_count;
206+
s32 ret = 0;
211207

212-
/* Adapter needs to support these two functions */
213208
if (!i2c_check_functionality(client->adapter,
214-
I2C_FUNC_SMBUS_BYTE_DATA |
215-
I2C_FUNC_SMBUS_I2C_BLOCK)){
209+
I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
216210
return -ENODEV;
217211
}
218212

219-
/* Get the length of block data */
220-
while (retries_length > 0) {
221-
ret = i2c_smbus_read_byte_data(client, address);
222-
if (ret >= 0)
223-
break;
224-
retries_length--;
225-
}
226-
227-
if (ret < 0) {
228-
dev_dbg(&client->dev,
229-
"%s: i2c read at address 0x%x failed\n",
230-
__func__, address);
231-
return ret;
232-
}
233-
234-
/* block_length does not include NULL terminator */
235-
block_length = ret;
236-
if (block_length > I2C_SMBUS_BLOCK_MAX) {
237-
dev_err(&client->dev,
238-
"%s: Returned block_length is longer than 0x%x\n",
239-
__func__, I2C_SMBUS_BLOCK_MAX);
240-
return -EINVAL;
241-
}
242-
243213
/* Get the block data */
244-
while (retries_block > 0) {
245-
ret = i2c_smbus_read_i2c_block_data(
246-
client, address,
247-
block_length + 1, block_buffer);
214+
while (retries > 0) {
215+
ret = i2c_smbus_read_block_data(client, address, values);
248216
if (ret >= 0)
249217
break;
250-
retries_block--;
218+
retries--;
251219
}
252220

253221
if (ret < 0) {
254-
dev_dbg(&client->dev,
255-
"%s: i2c read at address 0x%x failed\n",
256-
__func__, address);
222+
dev_dbg(&client->dev, "%s: failed to read block 0x%x: %d\n",
223+
__func__, address, ret);
257224
return ret;
258225
}
259226

260-
/* block_buffer[0] == block_length */
261-
memcpy(values, block_buffer + 1, block_length);
262-
values[block_length] = '\0';
227+
/* add string termination */
228+
values[ret] = '\0';
263229

264-
return ret;
230+
return 0;
265231
}
266232

267233
static int sbs_write_word_data(struct i2c_client *client, u8 address,
@@ -465,14 +431,7 @@ static int sbs_get_battery_property(struct i2c_client *client,
465431
static int sbs_get_battery_string_property(struct i2c_client *client,
466432
int reg_offset, enum power_supply_property psp, char *val)
467433
{
468-
s32 ret;
469-
470-
ret = sbs_read_string_data(client, sbs_data[reg_offset].addr, val);
471-
472-
if (ret < 0)
473-
return ret;
474-
475-
return 0;
434+
return sbs_read_string_data(client, sbs_data[reg_offset].addr, val);
476435
}
477436

478437
static void sbs_unit_adjustment(struct i2c_client *client,

0 commit comments

Comments
 (0)