aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/power/supply/sbs-battery.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
index 83b9924033bd..74221b9279a9 100644
--- a/drivers/power/supply/sbs-battery.c
+++ b/drivers/power/supply/sbs-battery.c
@@ -263,8 +263,7 @@ static int sbs_read_word_data(struct i2c_client *client, u8 address)
return ret;
}
-static int sbs_read_string_data(struct i2c_client *client, u8 address,
- char *values)
+static int sbs_read_string_data_fallback(struct i2c_client *client, u8 address, char *values)
{
struct sbs_info *chip = i2c_get_clientdata(client);
s32 ret = 0, block_length = 0;
@@ -274,6 +273,8 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
retries_length = chip->i2c_retry_count;
retries_block = chip->i2c_retry_count;
+ dev_warn_once(&client->dev, "I2C adapter does not support I2C_FUNC_SMBUS_READ_BLOCK_DATA.\n");
+
/* Adapter needs to support these two functions */
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA |
@@ -329,6 +330,32 @@ static int sbs_read_string_data(struct i2c_client *client, u8 address,
return ret;
}
+static int sbs_read_string_data(struct i2c_client *client, u8 address, char *values)
+{
+ struct sbs_info *chip = i2c_get_clientdata(client);
+ int retries = chip->i2c_retry_count;
+ int ret = 0;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA))
+ return sbs_read_string_data_fallback(client, address, values);
+
+ while (retries > 0) {
+ ret = i2c_smbus_read_block_data(client, address, values);
+ if (ret >= 0)
+ break;
+ retries--;
+ }
+
+ if (ret < 0) {
+ dev_dbg(&client->dev, "failed to read block 0x%x: %d\n", address, ret);
+ return ret;
+ }
+
+ /* add string termination */
+ values[ret] = '\0';
+ return ret;
+}
+
static int sbs_write_word_data(struct i2c_client *client, u8 address,
u16 value)
{