* [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 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