diff options
| author | Mark Brown <broonie@kernel.org> | 2026-07-30 13:16:16 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-30 13:16:16 +0100 |
| commit | c719993dfbd30b0b8de6cb917a25254dee47ff51 (patch) | |
| tree | 51cbcd174b6ce0266437a3d885eefe921892638c /drivers/iio/adc | |
| parent | 303fbd94993dfdb47e45547ae4e171f99b2bded5 (diff) | |
| parent | 14655cda0acaa018d35b94c3f759320b9066d020 (diff) | |
| download | linux-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/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/iio/adc/ad4080.c | 5 | ||||
| -rw-r--r-- | drivers/iio/adc/adi-axi-adc.c | 30 | ||||
| -rw-r--r-- | drivers/iio/adc/ti-ads7138.c | 42 |
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; |
