// SPDX-License-Identifier: GPL-2.0-only /* * Helpers for parsing common ADC information from a firmware node. * * Copyright (c) 2025 Matti Vaittinen */ #include #include #include #include #include #include #include #include /** * devm_iio_adc_device_alloc_chaninfo_se - allocate and fill iio_chan_spec for ADC * * Scan the device node for single-ended ADC channel information. Channel ID is * expected to be found from the "reg" property. Allocate and populate the * iio_chan_spec structure corresponding to channels that are found. The memory * for iio_chan_spec structure will be freed upon device detach. * * @dev: Pointer to the ADC device. * @template: Template iio_chan_spec from which the fields of all * found and allocated channels are initialized. * @max_chan_id: Maximum value of a channel ID. Use negative value if no * checking is required. * @cs: Location where pointer to allocated iio_chan_spec * should be stored. * * Return: Number of found channels on success. Negative value to indicate * failure. Specifically, -ENOENT if no channel nodes were found. */ int devm_iio_adc_device_alloc_chaninfo_se(struct device *dev, const struct iio_chan_spec *template, int max_chan_id, struct iio_chan_spec **cs) { struct iio_chan_spec *chan_array, *chan; int num_chan, ret; num_chan = iio_adc_device_num_channels(dev); if (num_chan < 0) return num_chan; if (!num_chan) return -ENOENT; chan_array = devm_kcalloc(dev, num_chan, sizeof(*chan_array), GFP_KERNEL); if (!chan_array) return -ENOMEM; chan = &chan_array[0]; device_for_each_named_child_node_scoped(dev, child, "channel") { u32 ch; ret = fwnode_property_read_u32(child, "reg", &ch); if (ret) return ret; if (max_chan_id >= 0 && ch > max_chan_id) return -ERANGE; *chan = *template; chan->channel = ch; chan++; } *cs = chan_array; return num_chan; } EXPORT_SYMBOL_NS_GPL(devm_iio_adc_device_alloc_chaninfo_se, "IIO_DRIVER"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Matti Vaittinen "); MODULE_DESCRIPTION("IIO ADC fwnode parsing helpers");