Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: b1f81b496b0d ("platform/x86: surface3_power: MSHW0011 rev-eng implementation")
BugLink: https://github.com/linux-surface/linux-surface/issues/608
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Reviewed-by: Maximilian Luz <luzmaximilian@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20220224101848.7219-1-hdegoede@redhat.com

+10 -3
+10 -3
drivers/platform/surface/surface3_power.c
··· 232 232 } 233 233 bix->last_full_charg_capacity = ret; 234 234 235 - /* get serial number */ 235 + /* 236 + * Get serial number, on some devices (with unofficial replacement 237 + * battery?) reading any of the serial number range addresses gets 238 + * nacked in this case just leave the serial number empty. 239 + */ 236 240 ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO, 237 241 sizeof(buf), buf); 238 - if (ret != sizeof(buf)) { 242 + if (ret == -EREMOTEIO) { 243 + /* no serial number available */ 244 + } else if (ret != sizeof(buf)) { 239 245 dev_err(&client->dev, "Error reading serial no: %d\n", ret); 240 246 return ret; 247 + } else { 248 + snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf); 241 249 } 242 - snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf); 243 250 244 251 /* get cycle count */ 245 252 ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);