iio: adc: sun20i-gpadc: Use adc-helpers
authorMatti Vaittinen <mazziesaccount@gmail.com>
Mon, 24 Mar 2025 07:13:28 +0000 (09:13 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Tue, 22 Apr 2025 18:09:52 +0000 (19:09 +0100)
The new devm_iio_adc_device_alloc_chaninfo_se() -helper is intended to
help drivers avoid open-coding the for_each_node -loop for getting the
channel IDs. The helper provides standard way to detect the ADC channel
nodes (by the node name), and a standard way to convert the "reg"
-properties to channel identification numbers, used in the struct
iio_chan_spec. Furthermore, the helper can optionally check the found
channel IDs are smaller than given maximum. This is useful for callers
which later use the IDs for example for indexing a channel data array.

The original driver treated all found child nodes as channel nodes. The
new helper requires channel nodes to be named channel[@N]. This should
help avoid problems with devices which may contain also other but ADC
child nodes. Quick grep from arch/* with the sun20i-gpadc's compatible
string didn't reveal any in-tree .dts with channel nodes named
otherwise. Also, same grep shows all the in-tree .dts seem to have
channel IDs between 0..num of channels.

Use the new helper.

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/e367a803c0d625e60c9fca16c55a25eee06b5a89.1742560649.git.mazziesaccount@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/Kconfig
drivers/iio/adc/sun20i-gpadc-iio.c

index 57ea8cd464ca33e615e4a4bc2cc624f960a94da4..5089d95d6a0057b79700195203ef0f5f70279a8a 100644 (file)
@@ -1401,6 +1401,7 @@ config SUN4I_GPADC
 config SUN20I_GPADC
        tristate "Allwinner D1/T113s/T507/R329 and similar GPADCs driver"
        depends on ARCH_SUNXI || COMPILE_TEST
+       select IIO_ADC_HELPER
        help
          Say yes here to build support for Allwinner (D1, T113, T507 and R329)
          SoCs GPADC. This ADC provides up to 16 channels.
index 136b8d9c294f4679adf813316eae19c2926a2742..2428ea69d6761f546993533555b3172050b866d4 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/property.h>
 #include <linux/reset.h>
 
+#include <linux/iio/adc-helpers.h>
 #include <linux/iio/iio.h>
 
 #define SUN20I_GPADC_DRIVER_NAME       "sun20i-gpadc"
@@ -149,36 +150,23 @@ static void sun20i_gpadc_reset_assert(void *data)
        reset_control_assert(rst);
 }
 
+static const struct iio_chan_spec sun20i_gpadc_chan_template = {
+       .type = IIO_VOLTAGE,
+       .indexed = 1,
+       .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
+};
+
 static int sun20i_gpadc_alloc_channels(struct iio_dev *indio_dev,
                                       struct device *dev)
 {
-       unsigned int channel;
-       int num_channels, i, ret;
+       int num_channels;
        struct iio_chan_spec *channels;
 
-       num_channels = device_get_child_node_count(dev);
-       if (num_channels == 0)
-               return dev_err_probe(dev, -ENODEV, "no channel children\n");
-
-       channels = devm_kcalloc(dev, num_channels, sizeof(*channels),
-                               GFP_KERNEL);
-       if (!channels)
-               return -ENOMEM;
-
-       i = 0;
-       device_for_each_child_node_scoped(dev, node) {
-               ret = fwnode_property_read_u32(node, "reg", &channel);
-               if (ret)
-                       return dev_err_probe(dev, ret, "invalid channel number\n");
-
-               channels[i].type = IIO_VOLTAGE;
-               channels[i].indexed = 1;
-               channels[i].channel = channel;
-               channels[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
-               channels[i].info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
-
-               i++;
-       }
+       num_channels = devm_iio_adc_device_alloc_chaninfo_se(dev,
+                               &sun20i_gpadc_chan_template, -1, &channels);
+       if (num_channels < 0)
+               return num_channels;
 
        indio_dev->channels = channels;
        indio_dev->num_channels = num_channels;
@@ -271,3 +259,4 @@ module_platform_driver(sun20i_gpadc_driver);
 MODULE_DESCRIPTION("ADC driver for sunxi platforms");
 MODULE_AUTHOR("Maksim Kiselev <bigunclemax@gmail.com>");
 MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("IIO_DRIVER");