summaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorJulien Stephan <jstephan@baylibre.com>2024-10-30 14:44:26 +0100
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2024-11-09 10:41:13 +0000
commit0e1168f8f2bfb43dd29a8d224d0a4d3ffccd47d9 (patch)
tree2f60930ea03e506c76118dfc6485d04e8b23cb7f /drivers/iio
parent19406b0a3152dd94fe3b6c454412454acbf2439a (diff)
downloadlinux-stable-0e1168f8f2bfb43dd29a8d224d0a4d3ffccd47d9.tar.gz
linux-stable-0e1168f8f2bfb43dd29a8d224d0a4d3ffccd47d9.tar.bz2
linux-stable-0e1168f8f2bfb43dd29a8d224d0a4d3ffccd47d9.zip
iio: adc: ad7380: fix oversampling formula
The formula in the datasheet for oversampling time conversion seems to be valid when device is at full speed using the maximum number of SDO lines. The driver currently support only 1 SDO line. The correct formula is: t_convert = T_CONVERT_0_NS + T_CONVERT_X_NS*(x - 1)*num_channel/number_of_sdo_lines. It will produce larger delays than what is currently set, but some devices actually require it. Signed-off-by: Julien Stephan <jstephan@baylibre.com> Reviewed-by: David Lechner <dlechner@baylibre.com> Link: https://patch.msgid.link/20241030-ad7380-add-adaq4380-4-support-v4-2-864ff02babae@baylibre.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/adc/ad7380.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index fb728570debe..e5eececaaf50 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -77,6 +77,12 @@
#define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */
#define T_POWERUP_US 5000 /* Power up */
+/*
+ * AD738x support several SDO lines to increase throughput, but driver currently
+ * supports only 1 SDO line (standard SPI transaction)
+ */
+#define AD7380_NUM_SDO_LINES 1
+
struct ad7380_timing_specs {
const unsigned int t_csh_ns; /* CS minimum high time */
};
@@ -649,7 +655,8 @@ static int ad7380_set_ch(struct ad7380_state *st, unsigned int ch)
if (st->oversampling_ratio > 1)
xfer.delay.value = T_CONVERT_0_NS +
- T_CONVERT_X_NS * (st->oversampling_ratio - 1);
+ T_CONVERT_X_NS * (st->oversampling_ratio - 1) *
+ st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES;
return spi_sync_transfer(st->spi, &xfer, 1);
}
@@ -672,7 +679,8 @@ static void ad7380_update_xfers(struct ad7380_state *st,
*/
if (st->oversampling_ratio > 1)
t_convert = T_CONVERT_0_NS + T_CONVERT_X_NS *
- (st->oversampling_ratio - 1);
+ (st->oversampling_ratio - 1) *
+ st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES;
if (st->seq) {
xfer[0].delay.value = xfer[1].delay.value = t_convert;
@@ -1021,7 +1029,8 @@ static int ad7380_init(struct ad7380_state *st, bool external_ref_en)
/* SPI 1-wire mode */
return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2,
AD7380_CONFIG2_SDO,
- FIELD_PREP(AD7380_CONFIG2_SDO, 1));
+ FIELD_PREP(AD7380_CONFIG2_SDO,
+ AD7380_NUM_SDO_LINES));
}
static int ad7380_probe(struct spi_device *spi)