[RFC PATCH 4/7] iio: adc: stm32-dfsdm: adopt generic channel bindings

From: Olivier Moysan
Date: Fri Jun 23 2023 - 10:13:16 EST


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@xxxxxxxxxxx>
---
drivers/iio/adc/stm32-dfsdm-adc.c | 93 ++++++++++++++++---------------
1 file changed, 49 insertions(+), 44 deletions(-)

diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c
index 20756d496c52..2e76497cee51 100644
--- a/drivers/iio/adc/stm32-dfsdm-adc.c
+++ b/drivers/iio/adc/stm32-dfsdm-adc.c
@@ -595,45 +595,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)
@@ -643,9 +633,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)
@@ -655,10 +643,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;
@@ -1353,14 +1339,17 @@ 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 %d\n", ch->scan_index);
return ret;
+ }

ch->type = IIO_VOLTAGE;
ch->indexed = 1;
@@ -1386,6 +1375,31 @@ 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) {
+ channels[chan_idx].scan_index = chan_idx;
+ 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;
@@ -1399,7 +1413,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);
+ stm32_dfsdm_generic_chan_init(indio_dev, adc, ch);
if (ret < 0) {
dev_err(&indio_dev->dev, "Channels init failed\n");
return ret;
@@ -1421,33 +1435,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;
--
2.25.1