]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iio: adc: ad7476: Drop convstart chan_spec
authorMatti Vaittinen <mazziesaccount@gmail.com>
Mon, 11 Aug 2025 08:51:28 +0000 (11:51 +0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 16 Aug 2025 12:21:20 +0000 (13:21 +0100)
The ad7476 driver defines separate chan_spec structures for operation
with and without convstart GPIO. At quick glance this may seem as if the
driver did provide more than 1 data-channel to users - one for the
regular data, other for the data obtained with the convstart GPIO.

The only difference between the 'convstart' and 'non convstart'
-channels is presence / absence of the BIT(IIO_CHAN_INFO_RAW) in
channel's flags.

We can drop the convstart channel spec, and related convstart macro, by
allocating a mutable per driver instance channel spec and adding the flag
in probe if needed. This will simplify the driver with the cost of added
memory consumption.

Assuming there aren't systems with very many ADCs and very few
resources, this tradeoff seems worth making.

Simplify the driver by dropping the 'convstart' channel spec and
allocating the channel spec for each driver instance.

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://patch.msgid.link/cd7c72e3ee00f279d3381873f54e0c5b75b5ad11.1754901948.git.mazziesaccount@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad7476.c

index 1445f0f599d96d8a1d4fef6d3b18439eefe58c94..ad9e629f0cbde350dcb0b8f28219be1af41c28e8 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright 2010 Analog Devices Inc.
  */
 
+#include <linux/bitops.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -29,8 +30,6 @@ struct ad7476_state;
 struct ad7476_chip_info {
        unsigned int                    int_vref_mv;
        struct iio_chan_spec            channel[2];
-       /* channels used when convst gpio is defined */
-       struct iio_chan_spec            convst_channel[2];
        void (*reset)(struct ad7476_state *);
        bool                            has_vref;
        bool                            has_vdrive;
@@ -42,6 +41,7 @@ struct ad7476_state {
        struct gpio_desc                *convst_gpio;
        struct spi_transfer             xfer;
        struct spi_message              msg;
+       struct iio_chan_spec            channel[2];
        int                             scale_mv;
        /*
         * DMA (thus cache coherency maintenance) may require the
@@ -154,24 +154,18 @@ static int ad7476_read_raw(struct iio_dev *indio_dev,
 #define AD7940_CHAN(bits) _AD7476_CHAN((bits), 15 - (bits), \
                BIT(IIO_CHAN_INFO_RAW))
 #define AD7091R_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), 0)
-#define AD7091R_CONVST_CHAN(bits) _AD7476_CHAN((bits), 16 - (bits), \
-               BIT(IIO_CHAN_INFO_RAW))
 #define ADS786X_CHAN(bits) _AD7476_CHAN((bits), 12 - (bits), \
                BIT(IIO_CHAN_INFO_RAW))
 
 static const struct ad7476_chip_info ad7091_chip_info = {
        .channel[0] = AD7091R_CHAN(12),
        .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
-       .convst_channel[0] = AD7091R_CONVST_CHAN(12),
-       .convst_channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
        .reset = ad7091_reset,
 };
 
 static const struct ad7476_chip_info ad7091r_chip_info = {
        .channel[0] = AD7091R_CHAN(12),
        .channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
-       .convst_channel[0] = AD7091R_CONVST_CHAN(12),
-       .convst_channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
        .int_vref_mv = 2500,
        .has_vref = true,
        .reset = ad7091_reset,
@@ -282,6 +276,7 @@ static int ad7476_probe(struct spi_device *spi)
 {
        struct ad7476_state *st;
        struct iio_dev *indio_dev;
+       unsigned int i;
        int ret;
 
        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@@ -332,16 +327,28 @@ static int ad7476_probe(struct spi_device *spi)
        if (IS_ERR(st->convst_gpio))
                return PTR_ERR(st->convst_gpio);
 
+       /*
+        * This will never happen. Unless someone changes the channel specs
+        * in this driver. And if someone does, without changing the loop
+        * below, then we'd better immediately produce a big fat error, before
+        * the change proceeds from that developer's table.
+        */
+       static_assert(ARRAY_SIZE(st->channel) == ARRAY_SIZE(st->chip_info->channel));
+       for (i = 0; i < ARRAY_SIZE(st->channel); i++) {
+               st->channel[i] = st->chip_info->channel[i];
+               if (st->convst_gpio)
+                       __set_bit(IIO_CHAN_INFO_RAW,
+                                 &st->channel[i].info_mask_separate);
+       }
+
        st->spi = spi;
 
        indio_dev->name = spi_get_device_id(spi)->name;
        indio_dev->modes = INDIO_DIRECT_MODE;
-       indio_dev->channels = st->chip_info->channel;
-       indio_dev->num_channels = 2;
+       indio_dev->channels = st->channel;
+       indio_dev->num_channels = ARRAY_SIZE(st->channel);
        indio_dev->info = &ad7476_info;
 
-       if (st->convst_gpio)
-               indio_dev->channels = st->chip_info->convst_channel;
        /* Setup default message */
 
        st->xfer.rx_buf = &st->data;