iio: adc: sun20i-gpadc: Use adc-helpers

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>
This commit is contained in:
Matti Vaittinen
2025-03-24 09:13:28 +02:00
committed by Jonathan Cameron
parent 2d17ed10e4
commit 19d8a86918
2 changed files with 15 additions and 25 deletions

View 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.

View 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");