1 // SPDX-License-Identifier: GPL-2.0+
3 * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver
5 * Copyright 2010 Analog Devices Inc.
8 #include <linux/interrupt.h>
10 #include <linux/delay.h>
11 #include <linux/mutex.h>
12 #include <linux/device.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/sysfs.h>
16 #include <linux/list.h>
17 #include <linux/module.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
24 static ssize_t ade7854_read_8bit(struct device *dev,
25 struct device_attribute *attr,
30 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
31 struct ade7854_state *st = iio_priv(indio_dev);
32 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
34 ret = st->read_reg(dev, this_attr->address, &val, 8);
38 return sprintf(buf, "%u\n", val);
41 static ssize_t ade7854_read_16bit(struct device *dev,
42 struct device_attribute *attr,
47 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
48 struct ade7854_state *st = iio_priv(indio_dev);
49 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
51 ret = st->read_reg(dev, this_attr->address, &val, 16);
55 return sprintf(buf, "%u\n", val);
58 static ssize_t ade7854_read_24bit(struct device *dev,
59 struct device_attribute *attr,
64 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
65 struct ade7854_state *st = iio_priv(indio_dev);
66 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
68 ret = st->read_reg(dev, this_attr->address, &val, 24);
72 return sprintf(buf, "%u\n", val);
75 static ssize_t ade7854_read_32bit(struct device *dev,
76 struct device_attribute *attr,
81 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
82 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
83 struct ade7854_state *st = iio_priv(indio_dev);
85 ret = st->read_reg(dev, this_attr->address, &val, 32);
89 return sprintf(buf, "%u\n", val);
92 static ssize_t ade7854_write_8bit(struct device *dev,
93 struct device_attribute *attr,
97 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
98 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
99 struct ade7854_state *st = iio_priv(indio_dev);
104 ret = kstrtou8(buf, 10, &val);
107 ret = st->write_reg(dev, this_attr->address, val, 8);
110 return ret ? ret : len;
113 static ssize_t ade7854_write_16bit(struct device *dev,
114 struct device_attribute *attr,
118 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
119 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
120 struct ade7854_state *st = iio_priv(indio_dev);
125 ret = kstrtou16(buf, 10, &val);
128 ret = st->write_reg(dev, this_attr->address, val, 16);
131 return ret ? ret : len;
134 static ssize_t ade7854_write_24bit(struct device *dev,
135 struct device_attribute *attr,
139 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
140 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
141 struct ade7854_state *st = iio_priv(indio_dev);
146 ret = kstrtou32(buf, 10, &val);
149 ret = st->write_reg(dev, this_attr->address, val, 24);
152 return ret ? ret : len;
155 static ssize_t ade7854_write_32bit(struct device *dev,
156 struct device_attribute *attr,
160 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
161 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
162 struct ade7854_state *st = iio_priv(indio_dev);
167 ret = kstrtou32(buf, 10, &val);
170 ret = st->write_reg(dev, this_attr->address, val, 32);
173 return ret ? ret : len;
176 static int ade7854_reset(struct device *dev)
178 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
179 struct ade7854_state *st = iio_priv(indio_dev);
182 st->read_reg(dev, ADE7854_CONFIG, &val, 16);
183 val |= BIT(7); /* Software Chip Reset */
185 return st->write_reg(dev, ADE7854_CONFIG, val, 16);
188 static IIO_DEV_ATTR_AIGAIN(0644,
192 static IIO_DEV_ATTR_BIGAIN(0644,
196 static IIO_DEV_ATTR_CIGAIN(0644,
200 static IIO_DEV_ATTR_NIGAIN(0644,
204 static IIO_DEV_ATTR_AVGAIN(0644,
208 static IIO_DEV_ATTR_BVGAIN(0644,
212 static IIO_DEV_ATTR_CVGAIN(0644,
216 static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(0644,
220 static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(0644,
224 static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(0644,
228 static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(0644,
232 static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(0644,
236 static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(0644,
240 static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(0644,
244 static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(0644,
248 static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(0644,
252 static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(0644,
256 static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(0644,
260 static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(0644,
264 static IIO_DEV_ATTR_VPEAK(0644,
268 static IIO_DEV_ATTR_IPEAK(0644,
272 static IIO_DEV_ATTR_APHCAL(0644,
276 static IIO_DEV_ATTR_BPHCAL(0644,
280 static IIO_DEV_ATTR_CPHCAL(0644,
284 static IIO_DEV_ATTR_CF1DEN(0644,
288 static IIO_DEV_ATTR_CF2DEN(0644,
292 static IIO_DEV_ATTR_CF3DEN(0644,
296 static IIO_DEV_ATTR_LINECYC(0644,
300 static IIO_DEV_ATTR_SAGCYC(0644,
304 static IIO_DEV_ATTR_CFCYC(0644,
308 static IIO_DEV_ATTR_PEAKCYC(0644,
312 static IIO_DEV_ATTR_CHKSUM(ade7854_read_24bit,
314 static IIO_DEV_ATTR_ANGLE0(ade7854_read_24bit,
316 static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit,
318 static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit,
320 static IIO_DEV_ATTR_AIRMS(0444,
324 static IIO_DEV_ATTR_BIRMS(0444,
328 static IIO_DEV_ATTR_CIRMS(0444,
332 static IIO_DEV_ATTR_NIRMS(0444,
336 static IIO_DEV_ATTR_AVRMS(0444,
340 static IIO_DEV_ATTR_BVRMS(0444,
344 static IIO_DEV_ATTR_CVRMS(0444,
348 static IIO_DEV_ATTR_AIRMSOS(0444,
352 static IIO_DEV_ATTR_BIRMSOS(0444,
356 static IIO_DEV_ATTR_CIRMSOS(0444,
360 static IIO_DEV_ATTR_AVRMSOS(0444,
364 static IIO_DEV_ATTR_BVRMSOS(0444,
368 static IIO_DEV_ATTR_CVRMSOS(0444,
372 static IIO_DEV_ATTR_VOLT_A(ade7854_read_24bit,
374 static IIO_DEV_ATTR_VOLT_B(ade7854_read_24bit,
376 static IIO_DEV_ATTR_VOLT_C(ade7854_read_24bit,
378 static IIO_DEV_ATTR_CURRENT_A(ade7854_read_24bit,
380 static IIO_DEV_ATTR_CURRENT_B(ade7854_read_24bit,
382 static IIO_DEV_ATTR_CURRENT_C(ade7854_read_24bit,
384 static IIO_DEV_ATTR_AWATTHR(ade7854_read_32bit,
386 static IIO_DEV_ATTR_BWATTHR(ade7854_read_32bit,
388 static IIO_DEV_ATTR_CWATTHR(ade7854_read_32bit,
390 static IIO_DEV_ATTR_AFWATTHR(ade7854_read_32bit,
392 static IIO_DEV_ATTR_BFWATTHR(ade7854_read_32bit,
394 static IIO_DEV_ATTR_CFWATTHR(ade7854_read_32bit,
396 static IIO_DEV_ATTR_AVARHR(ade7854_read_32bit,
398 static IIO_DEV_ATTR_BVARHR(ade7854_read_32bit,
400 static IIO_DEV_ATTR_CVARHR(ade7854_read_32bit,
402 static IIO_DEV_ATTR_AVAHR(ade7854_read_32bit,
404 static IIO_DEV_ATTR_BVAHR(ade7854_read_32bit,
406 static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit,
409 static int ade7854_set_irq(struct device *dev, bool enable)
411 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
412 struct ade7854_state *st = iio_priv(indio_dev);
417 ret = st->read_reg(dev, ADE7854_MASK0, &irqen, 32);
422 irqen |= BIT(17); /* 1: interrupt enabled when all periodical
423 * (at 8 kHz rate) DSP computations finish.
428 return st->write_reg(dev, ADE7854_MASK0, irqen, 32);
431 static int ade7854_initial_setup(struct iio_dev *indio_dev)
434 struct device *dev = &indio_dev->dev;
437 ret = ade7854_set_irq(dev, false);
439 dev_err(dev, "disable irq failed");
444 usleep_range(ADE7854_STARTUP_DELAY, ADE7854_STARTUP_DELAY + 100);
450 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000");
452 static IIO_CONST_ATTR(name, "ade7854");
454 static struct attribute *ade7854_attributes[] = {
455 &iio_dev_attr_aigain.dev_attr.attr,
456 &iio_dev_attr_bigain.dev_attr.attr,
457 &iio_dev_attr_cigain.dev_attr.attr,
458 &iio_dev_attr_nigain.dev_attr.attr,
459 &iio_dev_attr_avgain.dev_attr.attr,
460 &iio_dev_attr_bvgain.dev_attr.attr,
461 &iio_dev_attr_cvgain.dev_attr.attr,
462 &iio_dev_attr_linecyc.dev_attr.attr,
463 &iio_dev_attr_sagcyc.dev_attr.attr,
464 &iio_dev_attr_cfcyc.dev_attr.attr,
465 &iio_dev_attr_peakcyc.dev_attr.attr,
466 &iio_dev_attr_chksum.dev_attr.attr,
467 &iio_dev_attr_apparent_power_a_gain.dev_attr.attr,
468 &iio_dev_attr_apparent_power_b_gain.dev_attr.attr,
469 &iio_dev_attr_apparent_power_c_gain.dev_attr.attr,
470 &iio_dev_attr_active_power_a_offset.dev_attr.attr,
471 &iio_dev_attr_active_power_b_offset.dev_attr.attr,
472 &iio_dev_attr_active_power_c_offset.dev_attr.attr,
473 &iio_dev_attr_reactive_power_a_gain.dev_attr.attr,
474 &iio_dev_attr_reactive_power_b_gain.dev_attr.attr,
475 &iio_dev_attr_reactive_power_c_gain.dev_attr.attr,
476 &iio_dev_attr_reactive_power_a_offset.dev_attr.attr,
477 &iio_dev_attr_reactive_power_b_offset.dev_attr.attr,
478 &iio_dev_attr_reactive_power_c_offset.dev_attr.attr,
479 &iio_dev_attr_awatthr.dev_attr.attr,
480 &iio_dev_attr_bwatthr.dev_attr.attr,
481 &iio_dev_attr_cwatthr.dev_attr.attr,
482 &iio_dev_attr_afwatthr.dev_attr.attr,
483 &iio_dev_attr_bfwatthr.dev_attr.attr,
484 &iio_dev_attr_cfwatthr.dev_attr.attr,
485 &iio_dev_attr_avarhr.dev_attr.attr,
486 &iio_dev_attr_bvarhr.dev_attr.attr,
487 &iio_dev_attr_cvarhr.dev_attr.attr,
488 &iio_dev_attr_angle0.dev_attr.attr,
489 &iio_dev_attr_angle1.dev_attr.attr,
490 &iio_dev_attr_angle2.dev_attr.attr,
491 &iio_dev_attr_avahr.dev_attr.attr,
492 &iio_dev_attr_bvahr.dev_attr.attr,
493 &iio_dev_attr_cvahr.dev_attr.attr,
494 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
495 &iio_const_attr_name.dev_attr.attr,
496 &iio_dev_attr_vpeak.dev_attr.attr,
497 &iio_dev_attr_ipeak.dev_attr.attr,
498 &iio_dev_attr_aphcal.dev_attr.attr,
499 &iio_dev_attr_bphcal.dev_attr.attr,
500 &iio_dev_attr_cphcal.dev_attr.attr,
501 &iio_dev_attr_cf1den.dev_attr.attr,
502 &iio_dev_attr_cf2den.dev_attr.attr,
503 &iio_dev_attr_cf3den.dev_attr.attr,
504 &iio_dev_attr_airms.dev_attr.attr,
505 &iio_dev_attr_birms.dev_attr.attr,
506 &iio_dev_attr_cirms.dev_attr.attr,
507 &iio_dev_attr_nirms.dev_attr.attr,
508 &iio_dev_attr_avrms.dev_attr.attr,
509 &iio_dev_attr_bvrms.dev_attr.attr,
510 &iio_dev_attr_cvrms.dev_attr.attr,
511 &iio_dev_attr_airmsos.dev_attr.attr,
512 &iio_dev_attr_birmsos.dev_attr.attr,
513 &iio_dev_attr_cirmsos.dev_attr.attr,
514 &iio_dev_attr_avrmsos.dev_attr.attr,
515 &iio_dev_attr_bvrmsos.dev_attr.attr,
516 &iio_dev_attr_cvrmsos.dev_attr.attr,
517 &iio_dev_attr_volt_a.dev_attr.attr,
518 &iio_dev_attr_volt_b.dev_attr.attr,
519 &iio_dev_attr_volt_c.dev_attr.attr,
520 &iio_dev_attr_current_a.dev_attr.attr,
521 &iio_dev_attr_current_b.dev_attr.attr,
522 &iio_dev_attr_current_c.dev_attr.attr,
526 static const struct attribute_group ade7854_attribute_group = {
527 .attrs = ade7854_attributes,
530 static const struct iio_info ade7854_info = {
531 .attrs = &ade7854_attribute_group,
534 int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
537 struct ade7854_state *st = iio_priv(indio_dev);
538 /* setup the industrialio driver allocated elements */
539 mutex_init(&st->buf_lock);
541 indio_dev->dev.parent = dev;
542 indio_dev->info = &ade7854_info;
543 indio_dev->modes = INDIO_DIRECT_MODE;
545 ret = devm_iio_device_register(dev, indio_dev);
549 /* Get the device into a sane initial state */
550 return ade7854_initial_setup(indio_dev);
552 EXPORT_SYMBOL(ade7854_probe);
555 MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Energy Meter");
556 MODULE_LICENSE("GPL v2");