adc: stm32mp15: add support of generic channels binding
authorOlivier Moysan <olivier.moysan@foss.st.com>
Wed, 23 Nov 2022 15:20:16 +0000 (16:20 +0100)
committerPatrice Chotard <patrice.chotard@foss.st.com>
Wed, 7 Dec 2022 16:00:26 +0000 (17:00 +0100)
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>
drivers/adc/stm32-adc.c

index 1250385..85efc11 100644 (file)
@@ -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;