Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ade7854.c
Go to the documentation of this file.
1 /*
2  * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver
3  *
4  * Copyright 2010 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8 
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>
19 
20 #include <linux/iio/iio.h>
21 #include <linux/iio/sysfs.h>
22 #include "meter.h"
23 #include "ade7854.h"
24 
25 static ssize_t ade7854_read_8bit(struct device *dev,
26  struct device_attribute *attr,
27  char *buf)
28 {
29  int ret;
30  u8 val = 0;
31  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
32  struct ade7854_state *st = iio_priv(indio_dev);
33  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
34 
35  ret = st->read_reg_8(dev, this_attr->address, &val);
36  if (ret)
37  return ret;
38 
39  return sprintf(buf, "%u\n", val);
40 }
41 
42 static ssize_t ade7854_read_16bit(struct device *dev,
43  struct device_attribute *attr,
44  char *buf)
45 {
46  int ret;
47  u16 val = 0;
48  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
49  struct ade7854_state *st = iio_priv(indio_dev);
50  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
51 
52  ret = st->read_reg_16(dev, this_attr->address, &val);
53  if (ret)
54  return ret;
55 
56  return sprintf(buf, "%u\n", val);
57 }
58 
59 static ssize_t ade7854_read_24bit(struct device *dev,
60  struct device_attribute *attr,
61  char *buf)
62 {
63  int ret;
64  u32 val;
65  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
66  struct ade7854_state *st = iio_priv(indio_dev);
67  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
68 
69  ret = st->read_reg_24(dev, this_attr->address, &val);
70  if (ret)
71  return ret;
72 
73  return sprintf(buf, "%u\n", val);
74 }
75 
76 static ssize_t ade7854_read_32bit(struct device *dev,
77  struct device_attribute *attr,
78  char *buf)
79 {
80  int ret;
81  u32 val = 0;
82  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
83  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
84  struct ade7854_state *st = iio_priv(indio_dev);
85 
86  ret = st->read_reg_32(dev, this_attr->address, &val);
87  if (ret)
88  return ret;
89 
90  return sprintf(buf, "%u\n", val);
91 }
92 
93 static ssize_t ade7854_write_8bit(struct device *dev,
94  struct device_attribute *attr,
95  const char *buf,
96  size_t len)
97 {
98  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
99  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
100  struct ade7854_state *st = iio_priv(indio_dev);
101 
102  int ret;
103  long val;
104 
105  ret = strict_strtol(buf, 10, &val);
106  if (ret)
107  goto error_ret;
108  ret = st->write_reg_8(dev, this_attr->address, val);
109 
110 error_ret:
111  return ret ? ret : len;
112 }
113 
114 static ssize_t ade7854_write_16bit(struct device *dev,
115  struct device_attribute *attr,
116  const char *buf,
117  size_t len)
118 {
119  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
120  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
121  struct ade7854_state *st = iio_priv(indio_dev);
122 
123  int ret;
124  long val;
125 
126  ret = strict_strtol(buf, 10, &val);
127  if (ret)
128  goto error_ret;
129  ret = st->write_reg_16(dev, this_attr->address, val);
130 
131 error_ret:
132  return ret ? ret : len;
133 }
134 
135 static ssize_t ade7854_write_24bit(struct device *dev,
136  struct device_attribute *attr,
137  const char *buf,
138  size_t len)
139 {
140  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
141  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
142  struct ade7854_state *st = iio_priv(indio_dev);
143 
144  int ret;
145  long val;
146 
147  ret = strict_strtol(buf, 10, &val);
148  if (ret)
149  goto error_ret;
150  ret = st->write_reg_24(dev, this_attr->address, val);
151 
152 error_ret:
153  return ret ? ret : len;
154 }
155 
156 static ssize_t ade7854_write_32bit(struct device *dev,
157  struct device_attribute *attr,
158  const char *buf,
159  size_t len)
160 {
161  struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
162  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
163  struct ade7854_state *st = iio_priv(indio_dev);
164 
165  int ret;
166  long val;
167 
168  ret = strict_strtol(buf, 10, &val);
169  if (ret)
170  goto error_ret;
171  ret = st->write_reg_32(dev, this_attr->address, val);
172 
173 error_ret:
174  return ret ? ret : len;
175 }
176 
177 static int ade7854_reset(struct device *dev)
178 {
179  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
180  struct ade7854_state *st = iio_priv(indio_dev);
181  u16 val;
182 
183  st->read_reg_16(dev, ADE7854_CONFIG, &val);
184  val |= 1 << 7; /* Software Chip Reset */
185 
186  return st->write_reg_16(dev, ADE7854_CONFIG, val);
187 }
188 
189 
190 static ssize_t ade7854_write_reset(struct device *dev,
191  struct device_attribute *attr,
192  const char *buf, size_t len)
193 {
194  if (len < 1)
195  return -1;
196  switch (buf[0]) {
197  case '1':
198  case 'y':
199  case 'Y':
200  return ade7854_reset(dev);
201  }
202  return -1;
203 }
204 
206  ade7854_read_24bit,
207  ade7854_write_24bit,
210  ade7854_read_24bit,
211  ade7854_write_24bit,
214  ade7854_read_24bit,
215  ade7854_write_24bit,
218  ade7854_read_24bit,
219  ade7854_write_24bit,
222  ade7854_read_24bit,
223  ade7854_write_24bit,
226  ade7854_read_24bit,
227  ade7854_write_24bit,
230  ade7854_read_24bit,
231  ade7854_write_24bit,
234  ade7854_read_24bit,
235  ade7854_write_24bit,
238  ade7854_read_24bit,
239  ade7854_write_24bit,
242  ade7854_read_24bit,
243  ade7854_write_24bit,
246  ade7854_read_24bit,
247  ade7854_write_24bit,
250  ade7854_read_24bit,
251  ade7854_write_24bit,
254  ade7854_read_24bit,
255  ade7854_write_24bit,
258  ade7854_read_24bit,
259  ade7854_write_24bit,
262  ade7854_read_24bit,
263  ade7854_write_24bit,
266  ade7854_read_24bit,
267  ade7854_write_24bit,
270  ade7854_read_24bit,
271  ade7854_write_24bit,
274  ade7854_read_24bit,
275  ade7854_write_24bit,
278  ade7854_read_24bit,
279  ade7854_write_24bit,
282  ade7854_read_32bit,
283  ade7854_write_32bit,
284  ADE7854_VPEAK);
286  ade7854_read_32bit,
287  ade7854_write_32bit,
288  ADE7854_VPEAK);
290  ade7854_read_16bit,
291  ade7854_write_16bit,
294  ade7854_read_16bit,
295  ade7854_write_16bit,
298  ade7854_read_16bit,
299  ade7854_write_16bit,
302  ade7854_read_16bit,
303  ade7854_write_16bit,
306  ade7854_read_16bit,
307  ade7854_write_16bit,
310  ade7854_read_16bit,
311  ade7854_write_16bit,
314  ade7854_read_16bit,
315  ade7854_write_16bit,
318  ade7854_read_8bit,
319  ade7854_write_8bit,
322  ade7854_read_8bit,
323  ade7854_write_8bit,
324  ADE7854_CFCYC);
326  ade7854_read_8bit,
327  ade7854_write_8bit,
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,
338  ade7854_read_24bit,
339  NULL,
340  ADE7854_AIRMS);
342  ade7854_read_24bit,
343  NULL,
344  ADE7854_BIRMS);
346  ade7854_read_24bit,
347  NULL,
348  ADE7854_CIRMS);
350  ade7854_read_24bit,
351  NULL,
352  ADE7854_NIRMS);
354  ade7854_read_24bit,
355  NULL,
356  ADE7854_AVRMS);
358  ade7854_read_24bit,
359  NULL,
360  ADE7854_BVRMS);
362  ade7854_read_24bit,
363  NULL,
364  ADE7854_CVRMS);
366  ade7854_read_16bit,
367  ade7854_write_16bit,
370  ade7854_read_16bit,
371  ade7854_write_16bit,
374  ade7854_read_16bit,
375  ade7854_write_16bit,
378  ade7854_read_16bit,
379  ade7854_write_16bit,
382  ade7854_read_16bit,
383  ade7854_write_16bit,
386  ade7854_read_16bit,
387  ade7854_write_16bit,
389 static IIO_DEV_ATTR_VOLT_A(ade7854_read_24bit,
390  ADE7854_VAWV);
391 static IIO_DEV_ATTR_VOLT_B(ade7854_read_24bit,
392  ADE7854_VBWV);
393 static IIO_DEV_ATTR_VOLT_C(ade7854_read_24bit,
394  ADE7854_VCWV);
395 static IIO_DEV_ATTR_CURRENT_A(ade7854_read_24bit,
396  ADE7854_IAWV);
397 static IIO_DEV_ATTR_CURRENT_B(ade7854_read_24bit,
398  ADE7854_IBWV);
399 static IIO_DEV_ATTR_CURRENT_C(ade7854_read_24bit,
400  ADE7854_ICWV);
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,
420  ADE7854_AVAHR);
421 static IIO_DEV_ATTR_BVAHR(ade7854_read_32bit,
422  ADE7854_BVAHR);
423 static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit,
424  ADE7854_CVAHR);
425 
426 static int ade7854_set_irq(struct device *dev, bool enable)
427 {
428  struct iio_dev *indio_dev = dev_to_iio_dev(dev);
429  struct ade7854_state *st = iio_priv(indio_dev);
430 
431  int ret;
432  u32 irqen;
433 
434  ret = st->read_reg_32(dev, ADE7854_MASK0, &irqen);
435  if (ret)
436  goto error_ret;
437 
438  if (enable)
439  irqen |= 1 << 17; /* 1: interrupt enabled when all periodical
440  (at 8 kHz rate) DSP computations finish. */
441  else
442  irqen &= ~(1 << 17);
443 
444  ret = st->write_reg_32(dev, ADE7854_MASK0, irqen);
445  if (ret)
446  goto error_ret;
447 
448 error_ret:
449  return ret;
450 }
451 
452 static int ade7854_initial_setup(struct iio_dev *indio_dev)
453 {
454  int ret;
455  struct device *dev = &indio_dev->dev;
456 
457  /* Disable IRQ */
458  ret = ade7854_set_irq(dev, false);
459  if (ret) {
460  dev_err(dev, "disable irq failed");
461  goto err_ret;
462  }
463 
464  ade7854_reset(dev);
466 
467 err_ret:
468  return ret;
469 }
470 
471 static IIO_DEV_ATTR_RESET(ade7854_write_reset);
472 
473 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000");
474 
475 static IIO_CONST_ATTR(name, "ade7854");
476 
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,
547  NULL,
548 };
549 
550 static const struct attribute_group ade7854_attribute_group = {
551  .attrs = ade7854_attributes,
552 };
553 
554 static const struct iio_info ade7854_info = {
555  .attrs = &ade7854_attribute_group,
556  .driver_module = THIS_MODULE,
557 };
558 
559 int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
560 {
561  int ret;
562  struct ade7854_state *st = iio_priv(indio_dev);
563  /* setup the industrialio driver allocated elements */
564  mutex_init(&st->buf_lock);
565 
566  indio_dev->dev.parent = dev;
567  indio_dev->info = &ade7854_info;
568  indio_dev->modes = INDIO_DIRECT_MODE;
569 
570  ret = iio_device_register(indio_dev);
571  if (ret)
572  goto error_free_dev;
573 
574  /* Get the device into a sane initial state */
575  ret = ade7854_initial_setup(indio_dev);
576  if (ret)
577  goto error_unreg_dev;
578 
579  return 0;
580 
581 error_unreg_dev:
582  iio_device_unregister(indio_dev);
583 error_free_dev:
584  iio_device_free(indio_dev);
585 
586  return ret;
587 }
589 
590 int ade7854_remove(struct iio_dev *indio_dev)
591 {
592  iio_device_unregister(indio_dev);
593  iio_device_free(indio_dev);
594 
595  return 0;
596 }
598 
599 MODULE_AUTHOR("Barry Song <[email protected]>");
600 MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Energy Meter");
601 MODULE_LICENSE("GPL v2");