Commit 19d8a869 authored by Matti Vaittinen's avatar Matti Vaittinen Committed by Jonathan Cameron
Browse files

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: default avatarMatti Vaittinen <mazziesaccount@gmail.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/e367a803c0d625e60c9fca16c55a25eee06b5a89.1742560649.git.mazziesaccount@gmail.com


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 2d17ed10
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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.
+14 −25
Original line number Diff line number Diff line
@@ -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");