[RFC v2 06/11] iio: adc: stm32-dfsdm: adopt generic channel bindings
Olivier Moysan
olivier.moysan at foss.st.com
Thu Jul 27 08:03:17 PDT 2023
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 at foss.st.com>
---
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 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;
--
2.25.1
More information about the linux-arm-kernel
mailing list