linux/drivers/staging/iio/accel/lis3l02dq_core.c
<<
>>
Prefs
   1/*
   2 * lis3l02dq.c  support STMicroelectronics LISD02DQ
   3 *              3d 2g Linear Accelerometers via SPI
   4 *
   5 * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 * Settings:
  12 * 16 bit left justified mode used.
  13 */
  14
  15#include <linux/interrupt.h>
  16#include <linux/irq.h>
  17#include <linux/gpio.h>
  18#include <linux/of_gpio.h>
  19#include <linux/mutex.h>
  20#include <linux/device.h>
  21#include <linux/kernel.h>
  22#include <linux/spi/spi.h>
  23#include <linux/slab.h>
  24#include <linux/sysfs.h>
  25#include <linux/module.h>
  26
  27#include <linux/iio/iio.h>
  28#include <linux/iio/sysfs.h>
  29#include <linux/iio/events.h>
  30#include <linux/iio/buffer.h>
  31
  32#include "lis3l02dq.h"
  33
  34/* At the moment the spi framework doesn't allow global setting of cs_change.
  35 * It's in the likely to be added comment at the top of spi.h.
  36 * This means that use cannot be made of spi_write etc.
  37 */
  38/* direct copy of the irq_default_primary_handler */
  39#ifndef CONFIG_IIO_BUFFER
  40static irqreturn_t lis3l02dq_nobuffer(int irq, void *private)
  41{
  42        return IRQ_WAKE_THREAD;
  43}
  44#endif
  45
  46/**
  47 * lis3l02dq_spi_read_reg_8() - read single byte from a single register
  48 * @indio_dev: iio_dev for this actual device
  49 * @reg_address: the address of the register to be read
  50 * @val: pass back the resulting value
  51 **/
  52int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
  53                             u8 reg_address, u8 *val)
  54{
  55        struct lis3l02dq_state *st = iio_priv(indio_dev);
  56        int ret;
  57        struct spi_transfer xfer = {
  58                .tx_buf = st->tx,
  59                .rx_buf = st->rx,
  60                .bits_per_word = 8,
  61                .len = 2,
  62        };
  63
  64        mutex_lock(&st->buf_lock);
  65        st->tx[0] = LIS3L02DQ_READ_REG(reg_address);
  66        st->tx[1] = 0;
  67
  68        ret = spi_sync_transfer(st->us, &xfer, 1);
  69        *val = st->rx[1];
  70        mutex_unlock(&st->buf_lock);
  71
  72        return ret;
  73}
  74
  75/**
  76 * lis3l02dq_spi_write_reg_8() - write single byte to a register
  77 * @indio_dev: iio_dev for this device
  78 * @reg_address: the address of the register to be written
  79 * @val: the value to write
  80 **/
  81int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
  82                              u8 reg_address,
  83                              u8 val)
  84{
  85        int ret;
  86        struct lis3l02dq_state *st = iio_priv(indio_dev);
  87
  88        mutex_lock(&st->buf_lock);
  89        st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
  90        st->tx[1] = val;
  91        ret = spi_write(st->us, st->tx, 2);
  92        mutex_unlock(&st->buf_lock);
  93
  94        return ret;
  95}
  96
  97/**
  98 * lisl302dq_spi_write_reg_s16() - write 2 bytes to a pair of registers
  99 * @indio_dev: iio_dev for this device
 100 * @lower_reg_address: the address of the lower of the two registers.
 101 *               Second register is assumed to have address one greater.
 102 * @value: value to be written
 103 **/
 104static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
 105                                       u8 lower_reg_address,
 106                                       s16 value)
 107{
 108        int ret;
 109        struct lis3l02dq_state *st = iio_priv(indio_dev);
 110        struct spi_transfer xfers[] = { {
 111                        .tx_buf = st->tx,
 112                        .bits_per_word = 8,
 113                        .len = 2,
 114                        .cs_change = 1,
 115                }, {
 116                        .tx_buf = st->tx + 2,
 117                        .bits_per_word = 8,
 118                        .len = 2,
 119                },
 120        };
 121
 122        mutex_lock(&st->buf_lock);
 123        st->tx[0] = LIS3L02DQ_WRITE_REG(lower_reg_address);
 124        st->tx[1] = value & 0xFF;
 125        st->tx[2] = LIS3L02DQ_WRITE_REG(lower_reg_address + 1);
 126        st->tx[3] = (value >> 8) & 0xFF;
 127
 128        ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
 129        mutex_unlock(&st->buf_lock);
 130
 131        return ret;
 132}
 133
 134static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
 135                                  u8 lower_reg_address,
 136                                  int *val)
 137{
 138        struct lis3l02dq_state *st = iio_priv(indio_dev);
 139        int ret;
 140        s16 tempval;
 141        struct spi_transfer xfers[] = { {
 142                        .tx_buf = st->tx,
 143                        .rx_buf = st->rx,
 144                        .bits_per_word = 8,
 145                        .len = 2,
 146                        .cs_change = 1,
 147                }, {
 148                        .tx_buf = st->tx + 2,
 149                        .rx_buf = st->rx + 2,
 150                        .bits_per_word = 8,
 151                        .len = 2,
 152                },
 153        };
 154
 155        mutex_lock(&st->buf_lock);
 156        st->tx[0] = LIS3L02DQ_READ_REG(lower_reg_address);
 157        st->tx[1] = 0;
 158        st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address + 1);
 159        st->tx[3] = 0;
 160
 161        ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
 162        if (ret) {
 163                dev_err(&st->us->dev, "problem when reading 16 bit register");
 164                goto error_ret;
 165        }
 166        tempval = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
 167
 168        *val = tempval;
 169error_ret:
 170        mutex_unlock(&st->buf_lock);
 171        return ret;
 172}
 173
 174enum lis3l02dq_rm_ind {
 175        LIS3L02DQ_ACCEL,
 176        LIS3L02DQ_GAIN,
 177        LIS3L02DQ_BIAS,
 178};
 179
 180static u8 lis3l02dq_axis_map[3][3] = {
 181        [LIS3L02DQ_ACCEL] = { LIS3L02DQ_REG_OUT_X_L_ADDR,
 182                              LIS3L02DQ_REG_OUT_Y_L_ADDR,
 183                              LIS3L02DQ_REG_OUT_Z_L_ADDR },
 184        [LIS3L02DQ_GAIN] = { LIS3L02DQ_REG_GAIN_X_ADDR,
 185                             LIS3L02DQ_REG_GAIN_Y_ADDR,
 186                             LIS3L02DQ_REG_GAIN_Z_ADDR },
 187        [LIS3L02DQ_BIAS] = { LIS3L02DQ_REG_OFFSET_X_ADDR,
 188                             LIS3L02DQ_REG_OFFSET_Y_ADDR,
 189                             LIS3L02DQ_REG_OFFSET_Z_ADDR }
 190};
 191
 192static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
 193                                 const struct iio_chan_spec *chan,
 194                                 enum iio_event_type type,
 195                                 enum iio_event_direction dir,
 196                                 enum iio_event_info info,
 197                                 int *val, int *val2)
 198{
 199        int ret;
 200
 201        ret = lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
 202        if (ret)
 203                return ret;
 204        return IIO_VAL_INT;
 205}
 206
 207static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
 208                                  const struct iio_chan_spec *chan,
 209                                  enum iio_event_type type,
 210                                  enum iio_event_direction dir,
 211                                  enum iio_event_info info,
 212                                  int val, int val2)
 213{
 214        u16 value = val;
 215        return lis3l02dq_spi_write_reg_s16(indio_dev,
 216                                           LIS3L02DQ_REG_THS_L_ADDR,
 217                                           value);
 218}
 219
 220static int lis3l02dq_write_raw(struct iio_dev *indio_dev,
 221                               struct iio_chan_spec const *chan,
 222                               int val,
 223                               int val2,
 224                               long mask)
 225{
 226        int ret = -EINVAL, reg;
 227        u8 uval;
 228        s8 sval;
 229        switch (mask) {
 230        case IIO_CHAN_INFO_CALIBBIAS:
 231                if (val > 255 || val < -256)
 232                        return -EINVAL;
 233                sval = val;
 234                reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
 235                ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, sval);
 236                break;
 237        case IIO_CHAN_INFO_CALIBSCALE:
 238                if (val & ~0xFF)
 239                        return -EINVAL;
 240                uval = val;
 241                reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
 242                ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, uval);
 243                break;
 244        }
 245        return ret;
 246}
 247
 248static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
 249                              struct iio_chan_spec const *chan,
 250                              int *val,
 251                              int *val2,
 252                              long mask)
 253{
 254        u8 utemp;
 255        s8 stemp;
 256        ssize_t ret = 0;
 257        u8 reg;
 258
 259        switch (mask) {
 260        case IIO_CHAN_INFO_RAW:
 261                /* Take the iio_dev status lock */
 262                mutex_lock(&indio_dev->mlock);
 263                if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
 264                        ret = -EBUSY;
 265                } else {
 266                        reg = lis3l02dq_axis_map
 267                                [LIS3L02DQ_ACCEL][chan->address];
 268                        ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
 269                }
 270                mutex_unlock(&indio_dev->mlock);
 271                if (ret < 0)
 272                        goto error_ret;
 273                return IIO_VAL_INT;
 274        case IIO_CHAN_INFO_SCALE:
 275                *val = 0;
 276                *val2 = 9580;
 277                return IIO_VAL_INT_PLUS_MICRO;
 278        case IIO_CHAN_INFO_CALIBSCALE:
 279                reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
 280                ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, &utemp);
 281                if (ret)
 282                        goto error_ret;
 283                /* to match with what previous code does */
 284                *val = utemp;
 285                return IIO_VAL_INT;
 286
 287        case IIO_CHAN_INFO_CALIBBIAS:
 288                reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
 289                ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, (u8 *)&stemp);
 290                /* to match with what previous code does */
 291                *val = stemp;
 292                return IIO_VAL_INT;
 293        }
 294error_ret:
 295        return ret;
 296}
 297
 298static ssize_t lis3l02dq_read_frequency(struct device *dev,
 299                                        struct device_attribute *attr,
 300                                        char *buf)
 301{
 302        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 303        int ret, len = 0;
 304        s8 t;
 305        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 306                                       LIS3L02DQ_REG_CTRL_1_ADDR,
 307                                       (u8 *)&t);
 308        if (ret)
 309                return ret;
 310        t &= LIS3L02DQ_DEC_MASK;
 311        switch (t) {
 312        case LIS3L02DQ_REG_CTRL_1_DF_128:
 313                len = sprintf(buf, "280\n");
 314                break;
 315        case LIS3L02DQ_REG_CTRL_1_DF_64:
 316                len = sprintf(buf, "560\n");
 317                break;
 318        case LIS3L02DQ_REG_CTRL_1_DF_32:
 319                len = sprintf(buf, "1120\n");
 320                break;
 321        case LIS3L02DQ_REG_CTRL_1_DF_8:
 322                len = sprintf(buf, "4480\n");
 323                break;
 324        }
 325        return len;
 326}
 327
 328static ssize_t lis3l02dq_write_frequency(struct device *dev,
 329                                         struct device_attribute *attr,
 330                                         const char *buf,
 331                                         size_t len)
 332{
 333        struct iio_dev *indio_dev = dev_to_iio_dev(dev);
 334        unsigned long val;
 335        int ret;
 336        u8 t;
 337
 338        ret = kstrtoul(buf, 10, &val);
 339        if (ret)
 340                return ret;
 341
 342        mutex_lock(&indio_dev->mlock);
 343        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 344                                       LIS3L02DQ_REG_CTRL_1_ADDR,
 345                                       &t);
 346        if (ret)
 347                goto error_ret_mutex;
 348        /* Wipe the bits clean */
 349        t &= ~LIS3L02DQ_DEC_MASK;
 350        switch (val) {
 351        case 280:
 352                t |= LIS3L02DQ_REG_CTRL_1_DF_128;
 353                break;
 354        case 560:
 355                t |= LIS3L02DQ_REG_CTRL_1_DF_64;
 356                break;
 357        case 1120:
 358                t |= LIS3L02DQ_REG_CTRL_1_DF_32;
 359                break;
 360        case 4480:
 361                t |= LIS3L02DQ_REG_CTRL_1_DF_8;
 362                break;
 363        default:
 364                ret = -EINVAL;
 365                goto error_ret_mutex;
 366        }
 367
 368        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 369                                        LIS3L02DQ_REG_CTRL_1_ADDR,
 370                                        t);
 371
 372error_ret_mutex:
 373        mutex_unlock(&indio_dev->mlock);
 374
 375        return ret ? ret : len;
 376}
 377
 378static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
 379{
 380        struct lis3l02dq_state *st = iio_priv(indio_dev);
 381        int ret;
 382        u8 val, valtest;
 383
 384        st->us->mode = SPI_MODE_3;
 385
 386        spi_setup(st->us);
 387
 388        val = LIS3L02DQ_DEFAULT_CTRL1;
 389        /* Write suitable defaults to ctrl1 */
 390        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 391                                        LIS3L02DQ_REG_CTRL_1_ADDR,
 392                                        val);
 393        if (ret) {
 394                dev_err(&st->us->dev, "problem with setup control register 1");
 395                goto err_ret;
 396        }
 397        /* Repeat as sometimes doesn't work first time? */
 398        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 399                                        LIS3L02DQ_REG_CTRL_1_ADDR,
 400                                        val);
 401        if (ret) {
 402                dev_err(&st->us->dev, "problem with setup control register 1");
 403                goto err_ret;
 404        }
 405
 406        /* Read back to check this has worked acts as loose test of correct
 407         * chip */
 408        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 409                                       LIS3L02DQ_REG_CTRL_1_ADDR,
 410                                       &valtest);
 411        if (ret || (valtest != val)) {
 412                dev_err(&indio_dev->dev,
 413                        "device not playing ball %d %d\n", valtest, val);
 414                ret = -EINVAL;
 415                goto err_ret;
 416        }
 417
 418        val = LIS3L02DQ_DEFAULT_CTRL2;
 419        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 420                                        LIS3L02DQ_REG_CTRL_2_ADDR,
 421                                        val);
 422        if (ret) {
 423                dev_err(&st->us->dev, "problem with setup control register 2");
 424                goto err_ret;
 425        }
 426
 427        val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
 428        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 429                                        LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 430                                        val);
 431        if (ret)
 432                dev_err(&st->us->dev, "problem with interrupt cfg register");
 433err_ret:
 434
 435        return ret;
 436}
 437
 438static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 439                              lis3l02dq_read_frequency,
 440                              lis3l02dq_write_frequency);
 441
 442static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
 443
 444static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 445{
 446        struct iio_dev *indio_dev = private;
 447        u8 t;
 448
 449        s64 timestamp = iio_get_time_ns();
 450
 451        lis3l02dq_spi_read_reg_8(indio_dev,
 452                                 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
 453                                 &t);
 454
 455        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
 456                iio_push_event(indio_dev,
 457                               IIO_MOD_EVENT_CODE(IIO_ACCEL,
 458                                                  0,
 459                                                  IIO_MOD_Z,
 460                                                  IIO_EV_TYPE_THRESH,
 461                                                  IIO_EV_DIR_RISING),
 462                               timestamp);
 463
 464        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
 465                iio_push_event(indio_dev,
 466                               IIO_MOD_EVENT_CODE(IIO_ACCEL,
 467                                                  0,
 468                                                  IIO_MOD_Z,
 469                                                  IIO_EV_TYPE_THRESH,
 470                                                  IIO_EV_DIR_FALLING),
 471                               timestamp);
 472
 473        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
 474                iio_push_event(indio_dev,
 475                               IIO_MOD_EVENT_CODE(IIO_ACCEL,
 476                                                  0,
 477                                                  IIO_MOD_Y,
 478                                                  IIO_EV_TYPE_THRESH,
 479                                                  IIO_EV_DIR_RISING),
 480                               timestamp);
 481
 482        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
 483                iio_push_event(indio_dev,
 484                               IIO_MOD_EVENT_CODE(IIO_ACCEL,
 485                                                  0,
 486                                                  IIO_MOD_Y,
 487                                                  IIO_EV_TYPE_THRESH,
 488                                                  IIO_EV_DIR_FALLING),
 489                               timestamp);
 490
 491        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
 492                iio_push_event(indio_dev,
 493                               IIO_MOD_EVENT_CODE(IIO_ACCEL,
 494                                                  0,
 495                                                  IIO_MOD_X,
 496                                                  IIO_EV_TYPE_THRESH,
 497                                                  IIO_EV_DIR_RISING),
 498                               timestamp);
 499
 500        if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
 501                iio_push_event(indio_dev,
 502                               IIO_MOD_EVENT_CODE(IIO_ACCEL,
 503                                                  0,
 504                                                  IIO_MOD_X,
 505                                                  IIO_EV_TYPE_THRESH,
 506                                                  IIO_EV_DIR_FALLING),
 507                               timestamp);
 508
 509        /* Ack and allow for new interrupts */
 510        lis3l02dq_spi_read_reg_8(indio_dev,
 511                                 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
 512                                 &t);
 513
 514        return IRQ_HANDLED;
 515}
 516
 517static const struct iio_event_spec lis3l02dq_event[] = {
 518        {
 519                .type = IIO_EV_TYPE_THRESH,
 520                .dir = IIO_EV_DIR_RISING,
 521                .mask_separate = BIT(IIO_EV_INFO_ENABLE),
 522                .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
 523        }, {
 524                .type = IIO_EV_TYPE_THRESH,
 525                .dir = IIO_EV_DIR_FALLING,
 526                .mask_separate = BIT(IIO_EV_INFO_ENABLE),
 527                .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
 528        }
 529};
 530
 531#define LIS3L02DQ_CHAN(index, mod)                              \
 532        {                                                       \
 533                .type = IIO_ACCEL,                              \
 534                .modified = 1,                                  \
 535                .channel2 = mod,                                \
 536                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |  \
 537                        BIT(IIO_CHAN_INFO_CALIBSCALE) |         \
 538                        BIT(IIO_CHAN_INFO_CALIBBIAS),           \
 539                .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
 540                .address = index,                               \
 541                .scan_index = index,                            \
 542                .scan_type = {                                  \
 543                        .sign = 's',                            \
 544                        .realbits = 12,                         \
 545                        .storagebits = 16,                      \
 546                },                                              \
 547                .event_spec = lis3l02dq_event,                  \
 548                .num_event_specs = ARRAY_SIZE(lis3l02dq_event), \
 549         }
 550
 551static const struct iio_chan_spec lis3l02dq_channels[] = {
 552        LIS3L02DQ_CHAN(0, IIO_MOD_X),
 553        LIS3L02DQ_CHAN(1, IIO_MOD_Y),
 554        LIS3L02DQ_CHAN(2, IIO_MOD_Z),
 555        IIO_CHAN_SOFT_TIMESTAMP(3)
 556};
 557
 558
 559static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
 560                                       const struct iio_chan_spec *chan,
 561                                       enum iio_event_type type,
 562                                       enum iio_event_direction dir)
 563{
 564
 565        u8 val;
 566        int ret;
 567        u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
 568        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 569                                       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 570                                       &val);
 571        if (ret < 0)
 572                return ret;
 573
 574        return !!(val & mask);
 575}
 576
 577int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
 578{
 579        int ret;
 580        u8 control, val;
 581
 582        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 583                                       LIS3L02DQ_REG_CTRL_2_ADDR,
 584                                       &control);
 585
 586        control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
 587        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 588                                        LIS3L02DQ_REG_CTRL_2_ADDR,
 589                                        control);
 590        if (ret)
 591                goto error_ret;
 592        /* Also for consistency clear the mask */
 593        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 594                                       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 595                                       &val);
 596        if (ret)
 597                goto error_ret;
 598        val &= ~0x3f;
 599
 600        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 601                                        LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 602                                        val);
 603        if (ret)
 604                goto error_ret;
 605
 606        ret = control;
 607error_ret:
 608        return ret;
 609}
 610
 611static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
 612                                        const struct iio_chan_spec *chan,
 613                                        enum iio_event_type type,
 614                                        enum iio_event_direction dir,
 615                                        int state)
 616{
 617        int ret = 0;
 618        u8 val, control;
 619        u8 currentlyset;
 620        bool changed = false;
 621        u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING)));
 622
 623        mutex_lock(&indio_dev->mlock);
 624        /* read current control */
 625        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 626                                       LIS3L02DQ_REG_CTRL_2_ADDR,
 627                                       &control);
 628        if (ret)
 629                goto error_ret;
 630        ret = lis3l02dq_spi_read_reg_8(indio_dev,
 631                                       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 632                                       &val);
 633        if (ret < 0)
 634                goto error_ret;
 635        currentlyset = val & mask;
 636
 637        if (!currentlyset && state) {
 638                changed = true;
 639                val |= mask;
 640        } else if (currentlyset && !state) {
 641                changed = true;
 642                val &= ~mask;
 643        }
 644
 645        if (changed) {
 646                ret = lis3l02dq_spi_write_reg_8(indio_dev,
 647                                                LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
 648                                                val);
 649                if (ret)
 650                        goto error_ret;
 651                control = val & 0x3f ?
 652                        (control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
 653                        (control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
 654                ret = lis3l02dq_spi_write_reg_8(indio_dev,
 655                                               LIS3L02DQ_REG_CTRL_2_ADDR,
 656                                               control);
 657                if (ret)
 658                        goto error_ret;
 659        }
 660
 661error_ret:
 662        mutex_unlock(&indio_dev->mlock);
 663        return ret;
 664}
 665
 666static struct attribute *lis3l02dq_attributes[] = {
 667        &iio_dev_attr_sampling_frequency.dev_attr.attr,
 668        &iio_const_attr_sampling_frequency_available.dev_attr.attr,
 669        NULL
 670};
 671
 672static const struct attribute_group lis3l02dq_attribute_group = {
 673        .attrs = lis3l02dq_attributes,
 674};
 675
 676static const struct iio_info lis3l02dq_info = {
 677        .read_raw = &lis3l02dq_read_raw,
 678        .write_raw = &lis3l02dq_write_raw,
 679        .read_event_value = &lis3l02dq_read_thresh,
 680        .write_event_value = &lis3l02dq_write_thresh,
 681        .write_event_config = &lis3l02dq_write_event_config,
 682        .read_event_config = &lis3l02dq_read_event_config,
 683        .driver_module = THIS_MODULE,
 684        .attrs = &lis3l02dq_attribute_group,
 685};
 686
 687static int lis3l02dq_probe(struct spi_device *spi)
 688{
 689        int ret;
 690        struct lis3l02dq_state *st;
 691        struct iio_dev *indio_dev;
 692
 693        indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
 694        if (!indio_dev)
 695                return -ENOMEM;
 696        st = iio_priv(indio_dev);
 697        /* this is only used for removal purposes */
 698        spi_set_drvdata(spi, indio_dev);
 699
 700        st->us = spi;
 701        st->gpio = of_get_gpio(spi->dev.of_node, 0);
 702        mutex_init(&st->buf_lock);
 703        indio_dev->name = spi->dev.driver->name;
 704        indio_dev->dev.parent = &spi->dev;
 705        indio_dev->info = &lis3l02dq_info;
 706        indio_dev->channels = lis3l02dq_channels;
 707        indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
 708
 709        indio_dev->modes = INDIO_DIRECT_MODE;
 710
 711        ret = lis3l02dq_configure_buffer(indio_dev);
 712        if (ret)
 713                return ret;
 714
 715        ret = iio_buffer_register(indio_dev,
 716                                  lis3l02dq_channels,
 717                                  ARRAY_SIZE(lis3l02dq_channels));
 718        if (ret) {
 719                dev_err(&spi->dev, "failed to initialize the buffer\n");
 720                goto error_unreg_buffer_funcs;
 721        }
 722
 723        if (spi->irq) {
 724                ret = request_threaded_irq(st->us->irq,
 725                                           &lis3l02dq_th,
 726                                           &lis3l02dq_event_handler,
 727                                           IRQF_TRIGGER_RISING,
 728                                           "lis3l02dq",
 729                                           indio_dev);
 730                if (ret)
 731                        goto error_uninitialize_buffer;
 732
 733                ret = lis3l02dq_probe_trigger(indio_dev);
 734                if (ret)
 735                        goto error_free_interrupt;
 736        }
 737
 738        /* Get the device into a sane initial state */
 739        ret = lis3l02dq_initial_setup(indio_dev);
 740        if (ret)
 741                goto error_remove_trigger;
 742
 743        ret = iio_device_register(indio_dev);
 744        if (ret)
 745                goto error_remove_trigger;
 746
 747        return 0;
 748
 749error_remove_trigger:
 750        if (spi->irq)
 751                lis3l02dq_remove_trigger(indio_dev);
 752error_free_interrupt:
 753        if (spi->irq)
 754                free_irq(st->us->irq, indio_dev);
 755error_uninitialize_buffer:
 756        iio_buffer_unregister(indio_dev);
 757error_unreg_buffer_funcs:
 758        lis3l02dq_unconfigure_buffer(indio_dev);
 759        return ret;
 760}
 761
 762/* Power down the device */
 763static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 764{
 765        int ret;
 766        struct lis3l02dq_state *st = iio_priv(indio_dev);
 767        u8 val = 0;
 768
 769        mutex_lock(&indio_dev->mlock);
 770        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 771                                        LIS3L02DQ_REG_CTRL_1_ADDR,
 772                                        val);
 773        if (ret) {
 774                dev_err(&st->us->dev, "problem with turning device off: ctrl1");
 775                goto err_ret;
 776        }
 777
 778        ret = lis3l02dq_spi_write_reg_8(indio_dev,
 779                                        LIS3L02DQ_REG_CTRL_2_ADDR,
 780                                        val);
 781        if (ret)
 782                dev_err(&st->us->dev, "problem with turning device off: ctrl2");
 783err_ret:
 784        mutex_unlock(&indio_dev->mlock);
 785        return ret;
 786}
 787
 788/* fixme, confirm ordering in this function */
 789static int lis3l02dq_remove(struct spi_device *spi)
 790{
 791        struct iio_dev *indio_dev = spi_get_drvdata(spi);
 792        struct lis3l02dq_state *st = iio_priv(indio_dev);
 793
 794        iio_device_unregister(indio_dev);
 795
 796        lis3l02dq_disable_all_events(indio_dev);
 797        lis3l02dq_stop_device(indio_dev);
 798
 799        if (spi->irq)
 800                free_irq(st->us->irq, indio_dev);
 801
 802        lis3l02dq_remove_trigger(indio_dev);
 803        iio_buffer_unregister(indio_dev);
 804        lis3l02dq_unconfigure_buffer(indio_dev);
 805
 806        return 0;
 807}
 808
 809static struct spi_driver lis3l02dq_driver = {
 810        .driver = {
 811                .name = "lis3l02dq",
 812                .owner = THIS_MODULE,
 813        },
 814        .probe = lis3l02dq_probe,
 815        .remove = lis3l02dq_remove,
 816};
 817module_spi_driver(lis3l02dq_driver);
 818
 819MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
 820MODULE_DESCRIPTION("ST LIS3L02DQ Accelerometer SPI driver");
 821MODULE_LICENSE("GPL v2");
 822MODULE_ALIAS("spi:lis3l02dq");
 823