summaryrefslogtreecommitdiff
path: root/drivers/adc
diff options
context:
space:
mode:
authorOlivier Moysan <olivier.moysan@foss.st.com>2022-11-23 16:20:16 +0100
committerPatrice Chotard <patrice.chotard@foss.st.com>2022-12-07 17:00:26 +0100
commita9aa2aef5fbe9cbab61fbcc6e61cbabb7176f4f7 (patch)
treef7fbe5931a23f0fe46ec46c995c3accdf1e84bcd /drivers/adc
parent1727d46bf9b75722e08e7de98fca74ebd6b05cc4 (diff)
downloadu-boot-a9aa2aef5fbe9cbab61fbcc6e61cbabb7176f4f7.tar.gz
u-boot-a9aa2aef5fbe9cbab61fbcc6e61cbabb7176f4f7.tar.bz2
u-boot-a9aa2aef5fbe9cbab61fbcc6e61cbabb7176f4f7.zip
adc: stm32mp15: add support of generic channels binding
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> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Diffstat (limited to 'drivers/adc')
-rw-r--r--drivers/adc/stm32-adc.c51
1 files changed, 45 insertions, 6 deletions
diff --git a/drivers/adc/stm32-adc.c b/drivers/adc/stm32-adc.c
index 1250385fbb..85efc119db 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;