[PATCH 0/2] adc: stm32mp15: add support of generic channels binding

Add support of generic IIO channels binding: ./devicetree/bindings/iio/adc/adc.yaml
Keep support of legacy property st,adc-channels for backward compatibility. However, the st,adc-channels property is deprecated, and generic channel bindings should be used instead. Mixing of generic and legacy property is not supported. If generic channels are present in the device tree, legacy properties will be skipped.
Olivier Moysan (2): adc: stm32mp15: split channel init into several routines adc: stm32mp15: add support of generic channels binding
drivers/adc/stm32-adc.c | 83 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 73 insertions(+), 10 deletions(-)

Split stm32_adc_chan_of_init channel initialization function into several routines to increase readability and prepare channel generic binding handling.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com ---
drivers/adc/stm32-adc.c | 44 +++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index ad8d1a32cdba..1250385fbb92 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -162,12 +162,8 @@ static int stm32_adc_channel_data(struct udevice *dev, int channel, return 0; }
-static int stm32_adc_chan_of_init(struct udevice *dev) +static int stm32_adc_get_legacy_chan_count(struct udevice *dev) { - struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); - struct stm32_adc *adc = dev_get_priv(dev); - u32 chans[STM32_ADC_CH_MAX]; - unsigned int i, num_channels; int ret;
/* Retrieve single ended channels listed in device tree */ @@ -176,12 +172,16 @@ static int stm32_adc_chan_of_init(struct udevice *dev) dev_err(dev, "can't get st,adc-channels: %d\n", ret); return ret; } - num_channels = ret / sizeof(u32);
- if (num_channels > adc->cfg->max_channels) { - dev_err(dev, "too many st,adc-channels: %d\n", num_channels); - return -EINVAL; - } + return (ret / sizeof(u32)); +} + +static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_channels) +{ + struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); + struct stm32_adc *adc = dev_get_priv(dev); + u32 chans[STM32_ADC_CH_MAX]; + int i, ret;
ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels); if (ret < 0) { @@ -197,6 +197,30 @@ static int stm32_adc_chan_of_init(struct udevice *dev) uc_pdata->channel_mask |= 1 << chans[i]; }
+ return ret; +} + +static int stm32_adc_chan_of_init(struct udevice *dev) +{ + struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); + struct stm32_adc *adc = dev_get_priv(dev); + unsigned int num_channels; + int ret; + + ret = stm32_adc_get_legacy_chan_count(dev); + if (ret < 0) + return ret; + num_channels = ret; + + if (num_channels > adc->cfg->max_channels) { + dev_err(dev, "too many st,adc-channels: %d\n", num_channels); + return -EINVAL; + } + + ret = stm32_adc_legacy_chan_init(dev, num_channels); + if (ret < 0) + return ret; + uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1; uc_pdata->data_format = ADC_DATA_FORMAT_BIN; uc_pdata->data_timeout_us = 100000;

