iio: dac: ad5504: fix voltage scaling and add missing bindings
Subsystems (3)
cover iio: dac: ad5504: fix voltage scaling and add missing bindings
This series fixes the voltage scale calculation for the AD5504 DAC and updates the devicetree bindings to support the necessary hardware configuration.
Previously, the driver calculated the scale based on the VCC supply voltage.
However, as confirmed by the datasheet (Rev. B) and discussion on the mailing list [1], the AD5504 has an integrated precision reference, and the output range is determined strictly by the state of the R_SEL pin (0-30V or 0-60V).
To address this:
1. Patch 1 adds adi,output-range-volts (and GPIO equivalents) to the bindings to describe the hardware state of the R_SEL pin, along with other missing properties (vlogic, clear, ldac).
2. Patch 2 updates the driver to use this property for scale calculation, falling back to the 60V range if unspecified, while retaining the VCC regulator enable for power.
Taha Ed-Dafili (2):
dt-bindings: iio: dac: ad5504: add output-range and missing gpios
iio: dac: ad5504: use adi,output-range-volts for scale calculation
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml | 20 ++++++++++++++++++++ drivers/iio/dac/ad5504.c | 15 ++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-)
Taha Ed-Dafili (2):
dt-bindings: iio: dac: ad5504: add output-range and missing gpios
iio: dac: ad5504: use adi,output-range-volts for scale calculation
.../bindings/iio/dac/adi,ad5504.yaml | 38 +++++++++++++++++++ drivers/iio/dac/ad5504.c | 26 ++++++++----- 2 files changed, 54 insertions(+), 10 deletions(-)
Signature · 1 line
2.47.3
PATCH 1/2 dt-bindings: iio: dac: ad5504: add output-range and missing gpios
The AD5504 output range (0-30V or 0-60V) is determined by the R_SEL pin.
Add adi,output-range-volts and adi,output-range-gpios to describe this hardware state, using allOf to enforce mutual exclusivity. Also add vlogic-supply, clear-gpios, and ldac-gpios to complete the hardware description.
--- .../bindings/iio/dac/adi,ad5504.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+)
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml +38 -0
@@ -27,12 +27,50 @@ properties: maxItems: 1 vcc-supply: true + vlogic-supply: true + + adi,output-range-volts: + description: + Hard-wired /R_SEL pin state. 30 V when pin is high and 60 V when + pin is low. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [30, 60] + default: 60 + + adi,output-range-gpios: + description: + GPIO connected to the R_SEL pin to select the output voltage range. + maxItems: 1 + + clear-gpios: + description: GPIO that controls the /CLR pin (active low). + maxItems: 1 + + ldac-gpios: + description: GPIO that controls the /LDAC pin (active low). + maxItems: 1 additionalProperties: false required: - compatible - reg + - vcc-supply + +allOf: + - if: + required: + - adi,output-range-gpios + then: + properties: + adi,output-range-volts: false + + - if: + required: + - adi,output-range-volts + then: + properties: + adi,output-range-gpios: false examples: - |
Signature · 1 line
2.47.3
Re: [PATCH v1 1/2] dt-bindings: iio: dac: ad5504: add output-range and missing gpios
Quoted 18 lines · Taha Ed-Dafili
The AD5504 output range (0-30V or 0-60V) is determined by the
R_SELpin.Add
adi,output-range-voltsandadi,output-range-gpiosto describe this hardware state, usingallOfto enforce mutual exclusivity. Also addvlogic-supply,clear-gpios, andldac-gpiosto complete the hardware description.Suggested-by David Lechner <[email protected]>Signed-off-by Taha Ed-Dafili <[email protected]>--- .../bindings/iio/dac/adi,ad5504.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+)Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml +0
-0
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml properties: · line 32
Quoted 6 lines
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml +3
-0@@ -27,12 +27,50 @@ properties: maxItems: 1 vcc-supply: true + vlogic-supply: true + + adi,output-range-volts:
Use proper property unit suffix, see dt-schema.
And really, you should have checked - you already have properties for this! See dac schema.
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml properties: · line 40
Quoted 8 lines
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml +8
-0+ description: + Hard-wired /R_SEL pin state. 30 V when pin is high and 60 V when + pin is low. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [30, 60] + default: 60 + + adi,output-range-gpios:
So another same roperty? If you looked around you would find adi,range-gpios, which would be better than multiplying properties. Anyway, gpios do not take vendor prefixes, so you want range-sel-gpios or range-gpios. I guess the latter.
Quoted 10 lines
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml +10
-0+ description: + GPIO connected to the R_SEL pin to select the output voltage range. + maxItems: 1 + + clear-gpios: + description: GPIO that controls the /CLR pin (active low). + maxItems: 1 + + ldac-gpios: + description: GPIO that controls the /LDAC pin (active low).
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml properties: · line 60
Quoted 10 lines
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml +4
-0+ maxItems: 1 additionalProperties: false required: - compatible - reg + - vcc-supply + +allOf:
allOf:
- not:
required:
- foo
- bar
Should give you exactly same result, with less code.
Quoted 19 lines
Documentation/devicetree/bindings/iio/dac/adi,ad5504.yaml +13
-0+ - if: + required: + - adi,output-range-gpios + then: + properties: + adi,output-range-volts: false + + - if: + required: + - adi,output-range-volts + then: + properties: + adi,output-range-gpios: false examples: - |Signature · 1 line
2.47.3
Re: [PATCH v1 1/2] dt-bindings: iio: dac: ad5504: add output-range and missing gpios
Hello Krzysztof,
Thank you for the detailed review and for pointing me toward the standard DAC schema.
I'll update the bindings in v2 to address your comments, and I will also ensure I check the common schemas more thoroughly for future patches.
Best regards,
Taha
Re: [PATCH v1 1/2] dt-bindings: iio: dac: ad5504: add output-range and missing gpios
Quoted 7 lines · Taha Ed-Dafili
Hello Krzysztof,
Thank you for the detailed review and for pointing me toward the standard DAC schema.
I'll update the bindings in v2 to address your comments, and I will also ensure I check the common schemas more thoroughly for future patches.
Thanks.
Best regards,
Krzysztof
PATCH 2/2 iio: dac: ad5504: use adi,output-range-volts for scale calculation
In reply to Taha Ed-DafiliThe driver previously used VCC to calculate the scale, but the datasheet states the output range is fixed by the R_SEL pin (0-30V or 0-60V).
Update probe to read adi,output-range-volts for the scale. Default to the 60V range if the property is missing, while keeping the VCC regulator enable for power.
--- drivers/iio/dac/ad5504.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
drivers/iio/dac/ad5504.c +16 -10
@@ -15,6 +15,7 @@#include <linux/regulator/consumer.h> #include <linux/module.h> #include <linux/bitops.h> +#include <linux/property.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h>
@@ -274,6 +275,7 @@ static int ad5504_probe(struct spi_device *spi)struct iio_dev *indio_dev;struct ad5504_state *st;int ret; +u32 val; indio_dev =devm_iio_device_alloc (&spi->dev,sizeof (*st));if (!indio_dev)
@@ -281,17 +283,21 @@ static int ad5504_probe(struct spi_device *spi) st =iio_priv (indio_dev); - ret =devm_regulator_get_enable_read_voltage (&spi->dev,"vcc" ); -if (ret <0 && ret != -ENODEV ) + ret =devm_regulator_get_enable (&spi->dev,"vcc" ); +if (ret)return ret; -if (ret == -ENODEV ) { -if (pdata->vref_mv) - st->vref_mv = pdata->vref_mv; -else -dev_warn (&spi->dev,"reference voltage unspecified\n" ); - }else { - st->vref_mv = ret /1000 ; - } + + ret =device_property_read_u32 (&spi->dev,"adi,output-range-volts" , &val); +if (ret) + val =60 ; + +if (val ==60 ) + st->vref_mv =60000 ; +else + st->vref_mv =30000 ; + +if (pdata && pdata->vref_mv) + st->vref_mv = pdata->vref_mv; st->spi = spi; indio_dev->name =spi_get_device_id (st->spi)->name;
Signature · 1 line
2.47.3
Re: [PATCH v1 2/2] iio: dac: ad5504: use adi,output-range-volts for scale calculation
Quoted 6 lines · Taha Ed-Dafili
The driver previously used VCC to calculate the scale, but the datasheet states the output range is fixed by the
R_SELpin (0-30V or 0-60V).Update probe to read
adi,output-range-voltsfor the scale. Default to the 60V range if the property is missing, while keeping the VCC regulator enable for power.
...
Quoted 4 lines
#include <
linux/regulator/consumer.h>
#include <linux/module.h>
#include <linux/bitops.h>
+#include <linux/property.h>
Add it before 'linux/s*.h' includes to make less ordering issues. Ideally one additional patch to sort the headers and one to replace "proxy" headers (following IWYU principle).
...
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 290
Quoted 1 line
drivers/iio/dac/ad5504.c +1
-0+ ret =device_property_read_u32 (&spi->dev,"adi,output-range-volts" , &val);
You can pack this into 80 limit with help of
struct device *dev = &spi->dev;
being defined in the top of the function.
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (ret) + val = 60;
Also this seems an optional, so
val = 60; device_property_read_u32(dev, "adi,output-range-volts", &val);
would be enough.
...
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 295
Quoted 2 lines
drivers/iio/dac/ad5504.c +2
-0+if (val ==60 ) + st->vref_mv =60000 ;
60 * MILLI;
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 297
Quoted 2 lines
drivers/iio/dac/ad5504.c +2
-0+else + st->vref_mv =30000 ;
30 * MILLI;
Needs units.h.
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH v1 2/2] iio: dac: ad5504: use adi,output-range-volts for scale calculation
Hi Andy,
Thank you for the detailed feedback, I'll make sure to add those changes in the upcoming v2 series.
Best regards,
Taha
Jonathan Cameron
maintainerRe: [PATCH v1 2/2] iio: dac: ad5504: use adi,output-range-volts for scale calculation
Quoted 7 lines · On Fri, 13 Feb 2026 18:05:02 +0100 Taha Ed-Dafili <[email protected]> wrote:
Hi Andy,
Thank you for the detailed feedback, I'll make sure to add those changes in the upcoming v2 series.
Best regards,
Taha
Hi Taha,
Small process thing. Please save thanks like this for the change log on the next version. I know it can feel a little less polite, but if everyone sent a thanks message, that would add at least 1/3rd to the volume of emails and we have too many of those :(
A simple, thanks under the --- or in the cover letter for the next version doesn't have that problem and still acknowledges the inputs of reviewers.
Thanks,
Jonathan
Jonathan Cameron
maintainerRe: [PATCH v1 2/2] iio: dac: ad5504: use adi,output-range-volts for scale calculation
In reply to Andy ShevchenkoQuoted 37 lines · On Thu, 12 Feb 2026 22:15:55 +0200 Andy Shevchenko…
Quoted 6 lines · Taha Ed-Dafili
The driver previously used VCC to calculate the scale, but the datasheet states the output range is fixed by the
R_SELpin (0-30V or 0-60V).Update probe to read
adi,output-range-voltsfor the scale. Default to the 60V range if the property is missing, while keeping the VCC regulator enable for power....
Quoted 4 lines
#include <
linux/regulator/consumer.h>
#include <linux/module.h>
#include <linux/bitops.h>
+#include <linux/property.h>Add it before '
linux/s*.h' includes to make less ordering issues. Ideally one additional patch to sort the headers and one to replace "proxy" headers (following IWYU principle)....
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 290
Quoted 1 line
drivers/iio/dac/ad5504.c +1
-0+ ret =device_property_read_u32 (&spi->dev,"adi,output-range-volts" , &val);You can pack this into 80 limit with help of
struct device *dev = &spi->dev;being defined in the top of the function.
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (ret) + val = 60;Also this seems an optional, so
val = 60; device_property_read_u32(dev, "adi,output-range-volts", &val);
Quoted 8 lines
would be enough.
...
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 295
Quoted 2 lines
drivers/iio/dac/ad5504.c +2
-0+if (val ==60 ) + st->vref_mv =60000 ;60 * MILLI;
val * MILLI
given it only takes the values 30 and 60 I think. If you want to protect against other values, then check it explicitly rather than everything than isn't 60 being assumed to be 30.
Thanks,
J
Quoted 8 lines
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 297
Quoted 3 lines
drivers/iio/dac/ad5504.c +2
-0+else + st->vref_mv =30000 ;30 * MILLI;
Needs
units.h.
Re: [PATCH v1 2/2] iio: dac: ad5504: use adi,output-range-volts for scale calculation
Quoted 3 lines · Jonathan Cameron
Quoted 1 line · On Thu, 12 Feb 2026 22:15:55 +0200 Andy Shevchenko…
On Thu, Feb 12, 2026 at 07:19:55PM +0100, Taha Ed-Dafili wrote:
...
Quoted 25 lines
Quoted 16 lines
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 290
Quoted 1 line
drivers/iio/dac/ad5504.c +1
-0+ ret =device_property_read_u32 (&spi->dev,"adi,output-range-volts" , &val);You can pack this into 80 limit with help of
struct device *dev = &spi->dev;being defined in the top of the function.
Review
Quoted 2 lines
(quoted diff) +2
-0+ if (ret) + val = 60;Also this seems an optional, so
val = 60; device_property_read_u32(dev, "adi,output-range-volts", &val);Quoted 8 lines
would be enough.
...
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 295
Quoted 2 lines
drivers/iio/dac/ad5504.c +2
-0+if (val ==60 ) + st->vref_mv =60000 ;60 * MILLI;
Quoted 4 lines
val * MILLI
given it only takes the values 30 and 60 I think. If you want to protect against other values, then check it explicitly rather than everything than isn't 60 being assumed to be 30.
With comment on DT in mind I think this multiplication will gone (as IIUC the DT units is microvolts or so).
Quoted 6 lines
Quoted 6 lines
drivers/iio/dac/ad5504.c static int ad5504_probe(struct spi_device *spi) · line 297
Quoted 2 lines
drivers/iio/dac/ad5504.c +2
-0+else + st->vref_mv =30000 ;30 * MILLI;
Needs
units.h.
Signature · 2 lines
With Best Regards, Andy Shevchenko