diff mbox series

[RFC,v2,06/11] iio: adc: stm32-dfsdm: adopt generic channel bindings

Message ID 20230727150324.1157933-7-olivier.moysan@foss.st.com (mailing list archive)
State Changes Requested
Headers show
Series iio: add iio backend device type | expand

Commit Message

Olivier Moysan July 27, 2023, 3:03 p.m. UTC
Adopt the generic channel bindings to ease the configuration
of the DFSDM channels as consumers of the SD modulator backend device.
Also adopt unified device property API in the same patch for this RFC.

Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
---
 drivers/iio/adc/stm32-dfsdm-adc.c | 93 ++++++++++++++++---------------
 1 file changed, 49 insertions(+), 44 deletions(-)
diff mbox series

Patch

diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
index 20f7dffcecdd..96f4e0c64cdc 100644
--- a/drivers/iio/adc/stm32-dfsdm-adc.c
+++ b/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -596,45 +596,35 @@  static int stm32_dfsdm_filter_configure(struct iio_dev *indio_dev,
 
 static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
 					struct iio_dev *indio_dev,
+					struct fwnode_handle *node,
 					struct iio_chan_spec *ch)
 {
 	struct stm32_dfsdm_channel *df_ch;
 	const char *of_str;
-	int chan_idx = ch->scan_index;
 	int ret, val;
 
-	ret = of_property_read_u32_index(indio_dev->dev.of_node,
-					 "st,adc-channels", chan_idx,
-					 &ch->channel);
+	ret = fwnode_property_read_u32(node, "reg", &ch->channel);
 	if (ret < 0) {
-		dev_err(&indio_dev->dev,
-			" Error parsing 'st,adc-channels' for idx %d\n",
-			chan_idx);
+		dev_err(&indio_dev->dev, "Missing channel index %d\n", ret);
 		return ret;
 	}
 	if (ch->channel >= dfsdm->num_chs) {
-		dev_err(&indio_dev->dev,
-			" Error bad channel number %d (max = %d)\n",
+		dev_err(&indio_dev->dev, " Error bad channel number %d (max = %d)\n",
 			ch->channel, dfsdm->num_chs);
 		return -EINVAL;
 	}
 
-	ret = of_property_read_string_index(indio_dev->dev.of_node,
-					    "st,adc-channel-names", chan_idx,
-					    &ch->datasheet_name);
+	ret = fwnode_property_read_string(node, "label", &ch->datasheet_name);
 	if (ret < 0) {
 		dev_err(&indio_dev->dev,
-			" Error parsing 'st,adc-channel-names' for idx %d\n",
-			chan_idx);
+			" Error parsing 'label' for idx %d\n", ch->channel);
 		return ret;
 	}
 
 	df_ch =  &dfsdm->ch_list[ch->channel];
 	df_ch->id = ch->channel;
 
-	ret = of_property_read_string_index(indio_dev->dev.of_node,
-					    "st,adc-channel-types", chan_idx,
-					    &of_str);
+	ret = fwnode_property_read_string(node, "st,adc-channel-types", &of_str);
 	if (!ret) {
 		val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_type);
 		if (val < 0)
@@ -644,9 +634,7 @@  static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
 	}
 	df_ch->type = val;
 
-	ret = of_property_read_string_index(indio_dev->dev.of_node,
-					    "st,adc-channel-clk-src", chan_idx,
-					    &of_str);
+	ret = fwnode_property_read_string(node, "st,adc-channel-clk-src", &of_str);
 	if (!ret) {
 		val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_src);
 		if (val < 0)
@@ -656,10 +644,8 @@  static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm,
 	}
 	df_ch->src = val;
 
-	ret = of_property_read_u32_index(indio_dev->dev.of_node,
-					 "st,adc-alt-channel", chan_idx,
-					 &df_ch->alt_si);
-	if (ret < 0)
+	ret = fwnode_property_read_u32(node, "st,adc-alt-channel", &df_ch->alt_si);
+	if (ret != -EINVAL)
 		df_ch->alt_si = 0;
 
 	return 0;