Hi,
On 11/23/22 16:20, Olivier Moysan wrote:
Split stm32_adc_chan_of_init channel initialization function into several routines to increase readability and prepare channel generic binding handling.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com
drivers/adc/stm32-adc.c | 44 +++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index ad8d1a32cdba..1250385fbb92 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -162,12 +162,8 @@ static int stm32_adc_channel_data(struct udevice *dev, int channel, return 0; }
-static int stm32_adc_chan_of_init(struct udevice *dev) +static int stm32_adc_get_legacy_chan_count(struct udevice *dev) {
struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct stm32_adc *adc = dev_get_priv(dev);
u32 chans[STM32_ADC_CH_MAX];
unsigned int i, num_channels; int ret;
/* Retrieve single ended channels listed in device tree */
@@ -176,12 +172,16 @@ static int stm32_adc_chan_of_init(struct udevice *dev) dev_err(dev, "can't get st,adc-channels: %d\n", ret); return ret; }
num_channels = ret / sizeof(u32);
if (num_channels > adc->cfg->max_channels) {
dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
return -EINVAL;
}
- return (ret / sizeof(u32));
+}
+static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_channels) +{
struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct stm32_adc *adc = dev_get_priv(dev);
u32 chans[STM32_ADC_CH_MAX];
int i, ret;
ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels); if (ret < 0) {
@@ -197,6 +197,30 @@ static int stm32_adc_chan_of_init(struct udevice *dev) uc_pdata->channel_mask |= 1 << chans[i]; }
- return ret;
+}
+static int stm32_adc_chan_of_init(struct udevice *dev) +{
- struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
- struct stm32_adc *adc = dev_get_priv(dev);
- unsigned int num_channels;
- int ret;
- ret = stm32_adc_get_legacy_chan_count(dev);
- if (ret < 0)
return ret;
- num_channels = ret;
- if (num_channels > adc->cfg->max_channels) {
dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
return -EINVAL;
- }
- ret = stm32_adc_legacy_chan_init(dev, num_channels);
- if (ret < 0)
return ret;
- uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1; uc_pdata->data_format = ADC_DATA_FORMAT_BIN; uc_pdata->data_timeout_us = 100000;
Reviewed-by: Patrick Delaunay patrick.delaunay@foss.st.com
Thanks Patrick

On 11/23/22 16:20, Olivier Moysan wrote:
Split stm32_adc_chan_of_init channel initialization function into several routines to increase readability and prepare channel generic binding handling.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com
drivers/adc/stm32-adc.c | 44 +++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index ad8d1a32cdba..1250385fbb92 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -162,12 +162,8 @@ static int stm32_adc_channel_data(struct udevice *dev, int channel, return 0; }
-static int stm32_adc_chan_of_init(struct udevice *dev) +static int stm32_adc_get_legacy_chan_count(struct udevice *dev) {
struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct stm32_adc *adc = dev_get_priv(dev);
u32 chans[STM32_ADC_CH_MAX];
unsigned int i, num_channels; int ret;
/* Retrieve single ended channels listed in device tree */
@@ -176,12 +172,16 @@ static int stm32_adc_chan_of_init(struct udevice *dev) dev_err(dev, "can't get st,adc-channels: %d\n", ret); return ret; }
num_channels = ret / sizeof(u32);
if (num_channels > adc->cfg->max_channels) {
dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
return -EINVAL;
}
- return (ret / sizeof(u32));
+}
+static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_channels) +{
struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct stm32_adc *adc = dev_get_priv(dev);
u32 chans[STM32_ADC_CH_MAX];
int i, ret;
ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels); if (ret < 0) {
@@ -197,6 +197,30 @@ static int stm32_adc_chan_of_init(struct udevice *dev) uc_pdata->channel_mask |= 1 << chans[i]; }
- return ret;
+}
+static int stm32_adc_chan_of_init(struct udevice *dev) +{
- struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
- struct stm32_adc *adc = dev_get_priv(dev);
- unsigned int num_channels;
- int ret;
- ret = stm32_adc_get_legacy_chan_count(dev);
- if (ret < 0)
return ret;
- num_channels = ret;
- if (num_channels > adc->cfg->max_channels) {
dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
return -EINVAL;
- }
- ret = stm32_adc_legacy_chan_init(dev, num_channels);
- if (ret < 0)
return ret;
- uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1; uc_pdata->data_format = ADC_DATA_FORMAT_BIN; uc_pdata->data_timeout_us = 100000;
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com
Thanks Patrice

On 12/7/22 16:54, Patrice CHOTARD wrote:
On 11/23/22 16:20, Olivier Moysan wrote:
Split stm32_adc_chan_of_init channel initialization function into several routines to increase readability and prepare channel generic binding handling.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com
drivers/adc/stm32-adc.c | 44 +++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index ad8d1a32cdba..1250385fbb92 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -162,12 +162,8 @@ static int stm32_adc_channel_data(struct udevice *dev, int channel, return 0; }
-static int stm32_adc_chan_of_init(struct udevice *dev) +static int stm32_adc_get_legacy_chan_count(struct udevice *dev) {
struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct stm32_adc *adc = dev_get_priv(dev);
u32 chans[STM32_ADC_CH_MAX];
unsigned int i, num_channels; int ret;
/* Retrieve single ended channels listed in device tree */
@@ -176,12 +172,16 @@ static int stm32_adc_chan_of_init(struct udevice *dev) dev_err(dev, "can't get st,adc-channels: %d\n", ret); return ret; }
num_channels = ret / sizeof(u32);
if (num_channels > adc->cfg->max_channels) {
dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
return -EINVAL;
}
- return (ret / sizeof(u32));
+}
+static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_channels) +{
struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct stm32_adc *adc = dev_get_priv(dev);
u32 chans[STM32_ADC_CH_MAX];
int i, ret;
ret = dev_read_u32_array(dev, "st,adc-channels", chans, num_channels); if (ret < 0) {
@@ -197,6 +197,30 @@ static int stm32_adc_chan_of_init(struct udevice *dev) uc_pdata->channel_mask |= 1 << chans[i]; }
- return ret;
+}
+static int stm32_adc_chan_of_init(struct udevice *dev) +{
- struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
- struct stm32_adc *adc = dev_get_priv(dev);
- unsigned int num_channels;
- int ret;
- ret = stm32_adc_get_legacy_chan_count(dev);
- if (ret < 0)
return ret;
- num_channels = ret;
- if (num_channels > adc->cfg->max_channels) {
dev_err(dev, "too many st,adc-channels: %d\n", num_channels);
return -EINVAL;
- }
- ret = stm32_adc_legacy_chan_init(dev, num_channels);
- if (ret < 0)
return ret;
- uc_pdata->data_mask = (1 << adc->cfg->num_bits) - 1; uc_pdata->data_format = ADC_DATA_FORMAT_BIN; uc_pdata->data_timeout_us = 100000;
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com
Thanks Patrice _______________________________________________ Uboot-stm32 mailing list Uboot-stm32@st-md-mailman.stormreply.com https://st-md-mailman.stormreply.com/mailman/listinfo/uboot-stm32
Applied to u-boot-stm/master
Thanks Patrice

Add support of generic IIO channels binding: ./devicetree/bindings/iio/adc/adc.yaml Keep support of st,adc-channels for backward compatibility.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com ---
drivers/adc/stm32-adc.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index 1250385fbb92..85efc119dbf1 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -200,24 +200,63 @@ static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_chan return ret; }
+static int stm32_adc_generic_chan_init(struct udevice *dev, unsigned int num_channels) +{ + struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); + struct stm32_adc *adc = dev_get_priv(dev); + ofnode child; + int val, ret; + + ofnode_for_each_subnode(child, dev_ofnode(dev)) { + ret = ofnode_read_u32(child, "reg", &val); + if (ret) { + dev_err(dev, "Missing channel index %d\n", ret); + return ret; + } + + if (val >= adc->cfg->max_channels) { + dev_err(dev, "Invalid channel %d\n", val); + return -EINVAL; + } + + uc_pdata->channel_mask |= 1 << val; + } + + return 0; +} + static int stm32_adc_chan_of_init(struct udevice *dev) { struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); struct stm32_adc *adc = dev_get_priv(dev); unsigned int num_channels; int ret; - - ret = stm32_adc_get_legacy_chan_count(dev); - if (ret < 0) - return ret; - num_channels = ret; + bool legacy = false; + + num_channels = dev_get_child_count(dev); + /* If no channels have been found, fallback to channels legacy properties. */ + if (!num_channels) { + legacy = true; + + ret = stm32_adc_get_legacy_chan_count(dev); + if (!ret) { + dev_err(dev, "No channel found\n"); + return -ENODATA; + } else if (ret < 0) { + return ret; + } + num_channels = ret; + }
if (num_channels > adc->cfg->max_channels) { dev_err(dev, "too many st,adc-channels: %d\n", num_channels); return -EINVAL; }
- ret = stm32_adc_legacy_chan_init(dev, num_channels); + if (legacy) + ret = stm32_adc_legacy_chan_init(dev, num_channels); + else + ret = stm32_adc_generic_chan_init(dev, num_channels); if (ret < 0) return ret;

