diff options
author | Olivier Moysan <olivier.moysan@foss.st.com> | 2022-11-23 16:20:16 +0100 |
---|---|---|
committer | Patrice Chotard <patrice.chotard@foss.st.com> | 2022-12-07 17:00:26 +0100 |
commit | a9aa2aef5fbe9cbab61fbcc6e61cbabb7176f4f7 (patch) | |
tree | f7fbe5931a23f0fe46ec46c995c3accdf1e84bcd /drivers/adc | |
parent | 1727d46bf9b75722e08e7de98fca74ebd6b05cc4 (diff) | |
download | u-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.c | 51 |
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; |