Commit 21d90aae authored by Hans de Goede's avatar Hans de Goede

surface: surface3_power: Fix battery readings on batteries without a serial number

The battery on the 2nd hand Surface 3 which I recently bought appears to
not have a serial number programmed in. This results in any I2C reads from
the registers containing the serial number failing with an I2C NACK.

This was causing mshw0011_bix() to fail causing the battery readings to
not work at all.

Ignore EREMOTEIO (I2C NACK) errors when retrieving the serial number and
continue with an empty serial number to fix this.

Fixes: b1f81b49 ("platform/x86: surface3_power: MSHW0011 rev-eng implementation")
BugLink: https://github.com/linux-surface/linux-surface/issues/608Reviewed-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Reviewed-by: default avatarMaximilian Luz <luzmaximilian@gmail.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20220224101848.7219-1-hdegoede@redhat.com
parent 68af2842
...@@ -232,14 +232,21 @@ static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix) ...@@ -232,14 +232,21 @@ static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix)
} }
bix->last_full_charg_capacity = ret; bix->last_full_charg_capacity = ret;
/* get serial number */ /*
* Get serial number, on some devices (with unofficial replacement
* battery?) reading any of the serial number range addresses gets
* nacked in this case just leave the serial number empty.
*/
ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO, ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO,
sizeof(buf), buf); sizeof(buf), buf);
if (ret != sizeof(buf)) { if (ret == -EREMOTEIO) {
/* no serial number available */
} else if (ret != sizeof(buf)) {
dev_err(&client->dev, "Error reading serial no: %d\n", ret); dev_err(&client->dev, "Error reading serial no: %d\n", ret);
return ret; return ret;
} else {
snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
} }
snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
/* get cycle count */ /* get cycle count */
ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT); ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment