1/* 2 * ADIS16209 Programmable Digital Vibration Sensor 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/gpio.h> 12#include <linux/delay.h> 13#include <linux/mutex.h> 14#include <linux/device.h> 15#include <linux/kernel.h> 16#include <linux/spi/spi.h> 17#include <linux/slab.h> 18#include <linux/sysfs.h> 19#include <linux/list.h> 20 21#include "../iio.h" 22#include "../sysfs.h" 23#include "../ring_generic.h" 24#include "accel.h" 25#include "inclinometer.h" 26#include "../gyro/gyro.h" 27#include "../adc/adc.h" 28 29#include "adis16209.h" 30 31#define DRIVER_NAME "adis16209" 32 33static int adis16209_check_status(struct device *dev); 34 35/** 36 * adis16209_spi_write_reg_8() - write single byte to a register 37 * @dev: device associated with child of actual device (iio_dev or iio_trig) 38 * @reg_address: the address of the register to be written 39 * @val: the value to write 40 **/ 41static int adis16209_spi_write_reg_8(struct device *dev, 42 u8 reg_address, 43 u8 val) 44{ 45 int ret; 46 struct iio_dev *indio_dev = dev_get_drvdata(dev); 47 struct adis16209_state *st = iio_dev_get_devdata(indio_dev); 48 49 mutex_lock(&st->buf_lock); 50 st->tx[0] = ADIS16209_WRITE_REG(reg_address); 51 st->tx[1] = val; 52 53 ret = spi_write(st->us, st->tx, 2); 54 mutex_unlock(&st->buf_lock); 55 56 return ret; 57} 58 59/** 60 * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers 61 * @dev: device associated with child of actual device (iio_dev or iio_trig) 62 * @reg_address: the address of the lower of the two registers. Second register 63 * is assumed to have address one greater. 64 * @val: value to be written 65 **/ 66static int adis16209_spi_write_reg_16(struct device *dev, 67 u8 lower_reg_address, 68 u16 value) 69{ 70 int ret; 71 struct spi_message msg; 72 struct iio_dev *indio_dev = dev_get_drvdata(dev); 73 struct adis16209_state *st = iio_dev_get_devdata(indio_dev); 74 struct spi_transfer xfers[] = { 75 { 76 .tx_buf = st->tx, 77 .bits_per_word = 8, 78 .len = 2, 79 .cs_change = 1, 80 .delay_usecs = 30, 81 }, { 82 .tx_buf = st->tx + 2, 83 .bits_per_word = 8, 84 .len = 2, 85 .cs_change = 1, 86 .delay_usecs = 30, 87 }, 88 }; 89 90 mutex_lock(&st->buf_lock); 91 st->tx[0] = ADIS16209_WRITE_REG(lower_reg_address); 92 st->tx[1] = value & 0xFF; 93 st->tx[2] = ADIS16209_WRITE_REG(lower_reg_address + 1); 94 st->tx[3] = (value >> 8) & 0xFF; 95 96 spi_message_init(&msg); 97 spi_message_add_tail(&xfers[0], &msg); 98 spi_message_add_tail(&xfers[1], &msg); 99 ret = spi_sync(st->us, &msg); 100 mutex_unlock(&st->buf_lock); 101 102 return ret; 103} 104 105/** 106 * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register 107 * @dev: device associated with child of actual device (iio_dev or iio_trig) 108 * @reg_address: the address of the lower of the two registers. Second register 109 * is assumed to have address one greater. 110 * @val: somewhere to pass back the value read 111 **/ 112static int adis16209_spi_read_reg_16(struct device *dev, 113 u8 lower_reg_address, 114 u16 *val) 115{ 116 struct spi_message msg; 117 struct iio_dev *indio_dev = dev_get_drvdata(dev); 118 struct adis16209_state *st = iio_dev_get_devdata(indio_dev); 119 int ret; 120 struct spi_transfer xfers[] = { 121 { 122 .tx_buf = st->tx, 123 .bits_per_word = 8, 124 .len = 2, 125 .cs_change = 1, 126 .delay_usecs = 30, 127 }, { 128 .rx_buf = st->rx, 129 .bits_per_word = 8, 130 .len = 2, 131 .cs_change = 1, 132 .delay_usecs = 30, 133 }, 134 }; 135 136 mutex_lock(&st->buf_lock); 137 st->tx[0] = ADIS16209_READ_REG(lower_reg_address); 138 st->tx[1] = 0; 139 140 spi_message_init(&msg); 141 spi_message_add_tail(&xfers[0], &msg); 142 spi_message_add_tail(&xfers[1], &msg); 143 ret = spi_sync(st->us, &msg); 144 if (ret) { 145 dev_err(&st->us->dev, 146 "problem when reading 16 bit register 0x%02X", 147 lower_reg_address); 148 goto error_ret; 149 } 150 *val = (st->rx[0] << 8) | st->rx[1]; 151 152error_ret: 153 mutex_unlock(&st->buf_lock); 154 return ret; 155} 156 157static ssize_t adis16209_read_12bit_unsigned(struct device *dev, 158 struct device_attribute *attr, 159 char *buf) 160{ 161 int ret; 162 u16 val = 0; 163 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 164 165 ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val); 166 if (ret) 167 return ret; 168 169 if (val & ADIS16209_ERROR_ACTIVE) 170 adis16209_check_status(dev); 171 172 return sprintf(buf, "%u\n", val & 0x0FFF); 173} 174 175static ssize_t adis16209_read_14bit_unsigned(struct device *dev, 176 struct device_attribute *attr, 177 char *buf) 178{ 179 int ret; 180 u16 val = 0; 181 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 182 183 ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val); 184 if (ret) 185 return ret; 186 187 if (val & ADIS16209_ERROR_ACTIVE) 188 adis16209_check_status(dev); 189 190 return sprintf(buf, "%u\n", val & 0x3FFF); 191} 192 193static ssize_t adis16209_read_temp(struct device *dev, 194 struct device_attribute *attr, 195 char *buf) 196{ 197 struct iio_dev *indio_dev = dev_get_drvdata(dev); 198 ssize_t ret; 199 u16 val; 200 201 /* Take the iio_dev status lock */ 202 mutex_lock(&indio_dev->mlock); 203 204 ret = adis16209_spi_read_reg_16(dev, ADIS16209_TEMP_OUT, (u16 *)&val); 205 if (ret) 206 goto error_ret; 207 208 if (val & ADIS16209_ERROR_ACTIVE) 209 adis16209_check_status(dev); 210 211 val &= 0xFFF; 212 ret = sprintf(buf, "%d\n", val); 213 214error_ret: 215 mutex_unlock(&indio_dev->mlock); 216 return ret; 217} 218 219static ssize_t adis16209_read_14bit_signed(struct device *dev, 220 struct device_attribute *attr, 221 char *buf) 222{ 223 struct iio_dev *indio_dev = dev_get_drvdata(dev); 224 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 225 s16 val = 0; 226 ssize_t ret; 227 228 mutex_lock(&indio_dev->mlock); 229 230 ret = adis16209_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); 231 if (!ret) { 232 if (val & ADIS16209_ERROR_ACTIVE) 233 adis16209_check_status(dev); 234 235 val = ((s16)(val << 2) >> 2); 236 ret = sprintf(buf, "%d\n", val); 237 } 238 239 mutex_unlock(&indio_dev->mlock); 240 241 return ret; 242} 243 244static ssize_t adis16209_write_16bit(struct device *dev, 245 struct device_attribute *attr, 246 const char *buf, 247 size_t len) 248{ 249 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 250 int ret; 251 long val; 252 253 ret = strict_strtol(buf, 10, &val); 254 if (ret) 255 goto error_ret; 256 ret = adis16209_spi_write_reg_16(dev, this_attr->address, val); 257 258error_ret: 259 return ret ? ret : len; 260} 261 262static int adis16209_reset(struct device *dev) 263{ 264 int ret; 265 ret = adis16209_spi_write_reg_8(dev, 266 ADIS16209_GLOB_CMD, 267 ADIS16209_GLOB_CMD_SW_RESET); 268 if (ret) 269 dev_err(dev, "problem resetting device"); 270 271 return ret; 272} 273 274static ssize_t adis16209_write_reset(struct device *dev, 275 struct device_attribute *attr, 276 const char *buf, size_t len) 277{ 278 if (len < 1) 279 return -EINVAL; 280 switch (buf[0]) { 281 case '1': 282 case 'y': 283 case 'Y': 284 return adis16209_reset(dev); 285 } 286 return -EINVAL; 287} 288 289int adis16209_set_irq(struct device *dev, bool enable) 290{ 291 int ret = 0; 292 u16 msc; 293 294 ret = adis16209_spi_read_reg_16(dev, ADIS16209_MSC_CTRL, &msc); 295 if (ret) 296 goto error_ret; 297 298 msc |= ADIS16209_MSC_CTRL_ACTIVE_HIGH; 299 msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_DIO2; 300 if (enable) 301 msc |= ADIS16209_MSC_CTRL_DATA_RDY_EN; 302 else 303 msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN; 304 305 ret = adis16209_spi_write_reg_16(dev, ADIS16209_MSC_CTRL, msc); 306 307error_ret: 308 return ret; 309} 310 311static int adis16209_check_status(struct device *dev) 312{ 313 u16 status; 314 int ret; 315 316 ret = adis16209_spi_read_reg_16(dev, ADIS16209_DIAG_STAT, &status); 317 if (ret < 0) { 318 dev_err(dev, "Reading status failed\n"); 319 goto error_ret; 320 } 321 ret = status & 0x1F; 322 323 if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL) 324 dev_err(dev, "Self test failure\n"); 325 if (status & ADIS16209_DIAG_STAT_SPI_FAIL) 326 dev_err(dev, "SPI failure\n"); 327 if (status & ADIS16209_DIAG_STAT_FLASH_UPT) 328 dev_err(dev, "Flash update failed\n"); 329 if (status & ADIS16209_DIAG_STAT_POWER_HIGH) 330 dev_err(dev, "Power supply above 3.625V\n"); 331 if (status & ADIS16209_DIAG_STAT_POWER_LOW) 332 dev_err(dev, "Power supply below 3.15V\n"); 333 334error_ret: 335 return ret; 336} 337 338static int adis16209_self_test(struct device *dev) 339{ 340 int ret; 341 ret = adis16209_spi_write_reg_16(dev, 342 ADIS16209_MSC_CTRL, 343 ADIS16209_MSC_CTRL_SELF_TEST_EN); 344 if (ret) { 345 dev_err(dev, "problem starting self test"); 346 goto err_ret; 347 } 348 349 adis16209_check_status(dev); 350 351err_ret: 352 return ret; 353} 354 355static int adis16209_initial_setup(struct adis16209_state *st) 356{ 357 int ret; 358 struct device *dev = &st->indio_dev->dev; 359 360 /* Disable IRQ */ 361 ret = adis16209_set_irq(dev, false); 362 if (ret) { 363 dev_err(dev, "disable irq failed"); 364 goto err_ret; 365 } 366 367 /* Do self test */ 368 ret = adis16209_self_test(dev); 369 if (ret) { 370 dev_err(dev, "self test failure"); 371 goto err_ret; 372 } 373 374 /* Read status register to check the result */ 375 ret = adis16209_check_status(dev); 376 if (ret) { 377 adis16209_reset(dev); 378 dev_err(dev, "device not playing ball -> reset"); 379 msleep(ADIS16209_STARTUP_DELAY); 380 ret = adis16209_check_status(dev); 381 if (ret) { 382 dev_err(dev, "giving up"); 383 goto err_ret; 384 } 385 } 386 387 printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", 388 st->us->chip_select, st->us->irq); 389 390err_ret: 391 return ret; 392} 393 394static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16209_read_14bit_unsigned, 395 ADIS16209_SUPPLY_OUT); 396static IIO_CONST_ATTR(in_supply_scale, "0.30518"); 397static IIO_DEV_ATTR_IN_RAW(0, adis16209_read_12bit_unsigned, 398 ADIS16209_AUX_ADC); 399static IIO_CONST_ATTR(in0_scale, "0.6105"); 400 401static IIO_DEV_ATTR_ACCEL_X(adis16209_read_14bit_signed, 402 ADIS16209_XACCL_OUT); 403static IIO_DEV_ATTR_ACCEL_Y(adis16209_read_14bit_signed, 404 ADIS16209_YACCL_OUT); 405static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, 406 adis16209_read_14bit_signed, 407 adis16209_write_16bit, 408 ADIS16209_XACCL_NULL); 409static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, 410 adis16209_read_14bit_signed, 411 adis16209_write_16bit, 412 ADIS16209_YACCL_NULL); 413static IIO_CONST_ATTR(accel_scale, "0.24414"); 414 415static IIO_DEV_ATTR_INCLI_X(adis16209_read_14bit_signed, 416 ADIS16209_XINCL_OUT); 417static IIO_DEV_ATTR_INCLI_Y(adis16209_read_14bit_signed, 418 ADIS16209_YINCL_OUT); 419static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO, 420 adis16209_read_14bit_signed, 421 adis16209_write_16bit, 422 ADIS16209_XACCL_NULL); 423static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO, 424 adis16209_read_14bit_signed, 425 adis16209_write_16bit, 426 ADIS16209_YACCL_NULL); 427static IIO_CONST_ATTR(incli_scale, "0.025"); 428 429static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed, 430 NULL, ADIS16209_ROT_OUT); 431 432static IIO_DEV_ATTR_TEMP(adis16209_read_temp); 433static IIO_CONST_ATTR(temp_offset, "25"); 434static IIO_CONST_ATTR(temp_scale, "-0.47"); 435 436static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0); 437 438static IIO_CONST_ATTR(name, "adis16209"); 439 440static struct attribute *adis16209_event_attributes[] = { 441 NULL 442}; 443 444static struct attribute_group adis16209_event_attribute_group = { 445 .attrs = adis16209_event_attributes, 446}; 447 448static struct attribute *adis16209_attributes[] = { 449 &iio_dev_attr_in_supply_raw.dev_attr.attr, 450 &iio_const_attr_in_supply_scale.dev_attr.attr, 451 &iio_dev_attr_temp.dev_attr.attr, 452 &iio_const_attr_temp_offset.dev_attr.attr, 453 &iio_const_attr_temp_scale.dev_attr.attr, 454 &iio_dev_attr_reset.dev_attr.attr, 455 &iio_const_attr_name.dev_attr.attr, 456 &iio_dev_attr_in0_raw.dev_attr.attr, 457 &iio_const_attr_in0_scale.dev_attr.attr, 458 &iio_dev_attr_accel_x_raw.dev_attr.attr, 459 &iio_dev_attr_accel_y_raw.dev_attr.attr, 460 &iio_dev_attr_accel_x_offset.dev_attr.attr, 461 &iio_dev_attr_accel_y_offset.dev_attr.attr, 462 &iio_const_attr_accel_scale.dev_attr.attr, 463 &iio_dev_attr_incli_x_raw.dev_attr.attr, 464 &iio_dev_attr_incli_y_raw.dev_attr.attr, 465 &iio_dev_attr_incli_x_offset.dev_attr.attr, 466 &iio_dev_attr_incli_y_offset.dev_attr.attr, 467 &iio_const_attr_incli_scale.dev_attr.attr, 468 &iio_dev_attr_rot_raw.dev_attr.attr, 469 NULL 470}; 471 472static const struct attribute_group adis16209_attribute_group = { 473 .attrs = adis16209_attributes, 474}; 475 476static int __devinit adis16209_probe(struct spi_device *spi) 477{ 478 int ret, regdone = 0; 479 struct adis16209_state *st = kzalloc(sizeof *st, GFP_KERNEL); 480 if (!st) { 481 ret = -ENOMEM; 482 goto error_ret; 483 } 484 /* this is only used for removal purposes */ 485 spi_set_drvdata(spi, st); 486 487 /* Allocate the comms buffers */ 488 st->rx = kzalloc(sizeof(*st->rx)*ADIS16209_MAX_RX, GFP_KERNEL); 489 if (st->rx == NULL) { 490 ret = -ENOMEM; 491 goto error_free_st; 492 } 493 st->tx = kzalloc(sizeof(*st->tx)*ADIS16209_MAX_TX, GFP_KERNEL); 494 if (st->tx == NULL) { 495 ret = -ENOMEM; 496 goto error_free_rx; 497 } 498 st->us = spi; 499 mutex_init(&st->buf_lock); 500 /* setup the industrialio driver allocated elements */ 501 st->indio_dev = iio_allocate_device(); 502 if (st->indio_dev == NULL) { 503 ret = -ENOMEM; 504 goto error_free_tx; 505 } 506 507 st->indio_dev->dev.parent = &spi->dev; 508 st->indio_dev->num_interrupt_lines = 1; 509 st->indio_dev->event_attrs = &adis16209_event_attribute_group; 510 st->indio_dev->attrs = &adis16209_attribute_group; 511 st->indio_dev->dev_data = (void *)(st); 512 st->indio_dev->driver_module = THIS_MODULE; 513 st->indio_dev->modes = INDIO_DIRECT_MODE; 514 515 ret = adis16209_configure_ring(st->indio_dev); 516 if (ret) 517 goto error_free_dev; 518 519 ret = iio_device_register(st->indio_dev); 520 if (ret) 521 goto error_unreg_ring_funcs; 522 regdone = 1; 523 524 ret = iio_ring_buffer_register(st->indio_dev->ring, 0); 525 if (ret) { 526 printk(KERN_ERR "failed to initialize the ring\n"); 527 goto error_unreg_ring_funcs; 528 } 529 530 if (spi->irq) { 531 ret = iio_register_interrupt_line(spi->irq, 532 st->indio_dev, 533 0, 534 IRQF_TRIGGER_RISING, 535 "adis16209"); 536 if (ret) 537 goto error_uninitialize_ring; 538 539 ret = adis16209_probe_trigger(st->indio_dev); 540 if (ret) 541 goto error_unregister_line; 542 } 543 544 /* Get the device into a sane initial state */ 545 ret = adis16209_initial_setup(st); 546 if (ret) 547 goto error_remove_trigger; 548 return 0; 549 550error_remove_trigger: 551 adis16209_remove_trigger(st->indio_dev); 552error_unregister_line: 553 if (spi->irq) 554 iio_unregister_interrupt_line(st->indio_dev, 0); 555error_uninitialize_ring: 556 iio_ring_buffer_unregister(st->indio_dev->ring); 557error_unreg_ring_funcs: 558 adis16209_unconfigure_ring(st->indio_dev); 559error_free_dev: 560 if (regdone) 561 iio_device_unregister(st->indio_dev); 562 else 563 iio_free_device(st->indio_dev); 564error_free_tx: 565 kfree(st->tx); 566error_free_rx: 567 kfree(st->rx); 568error_free_st: 569 kfree(st); 570error_ret: 571 return ret; 572} 573 574static int adis16209_remove(struct spi_device *spi) 575{ 576 struct adis16209_state *st = spi_get_drvdata(spi); 577 struct iio_dev *indio_dev = st->indio_dev; 578 579 flush_scheduled_work(); 580 581 adis16209_remove_trigger(indio_dev); 582 if (spi->irq) 583 iio_unregister_interrupt_line(indio_dev, 0); 584 585 iio_ring_buffer_unregister(indio_dev->ring); 586 iio_device_unregister(indio_dev); 587 adis16209_unconfigure_ring(indio_dev); 588 kfree(st->tx); 589 kfree(st->rx); 590 kfree(st); 591 592 return 0; 593} 594 595static struct spi_driver adis16209_driver = { 596 .driver = { 597 .name = "adis16209", 598 .owner = THIS_MODULE, 599 }, 600 .probe = adis16209_probe, 601 .remove = __devexit_p(adis16209_remove), 602}; 603 604static __init int adis16209_init(void) 605{ 606 return spi_register_driver(&adis16209_driver); 607} 608module_init(adis16209_init); 609 610static __exit void adis16209_exit(void) 611{ 612 spi_unregister_driver(&adis16209_driver); 613} 614module_exit(adis16209_exit); 615 616MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 617MODULE_DESCRIPTION("Analog Devices ADIS16209 Digital Vibration Sensor driver"); 618MODULE_LICENSE("GPL v2"); 619