[PATCH v3 1/3] hwmon: (ads7871) Fix endianness bug in 16-bit register reads

From: Tabrez Ahmed

Date: Fri Apr 17 2026 - 23:48:33 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.

Reported-by: Sashiko <sashiko@xxxxxxxxxx>
Closes: https://sashiko.dev/#/patchset/20260329073352.270451-1-tabreztalks%40gmail.com
Signed-off-by: Tabrez Ahmed <tabreztalks@xxxxxxxxx>
---
drivers/hwmon/ads7871.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c
index 9bfdf9e6bcd77..9b52aa496d522 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,14 @@ 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 buf[2];
+
reg = reg | INST_READ_BM | INST_16BIT_BM;
- ret = spi_w8r16(spi, reg);
- return ret;
+ ret = spi_write_then_read(spi, &reg, 1, buf, 2);
+ if (ret < 0)
+ return ret;
+
+ return get_unaligned_le16(buf);
}

static int ads7871_write_reg8(struct spi_device *spi, int reg, u8 val)
--
2.43.0