Skip to content

Commit 05e0430

Browse files
committed
power: supply: sbs-battery: use i2c_smbus_read_block_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). Not all upstream systems using sbs-battery have I2C bus drivers supporting I2C_M_RECV_LEN, so old implementation is kept as fallback to keep things working. But this prints a warning, which hopefully results in people implementing support for it. Tested-by: Marek Szyprowski <[email protected]> Signed-off-by: Sebastian Reichel <[email protected]>
1 parent 1d85f6d commit 05e0430

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

drivers/power/supply/sbs-battery.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ static int sbs_read_word_data(struct i2c_client *client, u8 address)
263263
return ret;
264264
}
265265

266-
static int sbs_read_string_data(struct i2c_client *client, u8 address,
267-
char *values)
266+
static int sbs_read_string_data_fallback(struct i2c_client *client, u8 address, char *values)
268267
{
269268
struct sbs_info *chip = i2c_get_clientdata(client);
270269
s32 ret = 0, block_length = 0;
@@ -274,6 +273,8 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
274273
retries_length = chip->i2c_retry_count;
275274
retries_block = chip->i2c_retry_count;
276275

276+
dev_warn_once(&client->dev, "I2C adapter does not support I2C_FUNC_SMBUS_READ_BLOCK_DATA.\n");
277+
277278
/* Adapter needs to support these two functions */
278279
if (!i2c_check_functionality(client->adapter,
279280
I2C_FUNC_SMBUS_BYTE_DATA |
@@ -329,6 +330,32 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
329330
return ret;
330331
}
331332

333+
static int sbs_read_string_data(struct i2c_client *client, u8 address, char *values)
334+
{
335+
struct sbs_info *chip = i2c_get_clientdata(client);
336+
int retries = chip->i2c_retry_count;
337+
int ret = 0;
338+
339+
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA))
340+
return sbs_read_string_data_fallback(client, address, values);
341+
342+
while (retries > 0) {
343+
ret = i2c_smbus_read_block_data(client, address, values);
344+
if (ret >= 0)
345+
break;
346+
retries--;
347+
}
348+
349+
if (ret < 0) {
350+
dev_dbg(&client->dev, "failed to read block 0x%x: %d\n", address, ret);
351+
return ret;
352+
}
353+
354+
/* add string termination */
355+
values[ret] = '\0';
356+
return ret;
357+
}
358+
332359
static int sbs_write_word_data(struct i2c_client *client, u8 address,
333360
u16 value)
334361
{

0 commit comments

Comments
 (0)