0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/interrupt.h>
0009 #include <linux/irq.h>
0010 #include <linux/delay.h>
0011 #include <linux/mutex.h>
0012 #include <linux/device.h>
0013 #include <linux/kernel.h>
0014 #include <linux/slab.h>
0015 #include <linux/sysfs.h>
0016 #include <linux/list.h>
0017 #include <linux/module.h>
0018
0019 #include <linux/iio/iio.h>
0020 #include <linux/iio/sysfs.h>
0021 #include "meter.h"
0022 #include "ade7854.h"
0023
0024 static ssize_t ade7854_read_8bit(struct device *dev,
0025 struct device_attribute *attr,
0026 char *buf)
0027 {
0028 int ret;
0029 u32 val = 0;
0030 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0031 struct ade7854_state *st = iio_priv(indio_dev);
0032 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0033
0034 ret = st->read_reg(dev, this_attr->address, &val, 8);
0035 if (ret < 0)
0036 return ret;
0037
0038 return sprintf(buf, "%u\n", val);
0039 }
0040
0041 static ssize_t ade7854_read_16bit(struct device *dev,
0042 struct device_attribute *attr,
0043 char *buf)
0044 {
0045 int ret;
0046 u32 val = 0;
0047 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0048 struct ade7854_state *st = iio_priv(indio_dev);
0049 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0050
0051 ret = st->read_reg(dev, this_attr->address, &val, 16);
0052 if (ret < 0)
0053 return ret;
0054
0055 return sprintf(buf, "%u\n", val);
0056 }
0057
0058 static ssize_t ade7854_read_24bit(struct device *dev,
0059 struct device_attribute *attr,
0060 char *buf)
0061 {
0062 int ret;
0063 u32 val;
0064 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0065 struct ade7854_state *st = iio_priv(indio_dev);
0066 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0067
0068 ret = st->read_reg(dev, this_attr->address, &val, 24);
0069 if (ret < 0)
0070 return ret;
0071
0072 return sprintf(buf, "%u\n", val);
0073 }
0074
0075 static ssize_t ade7854_read_32bit(struct device *dev,
0076 struct device_attribute *attr,
0077 char *buf)
0078 {
0079 int ret;
0080 u32 val = 0;
0081 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0082 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0083 struct ade7854_state *st = iio_priv(indio_dev);
0084
0085 ret = st->read_reg(dev, this_attr->address, &val, 32);
0086 if (ret < 0)
0087 return ret;
0088
0089 return sprintf(buf, "%u\n", val);
0090 }
0091
0092 static ssize_t ade7854_write_8bit(struct device *dev,
0093 struct device_attribute *attr,
0094 const char *buf,
0095 size_t len)
0096 {
0097 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0098 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0099 struct ade7854_state *st = iio_priv(indio_dev);
0100
0101 int ret;
0102 u8 val;
0103
0104 ret = kstrtou8(buf, 10, &val);
0105 if (ret)
0106 goto error_ret;
0107 ret = st->write_reg(dev, this_attr->address, val, 8);
0108
0109 error_ret:
0110 return ret ? ret : len;
0111 }
0112
0113 static ssize_t ade7854_write_16bit(struct device *dev,
0114 struct device_attribute *attr,
0115 const char *buf,
0116 size_t len)
0117 {
0118 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0119 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0120 struct ade7854_state *st = iio_priv(indio_dev);
0121
0122 int ret;
0123 u16 val;
0124
0125 ret = kstrtou16(buf, 10, &val);
0126 if (ret)
0127 goto error_ret;
0128 ret = st->write_reg(dev, this_attr->address, val, 16);
0129
0130 error_ret:
0131 return ret ? ret : len;
0132 }
0133
0134 static ssize_t ade7854_write_24bit(struct device *dev,
0135 struct device_attribute *attr,
0136 const char *buf,
0137 size_t len)
0138 {
0139 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0140 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0141 struct ade7854_state *st = iio_priv(indio_dev);
0142
0143 int ret;
0144 u32 val;
0145
0146 ret = kstrtou32(buf, 10, &val);
0147 if (ret)
0148 goto error_ret;
0149 ret = st->write_reg(dev, this_attr->address, val, 24);
0150
0151 error_ret:
0152 return ret ? ret : len;
0153 }
0154
0155 static ssize_t ade7854_write_32bit(struct device *dev,
0156 struct device_attribute *attr,
0157 const char *buf,
0158 size_t len)
0159 {
0160 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
0161 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0162 struct ade7854_state *st = iio_priv(indio_dev);
0163
0164 int ret;
0165 u32 val;
0166
0167 ret = kstrtou32(buf, 10, &val);
0168 if (ret)
0169 goto error_ret;
0170 ret = st->write_reg(dev, this_attr->address, val, 32);
0171
0172 error_ret:
0173 return ret ? ret : len;
0174 }
0175
0176 static int ade7854_reset(struct device *dev)
0177 {
0178 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0179 struct ade7854_state *st = iio_priv(indio_dev);
0180 u32 val;
0181
0182 st->read_reg(dev, ADE7854_CONFIG, &val, 16);
0183 val |= BIT(7);
0184
0185 return st->write_reg(dev, ADE7854_CONFIG, val, 16);
0186 }
0187
0188 static IIO_DEV_ATTR_AIGAIN(0644,
0189 ade7854_read_24bit,
0190 ade7854_write_24bit,
0191 ADE7854_AIGAIN);
0192 static IIO_DEV_ATTR_BIGAIN(0644,
0193 ade7854_read_24bit,
0194 ade7854_write_24bit,
0195 ADE7854_BIGAIN);
0196 static IIO_DEV_ATTR_CIGAIN(0644,
0197 ade7854_read_24bit,
0198 ade7854_write_24bit,
0199 ADE7854_CIGAIN);
0200 static IIO_DEV_ATTR_NIGAIN(0644,
0201 ade7854_read_24bit,
0202 ade7854_write_24bit,
0203 ADE7854_NIGAIN);
0204 static IIO_DEV_ATTR_AVGAIN(0644,
0205 ade7854_read_24bit,
0206 ade7854_write_24bit,
0207 ADE7854_AVGAIN);
0208 static IIO_DEV_ATTR_BVGAIN(0644,
0209 ade7854_read_24bit,
0210 ade7854_write_24bit,
0211 ADE7854_BVGAIN);
0212 static IIO_DEV_ATTR_CVGAIN(0644,
0213 ade7854_read_24bit,
0214 ade7854_write_24bit,
0215 ADE7854_CVGAIN);
0216 static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(0644,
0217 ade7854_read_24bit,
0218 ade7854_write_24bit,
0219 ADE7854_AVAGAIN);
0220 static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(0644,
0221 ade7854_read_24bit,
0222 ade7854_write_24bit,
0223 ADE7854_BVAGAIN);
0224 static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(0644,
0225 ade7854_read_24bit,
0226 ade7854_write_24bit,
0227 ADE7854_CVAGAIN);
0228 static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(0644,
0229 ade7854_read_24bit,
0230 ade7854_write_24bit,
0231 ADE7854_AWATTOS);
0232 static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(0644,
0233 ade7854_read_24bit,
0234 ade7854_write_24bit,
0235 ADE7854_BWATTOS);
0236 static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(0644,
0237 ade7854_read_24bit,
0238 ade7854_write_24bit,
0239 ADE7854_CWATTOS);
0240 static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(0644,
0241 ade7854_read_24bit,
0242 ade7854_write_24bit,
0243 ADE7854_AVARGAIN);
0244 static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(0644,
0245 ade7854_read_24bit,
0246 ade7854_write_24bit,
0247 ADE7854_BVARGAIN);
0248 static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(0644,
0249 ade7854_read_24bit,
0250 ade7854_write_24bit,
0251 ADE7854_CVARGAIN);
0252 static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(0644,
0253 ade7854_read_24bit,
0254 ade7854_write_24bit,
0255 ADE7854_AVAROS);
0256 static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(0644,
0257 ade7854_read_24bit,
0258 ade7854_write_24bit,
0259 ADE7854_BVAROS);
0260 static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(0644,
0261 ade7854_read_24bit,
0262 ade7854_write_24bit,
0263 ADE7854_CVAROS);
0264 static IIO_DEV_ATTR_VPEAK(0644,
0265 ade7854_read_32bit,
0266 ade7854_write_32bit,
0267 ADE7854_VPEAK);
0268 static IIO_DEV_ATTR_IPEAK(0644,
0269 ade7854_read_32bit,
0270 ade7854_write_32bit,
0271 ADE7854_IPEAK);
0272 static IIO_DEV_ATTR_APHCAL(0644,
0273 ade7854_read_16bit,
0274 ade7854_write_16bit,
0275 ADE7854_APHCAL);
0276 static IIO_DEV_ATTR_BPHCAL(0644,
0277 ade7854_read_16bit,
0278 ade7854_write_16bit,
0279 ADE7854_BPHCAL);
0280 static IIO_DEV_ATTR_CPHCAL(0644,
0281 ade7854_read_16bit,
0282 ade7854_write_16bit,
0283 ADE7854_CPHCAL);
0284 static IIO_DEV_ATTR_CF1DEN(0644,
0285 ade7854_read_16bit,
0286 ade7854_write_16bit,
0287 ADE7854_CF1DEN);
0288 static IIO_DEV_ATTR_CF2DEN(0644,
0289 ade7854_read_16bit,
0290 ade7854_write_16bit,
0291 ADE7854_CF2DEN);
0292 static IIO_DEV_ATTR_CF3DEN(0644,
0293 ade7854_read_16bit,
0294 ade7854_write_16bit,
0295 ADE7854_CF3DEN);
0296 static IIO_DEV_ATTR_LINECYC(0644,
0297 ade7854_read_16bit,
0298 ade7854_write_16bit,
0299 ADE7854_LINECYC);
0300 static IIO_DEV_ATTR_SAGCYC(0644,
0301 ade7854_read_8bit,
0302 ade7854_write_8bit,
0303 ADE7854_SAGCYC);
0304 static IIO_DEV_ATTR_CFCYC(0644,
0305 ade7854_read_8bit,
0306 ade7854_write_8bit,
0307 ADE7854_CFCYC);
0308 static IIO_DEV_ATTR_PEAKCYC(0644,
0309 ade7854_read_8bit,
0310 ade7854_write_8bit,
0311 ADE7854_PEAKCYC);
0312 static IIO_DEV_ATTR_CHKSUM(ade7854_read_24bit,
0313 ADE7854_CHECKSUM);
0314 static IIO_DEV_ATTR_ANGLE0(ade7854_read_24bit,
0315 ADE7854_ANGLE0);
0316 static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit,
0317 ADE7854_ANGLE1);
0318 static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit,
0319 ADE7854_ANGLE2);
0320 static IIO_DEV_ATTR_AIRMS(0444,
0321 ade7854_read_24bit,
0322 NULL,
0323 ADE7854_AIRMS);
0324 static IIO_DEV_ATTR_BIRMS(0444,
0325 ade7854_read_24bit,
0326 NULL,
0327 ADE7854_BIRMS);
0328 static IIO_DEV_ATTR_CIRMS(0444,
0329 ade7854_read_24bit,
0330 NULL,
0331 ADE7854_CIRMS);
0332 static IIO_DEV_ATTR_NIRMS(0444,
0333 ade7854_read_24bit,
0334 NULL,
0335 ADE7854_NIRMS);
0336 static IIO_DEV_ATTR_AVRMS(0444,
0337 ade7854_read_24bit,
0338 NULL,
0339 ADE7854_AVRMS);
0340 static IIO_DEV_ATTR_BVRMS(0444,
0341 ade7854_read_24bit,
0342 NULL,
0343 ADE7854_BVRMS);
0344 static IIO_DEV_ATTR_CVRMS(0444,
0345 ade7854_read_24bit,
0346 NULL,
0347 ADE7854_CVRMS);
0348 static IIO_DEV_ATTR_AIRMSOS(0444,
0349 ade7854_read_16bit,
0350 ade7854_write_16bit,
0351 ADE7854_AIRMSOS);
0352 static IIO_DEV_ATTR_BIRMSOS(0444,
0353 ade7854_read_16bit,
0354 ade7854_write_16bit,
0355 ADE7854_BIRMSOS);
0356 static IIO_DEV_ATTR_CIRMSOS(0444,
0357 ade7854_read_16bit,
0358 ade7854_write_16bit,
0359 ADE7854_CIRMSOS);
0360 static IIO_DEV_ATTR_AVRMSOS(0444,
0361 ade7854_read_16bit,
0362 ade7854_write_16bit,
0363 ADE7854_AVRMSOS);
0364 static IIO_DEV_ATTR_BVRMSOS(0444,
0365 ade7854_read_16bit,
0366 ade7854_write_16bit,
0367 ADE7854_BVRMSOS);
0368 static IIO_DEV_ATTR_CVRMSOS(0444,
0369 ade7854_read_16bit,
0370 ade7854_write_16bit,
0371 ADE7854_CVRMSOS);
0372 static IIO_DEV_ATTR_VOLT_A(ade7854_read_24bit,
0373 ADE7854_VAWV);
0374 static IIO_DEV_ATTR_VOLT_B(ade7854_read_24bit,
0375 ADE7854_VBWV);
0376 static IIO_DEV_ATTR_VOLT_C(ade7854_read_24bit,
0377 ADE7854_VCWV);
0378 static IIO_DEV_ATTR_CURRENT_A(ade7854_read_24bit,
0379 ADE7854_IAWV);
0380 static IIO_DEV_ATTR_CURRENT_B(ade7854_read_24bit,
0381 ADE7854_IBWV);
0382 static IIO_DEV_ATTR_CURRENT_C(ade7854_read_24bit,
0383 ADE7854_ICWV);
0384 static IIO_DEV_ATTR_AWATTHR(ade7854_read_32bit,
0385 ADE7854_AWATTHR);
0386 static IIO_DEV_ATTR_BWATTHR(ade7854_read_32bit,
0387 ADE7854_BWATTHR);
0388 static IIO_DEV_ATTR_CWATTHR(ade7854_read_32bit,
0389 ADE7854_CWATTHR);
0390 static IIO_DEV_ATTR_AFWATTHR(ade7854_read_32bit,
0391 ADE7854_AFWATTHR);
0392 static IIO_DEV_ATTR_BFWATTHR(ade7854_read_32bit,
0393 ADE7854_BFWATTHR);
0394 static IIO_DEV_ATTR_CFWATTHR(ade7854_read_32bit,
0395 ADE7854_CFWATTHR);
0396 static IIO_DEV_ATTR_AVARHR(ade7854_read_32bit,
0397 ADE7854_AVARHR);
0398 static IIO_DEV_ATTR_BVARHR(ade7854_read_32bit,
0399 ADE7854_BVARHR);
0400 static IIO_DEV_ATTR_CVARHR(ade7854_read_32bit,
0401 ADE7854_CVARHR);
0402 static IIO_DEV_ATTR_AVAHR(ade7854_read_32bit,
0403 ADE7854_AVAHR);
0404 static IIO_DEV_ATTR_BVAHR(ade7854_read_32bit,
0405 ADE7854_BVAHR);
0406 static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit,
0407 ADE7854_CVAHR);
0408
0409 static int ade7854_set_irq(struct device *dev, bool enable)
0410 {
0411 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0412 struct ade7854_state *st = iio_priv(indio_dev);
0413
0414 int ret;
0415 u32 irqen;
0416
0417 ret = st->read_reg(dev, ADE7854_MASK0, &irqen, 32);
0418 if (ret < 0)
0419 return ret;
0420
0421 if (enable)
0422 irqen |= BIT(17);
0423
0424
0425 else
0426 irqen &= ~BIT(17);
0427
0428 return st->write_reg(dev, ADE7854_MASK0, irqen, 32);
0429 }
0430
0431 static int ade7854_initial_setup(struct iio_dev *indio_dev)
0432 {
0433 int ret;
0434 struct device *dev = &indio_dev->dev;
0435
0436
0437 ret = ade7854_set_irq(dev, false);
0438 if (ret) {
0439 dev_err(dev, "disable irq failed");
0440 goto err_ret;
0441 }
0442
0443 ade7854_reset(dev);
0444 usleep_range(ADE7854_STARTUP_DELAY, ADE7854_STARTUP_DELAY + 100);
0445
0446 err_ret:
0447 return ret;
0448 }
0449
0450 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000");
0451
0452 static IIO_CONST_ATTR(name, "ade7854");
0453
0454 static struct attribute *ade7854_attributes[] = {
0455 &iio_dev_attr_aigain.dev_attr.attr,
0456 &iio_dev_attr_bigain.dev_attr.attr,
0457 &iio_dev_attr_cigain.dev_attr.attr,
0458 &iio_dev_attr_nigain.dev_attr.attr,
0459 &iio_dev_attr_avgain.dev_attr.attr,
0460 &iio_dev_attr_bvgain.dev_attr.attr,
0461 &iio_dev_attr_cvgain.dev_attr.attr,
0462 &iio_dev_attr_linecyc.dev_attr.attr,
0463 &iio_dev_attr_sagcyc.dev_attr.attr,
0464 &iio_dev_attr_cfcyc.dev_attr.attr,
0465 &iio_dev_attr_peakcyc.dev_attr.attr,
0466 &iio_dev_attr_chksum.dev_attr.attr,
0467 &iio_dev_attr_apparent_power_a_gain.dev_attr.attr,
0468 &iio_dev_attr_apparent_power_b_gain.dev_attr.attr,
0469 &iio_dev_attr_apparent_power_c_gain.dev_attr.attr,
0470 &iio_dev_attr_active_power_a_offset.dev_attr.attr,
0471 &iio_dev_attr_active_power_b_offset.dev_attr.attr,
0472 &iio_dev_attr_active_power_c_offset.dev_attr.attr,
0473 &iio_dev_attr_reactive_power_a_gain.dev_attr.attr,
0474 &iio_dev_attr_reactive_power_b_gain.dev_attr.attr,
0475 &iio_dev_attr_reactive_power_c_gain.dev_attr.attr,
0476 &iio_dev_attr_reactive_power_a_offset.dev_attr.attr,
0477 &iio_dev_attr_reactive_power_b_offset.dev_attr.attr,
0478 &iio_dev_attr_reactive_power_c_offset.dev_attr.attr,
0479 &iio_dev_attr_awatthr.dev_attr.attr,
0480 &iio_dev_attr_bwatthr.dev_attr.attr,
0481 &iio_dev_attr_cwatthr.dev_attr.attr,
0482 &iio_dev_attr_afwatthr.dev_attr.attr,
0483 &iio_dev_attr_bfwatthr.dev_attr.attr,
0484 &iio_dev_attr_cfwatthr.dev_attr.attr,
0485 &iio_dev_attr_avarhr.dev_attr.attr,
0486 &iio_dev_attr_bvarhr.dev_attr.attr,
0487 &iio_dev_attr_cvarhr.dev_attr.attr,
0488 &iio_dev_attr_angle0.dev_attr.attr,
0489 &iio_dev_attr_angle1.dev_attr.attr,
0490 &iio_dev_attr_angle2.dev_attr.attr,
0491 &iio_dev_attr_avahr.dev_attr.attr,
0492 &iio_dev_attr_bvahr.dev_attr.attr,
0493 &iio_dev_attr_cvahr.dev_attr.attr,
0494 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
0495 &iio_const_attr_name.dev_attr.attr,
0496 &iio_dev_attr_vpeak.dev_attr.attr,
0497 &iio_dev_attr_ipeak.dev_attr.attr,
0498 &iio_dev_attr_aphcal.dev_attr.attr,
0499 &iio_dev_attr_bphcal.dev_attr.attr,
0500 &iio_dev_attr_cphcal.dev_attr.attr,
0501 &iio_dev_attr_cf1den.dev_attr.attr,
0502 &iio_dev_attr_cf2den.dev_attr.attr,
0503 &iio_dev_attr_cf3den.dev_attr.attr,
0504 &iio_dev_attr_airms.dev_attr.attr,
0505 &iio_dev_attr_birms.dev_attr.attr,
0506 &iio_dev_attr_cirms.dev_attr.attr,
0507 &iio_dev_attr_nirms.dev_attr.attr,
0508 &iio_dev_attr_avrms.dev_attr.attr,
0509 &iio_dev_attr_bvrms.dev_attr.attr,
0510 &iio_dev_attr_cvrms.dev_attr.attr,
0511 &iio_dev_attr_airmsos.dev_attr.attr,
0512 &iio_dev_attr_birmsos.dev_attr.attr,
0513 &iio_dev_attr_cirmsos.dev_attr.attr,
0514 &iio_dev_attr_avrmsos.dev_attr.attr,
0515 &iio_dev_attr_bvrmsos.dev_attr.attr,
0516 &iio_dev_attr_cvrmsos.dev_attr.attr,
0517 &iio_dev_attr_volt_a.dev_attr.attr,
0518 &iio_dev_attr_volt_b.dev_attr.attr,
0519 &iio_dev_attr_volt_c.dev_attr.attr,
0520 &iio_dev_attr_current_a.dev_attr.attr,
0521 &iio_dev_attr_current_b.dev_attr.attr,
0522 &iio_dev_attr_current_c.dev_attr.attr,
0523 NULL,
0524 };
0525
0526 static const struct attribute_group ade7854_attribute_group = {
0527 .attrs = ade7854_attributes,
0528 };
0529
0530 static const struct iio_info ade7854_info = {
0531 .attrs = &ade7854_attribute_group,
0532 };
0533
0534 int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
0535 {
0536 int ret;
0537 struct ade7854_state *st = iio_priv(indio_dev);
0538
0539 mutex_init(&st->buf_lock);
0540
0541 indio_dev->dev.parent = dev;
0542 indio_dev->info = &ade7854_info;
0543 indio_dev->modes = INDIO_DIRECT_MODE;
0544
0545 ret = devm_iio_device_register(dev, indio_dev);
0546 if (ret)
0547 return ret;
0548
0549
0550 return ade7854_initial_setup(indio_dev);
0551 }
0552 EXPORT_SYMBOL(ade7854_probe);
0553
0554 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
0555 MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Energy Meter");
0556 MODULE_LICENSE("GPL v2");