* [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support
@ 2024-10-30 13:44 Julien Stephan
2024-10-30 13:44 ` [PATCH v4 1/5] dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts Julien Stephan
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Julien Stephan @ 2024-10-30 13:44 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Julien Stephan,
Conor Dooley
Hello,
This series add support for adaq4370-4 (2MSPS) and adaq4380-4 (4MSPS)
which are quad-channel precision data acquisition signal chain μModule
solutions compatible with the ad738x family, with the following differences:
- pin selectable gain in front of each 4 adc
- internal reference is 3V derived from refin-supply (5V)
- additional supplies
This series depends on [1] which fix several supplies issues
[1]: https://lore.kernel.org/all/20241007-ad7380-fix-supplies-v1-0-badcf813c9b9@baylibre.com/
Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
Changes in v4:
- Adding a new patch to pull out a local "dev" variable to shorten some
long lines
- Fix few minor comment from Jonathan Cameron and David Lechner
- Link to v3: https://lore.kernel.org/r/20241024-ad7380-add-adaq4380-4-support-v3-0-6a29bd0f79da@baylibre.com
Changes in v3:
bindings:
- remove item from channel reg property (should be part of V2, but get
lost during rebase)
- remove unnecessary () for channel property
- keep consistent quotes
- Link to v2: https://lore.kernel.org/r/20241023-ad7380-add-adaq4380-4-support-v2-0-d55faea3bedf@baylibre.com
Changes in v2:
- fix commit messages and documentation about the gain: pin selectable
gain instead of configurable gain
- add the enum of available gains inthe binding and array of available
gains in the driver as ad4000 series
- in the bindings, remove item from channel reg property
- in the bindings, merge additional supplies and channel properties inside
the same if branch for adaq devices
- fix comment as suggested by Jonathan in the driver
- Link to v1: https://lore.kernel.org/r/20241015-ad7380-add-adaq4380-4-support-v1-0-d2e1a95fb248@baylibre.com
---
Julien Stephan (5):
dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts
iio: adc: ad7380: fix oversampling formula
iio: adc: ad7380: use local dev variable to shorten long lines
iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4
docs: iio: ad7380: add adaq4370-4 and adaq4380-4
.../devicetree/bindings/iio/adc/adi,ad7380.yaml | 120 ++++++++++++++
Documentation/iio/ad7380.rst | 16 ++
drivers/iio/adc/ad7380.c | 178 ++++++++++++++++++---
3 files changed, 290 insertions(+), 24 deletions(-)
---
base-commit: 8bea3878a1511bceadc2fbf284b00bcc5a2ef28d
change-id: 20241015-ad7380-add-adaq4380-4-support-14dc17ec0029
prerequisite-change-id: 20241004-ad7380-fix-supplies-3677365cf8aa:v3
prerequisite-patch-id: 6127a52d3b14e82d1a6081c7e504d0e4eb323089
prerequisite-patch-id: 7dee57142d0d12682b0be3b62f1c16851aeac069
prerequisite-patch-id: f737e56a372cd91e5fac651a2063b06827f9aa21
prerequisite-patch-id: 7c8d5fbde82810057630b95e12bb2f6576da6980
prerequisite-patch-id: 972bdbf06bafa7c56f604dbe8eb7d236aadaad99
Best regards,
--
Julien Stephan <jstephan@baylibre.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/5] dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts
2024-10-30 13:44 [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support Julien Stephan
@ 2024-10-30 13:44 ` Julien Stephan
2024-10-30 13:44 ` [PATCH v4 2/5] iio: adc: ad7380: fix oversampling formula Julien Stephan
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Julien Stephan @ 2024-10-30 13:44 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Julien Stephan,
Conor Dooley
adaq4370-4 (2MSPS) and adaq4380-4 (4MSPS) are quad-channel precision data
acquisition signal chain μModule solutions compatible with the ad738x
family, with the following differences:
- pin selectable gain in front of each 4 adc
- internal reference is 3V derived from refin-supply (5V)
- additional supplies
To select the gain a new patternProperties is added to describe each
channel. It is restricted to adaq devices.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
.../devicetree/bindings/iio/adc/adi,ad7380.yaml | 120 +++++++++++++++++++++
1 file changed, 120 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
index 0065d650882489e21b952bb9fb25f1e3a070ee68..ada08005b3cd1ce7ba13f96484a33fdee0e83a1c 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
@@ -25,6 +25,8 @@ description: |
* https://www.analog.com/en/products/ad7386-4.html
* https://www.analog.com/en/products/ad7387-4.html
* https://www.analog.com/en/products/ad7388-4.html
+ * https://www.analog.com/en/products/adaq4370-4.html
+ * https://www.analog.com/en/products/adaq4380-4.html
$ref: /schemas/spi/spi-peripheral-props.yaml#
@@ -46,6 +48,8 @@ properties:
- adi,ad7386-4
- adi,ad7387-4
- adi,ad7388-4
+ - adi,adaq4370-4
+ - adi,adaq4380-4
reg:
maxItems: 1
@@ -70,6 +74,20 @@ properties:
refin-supply:
description:
A 2.5V to 3.3V supply for external reference voltage, for ad7380-4 only.
+ For adaq devices, a 5V supply voltage. A 3.3V internal reference is
+ derived from it. Connect to vs-p-supply for normal operation.
+
+ vs-p-supply:
+ description:
+ Amplifiers positive supply.
+
+ vs-n-supply:
+ description:
+ Amplifiers negative supply.
+
+ ldo-supply:
+ description:
+ LDO supply. Connect to vs-p-supply or a 3.6 to 5.5 V supply.
aina-supply:
description:
@@ -97,12 +115,45 @@ properties:
specify the ALERT interrupt.
maxItems: 1
+ "#address-cells":
+ const: 1
+
+ "#size-cells":
+ const: 0
+
required:
- compatible
- reg
- vcc-supply
- vlogic-supply
+patternProperties:
+ "^channel@[0-3]$":
+ $ref: adc.yaml
+ type: object
+
+ properties:
+ reg:
+ description:
+ The channel number. From 0 to 3 corresponding to channels A,B,C,D
+ minimum: 0
+ maximum: 3
+
+ adi,gain-milli:
+ description:
+ The hardware gain applied to the ADC input (in milli units).
+ If not present, default to 1000 (no actual gain applied).
+ Refer to the typical connection diagrams section of the datasheet for
+ pin wiring.
+ $ref: /schemas/types.yaml#/definitions/uint16
+ enum: [300, 600, 1000, 1600]
+ default: 1000
+
+ required:
+ - reg
+
+ additionalProperties: false
+
unevaluatedProperties: false
allOf:
@@ -140,6 +191,7 @@ allOf:
aind-supply: false
# ad7380-4 uses refin-supply as external reference.
+ # adaq devices use internal reference only, derived from refin-supply
# All other chips from ad738x family use refio as optional external reference.
# When refio-supply is omitted, internal reference is used.
- if:
@@ -147,6 +199,8 @@ allOf:
compatible:
enum:
- adi,ad7380-4
+ - adi,adaq4370-4
+ - adi,adaq4380-4
then:
properties:
refio-supply: false
@@ -156,6 +210,27 @@ allOf:
properties:
refin-supply: false
+ # adaq devices need more supplies and using channel to declare gain property
+ # only applies to adaq devices
+ - if:
+ properties:
+ compatible:
+ enum:
+ - adi,adaq4370-4
+ - adi,adaq4380-4
+ then:
+ required:
+ - vs-p-supply
+ - vs-n-supply
+ - ldo-supply
+ else:
+ properties:
+ vs-p-supply: false
+ vs-n-supply: false
+ ldo-supply: false
+ patternProperties:
+ "^channel@[0-3]$": false
+
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
@@ -180,3 +255,48 @@ examples:
refio-supply = <&supply_2_5V>;
};
};
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@0 {
+ compatible = "adi,adaq4380-4";
+ reg = <0>;
+
+ spi-cpol;
+ spi-cpha;
+ spi-max-frequency = <80000000>;
+
+ interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
+ interrupt-parent = <&gpio0>;
+
+ vcc-supply = <&supply_3_3V>;
+ vlogic-supply = <&supply_3_3V>;
+ refin-supply = <&supply_5V>;
+ vs-p-supply = <&supply_5V>;
+ vs-n-supply = <&supply_0V>;
+ ldo-supply = <&supply_5V>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 {
+ reg = <0>;
+ adi,gain-milli = /bits/ 16 <300>;
+ };
+
+ channel@2 {
+ reg = <2>;
+ adi,gain-milli = /bits/ 16 <600>;
+ };
+
+ channel@3 {
+ reg = <3>;
+ adi,gain-milli = /bits/ 16 <1000>;
+ };
+ };
+ };
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/5] iio: adc: ad7380: fix oversampling formula
2024-10-30 13:44 [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support Julien Stephan
2024-10-30 13:44 ` [PATCH v4 1/5] dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts Julien Stephan
@ 2024-10-30 13:44 ` Julien Stephan
2024-10-30 13:44 ` [PATCH v4 3/5] iio: adc: ad7380: use local dev variable to shorten long lines Julien Stephan
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Julien Stephan @ 2024-10-30 13:44 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Julien Stephan
The formula in the datasheet for oversampling time conversion seems to
be valid when device is at full speed using the maximum number of SDO
lines. The driver currently support only 1 SDO line. The correct formula
is: t_convert = T_CONVERT_0_NS + T_CONVERT_X_NS*(x -
1)*num_channel/number_of_sdo_lines.
It will produce larger delays than what is currently set, but some devices
actually require it.
Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
drivers/iio/adc/ad7380.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index fb728570debe6432d5f991595cb35e9e7af8b740..e5eececaaf501cda8f51d801c089e593111df714 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -77,6 +77,12 @@
#define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */
#define T_POWERUP_US 5000 /* Power up */
+/*
+ * AD738x support several SDO lines to increase throughput, but driver currently
+ * supports only 1 SDO line (standard SPI transaction)
+ */
+#define AD7380_NUM_SDO_LINES 1
+
struct ad7380_timing_specs {
const unsigned int t_csh_ns; /* CS minimum high time */
};
@@ -649,7 +655,8 @@ static int ad7380_set_ch(struct ad7380_state *st, unsigned int ch)
if (st->oversampling_ratio > 1)
xfer.delay.value = T_CONVERT_0_NS +
- T_CONVERT_X_NS * (st->oversampling_ratio - 1);
+ T_CONVERT_X_NS * (st->oversampling_ratio - 1) *
+ st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES;
return spi_sync_transfer(st->spi, &xfer, 1);
}
@@ -672,7 +679,8 @@ static void ad7380_update_xfers(struct ad7380_state *st,
*/
if (st->oversampling_ratio > 1)
t_convert = T_CONVERT_0_NS + T_CONVERT_X_NS *
- (st->oversampling_ratio - 1);
+ (st->oversampling_ratio - 1) *
+ st->chip_info->num_simult_channels / AD7380_NUM_SDO_LINES;
if (st->seq) {
xfer[0].delay.value = xfer[1].delay.value = t_convert;
@@ -1021,7 +1029,8 @@ static int ad7380_init(struct ad7380_state *st, bool external_ref_en)
/* SPI 1-wire mode */
return regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG2,
AD7380_CONFIG2_SDO,
- FIELD_PREP(AD7380_CONFIG2_SDO, 1));
+ FIELD_PREP(AD7380_CONFIG2_SDO,
+ AD7380_NUM_SDO_LINES));
}
static int ad7380_probe(struct spi_device *spi)
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/5] iio: adc: ad7380: use local dev variable to shorten long lines
2024-10-30 13:44 [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support Julien Stephan
2024-10-30 13:44 ` [PATCH v4 1/5] dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts Julien Stephan
2024-10-30 13:44 ` [PATCH v4 2/5] iio: adc: ad7380: fix oversampling formula Julien Stephan
@ 2024-10-30 13:44 ` Julien Stephan
2024-10-30 13:44 ` [PATCH v4 4/5] iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4 Julien Stephan
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Julien Stephan @ 2024-10-30 13:44 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Julien Stephan
Use local dev variable in the probe function to shorten long lines.
Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
drivers/iio/adc/ad7380.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index e5eececaaf501cda8f51d801c089e593111df714..206c894953f057acca20805fb30185cb7ab8a902 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -1035,12 +1035,13 @@ static int ad7380_init(struct ad7380_state *st, bool external_ref_en)
static int ad7380_probe(struct spi_device *spi)
{
+ struct device *dev = &spi->dev;
struct iio_dev *indio_dev;
struct ad7380_state *st;
bool external_ref_en;
int ret, i;
- indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@@ -1048,21 +1049,20 @@ static int ad7380_probe(struct spi_device *spi)
st->spi = spi;
st->chip_info = spi_get_device_match_data(spi);
if (!st->chip_info)
- return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n");
+ return dev_err_probe(dev, -EINVAL, "missing match data\n");
- ret = devm_regulator_bulk_get_enable(&spi->dev, st->chip_info->num_supplies,
+ ret = devm_regulator_bulk_get_enable(dev, st->chip_info->num_supplies,
st->chip_info->supplies);
if (ret)
- return dev_err_probe(&spi->dev, ret,
+ return dev_err_probe(dev, ret,
"Failed to enable power supplies\n");
fsleep(T_POWERUP_US);
if (st->chip_info->external_ref_only) {
- ret = devm_regulator_get_enable_read_voltage(&spi->dev,
- "refin");
+ ret = devm_regulator_get_enable_read_voltage(dev, "refin");
if (ret < 0)
- return dev_err_probe(&spi->dev, ret,
+ return dev_err_probe(dev, ret,
"Failed to get refin regulator\n");
st->vref_mv = ret / 1000;
@@ -1074,10 +1074,9 @@ static int ad7380_probe(struct spi_device *spi)
* If there is no REFIO supply, then it means that we are using
* the internal reference, otherwise REFIO is reference voltage.
*/
- ret = devm_regulator_get_enable_read_voltage(&spi->dev,
- "refio");
+ ret = devm_regulator_get_enable_read_voltage(dev, "refio");
if (ret < 0 && ret != -ENODEV)
- return dev_err_probe(&spi->dev, ret,
+ return dev_err_probe(dev, ret,
"Failed to get refio regulator\n");
external_ref_en = ret != -ENODEV;
@@ -1085,7 +1084,7 @@ static int ad7380_probe(struct spi_device *spi)
}
if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv))
- return dev_err_probe(&spi->dev, -EINVAL,
+ return dev_err_probe(dev, -EINVAL,
"invalid number of VCM supplies\n");
/*
@@ -1095,18 +1094,18 @@ static int ad7380_probe(struct spi_device *spi)
for (i = 0; i < st->chip_info->num_vcm_supplies; i++) {
const char *vcm = st->chip_info->vcm_supplies[i];
- ret = devm_regulator_get_enable_read_voltage(&spi->dev, vcm);
+ ret = devm_regulator_get_enable_read_voltage(dev, vcm);
if (ret < 0)
- return dev_err_probe(&spi->dev, ret,
+ return dev_err_probe(dev, ret,
"Failed to get %s regulator\n",
vcm);
st->vcm_mv[i] = ret / 1000;
}
- st->regmap = devm_regmap_init(&spi->dev, NULL, st, &ad7380_regmap_config);
+ st->regmap = devm_regmap_init(dev, NULL, st, &ad7380_regmap_config);
if (IS_ERR(st->regmap))
- return dev_err_probe(&spi->dev, PTR_ERR(st->regmap),
+ return dev_err_probe(dev, PTR_ERR(st->regmap),
"failed to allocate register map\n");
/*
@@ -1157,7 +1156,7 @@ static int ad7380_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->available_scan_masks = st->chip_info->available_scan_masks;
- ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
+ ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
iio_pollfunc_store_time,
ad7380_trigger_handler,
&ad7380_buffer_setup_ops);
@@ -1168,7 +1167,7 @@ static int ad7380_probe(struct spi_device *spi)
if (ret)
return ret;
- return devm_iio_device_register(&spi->dev, indio_dev);
+ return devm_iio_device_register(dev, indio_dev);
}
static const struct of_device_id ad7380_of_match_table[] = {
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 4/5] iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4
2024-10-30 13:44 [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support Julien Stephan
` (2 preceding siblings ...)
2024-10-30 13:44 ` [PATCH v4 3/5] iio: adc: ad7380: use local dev variable to shorten long lines Julien Stephan
@ 2024-10-30 13:44 ` Julien Stephan
2024-10-30 13:44 ` [PATCH v4 5/5] docs: iio: ad7380: add " Julien Stephan
2024-10-30 14:32 ` [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support David Lechner
5 siblings, 0 replies; 10+ messages in thread
From: Julien Stephan @ 2024-10-30 13:44 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Julien Stephan
adaq4370-4 (2MSPS) and adaq4380-4 (4MSPS) are quad-channel precision data
acquisition signal chain μModule solutions compatible with the ad738x
family, with the following differences:
- pin selectable gain in front of each 4 adc
- internal reference is 3V derived from refin-supply (5V)
- additional supplies
This implies that IIO_CHAN_INFO_SCALE can not be shared by type for
these new devices.
Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
drivers/iio/adc/ad7380.c | 130 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 126 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c
index 206c894953f057acca20805fb30185cb7ab8a902..4f32cb22f140442b831dc9a4f275e88e4ab2388e 100644
--- a/drivers/iio/adc/ad7380.c
+++ b/drivers/iio/adc/ad7380.c
@@ -13,6 +13,8 @@
* ad7381-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/ad7381-4.pdf
* ad7383/4-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/ad7383-4-ad7384-4.pdf
* ad7386/7/8-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/ad7386-4-7387-4-7388-4.pdf
+ * adaq4370-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4370-4.pdf
+ * adaq4380-4 : https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4380-4.pdf
*/
#include <linux/align.h>
@@ -22,11 +24,14 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kernel.h>
+#include <linux/math.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
+#include <linux/units.h>
+#include <linux/util_macros.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
@@ -36,6 +41,8 @@
#define MAX_NUM_CHANNELS 8
/* 2.5V internal reference voltage */
#define AD7380_INTERNAL_REF_MV 2500
+/* 3.3V internal reference voltage for ADAQ */
+#define ADAQ4380_INTERNAL_REF_MV 3300
/* reading and writing registers is more reliable at lower than max speed */
#define AD7380_REG_WR_SPEED_HZ 10000000
@@ -82,6 +89,7 @@
* supports only 1 SDO line (standard SPI transaction)
*/
#define AD7380_NUM_SDO_LINES 1
+#define AD7380_DEFAULT_GAIN_MILLI 1000
struct ad7380_timing_specs {
const unsigned int t_csh_ns; /* CS minimum high time */
@@ -92,10 +100,12 @@ struct ad7380_chip_info {
const struct iio_chan_spec *channels;
unsigned int num_channels;
unsigned int num_simult_channels;
+ bool has_hardware_gain;
bool has_mux;
const char * const *supplies;
unsigned int num_supplies;
bool external_ref_only;
+ bool adaq_internal_ref_only;
const char * const *vcm_supplies;
unsigned int num_vcm_supplies;
const unsigned long *available_scan_masks;
@@ -187,11 +197,12 @@ static const struct iio_scan_type ad7380_scan_type_16_u[] = {
},
};
-#define AD7380_CHANNEL(index, bits, diff, sign) { \
+#define _AD7380_CHANNEL(index, bits, diff, sign, gain) { \
.type = IIO_VOLTAGE, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ ((gain) ? BIT(IIO_CHAN_INFO_SCALE) : 0) | \
((diff) ? 0 : BIT(IIO_CHAN_INFO_OFFSET)), \
- .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
+ .info_mask_shared_by_type = ((gain) ? 0 : BIT(IIO_CHAN_INFO_SCALE)) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.info_mask_shared_by_type_available = \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
@@ -205,6 +216,12 @@ static const struct iio_scan_type ad7380_scan_type_16_u[] = {
.num_ext_scan_type = ARRAY_SIZE(ad7380_scan_type_##bits##_##sign), \
}
+#define AD7380_CHANNEL(index, bits, diff, sign) \
+ _AD7380_CHANNEL(index, bits, diff, sign, false)
+
+#define ADAQ4380_CHANNEL(index, bits, diff, sign) \
+ _AD7380_CHANNEL(index, bits, diff, sign, true)
+
#define DEFINE_AD7380_2_CHANNEL(name, bits, diff, sign) \
static const struct iio_chan_spec name[] = { \
AD7380_CHANNEL(0, bits, diff, sign), \
@@ -221,6 +238,15 @@ static const struct iio_chan_spec name[] = { \
IIO_CHAN_SOFT_TIMESTAMP(4), \
}
+#define DEFINE_ADAQ4380_4_CHANNEL(name, bits, diff, sign) \
+static const struct iio_chan_spec name[] = { \
+ ADAQ4380_CHANNEL(0, bits, diff, sign), \
+ ADAQ4380_CHANNEL(1, bits, diff, sign), \
+ ADAQ4380_CHANNEL(2, bits, diff, sign), \
+ ADAQ4380_CHANNEL(3, bits, diff, sign), \
+ IIO_CHAN_SOFT_TIMESTAMP(4), \
+}
+
#define DEFINE_AD7380_8_CHANNEL(name, bits, diff, sign) \
static const struct iio_chan_spec name[] = { \
AD7380_CHANNEL(0, bits, diff, sign), \
@@ -239,6 +265,7 @@ DEFINE_AD7380_2_CHANNEL(ad7380_channels, 16, 1, s);
DEFINE_AD7380_2_CHANNEL(ad7381_channels, 14, 1, s);
DEFINE_AD7380_4_CHANNEL(ad7380_4_channels, 16, 1, s);
DEFINE_AD7380_4_CHANNEL(ad7381_4_channels, 14, 1, s);
+DEFINE_ADAQ4380_4_CHANNEL(adaq4380_4_channels, 16, 1, s);
/* pseudo differential */
DEFINE_AD7380_2_CHANNEL(ad7383_channels, 16, 0, s);
DEFINE_AD7380_2_CHANNEL(ad7384_channels, 14, 0, s);
@@ -257,6 +284,10 @@ static const char * const ad7380_supplies[] = {
"vcc", "vlogic",
};
+static const char * const adaq4380_supplies[] = {
+ "ldo", "vcc", "vlogic", "vs-p", "vs-n", "refin",
+};
+
static const char * const ad7380_2_channel_vcm_supplies[] = {
"aina", "ainb",
};
@@ -347,6 +378,11 @@ static const int ad7380_oversampling_ratios[] = {
1, 2, 4, 8, 16, 32,
};
+/* Gains stored as fractions of 1000 so they can be expressed by integers. */
+static const int ad7380_gains[] = {
+ 300, 600, 1000, 1600,
+};
+
static const struct ad7380_chip_info ad7380_chip_info = {
.name = "ad7380",
.channels = ad7380_channels,
@@ -516,6 +552,32 @@ static const struct ad7380_chip_info ad7388_4_chip_info = {
.timing_specs = &ad7380_4_timing,
};
+static const struct ad7380_chip_info adaq4370_4_chip_info = {
+ .name = "adaq4370-4",
+ .channels = adaq4380_4_channels,
+ .num_channels = ARRAY_SIZE(adaq4380_4_channels),
+ .num_simult_channels = 4,
+ .supplies = adaq4380_supplies,
+ .num_supplies = ARRAY_SIZE(adaq4380_supplies),
+ .adaq_internal_ref_only = true,
+ .has_hardware_gain = true,
+ .available_scan_masks = ad7380_4_channel_scan_masks,
+ .timing_specs = &ad7380_4_timing,
+};
+
+static const struct ad7380_chip_info adaq4380_4_chip_info = {
+ .name = "adaq4380-4",
+ .channels = adaq4380_4_channels,
+ .num_channels = ARRAY_SIZE(adaq4380_4_channels),
+ .num_simult_channels = 4,
+ .supplies = adaq4380_supplies,
+ .num_supplies = ARRAY_SIZE(adaq4380_supplies),
+ .adaq_internal_ref_only = true,
+ .has_hardware_gain = true,
+ .available_scan_masks = ad7380_4_channel_scan_masks,
+ .timing_specs = &ad7380_4_timing,
+};
+
struct ad7380_state {
const struct ad7380_chip_info *chip_info;
struct spi_device *spi;
@@ -526,6 +588,7 @@ struct ad7380_state {
bool seq;
unsigned int vref_mv;
unsigned int vcm_mv[MAX_NUM_CHANNELS];
+ unsigned int gain_milli[MAX_NUM_CHANNELS];
/* xfers, message an buffer for reading sample data */
struct spi_transfer normal_xfer[2];
struct spi_message normal_msg;
@@ -876,8 +939,15 @@ static int ad7380_read_raw(struct iio_dev *indio_dev,
* * (2 × VREF) / 2^N, for differential chips
* * VREF / 2^N, for pseudo-differential chips
* where N is the ADC resolution (i.e realbits)
+ *
+ * The gain is stored as a fraction of 1000 and, as we need to
+ * divide vref_mv by the gain, we invert the gain/1000 fraction.
*/
- *val = st->vref_mv;
+ if (st->chip_info->has_hardware_gain)
+ *val = mult_frac(st->vref_mv, MILLI,
+ st->gain_milli[chan->scan_index]);
+ else
+ *val = st->vref_mv;
*val2 = scan_type->realbits - chan->differential;
return IIO_VAL_FRACTIONAL_LOG2;
@@ -1059,7 +1129,19 @@ static int ad7380_probe(struct spi_device *spi)
"Failed to enable power supplies\n");
fsleep(T_POWERUP_US);
- if (st->chip_info->external_ref_only) {
+ if (st->chip_info->adaq_internal_ref_only) {
+ /*
+ * ADAQ chips use fixed internal reference but still
+ * require a specific reference supply to power it.
+ * "refin" is already enabled with other power supplies
+ * in bulk_get_enable().
+ */
+
+ st->vref_mv = ADAQ4380_INTERNAL_REF_MV;
+
+ /* these chips don't have a register bit for this */
+ external_ref_en = false;
+ } else if (st->chip_info->external_ref_only) {
ret = devm_regulator_get_enable_read_voltage(dev, "refin");
if (ret < 0)
return dev_err_probe(dev, ret,
@@ -1103,6 +1185,42 @@ static int ad7380_probe(struct spi_device *spi)
st->vcm_mv[i] = ret / 1000;
}
+ for (i = 0; i < MAX_NUM_CHANNELS; i++)
+ st->gain_milli[i] = AD7380_DEFAULT_GAIN_MILLI;
+
+ if (st->chip_info->has_hardware_gain) {
+ device_for_each_child_node_scoped(dev, node) {
+ unsigned int channel, gain;
+ int gain_idx;
+
+ ret = fwnode_property_read_u32(node, "reg", &channel);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to read reg property\n");
+
+ if (channel >= st->chip_info->num_channels - 1)
+ return dev_err_probe(dev, -EINVAL,
+ "Invalid channel number %i\n",
+ channel);
+
+ ret = fwnode_property_read_u32(node, "adi,gain-milli",
+ &gain);
+ if (ret && ret != -EINVAL)
+ return dev_err_probe(dev, ret,
+ "Failed to read gain for channel %i\n",
+ channel);
+ if (ret != -EINVAL) {
+ /*
+ * Match gain value from dt to one of supported
+ * gains
+ */
+ gain_idx = find_closest(gain, ad7380_gains,
+ ARRAY_SIZE(ad7380_gains));
+ st->gain_milli[channel] = ad7380_gains[gain_idx];
+ }
+ }
+ }
+
st->regmap = devm_regmap_init(dev, NULL, st, &ad7380_regmap_config);
if (IS_ERR(st->regmap))
return dev_err_probe(dev, PTR_ERR(st->regmap),
@@ -1185,6 +1303,8 @@ static const struct of_device_id ad7380_of_match_table[] = {
{ .compatible = "adi,ad7386-4", .data = &ad7386_4_chip_info },
{ .compatible = "adi,ad7387-4", .data = &ad7387_4_chip_info },
{ .compatible = "adi,ad7388-4", .data = &ad7388_4_chip_info },
+ { .compatible = "adi,adaq4370-4", .data = &adaq4370_4_chip_info },
+ { .compatible = "adi,adaq4380-4", .data = &adaq4380_4_chip_info },
{ }
};
@@ -1203,6 +1323,8 @@ static const struct spi_device_id ad7380_id_table[] = {
{ "ad7386-4", (kernel_ulong_t)&ad7386_4_chip_info },
{ "ad7387-4", (kernel_ulong_t)&ad7387_4_chip_info },
{ "ad7388-4", (kernel_ulong_t)&ad7388_4_chip_info },
+ { "adaq4370-4", (kernel_ulong_t)&adaq4370_4_chip_info },
+ { "adaq4380-4", (kernel_ulong_t)&adaq4380_4_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad7380_id_table);
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 5/5] docs: iio: ad7380: add adaq4370-4 and adaq4380-4
2024-10-30 13:44 [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support Julien Stephan
` (3 preceding siblings ...)
2024-10-30 13:44 ` [PATCH v4 4/5] iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4 Julien Stephan
@ 2024-10-30 13:44 ` Julien Stephan
2024-10-30 14:27 ` David Lechner
2024-10-30 14:32 ` [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support David Lechner
5 siblings, 1 reply; 10+ messages in thread
From: Julien Stephan @ 2024-10-30 13:44 UTC (permalink / raw)
To: Lars-Peter Clausen, Michael Hennerich, Nuno Sá,
David Lechner, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Julien Stephan
Adding documentation for adaq4370-4 and adaq4380-4 supported devices. In
particular, document the reference voltage mechanism and the gain
parameter that are specific to adaq devices.
Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
Documentation/iio/ad7380.rst | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Documentation/iio/ad7380.rst b/Documentation/iio/ad7380.rst
index 6f70b49b9ef27c1ac32acaefecd1146e5c8bd6cc..1b9777c33e0c3e9e06f72d7c957a012346d4a26a 100644
--- a/Documentation/iio/ad7380.rst
+++ b/Documentation/iio/ad7380.rst
@@ -27,6 +27,8 @@ The following chips are supported by this driver:
* `AD7386-4 <https://www.analog.com/en/products/ad7386-4.html>`_
* `AD7387-4 <https://www.analog.com/en/products/ad7387-4.html>`_
* `AD7388-4 <https://www.analog.com/en/products/ad7388-4.html>`_
+* `ADAQ4370-4 <https://www.analog.com/en/products/adaq4370-4.html>`_
+* `ADAQ4380-4 <https://www.analog.com/en/products/adaq4380-4.html>`_
Supported features
@@ -47,6 +49,12 @@ ad7380-4
ad7380-4 supports only an external reference voltage (2.5V to 3.3V). It must be
declared in the device tree as ``refin-supply``.
+ADAQ devices
+~~~~~~~~~~~~
+
+adaq4370-4 and adaq4380-4 don't have an external reference, but use a 3V
+internal reference derived from one of its supplies (``refin-supply``)
+
All other devices from ad738x family
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -121,6 +129,14 @@ Example for AD7386/7/8 (2 channels parts):
When enabling sequencer mode, the effective sampling rate is divided by two.
+Gain (ADAQ devices only)
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+ADAQ devices have a pin selectable gain in front of each ADC. The appropriate
+gain is selectable from device tree using the ``adi,gain-milli`` property.
+Refer to the typical connection diagrams section of the datasheet for pin
+wiring.
+
Unimplemented features
----------------------
--
2.47.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 5/5] docs: iio: ad7380: add adaq4370-4 and adaq4380-4
2024-10-30 13:44 ` [PATCH v4 5/5] docs: iio: ad7380: add " Julien Stephan
@ 2024-10-30 14:27 ` David Lechner
0 siblings, 0 replies; 10+ messages in thread
From: David Lechner @ 2024-10-30 14:27 UTC (permalink / raw)
To: Julien Stephan, Lars-Peter Clausen, Michael Hennerich,
Nuno Sá, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc
On 10/30/24 8:44 AM, Julien Stephan wrote:
> Adding documentation for adaq4370-4 and adaq4380-4 supported devices. In
> particular, document the reference voltage mechanism and the gain
> parameter that are specific to adaq devices.
>
> Signed-off-by: Julien Stephan <jstephan@baylibre.com>
> ---
> Documentation/iio/ad7380.rst | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/Documentation/iio/ad7380.rst b/Documentation/iio/ad7380.rst
> index 6f70b49b9ef27c1ac32acaefecd1146e5c8bd6cc..1b9777c33e0c3e9e06f72d7c957a012346d4a26a 100644
> --- a/Documentation/iio/ad7380.rst
> +++ b/Documentation/iio/ad7380.rst
> @@ -27,6 +27,8 @@ The following chips are supported by this driver:
> * `AD7386-4 <https://www.analog.com/en/products/ad7386-4.html>`_
> * `AD7387-4 <https://www.analog.com/en/products/ad7387-4.html>`_
> * `AD7388-4 <https://www.analog.com/en/products/ad7388-4.html>`_
> +* `ADAQ4370-4 <https://www.analog.com/en/products/adaq4370-4.html>`_
> +* `ADAQ4380-4 <https://www.analog.com/en/products/adaq4380-4.html>`_
>
>
> Supported features
> @@ -47,6 +49,12 @@ ad7380-4
> ad7380-4 supports only an external reference voltage (2.5V to 3.3V). It must be
> declared in the device tree as ``refin-supply``.
>
> +ADAQ devices
> +~~~~~~~~~~~~
> +
> +adaq4370-4 and adaq4380-4 don't have an external reference, but use a 3V
It's 3.3V, not 3V
> +internal reference derived from one of its supplies (``refin-supply``)
> +
> All other devices from ad738x family
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> @@ -121,6 +129,14 @@ Example for AD7386/7/8 (2 channels parts):
>
> When enabling sequencer mode, the effective sampling rate is divided by two.
>
> +Gain (ADAQ devices only)
> +~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +ADAQ devices have a pin selectable gain in front of each ADC. The appropriate
> +gain is selectable from device tree using the ``adi,gain-milli`` property.
> +Refer to the typical connection diagrams section of the datasheet for pin
> +wiring.
> +
> Unimplemented features
> ----------------------
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support
2024-10-30 13:44 [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support Julien Stephan
` (4 preceding siblings ...)
2024-10-30 13:44 ` [PATCH v4 5/5] docs: iio: ad7380: add " Julien Stephan
@ 2024-10-30 14:32 ` David Lechner
2024-11-02 15:37 ` Jonathan Cameron
5 siblings, 1 reply; 10+ messages in thread
From: David Lechner @ 2024-10-30 14:32 UTC (permalink / raw)
To: Julien Stephan, Lars-Peter Clausen, Michael Hennerich,
Nuno Sá, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet
Cc: linux-iio, devicetree, linux-kernel, linux-doc, Conor Dooley
On 10/30/24 8:44 AM, Julien Stephan wrote:
> Hello,
>
> This series add support for adaq4370-4 (2MSPS) and adaq4380-4 (4MSPS)
> which are quad-channel precision data acquisition signal chain μModule
> solutions compatible with the ad738x family, with the following differences:
>
Reviewed-by: David Lechner <dlechner@baylibre.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support
2024-10-30 14:32 ` [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support David Lechner
@ 2024-11-02 15:37 ` Jonathan Cameron
2024-11-06 9:58 ` Jonathan Cameron
0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2024-11-02 15:37 UTC (permalink / raw)
To: David Lechner
Cc: Julien Stephan, Lars-Peter Clausen, Michael Hennerich,
Nuno Sá, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Corbet, linux-iio, devicetree, linux-kernel, linux-doc,
Conor Dooley
On Wed, 30 Oct 2024 09:32:23 -0500
David Lechner <dlechner@baylibre.com> wrote:
> On 10/30/24 8:44 AM, Julien Stephan wrote:
> > Hello,
> >
> > This series add support for adaq4370-4 (2MSPS) and adaq4380-4 (4MSPS)
> > which are quad-channel precision data acquisition signal chain μModule
> > solutions compatible with the ad738x family, with the following differences:
> >
> Reviewed-by: David Lechner <dlechner@baylibre.com>
FWIW, this looks fine to me and I can tweak the voltage in the docs whilst
applying. I'm stalled on merging this series by the fix dependency working
it's way into upstream.
Thanks,
Jonathan
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support
2024-11-02 15:37 ` Jonathan Cameron
@ 2024-11-06 9:58 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2024-11-06 9:58 UTC (permalink / raw)
To: David Lechner
Cc: Julien Stephan, Lars-Peter Clausen, Michael Hennerich,
Nuno Sá, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Jonathan Corbet, linux-iio, devicetree, linux-kernel, linux-doc,
Conor Dooley
On Sat, 2 Nov 2024 15:37:18 +0000
Jonathan Cameron <jic23@kernel.org> wrote:
> On Wed, 30 Oct 2024 09:32:23 -0500
> David Lechner <dlechner@baylibre.com> wrote:
>
> > On 10/30/24 8:44 AM, Julien Stephan wrote:
> > > Hello,
> > >
> > > This series add support for adaq4370-4 (2MSPS) and adaq4380-4 (4MSPS)
> > > which are quad-channel precision data acquisition signal chain μModule
> > > solutions compatible with the ad738x family, with the following differences:
> > >
> > Reviewed-by: David Lechner <dlechner@baylibre.com>
>
> FWIW, this looks fine to me and I can tweak the voltage in the docs whilst
> applying. I'm stalled on merging this series by the fix dependency working
> it's way into upstream.
Applied. I tweaked that voltage in the docs to 3.3V as per David's feedback.
Pushed out as testing to give 0-day a brief look.
Note I merged rc6 to get the fix this was dependent on.
>
> Thanks,
>
> Jonathan
>
> >
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-11-06 9:58 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-30 13:44 [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support Julien Stephan
2024-10-30 13:44 ` [PATCH v4 1/5] dt-bindings: iio: adc: ad7380: add adaq4370-4 and adaq4380-4 compatible parts Julien Stephan
2024-10-30 13:44 ` [PATCH v4 2/5] iio: adc: ad7380: fix oversampling formula Julien Stephan
2024-10-30 13:44 ` [PATCH v4 3/5] iio: adc: ad7380: use local dev variable to shorten long lines Julien Stephan
2024-10-30 13:44 ` [PATCH v4 4/5] iio: adc: ad7380: add support for adaq4370-4 and adaq4380-4 Julien Stephan
2024-10-30 13:44 ` [PATCH v4 5/5] docs: iio: ad7380: add " Julien Stephan
2024-10-30 14:27 ` David Lechner
2024-10-30 14:32 ` [PATCH v4 0/5] ad7380: add adaq4370-4 and adaq4380-4 support David Lechner
2024-11-02 15:37 ` Jonathan Cameron
2024-11-06 9:58 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox