]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
iio: adc: ad7606: wrap channel ranges & scales into struct
authorAlexandru Ardelean <aardelean@baylibre.com>
Thu, 19 Sep 2024 13:04:39 +0000 (16:04 +0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 30 Sep 2024 08:21:04 +0000 (09:21 +0100)
With the addition of AD7606C-16,18 which have differential & bipolar
channels (and ranges), which can vary from channel to channel, we'll need
to keep more information about each channel range.

To do that, we'll add a 'struct ad7606_chan_scale' type to hold just
configuration for each channel.
This includes the scales per channel (which can be different with
AD7606C-16,18), as well as the range for each channel.
This driver was already keeping the range value for each channel before,
and since this is couple with the scales, it also makes sense to put them
in the same struct.

Signed-off-by: Alexandru Ardelean <aardelean@baylibre.com>
Link: https://patch.msgid.link/20240919130444.2100447-5-aardelean@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad7606.c
drivers/iio/adc/ad7606.h

index 7dc299aeee154ef075dbbc4dfd71c140bc7c58d9..94a254c0725e84baa05b8c2985df1d1c870d76fb 100644 (file)
@@ -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);
        }
index 95f3b3cb0be32ecf173ddfedf7f604a851106997..2b90f52affba5f84d28e83615e4d737a2314499d 100644 (file)
@@ -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);