1/* 2 * ADE7754 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/spi/spi.h> 16#include <linux/slab.h> 17#include <linux/sysfs.h> 18#include <linux/list.h> 19#include <linux/module.h> 20 21#include "../iio.h" 22#include "../sysfs.h" 23#include "meter.h" 24#include "ade7754.h" 25 26static int ade7754_spi_write_reg_8(struct device *dev, 27 u8 reg_address, 28 u8 val) 29{ 30 int ret; 31 struct iio_dev *indio_dev = dev_get_drvdata(dev); 32 struct ade7754_state *st = iio_priv(indio_dev); 33 34 mutex_lock(&st->buf_lock); 35 st->tx[0] = ADE7754_WRITE_REG(reg_address); 36 st->tx[1] = val; 37 38 ret = spi_write(st->us, st->tx, 2); 39 mutex_unlock(&st->buf_lock); 40 41 return ret; 42} 43 44static int ade7754_spi_write_reg_16(struct device *dev, 45 u8 reg_address, 46 u16 value) 47{ 48 int ret; 49 struct iio_dev *indio_dev = dev_get_drvdata(dev); 50 struct ade7754_state *st = iio_priv(indio_dev); 51 52 mutex_lock(&st->buf_lock); 53 st->tx[0] = ADE7754_WRITE_REG(reg_address); 54 st->tx[1] = (value >> 8) & 0xFF; 55 st->tx[2] = value & 0xFF; 56 ret = spi_write(st->us, st->tx, 3); 57 mutex_unlock(&st->buf_lock); 58 59 return ret; 60} 61 62static int ade7754_spi_read_reg_8(struct device *dev, 63 u8 reg_address, 64 u8 *val) 65{ 66 struct iio_dev *indio_dev = dev_get_drvdata(dev); 67 struct ade7754_state *st = iio_priv(indio_dev); 68 int ret; 69 70 ret = spi_w8r8(st->us, ADE7754_READ_REG(reg_address)); 71 if (ret < 0) { 72 dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", 73 reg_address); 74 return ret; 75 } 76 *val = ret; 77 78 return 0; 79} 80 81static int ade7754_spi_read_reg_16(struct device *dev, 82 u8 reg_address, 83 u16 *val) 84{ 85 struct iio_dev *indio_dev = dev_get_drvdata(dev); 86 struct ade7754_state *st = iio_priv(indio_dev); 87 int ret; 88 89 ret = spi_w8r16(st->us, ADE7754_READ_REG(reg_address)); 90 if (ret < 0) { 91 dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", 92 reg_address); 93 return ret; 94 } 95 96 *val = ret; 97 *val = be16_to_cpup(val); 98 99 return 0; 100} 101 102static int ade7754_spi_read_reg_24(struct device *dev, 103 u8 reg_address, 104 u32 *val) 105{ 106 struct spi_message msg; 107 struct iio_dev *indio_dev = dev_get_drvdata(dev); 108 struct ade7754_state *st = iio_priv(indio_dev); 109 int ret; 110 struct spi_transfer xfers[] = { 111 { 112 .tx_buf = st->tx, 113 .rx_buf = st->rx, 114 .bits_per_word = 8, 115 .len = 4, 116 }, 117 }; 118 119 mutex_lock(&st->buf_lock); 120 st->tx[0] = ADE7754_READ_REG(reg_address); 121 st->tx[1] = 0; 122 st->tx[2] = 0; 123 st->tx[3] = 0; 124 125 spi_message_init(&msg); 126 spi_message_add_tail(xfers, &msg); 127 ret = spi_sync(st->us, &msg); 128 if (ret) { 129 dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", 130 reg_address); 131 goto error_ret; 132 } 133 *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; 134 135error_ret: 136 mutex_unlock(&st->buf_lock); 137 return ret; 138} 139 140static ssize_t ade7754_read_8bit(struct device *dev, 141 struct device_attribute *attr, 142 char *buf) 143{ 144 int ret; 145 u8 val = 0; 146 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 147 148 ret = ade7754_spi_read_reg_8(dev, this_attr->address, &val); 149 if (ret) 150 return ret; 151 152 return sprintf(buf, "%u\n", val); 153} 154 155static ssize_t ade7754_read_16bit(struct device *dev, 156 struct device_attribute *attr, 157 char *buf) 158{ 159 int ret; 160 u16 val = 0; 161 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 162 163 ret = ade7754_spi_read_reg_16(dev, this_attr->address, &val); 164 if (ret) 165 return ret; 166 167 return sprintf(buf, "%u\n", val); 168} 169 170static ssize_t ade7754_read_24bit(struct device *dev, 171 struct device_attribute *attr, 172 char *buf) 173{ 174 int ret; 175 u32 val = 0; 176 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 177 178 ret = ade7754_spi_read_reg_24(dev, this_attr->address, &val); 179 if (ret) 180 return ret; 181 182 return sprintf(buf, "%u\n", val & 0xFFFFFF); 183} 184 185static ssize_t ade7754_write_8bit(struct device *dev, 186 struct device_attribute *attr, 187 const char *buf, 188 size_t len) 189{ 190 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 191 int ret; 192 long val; 193 194 ret = strict_strtol(buf, 10, &val); 195 if (ret) 196 goto error_ret; 197 ret = ade7754_spi_write_reg_8(dev, this_attr->address, val); 198 199error_ret: 200 return ret ? ret : len; 201} 202 203static ssize_t ade7754_write_16bit(struct device *dev, 204 struct device_attribute *attr, 205 const char *buf, 206 size_t len) 207{ 208 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 209 int ret; 210 long val; 211 212 ret = strict_strtol(buf, 10, &val); 213 if (ret) 214 goto error_ret; 215 ret = ade7754_spi_write_reg_16(dev, this_attr->address, val); 216 217error_ret: 218 return ret ? ret : len; 219} 220 221static int ade7754_reset(struct device *dev) 222{ 223 u8 val; 224 225 ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); 226 val |= 1 << 6; /* Software Chip Reset */ 227 return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); 228} 229 230 231static ssize_t ade7754_write_reset(struct device *dev, 232 struct device_attribute *attr, 233 const char *buf, size_t len) 234{ 235 if (len < 1) 236 return -1; 237 switch (buf[0]) { 238 case '1': 239 case 'y': 240 case 'Y': 241 return ade7754_reset(dev); 242 } 243 return -1; 244} 245 246static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY); 247static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY); 248static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY); 249static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY); 250static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO, 251 ade7754_read_8bit, 252 ade7754_write_8bit, 253 ADE7754_VPEAK); 254static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO, 255 ade7754_read_8bit, 256 ade7754_write_8bit, 257 ADE7754_VPEAK); 258static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO, 259 ade7754_read_8bit, 260 ade7754_write_8bit, 261 ADE7754_APHCAL); 262static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO, 263 ade7754_read_8bit, 264 ade7754_write_8bit, 265 ADE7754_BPHCAL); 266static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO, 267 ade7754_read_8bit, 268 ade7754_write_8bit, 269 ADE7754_CPHCAL); 270static IIO_DEV_ATTR_AAPOS(S_IWUSR | S_IRUGO, 271 ade7754_read_16bit, 272 ade7754_write_16bit, 273 ADE7754_AAPOS); 274static IIO_DEV_ATTR_BAPOS(S_IWUSR | S_IRUGO, 275 ade7754_read_16bit, 276 ade7754_write_16bit, 277 ADE7754_BAPOS); 278static IIO_DEV_ATTR_CAPOS(S_IWUSR | S_IRUGO, 279 ade7754_read_16bit, 280 ade7754_write_16bit, 281 ADE7754_CAPOS); 282static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO, 283 ade7754_read_8bit, 284 ade7754_write_8bit, 285 ADE7754_WDIV); 286static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO, 287 ade7754_read_8bit, 288 ade7754_write_8bit, 289 ADE7754_VADIV); 290static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO, 291 ade7754_read_16bit, 292 ade7754_write_16bit, 293 ADE7754_CFNUM); 294static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO, 295 ade7754_read_16bit, 296 ade7754_write_16bit, 297 ADE7754_CFDEN); 298static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO, 299 ade7754_read_16bit, 300 ade7754_write_16bit, 301 ADE7754_AAPGAIN); 302static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO, 303 ade7754_read_16bit, 304 ade7754_write_16bit, 305 ADE7754_BAPGAIN); 306static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO, 307 ade7754_read_16bit, 308 ade7754_write_16bit, 309 ADE7754_CAPGAIN); 310static IIO_DEV_ATTR_AIRMS(S_IRUGO, 311 ade7754_read_24bit, 312 NULL, 313 ADE7754_AIRMS); 314static IIO_DEV_ATTR_BIRMS(S_IRUGO, 315 ade7754_read_24bit, 316 NULL, 317 ADE7754_BIRMS); 318static IIO_DEV_ATTR_CIRMS(S_IRUGO, 319 ade7754_read_24bit, 320 NULL, 321 ADE7754_CIRMS); 322static IIO_DEV_ATTR_AVRMS(S_IRUGO, 323 ade7754_read_24bit, 324 NULL, 325 ADE7754_AVRMS); 326static IIO_DEV_ATTR_BVRMS(S_IRUGO, 327 ade7754_read_24bit, 328 NULL, 329 ADE7754_BVRMS); 330static IIO_DEV_ATTR_CVRMS(S_IRUGO, 331 ade7754_read_24bit, 332 NULL, 333 ADE7754_CVRMS); 334static IIO_DEV_ATTR_AIRMSOS(S_IRUGO, 335 ade7754_read_16bit, 336 ade7754_write_16bit, 337 ADE7754_AIRMSOS); 338static IIO_DEV_ATTR_BIRMSOS(S_IRUGO, 339 ade7754_read_16bit, 340 ade7754_write_16bit, 341 ADE7754_BIRMSOS); 342static IIO_DEV_ATTR_CIRMSOS(S_IRUGO, 343 ade7754_read_16bit, 344 ade7754_write_16bit, 345 ADE7754_CIRMSOS); 346static IIO_DEV_ATTR_AVRMSOS(S_IRUGO, 347 ade7754_read_16bit, 348 ade7754_write_16bit, 349 ADE7754_AVRMSOS); 350static IIO_DEV_ATTR_BVRMSOS(S_IRUGO, 351 ade7754_read_16bit, 352 ade7754_write_16bit, 353 ADE7754_BVRMSOS); 354static IIO_DEV_ATTR_CVRMSOS(S_IRUGO, 355 ade7754_read_16bit, 356 ade7754_write_16bit, 357 ADE7754_CVRMSOS); 358 359static int ade7754_set_irq(struct device *dev, bool enable) 360{ 361 int ret; 362 u16 irqen; 363 ret = ade7754_spi_read_reg_16(dev, ADE7754_IRQEN, &irqen); 364 if (ret) 365 goto error_ret; 366 367 if (enable) 368 irqen |= 1 << 14; /* Enables an interrupt when a data is 369 present in the waveform register */ 370 else 371 irqen &= ~(1 << 14); 372 373 ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen); 374 if (ret) 375 goto error_ret; 376 377error_ret: 378 return ret; 379} 380 381/* Power down the device */ 382static int ade7754_stop_device(struct device *dev) 383{ 384 u8 val; 385 386 ade7754_spi_read_reg_8(dev, ADE7754_OPMODE, &val); 387 val |= 7 << 3; /* ADE7754 powered down */ 388 return ade7754_spi_write_reg_8(dev, ADE7754_OPMODE, val); 389} 390 391static int ade7754_initial_setup(struct iio_dev *indio_dev) 392{ 393 int ret; 394 struct ade7754_state *st = iio_priv(indio_dev); 395 struct device *dev = &indio_dev->dev; 396 397 /* use low spi speed for init */ 398 st->us->mode = SPI_MODE_3; 399 spi_setup(st->us); 400 401 /* Disable IRQ */ 402 ret = ade7754_set_irq(dev, false); 403 if (ret) { 404 dev_err(dev, "disable irq failed"); 405 goto err_ret; 406 } 407 408 ade7754_reset(dev); 409 msleep(ADE7754_STARTUP_DELAY); 410 411err_ret: 412 return ret; 413} 414 415static ssize_t ade7754_read_frequency(struct device *dev, 416 struct device_attribute *attr, 417 char *buf) 418{ 419 int ret; 420 u8 t; 421 int sps; 422 ret = ade7754_spi_read_reg_8(dev, 423 ADE7754_WAVMODE, 424 &t); 425 if (ret) 426 return ret; 427 428 t = (t >> 3) & 0x3; 429 sps = 26000 / (1 + t); 430 431 return sprintf(buf, "%d\n", sps); 432} 433 434static ssize_t ade7754_write_frequency(struct device *dev, 435 struct device_attribute *attr, 436 const char *buf, 437 size_t len) 438{ 439 struct iio_dev *indio_dev = dev_get_drvdata(dev); 440 struct ade7754_state *st = iio_priv(indio_dev); 441 unsigned long val; 442 int ret; 443 u8 reg, t; 444 445 ret = strict_strtol(buf, 10, &val); 446 if (ret) 447 return ret; 448 449 mutex_lock(&indio_dev->mlock); 450 451 t = (26000 / val); 452 if (t > 0) 453 t--; 454 455 if (t > 1) 456 st->us->max_speed_hz = ADE7754_SPI_SLOW; 457 else 458 st->us->max_speed_hz = ADE7754_SPI_FAST; 459 460 ret = ade7754_spi_read_reg_8(dev, ADE7754_WAVMODE, ®); 461 if (ret) 462 goto out; 463 464 reg &= ~(3 << 3); 465 reg |= t << 3; 466 467 ret = ade7754_spi_write_reg_8(dev, ADE7754_WAVMODE, reg); 468 469out: 470 mutex_unlock(&indio_dev->mlock); 471 472 return ret ? ret : len; 473} 474static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit); 475static IIO_CONST_ATTR(in_temp_offset, "129 C"); 476static IIO_CONST_ATTR(in_temp_scale, "4 C"); 477 478static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, 479 ade7754_read_frequency, 480 ade7754_write_frequency); 481 482static IIO_DEV_ATTR_RESET(ade7754_write_reset); 483 484static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000"); 485 486static struct attribute *ade7754_attributes[] = { 487 &iio_dev_attr_in_temp_raw.dev_attr.attr, 488 &iio_const_attr_in_temp_offset.dev_attr.attr, 489 &iio_const_attr_in_temp_scale.dev_attr.attr, 490 &iio_dev_attr_sampling_frequency.dev_attr.attr, 491 &iio_const_attr_sampling_frequency_available.dev_attr.attr, 492 &iio_dev_attr_reset.dev_attr.attr, 493 &iio_dev_attr_aenergy.dev_attr.attr, 494 &iio_dev_attr_laenergy.dev_attr.attr, 495 &iio_dev_attr_vaenergy.dev_attr.attr, 496 &iio_dev_attr_lvaenergy.dev_attr.attr, 497 &iio_dev_attr_vpeak.dev_attr.attr, 498 &iio_dev_attr_ipeak.dev_attr.attr, 499 &iio_dev_attr_aphcal.dev_attr.attr, 500 &iio_dev_attr_bphcal.dev_attr.attr, 501 &iio_dev_attr_cphcal.dev_attr.attr, 502 &iio_dev_attr_aapos.dev_attr.attr, 503 &iio_dev_attr_bapos.dev_attr.attr, 504 &iio_dev_attr_capos.dev_attr.attr, 505 &iio_dev_attr_wdiv.dev_attr.attr, 506 &iio_dev_attr_vadiv.dev_attr.attr, 507 &iio_dev_attr_cfnum.dev_attr.attr, 508 &iio_dev_attr_cfden.dev_attr.attr, 509 &iio_dev_attr_active_power_a_gain.dev_attr.attr, 510 &iio_dev_attr_active_power_b_gain.dev_attr.attr, 511 &iio_dev_attr_active_power_c_gain.dev_attr.attr, 512 &iio_dev_attr_airms.dev_attr.attr, 513 &iio_dev_attr_birms.dev_attr.attr, 514 &iio_dev_attr_cirms.dev_attr.attr, 515 &iio_dev_attr_avrms.dev_attr.attr, 516 &iio_dev_attr_bvrms.dev_attr.attr, 517 &iio_dev_attr_cvrms.dev_attr.attr, 518 &iio_dev_attr_airmsos.dev_attr.attr, 519 &iio_dev_attr_birmsos.dev_attr.attr, 520 &iio_dev_attr_cirmsos.dev_attr.attr, 521 &iio_dev_attr_avrmsos.dev_attr.attr, 522 &iio_dev_attr_bvrmsos.dev_attr.attr, 523 &iio_dev_attr_cvrmsos.dev_attr.attr, 524 NULL, 525}; 526 527static const struct attribute_group ade7754_attribute_group = { 528 .attrs = ade7754_attributes, 529}; 530 531static const struct iio_info ade7754_info = { 532 .attrs = &ade7754_attribute_group, 533 .driver_module = THIS_MODULE, 534}; 535 536static int __devinit ade7754_probe(struct spi_device *spi) 537{ 538 int ret; 539 struct ade7754_state *st; 540 struct iio_dev *indio_dev; 541 542 /* setup the industrialio driver allocated elements */ 543 indio_dev = iio_allocate_device(sizeof(*st)); 544 if (indio_dev == NULL) { 545 ret = -ENOMEM; 546 goto error_ret; 547 } 548 /* this is only used for removal purposes */ 549 spi_set_drvdata(spi, indio_dev); 550 551 st = iio_priv(indio_dev); 552 st->us = spi; 553 mutex_init(&st->buf_lock); 554 555 indio_dev->name = spi->dev.driver->name; 556 indio_dev->dev.parent = &spi->dev; 557 indio_dev->info = &ade7754_info; 558 indio_dev->modes = INDIO_DIRECT_MODE; 559 560 /* Get the device into a sane initial state */ 561 ret = ade7754_initial_setup(indio_dev); 562 if (ret) 563 goto error_free_dev; 564 ret = iio_device_register(indio_dev); 565 if (ret) 566 goto error_free_dev; 567 568 return 0; 569 570error_free_dev: 571 iio_free_device(indio_dev); 572 573error_ret: 574 return ret; 575} 576 577/* fixme, confirm ordering in this function */ 578static int ade7754_remove(struct spi_device *spi) 579{ 580 int ret; 581 struct iio_dev *indio_dev = spi_get_drvdata(spi); 582 583 iio_device_unregister(indio_dev); 584 ret = ade7754_stop_device(&(indio_dev->dev)); 585 if (ret) 586 goto err_ret; 587 588 iio_free_device(indio_dev); 589 590err_ret: 591 return ret; 592 593} 594 595static struct spi_driver ade7754_driver = { 596 .driver = { 597 .name = "ade7754", 598 .owner = THIS_MODULE, 599 }, 600 .probe = ade7754_probe, 601 .remove = __devexit_p(ade7754_remove), 602}; 603module_spi_driver(ade7754_driver); 604 605MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 606MODULE_DESCRIPTION("Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver"); 607MODULE_LICENSE("GPL v2"); 608MODULE_ALIAS("spi:ad7754"); 609