2 * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver
4 * Copyright 2010 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/interrupt.h>
10 #include <linux/irq.h>
11 #include <linux/delay.h>
12 #include <linux/mutex.h>
13 #include <linux/device.h>
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/sysfs.h>
17 #include <linux/list.h>
18 #include <linux/module.h>
25 static ssize_t
ade7854_read_8bit(struct device
*dev
,
26 struct device_attribute
*attr
,
31 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
32 struct ade7854_state
*st
= iio_priv(indio_dev
);
33 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
35 ret
= st
->read_reg_8(dev
, this_attr
->address
, &val
);
39 return sprintf(buf
, "%u\n", val
);
42 static ssize_t
ade7854_read_16bit(struct device
*dev
,
43 struct device_attribute
*attr
,
48 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
49 struct ade7854_state
*st
= iio_priv(indio_dev
);
50 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
52 ret
= st
->read_reg_16(dev
, this_attr
->address
, &val
);
56 return sprintf(buf
, "%u\n", val
);
59 static ssize_t
ade7854_read_24bit(struct device
*dev
,
60 struct device_attribute
*attr
,
65 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
66 struct ade7854_state
*st
= iio_priv(indio_dev
);
67 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
69 ret
= st
->read_reg_24(dev
, this_attr
->address
, &val
);
73 return sprintf(buf
, "%u\n", val
);
76 static ssize_t
ade7854_read_32bit(struct device
*dev
,
77 struct device_attribute
*attr
,
82 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
83 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
84 struct ade7854_state
*st
= iio_priv(indio_dev
);
86 ret
= st
->read_reg_32(dev
, this_attr
->address
, &val
);
90 return sprintf(buf
, "%u\n", val
);
93 static ssize_t
ade7854_write_8bit(struct device
*dev
,
94 struct device_attribute
*attr
,
98 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
99 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
100 struct ade7854_state
*st
= iio_priv(indio_dev
);
105 ret
= strict_strtol(buf
, 10, &val
);
108 ret
= st
->write_reg_8(dev
, this_attr
->address
, val
);
111 return ret
? ret
: len
;
114 static ssize_t
ade7854_write_16bit(struct device
*dev
,
115 struct device_attribute
*attr
,
119 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
120 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
121 struct ade7854_state
*st
= iio_priv(indio_dev
);
126 ret
= strict_strtol(buf
, 10, &val
);
129 ret
= st
->write_reg_16(dev
, this_attr
->address
, val
);
132 return ret
? ret
: len
;
135 static ssize_t
ade7854_write_24bit(struct device
*dev
,
136 struct device_attribute
*attr
,
140 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
141 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
142 struct ade7854_state
*st
= iio_priv(indio_dev
);
147 ret
= strict_strtol(buf
, 10, &val
);
150 ret
= st
->write_reg_24(dev
, this_attr
->address
, val
);
153 return ret
? ret
: len
;
156 static ssize_t
ade7854_write_32bit(struct device
*dev
,
157 struct device_attribute
*attr
,
161 struct iio_dev_attr
*this_attr
= to_iio_dev_attr(attr
);
162 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
163 struct ade7854_state
*st
= iio_priv(indio_dev
);
168 ret
= strict_strtol(buf
, 10, &val
);
171 ret
= st
->write_reg_32(dev
, this_attr
->address
, val
);
174 return ret
? ret
: len
;
177 static int ade7854_reset(struct device
*dev
)
179 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
180 struct ade7854_state
*st
= iio_priv(indio_dev
);
183 st
->read_reg_16(dev
, ADE7854_CONFIG
, &val
);
184 val
|= 1 << 7; /* Software Chip Reset */
186 return st
->write_reg_16(dev
, ADE7854_CONFIG
, val
);
190 static ssize_t
ade7854_write_reset(struct device
*dev
,
191 struct device_attribute
*attr
,
192 const char *buf
, size_t len
)
200 return ade7854_reset(dev
);
205 static IIO_DEV_ATTR_AIGAIN(S_IWUSR
| S_IRUGO
,
209 static IIO_DEV_ATTR_BIGAIN(S_IWUSR
| S_IRUGO
,
213 static IIO_DEV_ATTR_CIGAIN(S_IWUSR
| S_IRUGO
,
217 static IIO_DEV_ATTR_NIGAIN(S_IWUSR
| S_IRUGO
,
221 static IIO_DEV_ATTR_AVGAIN(S_IWUSR
| S_IRUGO
,
225 static IIO_DEV_ATTR_BVGAIN(S_IWUSR
| S_IRUGO
,
229 static IIO_DEV_ATTR_CVGAIN(S_IWUSR
| S_IRUGO
,
233 static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(S_IWUSR
| S_IRUGO
,
237 static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(S_IWUSR
| S_IRUGO
,
241 static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(S_IWUSR
| S_IRUGO
,
245 static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(S_IWUSR
| S_IRUGO
,
249 static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(S_IWUSR
| S_IRUGO
,
253 static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(S_IWUSR
| S_IRUGO
,
257 static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(S_IWUSR
| S_IRUGO
,
261 static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(S_IWUSR
| S_IRUGO
,
265 static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(S_IWUSR
| S_IRUGO
,
269 static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(S_IWUSR
| S_IRUGO
,
273 static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(S_IWUSR
| S_IRUGO
,
277 static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(S_IWUSR
| S_IRUGO
,
281 static IIO_DEV_ATTR_VPEAK(S_IWUSR
| S_IRUGO
,
285 static IIO_DEV_ATTR_IPEAK(S_IWUSR
| S_IRUGO
,
289 static IIO_DEV_ATTR_APHCAL(S_IWUSR
| S_IRUGO
,
293 static IIO_DEV_ATTR_BPHCAL(S_IWUSR
| S_IRUGO
,
297 static IIO_DEV_ATTR_CPHCAL(S_IWUSR
| S_IRUGO
,
301 static IIO_DEV_ATTR_CF1DEN(S_IWUSR
| S_IRUGO
,
305 static IIO_DEV_ATTR_CF2DEN(S_IWUSR
| S_IRUGO
,
309 static IIO_DEV_ATTR_CF3DEN(S_IWUSR
| S_IRUGO
,
313 static IIO_DEV_ATTR_LINECYC(S_IWUSR
| S_IRUGO
,
317 static IIO_DEV_ATTR_SAGCYC(S_IWUSR
| S_IRUGO
,
321 static IIO_DEV_ATTR_CFCYC(S_IWUSR
| S_IRUGO
,
325 static IIO_DEV_ATTR_PEAKCYC(S_IWUSR
| S_IRUGO
,
329 static IIO_DEV_ATTR_CHKSUM(ade7854_read_24bit
,
331 static IIO_DEV_ATTR_ANGLE0(ade7854_read_24bit
,
333 static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit
,
335 static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit
,
337 static IIO_DEV_ATTR_AIRMS(S_IRUGO
,
341 static IIO_DEV_ATTR_BIRMS(S_IRUGO
,
345 static IIO_DEV_ATTR_CIRMS(S_IRUGO
,
349 static IIO_DEV_ATTR_NIRMS(S_IRUGO
,
353 static IIO_DEV_ATTR_AVRMS(S_IRUGO
,
357 static IIO_DEV_ATTR_BVRMS(S_IRUGO
,
361 static IIO_DEV_ATTR_CVRMS(S_IRUGO
,
365 static IIO_DEV_ATTR_AIRMSOS(S_IRUGO
,
369 static IIO_DEV_ATTR_BIRMSOS(S_IRUGO
,
373 static IIO_DEV_ATTR_CIRMSOS(S_IRUGO
,
377 static IIO_DEV_ATTR_AVRMSOS(S_IRUGO
,
381 static IIO_DEV_ATTR_BVRMSOS(S_IRUGO
,
385 static IIO_DEV_ATTR_CVRMSOS(S_IRUGO
,
389 static IIO_DEV_ATTR_VOLT_A(ade7854_read_24bit
,
391 static IIO_DEV_ATTR_VOLT_B(ade7854_read_24bit
,
393 static IIO_DEV_ATTR_VOLT_C(ade7854_read_24bit
,
395 static IIO_DEV_ATTR_CURRENT_A(ade7854_read_24bit
,
397 static IIO_DEV_ATTR_CURRENT_B(ade7854_read_24bit
,
399 static IIO_DEV_ATTR_CURRENT_C(ade7854_read_24bit
,
401 static IIO_DEV_ATTR_AWATTHR(ade7854_read_32bit
,
403 static IIO_DEV_ATTR_BWATTHR(ade7854_read_32bit
,
405 static IIO_DEV_ATTR_CWATTHR(ade7854_read_32bit
,
407 static IIO_DEV_ATTR_AFWATTHR(ade7854_read_32bit
,
409 static IIO_DEV_ATTR_BFWATTHR(ade7854_read_32bit
,
411 static IIO_DEV_ATTR_CFWATTHR(ade7854_read_32bit
,
413 static IIO_DEV_ATTR_AVARHR(ade7854_read_32bit
,
415 static IIO_DEV_ATTR_BVARHR(ade7854_read_32bit
,
417 static IIO_DEV_ATTR_CVARHR(ade7854_read_32bit
,
419 static IIO_DEV_ATTR_AVAHR(ade7854_read_32bit
,
421 static IIO_DEV_ATTR_BVAHR(ade7854_read_32bit
,
423 static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit
,
426 static int ade7854_set_irq(struct device
*dev
, bool enable
)
428 struct iio_dev
*indio_dev
= dev_get_drvdata(dev
);
429 struct ade7854_state
*st
= iio_priv(indio_dev
);
434 ret
= st
->read_reg_32(dev
, ADE7854_MASK0
, &irqen
);
439 irqen
|= 1 << 17; /* 1: interrupt enabled when all periodical
440 (at 8 kHz rate) DSP computations finish. */
444 ret
= st
->write_reg_32(dev
, ADE7854_MASK0
, irqen
);
452 static int ade7854_initial_setup(struct iio_dev
*indio_dev
)
455 struct device
*dev
= &indio_dev
->dev
;
458 ret
= ade7854_set_irq(dev
, false);
460 dev_err(dev
, "disable irq failed");
465 msleep(ADE7854_STARTUP_DELAY
);
471 static IIO_DEV_ATTR_RESET(ade7854_write_reset
);
473 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000");
475 static IIO_CONST_ATTR(name
, "ade7854");
477 static struct attribute
*ade7854_attributes
[] = {
478 &iio_dev_attr_aigain
.dev_attr
.attr
,
479 &iio_dev_attr_bigain
.dev_attr
.attr
,
480 &iio_dev_attr_cigain
.dev_attr
.attr
,
481 &iio_dev_attr_nigain
.dev_attr
.attr
,
482 &iio_dev_attr_avgain
.dev_attr
.attr
,
483 &iio_dev_attr_bvgain
.dev_attr
.attr
,
484 &iio_dev_attr_cvgain
.dev_attr
.attr
,
485 &iio_dev_attr_linecyc
.dev_attr
.attr
,
486 &iio_dev_attr_sagcyc
.dev_attr
.attr
,
487 &iio_dev_attr_cfcyc
.dev_attr
.attr
,
488 &iio_dev_attr_peakcyc
.dev_attr
.attr
,
489 &iio_dev_attr_chksum
.dev_attr
.attr
,
490 &iio_dev_attr_apparent_power_a_gain
.dev_attr
.attr
,
491 &iio_dev_attr_apparent_power_b_gain
.dev_attr
.attr
,
492 &iio_dev_attr_apparent_power_c_gain
.dev_attr
.attr
,
493 &iio_dev_attr_active_power_a_offset
.dev_attr
.attr
,
494 &iio_dev_attr_active_power_b_offset
.dev_attr
.attr
,
495 &iio_dev_attr_active_power_c_offset
.dev_attr
.attr
,
496 &iio_dev_attr_reactive_power_a_gain
.dev_attr
.attr
,
497 &iio_dev_attr_reactive_power_b_gain
.dev_attr
.attr
,
498 &iio_dev_attr_reactive_power_c_gain
.dev_attr
.attr
,
499 &iio_dev_attr_reactive_power_a_offset
.dev_attr
.attr
,
500 &iio_dev_attr_reactive_power_b_offset
.dev_attr
.attr
,
501 &iio_dev_attr_reactive_power_c_offset
.dev_attr
.attr
,
502 &iio_dev_attr_awatthr
.dev_attr
.attr
,
503 &iio_dev_attr_bwatthr
.dev_attr
.attr
,
504 &iio_dev_attr_cwatthr
.dev_attr
.attr
,
505 &iio_dev_attr_afwatthr
.dev_attr
.attr
,
506 &iio_dev_attr_bfwatthr
.dev_attr
.attr
,
507 &iio_dev_attr_cfwatthr
.dev_attr
.attr
,
508 &iio_dev_attr_avarhr
.dev_attr
.attr
,
509 &iio_dev_attr_bvarhr
.dev_attr
.attr
,
510 &iio_dev_attr_cvarhr
.dev_attr
.attr
,
511 &iio_dev_attr_angle0
.dev_attr
.attr
,
512 &iio_dev_attr_angle1
.dev_attr
.attr
,
513 &iio_dev_attr_angle2
.dev_attr
.attr
,
514 &iio_dev_attr_avahr
.dev_attr
.attr
,
515 &iio_dev_attr_bvahr
.dev_attr
.attr
,
516 &iio_dev_attr_cvahr
.dev_attr
.attr
,
517 &iio_const_attr_sampling_frequency_available
.dev_attr
.attr
,
518 &iio_dev_attr_reset
.dev_attr
.attr
,
519 &iio_const_attr_name
.dev_attr
.attr
,
520 &iio_dev_attr_vpeak
.dev_attr
.attr
,
521 &iio_dev_attr_ipeak
.dev_attr
.attr
,
522 &iio_dev_attr_aphcal
.dev_attr
.attr
,
523 &iio_dev_attr_bphcal
.dev_attr
.attr
,
524 &iio_dev_attr_cphcal
.dev_attr
.attr
,
525 &iio_dev_attr_cf1den
.dev_attr
.attr
,
526 &iio_dev_attr_cf2den
.dev_attr
.attr
,
527 &iio_dev_attr_cf3den
.dev_attr
.attr
,
528 &iio_dev_attr_airms
.dev_attr
.attr
,
529 &iio_dev_attr_birms
.dev_attr
.attr
,
530 &iio_dev_attr_cirms
.dev_attr
.attr
,
531 &iio_dev_attr_nirms
.dev_attr
.attr
,
532 &iio_dev_attr_avrms
.dev_attr
.attr
,
533 &iio_dev_attr_bvrms
.dev_attr
.attr
,
534 &iio_dev_attr_cvrms
.dev_attr
.attr
,
535 &iio_dev_attr_airmsos
.dev_attr
.attr
,
536 &iio_dev_attr_birmsos
.dev_attr
.attr
,
537 &iio_dev_attr_cirmsos
.dev_attr
.attr
,
538 &iio_dev_attr_avrmsos
.dev_attr
.attr
,
539 &iio_dev_attr_bvrmsos
.dev_attr
.attr
,
540 &iio_dev_attr_cvrmsos
.dev_attr
.attr
,
541 &iio_dev_attr_volt_a
.dev_attr
.attr
,
542 &iio_dev_attr_volt_b
.dev_attr
.attr
,
543 &iio_dev_attr_volt_c
.dev_attr
.attr
,
544 &iio_dev_attr_current_a
.dev_attr
.attr
,
545 &iio_dev_attr_current_b
.dev_attr
.attr
,
546 &iio_dev_attr_current_c
.dev_attr
.attr
,
550 static const struct attribute_group ade7854_attribute_group
= {
551 .attrs
= ade7854_attributes
,
554 static const struct iio_info ade7854_info
= {
555 .attrs
= &ade7854_attribute_group
,
556 .driver_module
= THIS_MODULE
,
559 int ade7854_probe(struct iio_dev
*indio_dev
, struct device
*dev
)
562 struct ade7854_state
*st
= iio_priv(indio_dev
);
563 /* setup the industrialio driver allocated elements */
564 mutex_init(&st
->buf_lock
);
566 indio_dev
->dev
.parent
= dev
;
567 indio_dev
->info
= &ade7854_info
;
568 indio_dev
->modes
= INDIO_DIRECT_MODE
;
570 ret
= iio_device_register(indio_dev
);
574 /* Get the device into a sane initial state */
575 ret
= ade7854_initial_setup(indio_dev
);
577 goto error_unreg_dev
;
582 iio_device_unregister(indio_dev
);
584 iio_free_device(indio_dev
);
588 EXPORT_SYMBOL(ade7854_probe
);
590 int ade7854_remove(struct iio_dev
*indio_dev
)
592 iio_device_unregister(indio_dev
);
593 iio_free_device(indio_dev
);
597 EXPORT_SYMBOL(ade7854_remove
);
599 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
600 MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Energy Meter");
601 MODULE_LICENSE("GPL v2");