1/* 2 * ADIS16204 Programmable High-g Digital Impact Sensor and Recorder 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 "../buffer.h" 24 25#include "adis16204.h" 26 27#define DRIVER_NAME "adis16204" 28 29/** 30 * adis16204_spi_write_reg_8() - write single byte to a register 31 * @dev: device associated with child of actual device (iio_dev or iio_trig) 32 * @reg_address: the address of the register to be written 33 * @val: the value to write 34 **/ 35static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev, 36 u8 reg_address, 37 u8 val) 38{ 39 int ret; 40 struct adis16204_state *st = iio_priv(indio_dev); 41 42 mutex_lock(&st->buf_lock); 43 st->tx[0] = ADIS16204_WRITE_REG(reg_address); 44 st->tx[1] = val; 45 46 ret = spi_write(st->us, st->tx, 2); 47 mutex_unlock(&st->buf_lock); 48 49 return ret; 50} 51 52/** 53 * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers 54 * @indio_dev: iio device associated with child of actual device 55 * @reg_address: the address of the lower of the two registers. Second register 56 * is assumed to have address one greater. 57 * @val: value to be written 58 **/ 59static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev, 60 u8 lower_reg_address, 61 u16 value) 62{ 63 int ret; 64 struct spi_message msg; 65 struct adis16204_state *st = iio_priv(indio_dev); 66 struct spi_transfer xfers[] = { 67 { 68 .tx_buf = st->tx, 69 .bits_per_word = 8, 70 .len = 2, 71 .cs_change = 1, 72 }, { 73 .tx_buf = st->tx + 2, 74 .bits_per_word = 8, 75 .len = 2, 76 .cs_change = 1, 77 }, 78 }; 79 80 mutex_lock(&st->buf_lock); 81 st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address); 82 st->tx[1] = value & 0xFF; 83 st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1); 84 st->tx[3] = (value >> 8) & 0xFF; 85 86 spi_message_init(&msg); 87 spi_message_add_tail(&xfers[0], &msg); 88 spi_message_add_tail(&xfers[1], &msg); 89 ret = spi_sync(st->us, &msg); 90 mutex_unlock(&st->buf_lock); 91 92 return ret; 93} 94 95/** 96 * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register 97 * @indio_dev: iio device associated with child of actual device 98 * @reg_address: the address of the lower of the two registers. Second register 99 * is assumed to have address one greater. 100 * @val: somewhere to pass back the value read 101 **/ 102static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev, 103 u8 lower_reg_address, 104 u16 *val) 105{ 106 struct spi_message msg; 107 struct adis16204_state *st = iio_priv(indio_dev); 108 int ret; 109 struct spi_transfer xfers[] = { 110 { 111 .tx_buf = st->tx, 112 .bits_per_word = 8, 113 .len = 2, 114 .cs_change = 1, 115 .delay_usecs = 20, 116 }, { 117 .rx_buf = st->rx, 118 .bits_per_word = 8, 119 .len = 2, 120 .delay_usecs = 20, 121 }, 122 }; 123 124 mutex_lock(&st->buf_lock); 125 st->tx[0] = ADIS16204_READ_REG(lower_reg_address); 126 st->tx[1] = 0; 127 128 spi_message_init(&msg); 129 spi_message_add_tail(&xfers[0], &msg); 130 spi_message_add_tail(&xfers[1], &msg); 131 ret = spi_sync(st->us, &msg); 132 if (ret) { 133 dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", 134 lower_reg_address); 135 goto error_ret; 136 } 137 *val = (st->rx[0] << 8) | st->rx[1]; 138 139error_ret: 140 mutex_unlock(&st->buf_lock); 141 return ret; 142} 143 144static int adis16204_check_status(struct iio_dev *indio_dev) 145{ 146 u16 status; 147 int ret; 148 149 ret = adis16204_spi_read_reg_16(indio_dev, 150 ADIS16204_DIAG_STAT, &status); 151 if (ret < 0) { 152 dev_err(&indio_dev->dev, "Reading status failed\n"); 153 goto error_ret; 154 } 155 ret = status & 0x1F; 156 157 if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL) 158 dev_err(&indio_dev->dev, "Self test failure\n"); 159 if (status & ADIS16204_DIAG_STAT_SPI_FAIL) 160 dev_err(&indio_dev->dev, "SPI failure\n"); 161 if (status & ADIS16204_DIAG_STAT_FLASH_UPT) 162 dev_err(&indio_dev->dev, "Flash update failed\n"); 163 if (status & ADIS16204_DIAG_STAT_POWER_HIGH) 164 dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); 165 if (status & ADIS16204_DIAG_STAT_POWER_LOW) 166 dev_err(&indio_dev->dev, "Power supply below 2.975V\n"); 167 168error_ret: 169 return ret; 170} 171 172static ssize_t adis16204_read_14bit_signed(struct device *dev, 173 struct device_attribute *attr, 174 char *buf) 175{ 176 struct iio_dev *indio_dev = dev_get_drvdata(dev); 177 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 178 s16 val = 0; 179 ssize_t ret; 180 181 mutex_lock(&indio_dev->mlock); 182 183 ret = adis16204_spi_read_reg_16(indio_dev, 184 this_attr->address, (u16 *)&val); 185 if (!ret) { 186 if (val & ADIS16204_ERROR_ACTIVE) 187 adis16204_check_status(indio_dev); 188 189 val = ((s16)(val << 2) >> 2); 190 ret = sprintf(buf, "%d\n", val); 191 } 192 193 mutex_unlock(&indio_dev->mlock); 194 195 return ret; 196} 197 198static int adis16204_reset(struct iio_dev *indio_dev) 199{ 200 int ret; 201 ret = adis16204_spi_write_reg_8(indio_dev, 202 ADIS16204_GLOB_CMD, 203 ADIS16204_GLOB_CMD_SW_RESET); 204 if (ret) 205 dev_err(&indio_dev->dev, "problem resetting device"); 206 207 return ret; 208} 209 210static ssize_t adis16204_write_reset(struct device *dev, 211 struct device_attribute *attr, 212 const char *buf, size_t len) 213{ 214 struct iio_dev *indio_dev = dev_get_drvdata(dev); 215 216 if (len < 1) 217 return -EINVAL; 218 switch (buf[0]) { 219 case '1': 220 case 'y': 221 case 'Y': 222 return adis16204_reset(indio_dev); 223 } 224 return -EINVAL; 225} 226 227int adis16204_set_irq(struct iio_dev *indio_dev, bool enable) 228{ 229 int ret = 0; 230 u16 msc; 231 232 ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc); 233 if (ret) 234 goto error_ret; 235 236 msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH; 237 msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2; 238 if (enable) 239 msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN; 240 else 241 msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN; 242 243 ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc); 244 245error_ret: 246 return ret; 247} 248 249static int adis16204_self_test(struct iio_dev *indio_dev) 250{ 251 int ret; 252 ret = adis16204_spi_write_reg_16(indio_dev, 253 ADIS16204_MSC_CTRL, 254 ADIS16204_MSC_CTRL_SELF_TEST_EN); 255 if (ret) { 256 dev_err(&indio_dev->dev, "problem starting self test"); 257 goto err_ret; 258 } 259 260 adis16204_check_status(indio_dev); 261 262err_ret: 263 return ret; 264} 265 266static int adis16204_initial_setup(struct iio_dev *indio_dev) 267{ 268 int ret; 269 270 /* Disable IRQ */ 271 ret = adis16204_set_irq(indio_dev, false); 272 if (ret) { 273 dev_err(&indio_dev->dev, "disable irq failed"); 274 goto err_ret; 275 } 276 277 /* Do self test */ 278 ret = adis16204_self_test(indio_dev); 279 if (ret) { 280 dev_err(&indio_dev->dev, "self test failure"); 281 goto err_ret; 282 } 283 284 /* Read status register to check the result */ 285 ret = adis16204_check_status(indio_dev); 286 if (ret) { 287 adis16204_reset(indio_dev); 288 dev_err(&indio_dev->dev, "device not playing ball -> reset"); 289 msleep(ADIS16204_STARTUP_DELAY); 290 ret = adis16204_check_status(indio_dev); 291 if (ret) { 292 dev_err(&indio_dev->dev, "giving up"); 293 goto err_ret; 294 } 295 } 296 297err_ret: 298 return ret; 299} 300 301/* Unique to this driver currently */ 302#define IIO_DEV_ATTR_ACCEL_XY(_show, _addr) \ 303 IIO_DEVICE_ATTR(in_accel_xy, S_IRUGO, _show, NULL, _addr) 304#define IIO_DEV_ATTR_ACCEL_XYPEAK(_show, _addr) \ 305 IIO_DEVICE_ATTR(in_accel_xypeak, S_IRUGO, _show, NULL, _addr) 306 307static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed, 308 ADIS16204_XY_RSS_OUT); 309static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed, 310 ADIS16204_XY_PEAK_OUT); 311static IIO_CONST_ATTR(in_accel_xy_scale, "0.017125"); 312 313static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0); 314 315enum adis16204_channel { 316 in_supply, 317 in_aux, 318 temp, 319 accel_x, 320 accel_y, 321}; 322 323static u8 adis16204_addresses[5][3] = { 324 [in_supply] = { ADIS16204_SUPPLY_OUT }, 325 [in_aux] = { ADIS16204_AUX_ADC }, 326 [temp] = { ADIS16204_TEMP_OUT }, 327 [accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL, 328 ADIS16204_X_PEAK_OUT }, 329 [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL, 330 ADIS16204_Y_PEAK_OUT }, 331}; 332 333static int adis16204_read_raw(struct iio_dev *indio_dev, 334 struct iio_chan_spec const *chan, 335 int *val, int *val2, 336 long mask) 337{ 338 int ret; 339 int bits; 340 u8 addr; 341 s16 val16; 342 int addrind; 343 344 switch (mask) { 345 case 0: 346 mutex_lock(&indio_dev->mlock); 347 addr = adis16204_addresses[chan->address][0]; 348 ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); 349 if (ret) { 350 mutex_unlock(&indio_dev->mlock); 351 return ret; 352 } 353 354 if (val16 & ADIS16204_ERROR_ACTIVE) { 355 ret = adis16204_check_status(indio_dev); 356 if (ret) { 357 mutex_unlock(&indio_dev->mlock); 358 return ret; 359 } 360 } 361 val16 = val16 & ((1 << chan->scan_type.realbits) - 1); 362 if (chan->scan_type.sign == 's') 363 val16 = (s16)(val16 << 364 (16 - chan->scan_type.realbits)) >> 365 (16 - chan->scan_type.realbits); 366 *val = val16; 367 mutex_unlock(&indio_dev->mlock); 368 return IIO_VAL_INT; 369 case IIO_CHAN_INFO_SCALE: 370 switch (chan->type) { 371 case IIO_VOLTAGE: 372 *val = 0; 373 if (chan->channel == 0) 374 *val2 = 1220; 375 else 376 *val2 = 610; 377 return IIO_VAL_INT_PLUS_MICRO; 378 case IIO_TEMP: 379 *val = 0; 380 *val2 = -470000; 381 return IIO_VAL_INT_PLUS_MICRO; 382 case IIO_ACCEL: 383 *val = 0; 384 if (chan->channel == 'x') 385 *val2 = 17125; 386 else 387 *val2 = 8407; 388 return IIO_VAL_INT_PLUS_MICRO; 389 default: 390 return -EINVAL; 391 } 392 break; 393 case IIO_CHAN_INFO_OFFSET: 394 *val = 25; 395 return IIO_VAL_INT; 396 case IIO_CHAN_INFO_CALIBBIAS: 397 case IIO_CHAN_INFO_PEAK: 398 if (mask == IIO_CHAN_INFO_CALIBBIAS) { 399 bits = 12; 400 addrind = 1; 401 } else { /* PEAK_SEPARATE */ 402 bits = 14; 403 addrind = 2; 404 } 405 mutex_lock(&indio_dev->mlock); 406 addr = adis16204_addresses[chan->address][addrind]; 407 ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); 408 if (ret) { 409 mutex_unlock(&indio_dev->mlock); 410 return ret; 411 } 412 val16 &= (1 << bits) - 1; 413 val16 = (s16)(val16 << (16 - bits)) >> (16 - bits); 414 *val = val16; 415 mutex_unlock(&indio_dev->mlock); 416 return IIO_VAL_INT; 417 } 418 return -EINVAL; 419} 420 421static int adis16204_write_raw(struct iio_dev *indio_dev, 422 struct iio_chan_spec const *chan, 423 int val, 424 int val2, 425 long mask) 426{ 427 int bits; 428 s16 val16; 429 u8 addr; 430 switch (mask) { 431 case IIO_CHAN_INFO_CALIBBIAS: 432 switch (chan->type) { 433 case IIO_ACCEL: 434 bits = 12; 435 break; 436 default: 437 return -EINVAL; 438 }; 439 val16 = val & ((1 << bits) - 1); 440 addr = adis16204_addresses[chan->address][1]; 441 return adis16204_spi_write_reg_16(indio_dev, addr, val16); 442 } 443 return -EINVAL; 444} 445 446static struct iio_chan_spec adis16204_channels[] = { 447 IIO_CHAN(IIO_VOLTAGE, 0, 0, 0, "supply", 0, 0, 448 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, 449 in_supply, ADIS16204_SCAN_SUPPLY, 450 IIO_ST('u', 12, 16, 0), 0), 451 IIO_CHAN(IIO_VOLTAGE, 0, 1, 0, NULL, 1, 0, 452 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, 453 in_aux, ADIS16204_SCAN_AUX_ADC, 454 IIO_ST('u', 12, 16, 0), 0), 455 IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, 456 IIO_CHAN_INFO_SCALE_SEPARATE_BIT | 457 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, 458 temp, ADIS16204_SCAN_TEMP, 459 IIO_ST('u', 12, 16, 0), 0), 460 IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, 461 IIO_CHAN_INFO_SCALE_SEPARATE_BIT | 462 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | 463 IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 464 accel_x, ADIS16204_SCAN_ACC_X, 465 IIO_ST('s', 14, 16, 0), 0), 466 IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, 467 IIO_CHAN_INFO_SCALE_SEPARATE_BIT | 468 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | 469 IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 470 accel_y, ADIS16204_SCAN_ACC_Y, 471 IIO_ST('s', 14, 16, 0), 0), 472 IIO_CHAN_SOFT_TIMESTAMP(5), 473}; 474 475static struct attribute *adis16204_attributes[] = { 476 &iio_dev_attr_reset.dev_attr.attr, 477 &iio_dev_attr_in_accel_xy.dev_attr.attr, 478 &iio_dev_attr_in_accel_xypeak.dev_attr.attr, 479 &iio_const_attr_in_accel_xy_scale.dev_attr.attr, 480 NULL 481}; 482 483static const struct attribute_group adis16204_attribute_group = { 484 .attrs = adis16204_attributes, 485}; 486 487static const struct iio_info adis16204_info = { 488 .attrs = &adis16204_attribute_group, 489 .read_raw = &adis16204_read_raw, 490 .write_raw = &adis16204_write_raw, 491 .driver_module = THIS_MODULE, 492}; 493 494static int __devinit adis16204_probe(struct spi_device *spi) 495{ 496 int ret; 497 struct adis16204_state *st; 498 struct iio_dev *indio_dev; 499 500 /* setup the industrialio driver allocated elements */ 501 indio_dev = iio_allocate_device(sizeof(*st)); 502 if (indio_dev == NULL) { 503 ret = -ENOMEM; 504 goto error_ret; 505 } 506 st = iio_priv(indio_dev); 507 /* this is only used for removal purposes */ 508 spi_set_drvdata(spi, indio_dev); 509 st->us = spi; 510 mutex_init(&st->buf_lock); 511 512 indio_dev->name = spi->dev.driver->name; 513 indio_dev->dev.parent = &spi->dev; 514 indio_dev->info = &adis16204_info; 515 indio_dev->channels = adis16204_channels; 516 indio_dev->num_channels = ARRAY_SIZE(adis16204_channels); 517 indio_dev->modes = INDIO_DIRECT_MODE; 518 519 ret = adis16204_configure_ring(indio_dev); 520 if (ret) 521 goto error_free_dev; 522 523 ret = iio_buffer_register(indio_dev, 524 adis16204_channels, 525 ARRAY_SIZE(adis16204_channels)); 526 if (ret) { 527 printk(KERN_ERR "failed to initialize the ring\n"); 528 goto error_unreg_ring_funcs; 529 } 530 531 if (spi->irq) { 532 ret = adis16204_probe_trigger(indio_dev); 533 if (ret) 534 goto error_uninitialize_ring; 535 } 536 537 /* Get the device into a sane initial state */ 538 ret = adis16204_initial_setup(indio_dev); 539 if (ret) 540 goto error_remove_trigger; 541 ret = iio_device_register(indio_dev); 542 if (ret) 543 goto error_remove_trigger; 544 545 return 0; 546 547error_remove_trigger: 548 adis16204_remove_trigger(indio_dev); 549error_uninitialize_ring: 550 iio_buffer_unregister(indio_dev); 551error_unreg_ring_funcs: 552 adis16204_unconfigure_ring(indio_dev); 553error_free_dev: 554 iio_free_device(indio_dev); 555error_ret: 556 return ret; 557} 558 559static int adis16204_remove(struct spi_device *spi) 560{ 561 struct iio_dev *indio_dev = spi_get_drvdata(spi); 562 563 iio_device_unregister(indio_dev); 564 adis16204_remove_trigger(indio_dev); 565 iio_buffer_unregister(indio_dev); 566 adis16204_unconfigure_ring(indio_dev); 567 iio_free_device(indio_dev); 568 569 return 0; 570} 571 572static struct spi_driver adis16204_driver = { 573 .driver = { 574 .name = "adis16204", 575 .owner = THIS_MODULE, 576 }, 577 .probe = adis16204_probe, 578 .remove = __devexit_p(adis16204_remove), 579}; 580module_spi_driver(adis16204_driver); 581 582MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 583MODULE_DESCRIPTION("ADIS16204 High-g Digital Impact Sensor and Recorder"); 584MODULE_LICENSE("GPL v2"); 585MODULE_ALIAS("spi:adis16204"); 586