linux/drivers/staging/iio/accel/adis16209_core.c
<<
>>
Prefs
   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(0, supply, adis16209_read_14bit_unsigned,
 395                ADIS16209_SUPPLY_OUT);
 396static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.30518");
 397static IIO_DEV_ATTR_IN_RAW(1, adis16209_read_12bit_unsigned,
 398                ADIS16209_AUX_ADC);
 399static IIO_CONST_ATTR(in1_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_CALIBBIAS(S_IWUSR | S_IRUGO,
 406                adis16209_read_14bit_signed,
 407                adis16209_write_16bit,
 408                ADIS16209_XACCL_NULL);
 409static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
 410                adis16209_read_14bit_signed,
 411                adis16209_write_16bit,
 412                ADIS16209_YACCL_NULL);
 413static IIO_CONST_ATTR_ACCEL_SCALE("0.002394195531");
 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_CONST_ATTR(incli_scale, "0.00043633231");
 420
 421static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed,
 422                       NULL, ADIS16209_ROT_OUT);
 423
 424static IIO_DEV_ATTR_TEMP_RAW(adis16209_read_temp);
 425static IIO_CONST_ATTR_TEMP_OFFSET("25");
 426static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
 427
 428static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
 429
 430static IIO_CONST_ATTR_NAME("adis16209");
 431
 432static struct attribute *adis16209_event_attributes[] = {
 433        NULL
 434};
 435
 436static struct attribute_group adis16209_event_attribute_group = {
 437        .attrs = adis16209_event_attributes,
 438};
 439
 440static struct attribute *adis16209_attributes[] = {
 441        &iio_dev_attr_in0_supply_raw.dev_attr.attr,
 442        &iio_const_attr_in0_supply_scale.dev_attr.attr,
 443        &iio_dev_attr_temp_raw.dev_attr.attr,
 444        &iio_const_attr_temp_offset.dev_attr.attr,
 445        &iio_const_attr_temp_scale.dev_attr.attr,
 446        &iio_dev_attr_reset.dev_attr.attr,
 447        &iio_const_attr_name.dev_attr.attr,
 448        &iio_dev_attr_in1_raw.dev_attr.attr,
 449        &iio_const_attr_in1_scale.dev_attr.attr,
 450        &iio_dev_attr_accel_x_raw.dev_attr.attr,
 451        &iio_dev_attr_accel_y_raw.dev_attr.attr,
 452        &iio_dev_attr_accel_x_calibbias.dev_attr.attr,
 453        &iio_dev_attr_accel_y_calibbias.dev_attr.attr,
 454        &iio_const_attr_accel_scale.dev_attr.attr,
 455        &iio_dev_attr_incli_x_raw.dev_attr.attr,
 456        &iio_dev_attr_incli_y_raw.dev_attr.attr,
 457        &iio_const_attr_incli_scale.dev_attr.attr,
 458        &iio_dev_attr_rot_raw.dev_attr.attr,
 459        NULL
 460};
 461
 462static const struct attribute_group adis16209_attribute_group = {
 463        .attrs = adis16209_attributes,
 464};
 465
 466static int __devinit adis16209_probe(struct spi_device *spi)
 467{
 468        int ret, regdone = 0;
 469        struct adis16209_state *st = kzalloc(sizeof *st, GFP_KERNEL);
 470        if (!st) {
 471                ret =  -ENOMEM;
 472                goto error_ret;
 473        }
 474        /* this is only used for removal purposes */
 475        spi_set_drvdata(spi, st);
 476
 477        /* Allocate the comms buffers */
 478        st->rx = kzalloc(sizeof(*st->rx)*ADIS16209_MAX_RX, GFP_KERNEL);
 479        if (st->rx == NULL) {
 480                ret = -ENOMEM;
 481                goto error_free_st;
 482        }
 483        st->tx = kzalloc(sizeof(*st->tx)*ADIS16209_MAX_TX, GFP_KERNEL);
 484        if (st->tx == NULL) {
 485                ret = -ENOMEM;
 486                goto error_free_rx;
 487        }
 488        st->us = spi;
 489        mutex_init(&st->buf_lock);
 490        /* setup the industrialio driver allocated elements */
 491        st->indio_dev = iio_allocate_device();
 492        if (st->indio_dev == NULL) {
 493                ret = -ENOMEM;
 494                goto error_free_tx;
 495        }
 496
 497        st->indio_dev->dev.parent = &spi->dev;
 498        st->indio_dev->num_interrupt_lines = 1;
 499        st->indio_dev->event_attrs = &adis16209_event_attribute_group;
 500        st->indio_dev->attrs = &adis16209_attribute_group;
 501        st->indio_dev->dev_data = (void *)(st);
 502        st->indio_dev->driver_module = THIS_MODULE;
 503        st->indio_dev->modes = INDIO_DIRECT_MODE;
 504
 505        ret = adis16209_configure_ring(st->indio_dev);
 506        if (ret)
 507                goto error_free_dev;
 508
 509        ret = iio_device_register(st->indio_dev);
 510        if (ret)
 511                goto error_unreg_ring_funcs;
 512        regdone = 1;
 513
 514        ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
 515        if (ret) {
 516                printk(KERN_ERR "failed to initialize the ring\n");
 517                goto error_unreg_ring_funcs;
 518        }
 519
 520        if (spi->irq) {
 521                ret = iio_register_interrupt_line(spi->irq,
 522                                st->indio_dev,
 523                                0,
 524                                IRQF_TRIGGER_RISING,
 525                                "adis16209");
 526                if (ret)
 527                        goto error_uninitialize_ring;
 528
 529                ret = adis16209_probe_trigger(st->indio_dev);
 530                if (ret)
 531                        goto error_unregister_line;
 532        }
 533
 534        /* Get the device into a sane initial state */
 535        ret = adis16209_initial_setup(st);
 536        if (ret)
 537                goto error_remove_trigger;
 538        return 0;
 539
 540error_remove_trigger:
 541        adis16209_remove_trigger(st->indio_dev);
 542error_unregister_line:
 543        if (spi->irq)
 544                iio_unregister_interrupt_line(st->indio_dev, 0);
 545error_uninitialize_ring:
 546        iio_ring_buffer_unregister(st->indio_dev->ring);
 547error_unreg_ring_funcs:
 548        adis16209_unconfigure_ring(st->indio_dev);
 549error_free_dev:
 550        if (regdone)
 551                iio_device_unregister(st->indio_dev);
 552        else
 553                iio_free_device(st->indio_dev);
 554error_free_tx:
 555        kfree(st->tx);
 556error_free_rx:
 557        kfree(st->rx);
 558error_free_st:
 559        kfree(st);
 560error_ret:
 561        return ret;
 562}
 563
 564static int adis16209_remove(struct spi_device *spi)
 565{
 566        struct adis16209_state *st = spi_get_drvdata(spi);
 567        struct iio_dev *indio_dev = st->indio_dev;
 568
 569        flush_scheduled_work();
 570
 571        adis16209_remove_trigger(indio_dev);
 572        if (spi->irq)
 573                iio_unregister_interrupt_line(indio_dev, 0);
 574
 575        iio_ring_buffer_unregister(indio_dev->ring);
 576        iio_device_unregister(indio_dev);
 577        adis16209_unconfigure_ring(indio_dev);
 578        kfree(st->tx);
 579        kfree(st->rx);
 580        kfree(st);
 581
 582        return 0;
 583}
 584
 585static struct spi_driver adis16209_driver = {
 586        .driver = {
 587                .name = "adis16209",
 588                .owner = THIS_MODULE,
 589        },
 590        .probe = adis16209_probe,
 591        .remove = __devexit_p(adis16209_remove),
 592};
 593
 594static __init int adis16209_init(void)
 595{
 596        return spi_register_driver(&adis16209_driver);
 597}
 598module_init(adis16209_init);
 599
 600static __exit void adis16209_exit(void)
 601{
 602        spi_unregister_driver(&adis16209_driver);
 603}
 604module_exit(adis16209_exit);
 605
 606MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
 607MODULE_DESCRIPTION("Analog Devices ADIS16209 Digital Vibration Sensor driver");
 608MODULE_LICENSE("GPL v2");
 609