Hi,
On 11/23/22 16:20, Olivier Moysan wrote:
Add support of generic IIO channels binding: ./devicetree/bindings/iio/adc/adc.yaml Keep support of st,adc-channels for backward compatibility.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com
drivers/adc/stm32-adc.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index 1250385fbb92..85efc119dbf1 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -200,24 +200,63 @@ static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_chan return ret; }
+static int stm32_adc_generic_chan_init(struct udevice *dev, unsigned int num_channels) +{
- struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
- struct stm32_adc *adc = dev_get_priv(dev);
- ofnode child;
- int val, ret;
- ofnode_for_each_subnode(child, dev_ofnode(dev)) {
ret = ofnode_read_u32(child, "reg", &val);
if (ret) {
dev_err(dev, "Missing channel index %d\n", ret);
return ret;
}
if (val >= adc->cfg->max_channels) {
dev_err(dev, "Invalid channel %d\n", val);
return -EINVAL;
}
uc_pdata->channel_mask |= 1 << val;
- }
- return 0;
+}
- static int stm32_adc_chan_of_init(struct udevice *dev) { struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); struct stm32_adc *adc = dev_get_priv(dev); unsigned int num_channels; int ret;
- ret = stm32_adc_get_legacy_chan_count(dev);
- if (ret < 0)
return ret;
- num_channels = ret;
bool legacy = false;
num_channels = dev_get_child_count(dev);
/* If no channels have been found, fallback to channels legacy properties. */
if (!num_channels) {
legacy = true;
ret = stm32_adc_get_legacy_chan_count(dev);
if (!ret) {
dev_err(dev, "No channel found\n");
return -ENODATA;
} else if (ret < 0) {
return ret;
}
num_channels = ret;
}
if (num_channels > adc->cfg->max_channels) { dev_err(dev, "too many st,adc-channels: %d\n", num_channels); return -EINVAL; }
- ret = stm32_adc_legacy_chan_init(dev, num_channels);
- if (legacy)
ret = stm32_adc_legacy_chan_init(dev, num_channels);
- else
if (ret < 0) return ret;ret = stm32_adc_generic_chan_init(dev, num_channels);
Reviewed-by: Patrick Delaunay patrick.delaunay@foss.st.com
Thanks Patrick

