* [PATCH 0/4] iio: adc: ade9000: add support for ADE9078
@ 2026-07-20 11:07 Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 1/4] iio: adc: ade9000: introduce chip_info structure Antoniu Miclaus
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Antoniu Miclaus @ 2026-07-20 11:07 UTC (permalink / raw)
To: Antoniu Miclaus, Nuno Sá, Michael Hennerich,
Jonathan Cameron, David Lechner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet, Shuah Khan, Marcelo Schmitt,
Radu Sabau, Jorge Marques, Matti Vaittinen, Jonathan Santos,
Jishnu Prakash, linux-iio, linux, devicetree, linux-kernel,
linux-doc
The ADE9078 is a polyphase energy metering device from the same family as
the ADE9000 and is register compatible with it. The main differences
relevant to the driver are the absence of the on-chip dip/swell detection,
a lower maximum SPI clock (10 MHz), and slightly different full-scale ADC
codes.
This series adds support for the ADE9078 to the existing ade9000 driver.
It first refactors the driver to move the part-specific values (device
name, channel table, and full-scale codes) into a chip_info structure
retrieved via device match data, then adds the new device tree compatible
and the ADE9078 support itself, and finally updates the documentation.
Antoniu Miclaus (4):
iio: adc: ade9000: introduce chip_info structure
dt-bindings: iio: adc: adi,ade9000: add adi,ade9078 compatible
iio: adc: ade9000: add support for ADE9078
docs: iio: ade9000: document ADE9078 support
.../bindings/iio/adc/adi,ade9000.yaml | 30 ++-
Documentation/iio/ade9000.rst | 28 +--
drivers/iio/adc/Kconfig | 14 +-
drivers/iio/adc/ade9000.c | 178 ++++++++++++------
4 files changed, 169 insertions(+), 81 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] iio: adc: ade9000: introduce chip_info structure
2026-07-20 11:07 [PATCH 0/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
@ 2026-07-20 11:07 ` Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 2/4] dt-bindings: iio: adc: adi,ade9000: add adi,ade9078 compatible Antoniu Miclaus
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Antoniu Miclaus @ 2026-07-20 11:07 UTC (permalink / raw)
To: Antoniu Miclaus, Nuno Sá, Michael Hennerich,
Jonathan Cameron, David Lechner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet, Shuah Khan, Marcelo Schmitt,
Radu Sabau, Jorge Marques, Matti Vaittinen, Jonathan Santos,
Jishnu Prakash, linux-iio, linux, devicetree, linux-kernel,
linux-doc
The driver currently hardcodes the device name and the full-scale ADC
codes used to derive the IIO scale attributes. In preparation for
supporting additional parts of the ADE9000 family, move these
part-specific values into a new struct ade9000_chip_info and retrieve it
via spi_get_device_match_data() at probe time.
The channel table and its size are also referenced through the chip_info
so that parts with a different channel layout can be added without
touching the probe path.
No functional change intended for the ADE9000.
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
drivers/iio/adc/ade9000.c | 63 +++++++++++++++++++++++++++++----------
1 file changed, 47 insertions(+), 16 deletions(-)
diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c
index b80cdd8ad982..38a5c7e043b3 100644
--- a/drivers/iio/adc/ade9000.c
+++ b/drivers/iio/adc/ade9000.c
@@ -242,14 +242,6 @@
#define ADE9000_LAST_PAGE_BIT BIT(15)
#define ADE9000_MIDDLE_PAGE_BIT BIT(7)
-/*
- * Full scale Codes referred from Datasheet. Respective digital codes are
- * produced when ADC inputs are at full scale.
- */
-#define ADE9000_RMS_FULL_SCALE_CODES 52866837
-#define ADE9000_WATT_FULL_SCALE_CODES 20694066
-#define ADE9000_PCF_FULL_SCALE_CODES 74770000
-
/* Phase and channel definitions */
#define ADE9000_PHASE_A_NR 0
#define ADE9000_PHASE_B_NR 1
@@ -290,7 +282,29 @@ enum ade9000_wfb_cfg {
#define ADE9000_ADDR_ADJUST(addr, chan) \
(((chan) == 0 ? 0 : (chan) == 1 ? 2 : 4) << 4 | (addr))
+/**
+ * struct ade9000_chip_info - part-specific configuration
+ * @name: IIO device name reported to userspace
+ * @channels: channel specification for this part
+ * @num_channels: number of entries in @channels
+ * @rms_full_scale_codes: digital code produced at full-scale RMS input
+ * @watt_full_scale_codes: digital code produced at full-scale power input
+ * @pcf_full_scale_codes: digital code produced at full-scale xI_PCF/xV_PCF input
+ *
+ * The full-scale codes are taken from the respective datasheets and are used to
+ * derive the IIO scale of the raw measurement channels.
+ */
+struct ade9000_chip_info {
+ const char *name;
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+ unsigned int rms_full_scale_codes;
+ unsigned int watt_full_scale_codes;
+ unsigned int pcf_full_scale_codes;
+};
+
struct ade9000_state {
+ const struct ade9000_chip_info *info;
struct completion reset_completion;
struct mutex lock; /* Protects SPI transactions */
u8 wf_src;
@@ -623,6 +637,19 @@ static const struct iio_chan_spec ade9000_channels[] = {
ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_C_NR),
};
+/*
+ * Full-scale codes referred from the datasheet. These are the digital codes
+ * produced when the ADC inputs are at full scale.
+ */
+static const struct ade9000_chip_info ade9000_chip_info = {
+ .name = "ade9000",
+ .channels = ade9000_channels,
+ .num_channels = ARRAY_SIZE(ade9000_channels),
+ .rms_full_scale_codes = 52866837,
+ .watt_full_scale_codes = 20694066,
+ .pcf_full_scale_codes = 74770000,
+};
+
static const struct reg_sequence ade9000_initialization_sequence[] = {
{ ADE9000_REG_PGA_GAIN, ADE9000_PGA_GAIN },
{ ADE9000_REG_CONFIG0, ADE9000_CONFIG0 },
@@ -1064,7 +1091,7 @@ static int ade9000_read_raw(struct iio_dev *indio_dev,
case ADE9000_REG_CI_PCF:
case ADE9000_REG_CV_PCF:
*val = 1;
- *val2 = ADE9000_PCF_FULL_SCALE_CODES;
+ *val2 = st->info->pcf_full_scale_codes;
return IIO_VAL_FRACTIONAL;
case ADE9000_REG_AIRMS:
case ADE9000_REG_AVRMS:
@@ -1073,14 +1100,14 @@ static int ade9000_read_raw(struct iio_dev *indio_dev,
case ADE9000_REG_CIRMS:
case ADE9000_REG_CVRMS:
*val = 1;
- *val2 = ADE9000_RMS_FULL_SCALE_CODES;
+ *val2 = st->info->rms_full_scale_codes;
return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
case IIO_POWER:
*val = 1;
- *val2 = ADE9000_WATT_FULL_SCALE_CODES;
+ *val2 = st->info->watt_full_scale_codes;
return IIO_VAL_FRACTIONAL;
default:
break;
@@ -1692,6 +1719,10 @@ static int ade9000_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
+ st->info = spi_get_device_match_data(spi);
+ if (!st->info)
+ return -ENODEV;
+
regmap = devm_regmap_init(dev, NULL, st, &ade9000_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Unable to allocate ADE9000 regmap");
@@ -1726,7 +1757,7 @@ static int ade9000_probe(struct spi_device *spi)
if (ret)
return ret;
- indio_dev->name = "ade9000";
+ indio_dev->name = st->info->name;
indio_dev->info = &ade9000_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->setup_ops = &ade9000_buffer_ops;
@@ -1736,8 +1767,8 @@ static int ade9000_probe(struct spi_device *spi)
return dev_err_probe(&spi->dev, ret,
"Failed to get and enable vdd regulator\n");
- indio_dev->channels = ade9000_channels;
- indio_dev->num_channels = ARRAY_SIZE(ade9000_channels);
+ indio_dev->channels = st->info->channels;
+ indio_dev->num_channels = st->info->num_channels;
ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
&ade9000_buffer_ops);
@@ -1768,13 +1799,13 @@ static int ade9000_probe(struct spi_device *spi)
};
static const struct spi_device_id ade9000_id[] = {
- { .name = "ade9000" },
+ { .name = "ade9000", .driver_data = (kernel_ulong_t)&ade9000_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ade9000_id);
static const struct of_device_id ade9000_of_match[] = {
- { .compatible = "adi,ade9000" },
+ { .compatible = "adi,ade9000", .data = &ade9000_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ade9000_of_match);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] dt-bindings: iio: adc: adi,ade9000: add adi,ade9078 compatible
2026-07-20 11:07 [PATCH 0/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 1/4] iio: adc: ade9000: introduce chip_info structure Antoniu Miclaus
@ 2026-07-20 11:07 ` Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 3/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 4/4] docs: iio: ade9000: document ADE9078 support Antoniu Miclaus
3 siblings, 0 replies; 6+ messages in thread
From: Antoniu Miclaus @ 2026-07-20 11:07 UTC (permalink / raw)
To: Antoniu Miclaus, Nuno Sá, Michael Hennerich,
Jonathan Cameron, David Lechner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet, Shuah Khan, Marcelo Schmitt,
Radu Sabau, Jorge Marques, Matti Vaittinen, Jonathan Santos,
Jishnu Prakash, linux-iio, linux, devicetree, linux-kernel,
linux-doc
The ADE9078 is a polyphase energy metering device from the same family as
the ADE9000. It is register-compatible with the ADE9000 but does not
provide the on-chip dip/swell detection and is limited to a 10 MHz SPI
clock.
Add the new compatible along with a conditional constraint lowering the
maximum spi-max-frequency for the ADE9078.
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
.../bindings/iio/adc/adi,ade9000.yaml | 30 ++++++++++++++-----
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml
index f22eba0250ee..1e940e8c7297 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml
@@ -5,21 +5,23 @@
$id: http://devicetree.org/schemas/iio/adc/adi,ade9000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Analog Devices ADE9000 High Performance, Polyphase Energy Metering
+title: Analog Devices ADE9000/ADE9078 High Performance, Polyphase Energy Metering
maintainers:
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
- The ADE9000 is a highly accurate, fully integrated, multiphase energy and power
- quality monitoring device. Superior analog performance and a digital signal
- processing (DSP) core enable accurate energy monitoring over a wide dynamic
- range. An integrated high end reference ensures low drift over temperature
- with a combined drift of less than ±25 ppm/°C maximum for the entire channel
- including a programmable gain amplifier (PGA) and an analog-to-digital
- converter (ADC).
+ The ADE9000 and ADE9078 are highly accurate, fully integrated, multiphase
+ energy and power quality monitoring devices. Superior analog performance and a
+ digital signal processing (DSP) core enable accurate energy monitoring over a
+ wide dynamic range. An integrated high end reference ensures low drift over
+ temperature with a combined drift of less than ±25 ppm/°C maximum for the
+ entire channel including a programmable gain amplifier (PGA) and an
+ analog-to-digital converter (ADC). The ADE9078 does not provide the on-chip
+ dip/swell detection available on the ADE9000.
https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9000.pdf
+ https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9078.pdf
$ref: /schemas/spi/spi-peripheral-props.yaml#
@@ -27,6 +29,7 @@ properties:
compatible:
enum:
- adi,ade9000
+ - adi,ade9078
reg:
maxItems: 1
@@ -67,6 +70,17 @@ required:
- reg
- vdd-supply
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: adi,ade9078
+ then:
+ properties:
+ spi-max-frequency:
+ maximum: 10000000
+
unevaluatedProperties: false
examples:
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] iio: adc: ade9000: add support for ADE9078
2026-07-20 11:07 [PATCH 0/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 1/4] iio: adc: ade9000: introduce chip_info structure Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 2/4] dt-bindings: iio: adc: adi,ade9000: add adi,ade9078 compatible Antoniu Miclaus
@ 2026-07-20 11:07 ` Antoniu Miclaus
2026-07-20 11:22 ` sashiko-bot
2026-07-20 11:07 ` [PATCH 4/4] docs: iio: ade9000: document ADE9078 support Antoniu Miclaus
3 siblings, 1 reply; 6+ messages in thread
From: Antoniu Miclaus @ 2026-07-20 11:07 UTC (permalink / raw)
To: Antoniu Miclaus, Nuno Sá, Michael Hennerich,
Jonathan Cameron, David Lechner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet, Shuah Khan, Marcelo Schmitt,
Radu Sabau, Jorge Marques, Matti Vaittinen, Jonathan Santos,
Jishnu Prakash, linux-iio, linux, devicetree, linux-kernel,
linux-doc
The ADE9078 is a polyphase energy metering device that is register
compatible with the ADE9000. The main differences relevant to the driver
are the absence of the on-chip dip/swell detection and slightly different
full-scale ADC codes.
Add a dedicated channel table that omits the swell/dip voltage events and
a matching chip_info describing the ADE9078 full-scale codes. The RMS
voltage channel macro is split into a shared base and two variants so the
event-less table can reuse the common definition.
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
drivers/iio/adc/Kconfig | 14 ++---
drivers/iio/adc/ade9000.c | 121 +++++++++++++++++++++++++-------------
2 files changed, 86 insertions(+), 49 deletions(-)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index d1b198cb8a80..33f2c281b1aa 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -573,20 +573,20 @@ config AD9467
called ad9467.
config ADE9000
- tristate "Analog Devices ADE9000 Multiphase Energy, and Power Quality Monitoring IC Driver"
+ tristate "Analog Devices ADE9000/ADE9078 Multiphase Energy, and Power Quality Monitoring IC Driver"
depends on SPI
select REGMAP_SPI
select IIO_BUFFER
select IIO_KFIFO_BUF
help
- Say yes here to build support for the Analog Devices ADE9000,
- a highly accurate, multiphase energy and power quality monitoring
- integrated circuit.
+ Say yes here to build support for the Analog Devices ADE9000 and
+ ADE9078, highly accurate, multiphase energy and power quality
+ monitoring integrated circuits.
- The device features high-precision analog-to-digital converters
+ The devices feature high-precision analog-to-digital converters
and digital signal processing to compute RMS values, power factor,
- frequency, and harmonic analysis. It supports SPI communication
- and provides buffered data output through the IIO framework.
+ frequency, and harmonic analysis. They support SPI communication
+ and provide buffered data output through the IIO framework.
To compile this driver as a module, choose M here: the module will
be called ade9000.
diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c
index 38a5c7e043b3..0de55b7ad1ea 100644
--- a/drivers/iio/adc/ade9000.c
+++ b/drivers/iio/adc/ade9000.c
@@ -502,7 +502,7 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
.scan_index = -1 \
}
-#define ADE9000_ALTVOLTAGE_RMS_CHANNEL(num) { \
+#define ADE9000_ALTVOLTAGE_RMS_CHANNEL_BASE(num) \
.type = IIO_ALTVOLTAGE, \
.channel = num, \
.address = ADE9000_ADDR_ADJUST(ADE9000_REG_AVRMS, num), \
@@ -512,9 +512,18 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_CALIBBIAS), \
+ .scan_index = -1
+
+/* With swell/dip (sag) events - ADE9000 only */
+#define ADE9000_ALTVOLTAGE_RMS_CHANNEL(num) { \
+ ADE9000_ALTVOLTAGE_RMS_CHANNEL_BASE(num), \
.event_spec = ade9000_rms_voltage_events, \
.num_event_specs = ARRAY_SIZE(ade9000_rms_voltage_events), \
- .scan_index = -1 \
+}
+
+/* Without swell/dip events - parts lacking DIP_LVL/SWELL_LVL hardware */
+#define ADE9000_ALTVOLTAGE_RMS_CHANNEL_NO_EVENTS(num) { \
+ ADE9000_ALTVOLTAGE_RMS_CHANNEL_BASE(num), \
}
#define ADE9000_POWER_ACTIVE_CHANNEL(num) { \
@@ -598,48 +607,65 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
.scan_index = -1 \
}
-static const struct iio_chan_spec ade9000_channels[] = {
- /* Phase A channels */
- ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_A_NR),
- ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_A_NR),
- ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_A_NR),
- ADE9000_ALTVOLTAGE_RMS_CHANNEL(ADE9000_PHASE_A_NR),
- ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR),
- ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR),
- ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_A_NR),
- ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR, ADE9000_REG_AWATTHR_LO),
- ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_A_NR, ADE9000_REG_AVAHR_LO),
- ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR, ADE9000_REG_AFVARHR_LO),
- ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_A_NR),
- /* Phase B channels */
- ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_B_NR),
- ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_B_NR),
- ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_B_NR),
- ADE9000_ALTVOLTAGE_RMS_CHANNEL(ADE9000_PHASE_B_NR),
- ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR),
- ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR),
- ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_B_NR),
- ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR, ADE9000_REG_BWATTHR_LO),
- ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_B_NR, ADE9000_REG_BVAHR_LO),
- ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR, ADE9000_REG_BFVARHR_LO),
- ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_B_NR),
- /* Phase C channels */
- ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_C_NR),
- ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_C_NR),
- ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_C_NR),
- ADE9000_ALTVOLTAGE_RMS_CHANNEL(ADE9000_PHASE_C_NR),
- ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR),
- ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR),
- ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_C_NR),
- ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR, ADE9000_REG_CWATTHR_LO),
- ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_C_NR, ADE9000_REG_CVAHR_LO),
- ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR, ADE9000_REG_CFVARHR_LO),
- ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_C_NR),
-};
+/*
+ * Declare a full channel array. @altvoltage_rms picks the RMS voltage channel
+ * variant so parts without dip/swell hardware (e.g. ADE9078) omit those events.
+ */
+#define ADE9000_DECLARE_CHANNELS(_name, altvoltage_rms) \
+ static const struct iio_chan_spec _name[] = { \
+ /* Phase A channels */ \
+ ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_A_NR), \
+ ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_A_NR), \
+ ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_A_NR), \
+ altvoltage_rms(ADE9000_PHASE_A_NR), \
+ ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR), \
+ ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR), \
+ ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_A_NR), \
+ ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR, \
+ ADE9000_REG_AWATTHR_LO), \
+ ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_A_NR, \
+ ADE9000_REG_AVAHR_LO), \
+ ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR, \
+ ADE9000_REG_AFVARHR_LO), \
+ ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_A_NR), \
+ /* Phase B channels */ \
+ ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_B_NR), \
+ ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_B_NR), \
+ ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_B_NR), \
+ altvoltage_rms(ADE9000_PHASE_B_NR), \
+ ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR), \
+ ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR), \
+ ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_B_NR), \
+ ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR, \
+ ADE9000_REG_BWATTHR_LO), \
+ ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_B_NR, \
+ ADE9000_REG_BVAHR_LO), \
+ ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR, \
+ ADE9000_REG_BFVARHR_LO), \
+ ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_B_NR), \
+ /* Phase C channels */ \
+ ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_C_NR), \
+ ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_C_NR), \
+ ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_C_NR), \
+ altvoltage_rms(ADE9000_PHASE_C_NR), \
+ ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR), \
+ ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR), \
+ ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_C_NR), \
+ ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR, \
+ ADE9000_REG_CWATTHR_LO), \
+ ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_C_NR, \
+ ADE9000_REG_CVAHR_LO), \
+ ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR, \
+ ADE9000_REG_CFVARHR_LO), \
+ ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_C_NR), \
+ }
+
+ADE9000_DECLARE_CHANNELS(ade9000_channels, ADE9000_ALTVOLTAGE_RMS_CHANNEL);
+ADE9000_DECLARE_CHANNELS(ade9078_channels, ADE9000_ALTVOLTAGE_RMS_CHANNEL_NO_EVENTS);
/*
- * Full-scale codes referred from the datasheet. These are the digital codes
- * produced when the ADC inputs are at full scale.
+ * Full-scale codes referred from the respective datasheets. These are the
+ * digital codes produced when the ADC inputs are at full scale.
*/
static const struct ade9000_chip_info ade9000_chip_info = {
.name = "ade9000",
@@ -650,6 +676,15 @@ static const struct ade9000_chip_info ade9000_chip_info = {
.pcf_full_scale_codes = 74770000,
};
+static const struct ade9000_chip_info ade9078_chip_info = {
+ .name = "ade9078",
+ .channels = ade9078_channels,
+ .num_channels = ARRAY_SIZE(ade9078_channels),
+ .rms_full_scale_codes = 52866837,
+ .watt_full_scale_codes = 20823646,
+ .pcf_full_scale_codes = 74680000,
+};
+
static const struct reg_sequence ade9000_initialization_sequence[] = {
{ ADE9000_REG_PGA_GAIN, ADE9000_PGA_GAIN },
{ ADE9000_REG_CONFIG0, ADE9000_CONFIG0 },
@@ -1800,12 +1835,14 @@ static int ade9000_probe(struct spi_device *spi)
static const struct spi_device_id ade9000_id[] = {
{ .name = "ade9000", .driver_data = (kernel_ulong_t)&ade9000_chip_info },
+ { .name = "ade9078", .driver_data = (kernel_ulong_t)&ade9078_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ade9000_id);
static const struct of_device_id ade9000_of_match[] = {
{ .compatible = "adi,ade9000", .data = &ade9000_chip_info },
+ { .compatible = "adi,ade9078", .data = &ade9078_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ade9000_of_match);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] docs: iio: ade9000: document ADE9078 support
2026-07-20 11:07 [PATCH 0/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
` (2 preceding siblings ...)
2026-07-20 11:07 ` [PATCH 3/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
@ 2026-07-20 11:07 ` Antoniu Miclaus
3 siblings, 0 replies; 6+ messages in thread
From: Antoniu Miclaus @ 2026-07-20 11:07 UTC (permalink / raw)
To: Antoniu Miclaus, Nuno Sá, Michael Hennerich,
Jonathan Cameron, David Lechner, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jonathan Corbet, Shuah Khan, Marcelo Schmitt,
Radu Sabau, Jorge Marques, Matti Vaittinen, Jonathan Santos,
Jishnu Prakash, linux-iio, linux, devicetree, linux-kernel,
linux-doc
Add the ADE9078 to the list of supported devices and note that the
dip/swell voltage events are only available on the ADE9000.
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
---
Documentation/iio/ade9000.rst | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/Documentation/iio/ade9000.rst b/Documentation/iio/ade9000.rst
index c9ff702a4251..72737b5ec59c 100644
--- a/Documentation/iio/ade9000.rst
+++ b/Documentation/iio/ade9000.rst
@@ -1,24 +1,30 @@
.. SPDX-License-Identifier: GPL-2.0
-===============
-ADE9000 driver
-===============
+======================
+ADE9000/ADE9078 driver
+======================
-This driver supports Analog Device's ADE9000 energy measurement IC on SPI bus.
+This driver supports Analog Device's ADE9000 and ADE9078 energy measurement
+ICs on SPI bus.
1. Supported devices
====================
* `ADE9000 <https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9000.pdf>`_
-
-The ADE9000 is a highly accurate, fully integrated, multiphase energy and power
-quality monitoring device. Superior analog performance and a digital signal
-processing (DSP) core enable accurate energy monitoring over a wide dynamic
-range. An integrated high end reference ensures low drift over temperature
-with a combined drift of less than ±25 ppm/°C maximum for the entire channel
-including a programmable gain amplifier (PGA) and an analog-to-digital
+* `ADE9078 <https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9078.pdf>`_
+
+The ADE9000 and ADE9078 are highly accurate, fully integrated, multiphase energy
+and power quality monitoring devices. Superior analog performance and a digital
+signal processing (DSP) core enable accurate energy monitoring over a wide
+dynamic range. An integrated high end reference ensures low drift over
+temperature with a combined drift of less than ±25 ppm/°C maximum for the entire
+channel including a programmable gain amplifier (PGA) and an analog-to-digital
converter (ADC).
+The ADE9078 does not provide the on-chip dip/swell (sag) detection available on
+the ADE9000, so the RMS voltage swell/dip events described below are only
+available on the ADE9000.
+
2. Device attributes
====================
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 3/4] iio: adc: ade9000: add support for ADE9078
2026-07-20 11:07 ` [PATCH 3/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
@ 2026-07-20 11:22 ` sashiko-bot
0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-07-20 11:22 UTC (permalink / raw)
To: Antoniu Miclaus; +Cc: conor+dt, robh, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Duplicate and overlapping `scan_index` values assigned to phase B and C channels break the IIO buffer subsystem.
--
--- Patch [3]: [PATCH 3/4] iio: adc: ade9000: add support for ADE9078 ---
commit b9467a190f2a74b5ff3993276ef11d90860fe13b
Author: Antoniu Miclaus <antoniu.miclaus@analog.com>
iio: adc: ade9000: add support for ADE9078
This commit adds support for the ADE9078 polyphase energy metering device,
which is register-compatible with the ADE9000 but lacks dip/swell detection.
It introduces a dedicated channel table to omit those events and adds matching
chip_info for the full-scale codes.
> diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c
> index 52ad87ef05d0c..0d5aa26f6667b 100644
> --- a/drivers/iio/adc/ade9000.c
> +++ b/drivers/iio/adc/ade9000.c
[ ... ]
> +#define ADE9000_DECLARE_CHANNELS(_name, altvoltage_rms) \
> + static const struct iio_chan_spec _name[] = { \
> + /* Phase A channels */ \
> + ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_A_NR), \
> + ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_A_NR), \
[ ... ]
> + /* Phase B channels */ \
> + ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_B_NR), \
> + ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_B_NR), \
[Severity: High]
This is a pre-existing issue, but does this channel declaration cause the
driver probe to fail during IIO device registration?
Looking at the channel macros in drivers/iio/adc/ade9000.c:
ADE9000_CURRENT_CHANNEL(num) sets .scan_index = num
ADE9000_VOLTAGE_CHANNEL(num) sets .scan_index = num + 1
With ADE9000_PHASE_A_NR (0) and ADE9000_PHASE_B_NR (1), Phase A's voltage
channel gets scan_index 1, which perfectly collides with Phase B's current
channel (also scan_index 1).
Since ade9000_probe() calls devm_iio_kfifo_buffer_setup(), the
INDIO_BUFFER_SOFTWARE mode flag is set. When devm_iio_device_register() is
called, the IIO core invokes iio_check_unique_scan_index(), detects the
duplicate scan_index, and unconditionally returns -EINVAL.
It looks like ade9000_waveform_buffer_config() expects Phase B Current to
map to BIT(2), so shouldn't these macros use num * 2 and num * 2 + 1
instead?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720110754.7674-1-antoniu.miclaus@analog.com?part=3
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-20 11:22 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-20 11:07 [PATCH 0/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 1/4] iio: adc: ade9000: introduce chip_info structure Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 2/4] dt-bindings: iio: adc: adi,ade9000: add adi,ade9078 compatible Antoniu Miclaus
2026-07-20 11:07 ` [PATCH 3/4] iio: adc: ade9000: add support for ADE9078 Antoniu Miclaus
2026-07-20 11:22 ` sashiko-bot
2026-07-20 11:07 ` [PATCH 4/4] docs: iio: ade9000: document ADE9078 support Antoniu Miclaus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox