Commit 2d17ed10 authored by Matti Vaittinen's avatar Matti Vaittinen Committed by Jonathan Cameron
Browse files

iio: adc: rzg2l_adc: 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 rzg2l_adc's compatible
string didn't reveal any in-tree .dts with channel nodes named
otherwise. Also, same grep shows all the .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>
Tested-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: default avatarClaudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://patch.msgid.link/e84ccff01070eaee3dd1ae2d7e109f963168f586.1742560649.git.mazziesaccount@gmail.com


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent f3a8f870
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1266,6 +1266,7 @@ config RICHTEK_RTQ6056
config RZG2L_ADC
	tristate "Renesas RZ/G2L ADC driver"
	depends on ARCH_RZG2L || COMPILE_TEST
	select IIO_ADC_HELPER
	help
	  Say yes here to build support for the ADC found in Renesas
	  RZ/G2L family.
+16 −23
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/cleanup.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/iio/adc-helpers.h>
#include <linux/iio/iio.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -324,48 +325,39 @@ static irqreturn_t rzg2l_adc_isr(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static const struct iio_chan_spec rzg2l_adc_chan_template = {
	.indexed = 1,
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
};

static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l_adc *adc)
{
	const struct rzg2l_adc_hw_params *hw_params = adc->hw_params;
	struct iio_chan_spec *chan_array;
	struct rzg2l_adc_data *data;
	unsigned int channel;
	int num_channels;
	int ret;
	u8 i;

	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	num_channels = device_get_child_node_count(&pdev->dev);
	if (!num_channels)
		return dev_err_probe(&pdev->dev, -ENODEV, "no channel children\n");
	num_channels = devm_iio_adc_device_alloc_chaninfo_se(&pdev->dev,
						&rzg2l_adc_chan_template,
						hw_params->num_channels - 1,
						&chan_array);
	if (num_channels < 0)
		return num_channels;

	if (num_channels > hw_params->num_channels)
		return dev_err_probe(&pdev->dev, -EINVAL,
				     "num of channel children out of range\n");

	chan_array = devm_kcalloc(&pdev->dev, num_channels, sizeof(*chan_array),
				  GFP_KERNEL);
	if (!chan_array)
		return -ENOMEM;
	for (i = 0; i < num_channels; i++) {
		int channel = chan_array[i].channel;

	i = 0;
	device_for_each_child_node_scoped(&pdev->dev, fwnode) {
		ret = fwnode_property_read_u32(fwnode, "reg", &channel);
		if (ret)
			return ret;

		if (channel >= hw_params->num_channels)
			return -EINVAL;

		chan_array[i].type = rzg2l_adc_channels[channel].type;
		chan_array[i].indexed = 1;
		chan_array[i].channel = channel;
		chan_array[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
		chan_array[i].datasheet_name = rzg2l_adc_channels[channel].name;
		i++;
		chan_array[i].type = rzg2l_adc_channels[channel].type;
	}

	data->num_channels = num_channels;
@@ -626,3 +618,4 @@ module_platform_driver(rzg2l_adc_driver);
MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
MODULE_DESCRIPTION("Renesas RZ/G2L ADC driver");
MODULE_LICENSE("GPL v2");
MODULE_IMPORT_NS("IIO_DRIVER");