On 11/23/22 16:20, Olivier Moysan wrote:
Add support of generic IIO channels binding: ./devicetree/bindings/iio/adc/adc.yaml Keep support of st,adc-channels for backward compatibility.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com
drivers/adc/stm32-adc.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index 1250385fbb92..85efc119dbf1 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -200,24 +200,63 @@ static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_chan return ret; }
+static int stm32_adc_generic_chan_init(struct udevice *dev, unsigned int num_channels) +{
- struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
- struct stm32_adc *adc = dev_get_priv(dev);
- ofnode child;
- int val, ret;
- ofnode_for_each_subnode(child, dev_ofnode(dev)) {
ret = ofnode_read_u32(child, "reg", &val);
if (ret) {
dev_err(dev, "Missing channel index %d\n", ret);
return ret;
}
if (val >= adc->cfg->max_channels) {
dev_err(dev, "Invalid channel %d\n", val);
return -EINVAL;
}
uc_pdata->channel_mask |= 1 << val;
- }
- return 0;
+}
static int stm32_adc_chan_of_init(struct udevice *dev) { struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); struct stm32_adc *adc = dev_get_priv(dev); unsigned int num_channels; int ret;
- ret = stm32_adc_get_legacy_chan_count(dev);
- if (ret < 0)
return ret;
- num_channels = ret;
bool legacy = false;
num_channels = dev_get_child_count(dev);
/* If no channels have been found, fallback to channels legacy properties. */
if (!num_channels) {
legacy = true;
ret = stm32_adc_get_legacy_chan_count(dev);
if (!ret) {
dev_err(dev, "No channel found\n");
return -ENODATA;
} else if (ret < 0) {
return ret;
}
num_channels = ret;
}
if (num_channels > adc->cfg->max_channels) { dev_err(dev, "too many st,adc-channels: %d\n", num_channels); return -EINVAL; }
- ret = stm32_adc_legacy_chan_init(dev, num_channels);
- if (legacy)
ret = stm32_adc_legacy_chan_init(dev, num_channels);
- else
if (ret < 0) return ret;ret = stm32_adc_generic_chan_init(dev, num_channels);
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com
Thanks Patrice

