summaryrefslogtreecommitdiff
path: root/drivers/iio/adc
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-07-30 13:16:16 +0100
committerMark Brown <broonie@kernel.org>2026-07-30 13:16:16 +0100
commitc719993dfbd30b0b8de6cb917a25254dee47ff51 (patch)
tree51cbcd174b6ce0266437a3d885eefe921892638c /drivers/iio/adc
parent303fbd94993dfdb47e45547ae4e171f99b2bded5 (diff)
parent14655cda0acaa018d35b94c3f759320b9066d020 (diff)
downloadlinux-next-c719993dfbd30b0b8de6cb917a25254dee47ff51.tar.gz
linux-next-c719993dfbd30b0b8de6cb917a25254dee47ff51.zip
Merge branch 'fixes-togreg' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
Diffstat (limited to 'drivers/iio/adc')
-rw-r--r--drivers/iio/adc/Kconfig2
-rw-r--r--drivers/iio/adc/ad4080.c5
-rw-r--r--drivers/iio/adc/adi-axi-adc.c30
-rw-r--r--drivers/iio/adc/ti-ads7138.c42
4 files changed, 70 insertions, 9 deletions
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 3755a81c1efd..c6d3cf68b1f7 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -1076,6 +1076,7 @@ config MAX1363
config MAX14001
tristate "Analog Devices MAX14001/MAX14002 ADC driver"
depends on SPI
+ select REGMAP
help
Say yes here to build support for Analog Devices MAX14001/MAX14002
Configurable, Isolated 10-bit ADCs for Multi-Range Binary Inputs.
@@ -1086,6 +1087,7 @@ config MAX14001
config MAX34408
tristate "Maxim max34408/max344089 ADC driver"
depends on I2C
+ select REGMAP_I2C
help
Say yes here to build support for Maxim max34408/max34409 current sense
monitor with 8-bits ADC interface with overcurrent delay/threshold and
diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
index 0797d64aeaec..967144eee3eb 100644
--- a/drivers/iio/adc/ad4080.c
+++ b/drivers/iio/adc/ad4080.c
@@ -697,6 +697,11 @@ static int ad4080_setup_channel(struct ad4080_state *st, unsigned int ch)
if (ret)
return ret;
+ ret = iio_backend_data_size_set(st->back[ch],
+ st->info->channels[0].scan_type.realbits);
+ if (ret)
+ return ret;
+
if (!st->lvds_cnv_en)
return 0;
diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
index 26b9c75bd4d8..589f03618ecf 100644
--- a/drivers/iio/adc/adi-axi-adc.c
+++ b/drivers/iio/adc/adi-axi-adc.c
@@ -53,6 +53,10 @@
#define AXI_AD485X_PACKET_FORMAT_24BIT 0x1
#define AXI_AD485X_PACKET_FORMAT_32BIT 0x2
#define AXI_AD408X_CNTRL_3_FILTER_EN_MSK BIT(0)
+#define AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK GENMASK(3, 2)
+#define AXI_AD408X_PACKET_FORMAT_20BIT 0x0
+#define AXI_AD408X_PACKET_FORMAT_16BIT 0x1
+#define AXI_AD408X_PACKET_FORMAT_14BIT 0x2
#define ADI_AXI_ADC_REG_SYNC_STATUS 0x0068
#define ADI_AXI_ADC_SYNC_STATUS_ADC_SYNC_MSK BIT(0)
@@ -436,6 +440,31 @@ static int axi_adc_ad408x_filter_type_set(struct iio_backend *back,
AXI_AD408X_CNTRL_3_FILTER_EN_MSK);
}
+static int axi_adc_ad408x_data_size_set(struct iio_backend *back,
+ unsigned int size)
+{
+ struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+ unsigned int val;
+
+ switch (size) {
+ case 20:
+ val = AXI_AD408X_PACKET_FORMAT_20BIT;
+ break;
+ case 16:
+ val = AXI_AD408X_PACKET_FORMAT_16BIT;
+ break;
+ case 14:
+ val = AXI_AD408X_PACKET_FORMAT_14BIT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return regmap_update_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3,
+ AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK,
+ FIELD_PREP(AXI_AD408X_CNTRL_3_PACKET_FORMAT_MSK, val));
+}
+
static int axi_adc_ad408x_interface_data_align(struct iio_backend *back,
u32 timeout_us)
{
@@ -659,6 +688,7 @@ static const struct iio_backend_ops adi_ad408x_ops = {
.free_buffer = axi_adc_free_buffer,
.data_sample_trigger = axi_adc_data_sample_trigger,
.filter_type_set = axi_adc_ad408x_filter_type_set,
+ .data_size_set = axi_adc_ad408x_data_size_set,
.interface_data_align = axi_adc_ad408x_interface_data_align,
.num_lanes_set = axi_adc_num_lanes_set,
.debugfs_reg_access = iio_backend_debugfs_ptr(axi_adc_reg_access),
diff --git a/drivers/iio/adc/ti-ads7138.c b/drivers/iio/adc/ti-ads7138.c
index af87f5f19a0f..da82a6947b2b 100644
--- a/drivers/iio/adc/ti-ads7138.c
+++ b/drivers/iio/adc/ti-ads7138.c
@@ -227,6 +227,26 @@ static int ads7138_osr_to_bits(int osr)
return -EINVAL;
}
+static int ads7138_read_statistics(const struct i2c_client *client, u8 reg,
+ u8 *out_values, u8 length)
+{
+ int ret;
+
+ /* Disable statistics update so the value is not updated mid read */
+ ret = ads7138_i2c_clear_bit(client, ADS7138_REG_GENERAL_CFG,
+ ADS7138_GENERAL_CFG_STATS_EN);
+ if (ret)
+ return ret;
+
+ ret = ads7138_i2c_read_block(client, reg, out_values, length);
+ if (ret)
+ return ret;
+
+ /* Enable statistics update after read */
+ return ads7138_i2c_set_bit(client, ADS7138_REG_GENERAL_CFG,
+ ADS7138_GENERAL_CFG_STATS_EN);
+}
+
static int ads7138_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
@@ -236,28 +256,32 @@ static int ads7138_read_raw(struct iio_dev *indio_dev,
u8 values[2];
switch (mask) {
+ /*
+ * Reading the statistics registers reinitializes them. This is
+ * unfortunate but necessary to prevent data races.
+ */
case IIO_CHAN_INFO_RAW:
- ret = ads7138_i2c_read_block(data->client,
- ADS7138_REG_RECENT_LSB_CH(chan->channel),
- values, ARRAY_SIZE(values));
+ ret = ads7138_read_statistics(data->client,
+ ADS7138_REG_RECENT_LSB_CH(chan->channel),
+ values, ARRAY_SIZE(values));
if (ret)
return ret;
*val = get_unaligned_le16(values);
return IIO_VAL_INT;
case IIO_CHAN_INFO_PEAK:
- ret = ads7138_i2c_read_block(data->client,
- ADS7138_REG_MAX_LSB_CH(chan->channel),
- values, ARRAY_SIZE(values));
+ ret = ads7138_read_statistics(data->client,
+ ADS7138_REG_MAX_LSB_CH(chan->channel),
+ values, ARRAY_SIZE(values));
if (ret)
return ret;
*val = get_unaligned_le16(values);
return IIO_VAL_INT;
case IIO_CHAN_INFO_TROUGH:
- ret = ads7138_i2c_read_block(data->client,
- ADS7138_REG_MIN_LSB_CH(chan->channel),
- values, ARRAY_SIZE(values));
+ ret = ads7138_read_statistics(data->client,
+ ADS7138_REG_MIN_LSB_CH(chan->channel),
+ values, ARRAY_SIZE(values));
if (ret)
return ret;