@@ -1354,17 +1340,21 @@  static int stm32_dfsdm_dma_request(struct device *dev,
 }
 
 static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
+					 struct fwnode_handle *child,
 					 struct iio_chan_spec *ch)
 {
 	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
 	int ret;
 
-	ret = stm32_dfsdm_channel_parse_of(adc->dfsdm, indio_dev, ch);
-	if (ret < 0)
+	ret = stm32_dfsdm_channel_parse_of(adc->dfsdm, indio_dev, child, ch);
+	if (ret < 0) {
+		dev_err(&indio_dev->dev, "Failed to parse channel\n");
 		return ret;
+	}
 
 	ch->type = IIO_VOLTAGE;
 	ch->indexed = 1;
+	ch->scan_index = ch->channel;
 
 	/*
 	 * IIO_CHAN_INFO_RAW: used to compute regular conversion
@@ -1387,6 +1377,30 @@  static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev,
 					  &adc->dfsdm->ch_list[ch->channel]);
 }
 
+static int stm32_dfsdm_generic_chan_init(struct iio_dev *indio_dev, struct stm32_dfsdm_adc *adc,
+					 struct iio_chan_spec *channels)
+{
+	struct fwnode_handle *child;
+	int chan_idx = 0, ret;
+
+	device_for_each_child_node(&indio_dev->dev, child) {
+		ret = stm32_dfsdm_adc_chan_init_one(indio_dev, child, &channels[chan_idx]);
+		if (ret < 0) {
+			dev_err(&indio_dev->dev, "Channels init failed\n");
+			goto err;
+		}
+
+		chan_idx++;
+	}
+
+	return chan_idx;
+
+err:
+	fwnode_handle_put(child);
+
+	return ret;
+}
+
 static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev)
 {
 	struct iio_chan_spec *ch;
@@ -1400,7 +1414,7 @@  static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev)
 
 	ch->scan_index = 0;
 
-	ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch);
+	ret = stm32_dfsdm_generic_chan_init(indio_dev, adc, ch);
 	if (ret < 0) {
 		dev_err(&indio_dev->dev, "Channels init failed\n");
 		return ret;
@@ -1422,33 +1436,24 @@  static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev)
 	struct iio_chan_spec *ch;
 	struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
 	int num_ch;
-	int ret, chan_idx;
+	int ret;
 
 	adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING;
 	ret = stm32_dfsdm_compute_all_osrs(indio_dev, adc->oversamp);
 	if (ret < 0)
 		return ret;
 
-	num_ch = of_property_count_u32_elems(indio_dev->dev.of_node,
-					     "st,adc-channels");
-	if (num_ch < 0 || num_ch > adc->dfsdm->num_chs) {
-		dev_err(&indio_dev->dev, "Bad st,adc-channels\n");
-		return num_ch < 0 ? num_ch : -EINVAL;
-	}
+	num_ch = device_get_child_node_count(&indio_dev->dev);
+	if (!num_ch)
+		return -EINVAL;
 
-	ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch),
-			  GFP_KERNEL);
+	ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch), GFP_KERNEL);
 	if (!ch)
 		return -ENOMEM;
 
-	for (chan_idx = 0; chan_idx < num_ch; chan_idx++) {
-		ch[chan_idx].scan_index = chan_idx;
-		ret = stm32_dfsdm_adc_chan_init_one(indio_dev, &ch[chan_idx]);
-		if (ret < 0) {
-			dev_err(&indio_dev->dev, "Channels init failed\n");
-			return ret;
-		}
-	}
+	stm32_dfsdm_generic_chan_init(indio_dev, adc, ch);
+	if (ret < 0)
+		return ret;
 
 	indio_dev->num_channels = num_ch;
 	indio_dev->channels = ch;