diff --git a/drivers/iio/adc/ad7606.c b/drivers/iio/adc/ad7606.c index 7dc299aeee15..94a254c0725e 100644 --- a/drivers/iio/adc/ad7606.c +++ b/drivers/iio/adc/ad7606.c @@ -64,19 +64,21 @@ EXPORT_SYMBOL_NS_GPL(ad7606_reset, IIO_AD7606); static int ad7606_16bit_chan_scale_setup(struct ad7606_state *st, int ch) { + struct ad7606_chan_scale *cs = &st->chan_scales[ch]; + if (!st->sw_mode_en) { /* tied to logic low, analog input range is +/- 5V */ - st->range[ch] = 0; - st->scale_avail = ad7606_16bit_hw_scale_avail; - st->num_scales = ARRAY_SIZE(ad7606_16bit_hw_scale_avail); + cs->range = 0; + cs->scale_avail = ad7606_16bit_hw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7606_16bit_hw_scale_avail); return 0; } /* Scale of 0.076293 is only available in sw mode */ /* After reset, in software mode, ±10 V is set by default */ - st->range[ch] = 2; - st->scale_avail = ad7606_16bit_sw_scale_avail; - st->num_scales = ARRAY_SIZE(ad7606_16bit_sw_scale_avail); + cs->range = 2; + cs->scale_avail = ad7606_16bit_sw_scale_avail; + cs->num_scales = ARRAY_SIZE(ad7606_16bit_sw_scale_avail); return 0; } @@ -167,6 +169,7 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, { int ret, ch = 0; struct ad7606_state *st = iio_priv(indio_dev); + struct ad7606_chan_scale *cs; switch (m) { case IIO_CHAN_INFO_RAW: @@ -180,8 +183,9 @@ static int ad7606_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: if (st->sw_mode_en) ch = chan->address; + cs = &st->chan_scales[ch]; *val = 0; - *val2 = st->scale_avail[st->range[ch]]; + *val2 = cs->scale_avail[cs->range]; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: *val = st->oversampling; @@ -211,8 +215,9 @@ static ssize_t in_voltage_scale_available_show(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ad7606_state *st = iio_priv(indio_dev); + struct ad7606_chan_scale *cs = &st->chan_scales[0]; - return ad7606_show_avail(buf, st->scale_avail, st->num_scales, true); + return ad7606_show_avail(buf, cs->scale_avail, cs->num_scales, true); } static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); @@ -250,19 +255,21 @@ static int ad7606_write_raw(struct iio_dev *indio_dev, long mask) { struct ad7606_state *st = iio_priv(indio_dev); + struct ad7606_chan_scale *cs; int i, ret, ch = 0; guard(mutex)(&st->lock); switch (mask) { case IIO_CHAN_INFO_SCALE: - i = find_closest(val2, st->scale_avail, st->num_scales); if (st->sw_mode_en) ch = chan->address; + cs = &st->chan_scales[ch]; + i = find_closest(val2, cs->scale_avail, cs->num_scales); ret = st->write_scale(indio_dev, ch, i); if (ret < 0) return ret; - st->range[ch] = i; + cs->range = i; return 0; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: @@ -707,7 +714,7 @@ static int ad7606_resume(struct device *dev) struct ad7606_state *st = iio_priv(indio_dev); if (st->gpio_standby) { - gpiod_set_value(st->gpio_range, st->range[0]); + gpiod_set_value(st->gpio_range, st->chan_scales[0].range); gpiod_set_value(st->gpio_standby, 1); ad7606_reset(st); } diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h index 95f3b3cb0be3..2b90f52affba 100644 --- a/drivers/iio/adc/ad7606.h +++ b/drivers/iio/adc/ad7606.h @@ -8,6 +8,8 @@ #ifndef IIO_ADC_AD7606_H_ #define IIO_ADC_AD7606_H_ +#define AD760X_MAX_CHANNELS 16 + #define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -66,17 +68,27 @@ struct ad7606_chip_info { unsigned long init_delay_ms; }; +/** + * struct ad7606_chan_scale - channel scale configuration + * @scale_avail pointer to the array which stores the available scales + * @num_scales number of elements stored in the scale_avail array + * @range voltage range selection, selects which scale to apply + */ +struct ad7606_chan_scale { + const unsigned int *scale_avail; + unsigned int num_scales; + unsigned int range; +}; + /** * struct ad7606_state - driver instance specific data * @dev pointer to kernel device * @chip_info entry in the table of chips that describes this device * @bops bus operations (SPI or parallel) - * @range voltage range selection, selects which scale to apply + * @chan_scales scale configuration for channels * @oversampling oversampling selection * @base_address address from where to read data in parallel operation * @sw_mode_en software mode enabled - * @scale_avail pointer to the array which stores the available scales - * @num_scales number of elements stored in the scale_avail array * @oversampling_avail pointer to the array which stores the available * oversampling ratios. * @num_os_ratios number of elements stored in oversampling_avail array @@ -100,12 +112,10 @@ struct ad7606_state { struct device *dev; const struct ad7606_chip_info *chip_info; const struct ad7606_bus_ops *bops; - unsigned int range[16]; + struct ad7606_chan_scale chan_scales[AD760X_MAX_CHANNELS]; unsigned int oversampling; void __iomem *base_address; bool sw_mode_en; - const unsigned int *scale_avail; - unsigned int num_scales; const unsigned int *oversampling_avail; unsigned int num_os_ratios; int (*write_scale)(struct iio_dev *indio_dev, int ch, int val);