From: David Lechner Date: Fri, 2 May 2025 15:04:30 +0000 (-0500) Subject: iio: adc: ad7606: fix raw read for 18-bit chips X-Git-Tag: v6.16-rc1~30^2~35^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f5fd1717ae9497215f22aa748fc2c09df88b0e3;p=thirdparty%2Flinux.git iio: adc: ad7606: fix raw read for 18-bit chips Fix 18-bit raw read for 18-bit chips by applying a mask to the value we receive from the SPI controller. SPI controllers either return 1, 2 or 4 bytes per word depending on the bits_per_word. For 16-bit chips, there was no problem since they raw data fit exactly in the 2 bytes received from the SPI controller. But now that we have 18-bit chips and we are using bits_per_word = 18, we cannot assume that the extra bits in the 32-bit word are always zero. In fact, with the AXI SPI Engine controller, these bits are not always zero which caused the raw values to read 10s of 1000s of volts instead of the correct value. Therefore, we need to mask the value we receive from the SPI controller to ensure that only the 18 bits of real data are used. Fixes: f3838e934dff ("iio: adc: ad7606: add support for AD7606C-{16,18} parts") Signed-off-by: David Lechner Link: https://patch.msgid.link/20250502-iio-adc-ad7606-fix-raw-read-for-18-bit-chips-v1-1-06caa92d8f11@baylibre.com Cc: Signed-off-by: Jonathan Cameron --- diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 703556eb7257e..8ed65a35b4862 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -727,17 +727,16 @@ static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned int ch, goto error_ret; chan = &indio_dev->channels[ch + 1]; - if (chan->scan_type.sign == 'u') { - if (realbits > 16) - *val = st->data.buf32[ch]; - else - *val = st->data.buf16[ch]; - } else { - if (realbits > 16) - *val = sign_extend32(st->data.buf32[ch], realbits - 1); - else - *val = sign_extend32(st->data.buf16[ch], realbits - 1); - } + + if (realbits > 16) + *val = st->data.buf32[ch]; + else + *val = st->data.buf16[ch]; + + *val &= GENMASK(realbits - 1, 0); + + if (chan->scan_type.sign == 's') + *val = sign_extend32(*val, realbits - 1); error_ret: if (!st->gpio_convst) {