On 12/7/22 16:57, Patrice CHOTARD wrote:
On 11/23/22 16:20, Olivier Moysan wrote:
Add support of generic IIO channels binding: ./devicetree/bindings/iio/adc/adc.yaml Keep support of st,adc-channels for backward compatibility.
Signed-off-by: Olivier Moysan olivier.moysan@foss.st.com
drivers/adc/stm32-adc.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-)
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c index 1250385fbb92..85efc119dbf1 100644 --- a/drivers/adc/stm32-adc.c +++ b/drivers/adc/stm32-adc.c @@ -200,24 +200,63 @@ static int stm32_adc_legacy_chan_init(struct udevice *dev, unsigned int num_chan return ret; }
+static int stm32_adc_generic_chan_init(struct udevice *dev, unsigned int num_channels) +{
- struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
- struct stm32_adc *adc = dev_get_priv(dev);
- ofnode child;
- int val, ret;
- ofnode_for_each_subnode(child, dev_ofnode(dev)) {
ret = ofnode_read_u32(child, "reg", &val);
if (ret) {
dev_err(dev, "Missing channel index %d\n", ret);
return ret;
}
if (val >= adc->cfg->max_channels) {
dev_err(dev, "Invalid channel %d\n", val);
return -EINVAL;
}
uc_pdata->channel_mask |= 1 << val;
- }
- return 0;
+}
static int stm32_adc_chan_of_init(struct udevice *dev) { struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev); struct stm32_adc *adc = dev_get_priv(dev); unsigned int num_channels; int ret;
- ret = stm32_adc_get_legacy_chan_count(dev);
- if (ret < 0)
return ret;
- num_channels = ret;
bool legacy = false;
num_channels = dev_get_child_count(dev);
/* If no channels have been found, fallback to channels legacy properties. */
if (!num_channels) {
legacy = true;
ret = stm32_adc_get_legacy_chan_count(dev);
if (!ret) {
dev_err(dev, "No channel found\n");
return -ENODATA;
} else if (ret < 0) {
return ret;
}
num_channels = ret;
}
if (num_channels > adc->cfg->max_channels) { dev_err(dev, "too many st,adc-channels: %d\n", num_channels); return -EINVAL; }
- ret = stm32_adc_legacy_chan_init(dev, num_channels);
- if (legacy)
ret = stm32_adc_legacy_chan_init(dev, num_channels);
- else
if (ret < 0) return ret;ret = stm32_adc_generic_chan_init(dev, num_channels);
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com
Thanks Patrice _______________________________________________ Uboot-stm32 mailing list Uboot-stm32@st-md-mailman.stormreply.com https://st-md-mailman.stormreply.com/mailman/listinfo/uboot-stm32
Applied to u-boot-stm/master
Thanks Patrice
participants (3)
-
Olivier Moysan
-
Patrice CHOTARD
-
Patrick DELAUNAY