[PATCH v4 1/3] hwmon: (ads7871) Fix endianness bug in 16-bit register reads
From: Tabrez Ahmed
Date: Thu Apr 30 2026 - 21:31:16 EST
The ads7871_read_reg16() function relies on spi_w8r16() to read the
16-bit sensor output. The ADS7871 device transmits the Least Significant
Byte (LSB) first.
On Little-Endian architectures, spi_w8r16() correctly reconstructs the
16-bit value. However, on Big-Endian architectures, the byte swapping
causes the first received byte (LSB) to be placed in the most significant
byte of the u16, resulting in corrupted voltage readings.
Replace spi_w8r16() with a manual spi_write_then_read() into a byte array,
and safely reconstruct the integer using get_unaligned_le16() to ensure
correct behavior across all architectures. Additionally, use a u8
variable for the command byte to ensure the correct instruction is
transmitted on Big-Endian systems.
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Closes: https://sashiko.dev/#/patchset/20260418034601.90226-1-tabreztalks@xxxxxxxxx
Signed-off-by: Tabrez Ahmed <tabreztalks@xxxxxxxxx>
---
drivers/hwmon/ads7871.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c
index 9bfdf9e6bcd77..15104d9b2b733 100644
--- a/drivers/hwmon/ads7871.c
+++ b/drivers/hwmon/ads7871.c
@@ -59,6 +59,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/delay.h>
+#include <asm/unaligned.h>
#define DEVICE_NAME "ads7871"
@@ -77,9 +78,17 @@ static int ads7871_read_reg8(struct spi_device *spi, int reg)
static int ads7871_read_reg16(struct spi_device *spi, int reg)
{
int ret;
+ u8 tx_cmd;
+ u8 rx_buf[2];
+
reg = reg | INST_READ_BM | INST_16BIT_BM;
- ret = spi_w8r16(spi, reg);
- return ret;
+ tx_cmd = reg;
+
+ ret = spi_write_then_read(spi, &tx_cmd, 1, rx_buf, 2);
+ if (ret < 0)
+ return ret;
+
+ return get_unaligned_le16(rx_buf);
}
static int ads7871_write_reg8(struct spi_device *spi, int reg, u8 val)
--
2.43.0