linux/drivers/iio/accel/mma9551_core.c
<<
>>
Prefs
   1/*
   2 * Common code for Freescale MMA955x Intelligent Sensor Platform drivers
   3 * Copyright (c) 2014, Intel Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/i2c.h>
  17#include <linux/delay.h>
  18#include <linux/iio/iio.h>
  19#include <linux/pm_runtime.h>
  20#include "mma9551_core.h"
  21
  22/* Command masks for mailbox write command */
  23#define MMA9551_CMD_READ_VERSION_INFO   0x00
  24#define MMA9551_CMD_READ_CONFIG         0x10
  25#define MMA9551_CMD_WRITE_CONFIG        0x20
  26#define MMA9551_CMD_READ_STATUS         0x30
  27
  28/* Mailbox read command */
  29#define MMA9551_RESPONSE_COCO           BIT(7)
  30
  31/* Error-Status codes returned in mailbox read command */
  32#define MMA9551_MCI_ERROR_NONE                  0x00
  33#define MMA9551_MCI_ERROR_PARAM                 0x04
  34#define MMA9551_MCI_INVALID_COUNT               0x19
  35#define MMA9551_MCI_ERROR_COMMAND               0x1C
  36#define MMA9551_MCI_ERROR_INVALID_LENGTH        0x21
  37#define MMA9551_MCI_ERROR_FIFO_BUSY             0x22
  38#define MMA9551_MCI_ERROR_FIFO_ALLOCATED        0x23
  39#define MMA9551_MCI_ERROR_FIFO_OVERSIZE         0x24
  40
  41/* GPIO Application */
  42#define MMA9551_GPIO_POL_MSB            0x08
  43#define MMA9551_GPIO_POL_LSB            0x09
  44
  45/* Sleep/Wake application */
  46#define MMA9551_SLEEP_CFG               0x06
  47#define MMA9551_SLEEP_CFG_SNCEN         BIT(0)
  48#define MMA9551_SLEEP_CFG_FLEEN         BIT(1)
  49#define MMA9551_SLEEP_CFG_SCHEN         BIT(2)
  50
  51/* AFE application */
  52#define MMA9551_AFE_X_ACCEL_REG         0x00
  53#define MMA9551_AFE_Y_ACCEL_REG         0x02
  54#define MMA9551_AFE_Z_ACCEL_REG         0x04
  55
  56/* Reset/Suspend/Clear application */
  57#define MMA9551_RSC_RESET               0x00
  58#define MMA9551_RSC_OFFSET(mask)        (3 - (ffs(mask) - 1) / 8)
  59#define MMA9551_RSC_VAL(mask)           (mask >> (((ffs(mask) - 1) / 8) * 8))
  60
  61/*
  62 * A response is composed of:
  63 * - control registers: MB0-3
  64 * - data registers: MB4-31
  65 *
  66 * A request is composed of:
  67 * - mbox to write to (always 0)
  68 * - control registers: MB1-4
  69 * - data registers: MB5-31
  70 */
  71#define MMA9551_MAILBOX_CTRL_REGS       4
  72#define MMA9551_MAX_MAILBOX_DATA_REGS   28
  73#define MMA9551_MAILBOX_REGS            32
  74
  75#define MMA9551_I2C_READ_RETRIES        5
  76#define MMA9551_I2C_READ_DELAY  50      /* us */
  77
  78struct mma9551_mbox_request {
  79        u8 start_mbox;          /* Always 0. */
  80        u8 app_id;
  81        /*
  82         * See Section 5.3.1 of the MMA955xL Software Reference Manual.
  83         *
  84         * Bit 7: reserved, always 0
  85         * Bits 6-4: command
  86         * Bits 3-0: upper bits of register offset
  87         */
  88        u8 cmd_off;
  89        u8 lower_off;
  90        u8 nbytes;
  91        u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS - 1];
  92} __packed;
  93
  94struct mma9551_mbox_response {
  95        u8 app_id;
  96        /*
  97         * See Section 5.3.3 of the MMA955xL Software Reference Manual.
  98         *
  99         * Bit 7: COCO
 100         * Bits 6-0: Error code.
 101         */
 102        u8 coco_err;
 103        u8 nbytes;
 104        u8 req_bytes;
 105        u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS];
 106} __packed;
 107
 108struct mma9551_version_info {
 109        __be32 device_id;
 110        u8 rom_version[2];
 111        u8 fw_version[2];
 112        u8 hw_version[2];
 113        u8 fw_build[2];
 114};
 115
 116static int mma9551_transfer(struct i2c_client *client,
 117                            u8 app_id, u8 command, u16 offset,
 118                            u8 *inbytes, int num_inbytes,
 119                            u8 *outbytes, int num_outbytes)
 120{
 121        struct mma9551_mbox_request req;
 122        struct mma9551_mbox_response rsp;
 123        struct i2c_msg in, out;
 124        u8 req_len, err_code;
 125        int ret, retries;
 126
 127        if (offset >= 1 << 12) {
 128                dev_err(&client->dev, "register offset too large\n");
 129                return -EINVAL;
 130        }
 131
 132        req_len = 1 + MMA9551_MAILBOX_CTRL_REGS + num_inbytes;
 133        req.start_mbox = 0;
 134        req.app_id = app_id;
 135        req.cmd_off = command | (offset >> 8);
 136        req.lower_off = offset;
 137
 138        if (command == MMA9551_CMD_WRITE_CONFIG)
 139                req.nbytes = num_inbytes;
 140        else
 141                req.nbytes = num_outbytes;
 142        if (num_inbytes)
 143                memcpy(req.buf, inbytes, num_inbytes);
 144
 145        out.addr = client->addr;
 146        out.flags = 0;
 147        out.len = req_len;
 148        out.buf = (u8 *)&req;
 149
 150        ret = i2c_transfer(client->adapter, &out, 1);
 151        if (ret < 0) {
 152                dev_err(&client->dev, "i2c write failed\n");
 153                return ret;
 154        }
 155
 156        retries = MMA9551_I2C_READ_RETRIES;
 157        do {
 158                udelay(MMA9551_I2C_READ_DELAY);
 159
 160                in.addr = client->addr;
 161                in.flags = I2C_M_RD;
 162                in.len = sizeof(rsp);
 163                in.buf = (u8 *)&rsp;
 164
 165                ret = i2c_transfer(client->adapter, &in, 1);
 166                if (ret < 0) {
 167                        dev_err(&client->dev, "i2c read failed\n");
 168                        return ret;
 169                }
 170
 171                if (rsp.coco_err & MMA9551_RESPONSE_COCO)
 172                        break;
 173        } while (--retries > 0);
 174
 175        if (retries == 0) {
 176                dev_err(&client->dev,
 177                        "timed out while waiting for command response\n");
 178                return -ETIMEDOUT;
 179        }
 180
 181        if (rsp.app_id != app_id) {
 182                dev_err(&client->dev,
 183                        "app_id mismatch in response got %02x expected %02x\n",
 184                        rsp.app_id, app_id);
 185                return -EINVAL;
 186        }
 187
 188        err_code = rsp.coco_err & ~MMA9551_RESPONSE_COCO;
 189        if (err_code != MMA9551_MCI_ERROR_NONE) {
 190                dev_err(&client->dev, "read returned error %x\n", err_code);
 191                return -EINVAL;
 192        }
 193
 194        if (rsp.nbytes != rsp.req_bytes) {
 195                dev_err(&client->dev,
 196                        "output length mismatch got %d expected %d\n",
 197                        rsp.nbytes, rsp.req_bytes);
 198                return -EINVAL;
 199        }
 200
 201        if (num_outbytes)
 202                memcpy(outbytes, rsp.buf, num_outbytes);
 203
 204        return 0;
 205}
 206
 207/**
 208 * mma9551_read_config_byte() - read 1 configuration byte
 209 * @client:     I2C client
 210 * @app_id:     Application ID
 211 * @reg:        Application register
 212 * @val:        Pointer to store value read
 213 *
 214 * Read one configuration byte from the device using MMA955xL command format.
 215 * Commands to the MMA955xL platform consist of a write followed
 216 * by one or more reads.
 217 *
 218 * Locking note: This function must be called with the device lock held.
 219 * Locking is not handled inside the function. Callers should ensure they
 220 * serialize access to the HW.
 221 *
 222 * Returns: 0 on success, negative value on failure.
 223 */
 224int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
 225                             u16 reg, u8 *val)
 226{
 227        return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
 228                                reg, NULL, 0, val, 1);
 229}
 230EXPORT_SYMBOL(mma9551_read_config_byte);
 231
 232/**
 233 * mma9551_write_config_byte() - write 1 configuration byte
 234 * @client:     I2C client
 235 * @app_id:     Application ID
 236 * @reg:        Application register
 237 * @val:        Value to write
 238 *
 239 * Write one configuration byte from the device using MMA955xL command format.
 240 * Commands to the MMA955xL platform consist of a write followed by one or
 241 * more reads.
 242 *
 243 * Locking note: This function must be called with the device lock held.
 244 * Locking is not handled inside the function. Callers should ensure they
 245 * serialize access to the HW.
 246 *
 247 * Returns: 0 on success, negative value on failure.
 248 */
 249int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
 250                              u16 reg, u8 val)
 251{
 252        return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
 253                                &val, 1, NULL, 0);
 254}
 255EXPORT_SYMBOL(mma9551_write_config_byte);
 256
 257/**
 258 * mma9551_read_status_byte() - read 1 status byte
 259 * @client:     I2C client
 260 * @app_id:     Application ID
 261 * @reg:        Application register
 262 * @val:        Pointer to store value read
 263 *
 264 * Read one status byte from the device using MMA955xL command format.
 265 * Commands to the MMA955xL platform consist of a write followed by one or
 266 * more reads.
 267 *
 268 * Locking note: This function must be called with the device lock held.
 269 * Locking is not handled inside the function. Callers should ensure they
 270 * serialize access to the HW.
 271 *
 272 * Returns: 0 on success, negative value on failure.
 273 */
 274int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
 275                             u16 reg, u8 *val)
 276{
 277        return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
 278                                reg, NULL, 0, val, 1);
 279}
 280EXPORT_SYMBOL(mma9551_read_status_byte);
 281
 282/**
 283 * mma9551_read_config_word() - read 1 config word
 284 * @client:     I2C client
 285 * @app_id:     Application ID
 286 * @reg:        Application register
 287 * @val:        Pointer to store value read
 288 *
 289 * Read one configuration word from the device using MMA955xL command format.
 290 * Commands to the MMA955xL platform consist of a write followed by one or
 291 * more reads.
 292 *
 293 * Locking note: This function must be called with the device lock held.
 294 * Locking is not handled inside the function. Callers should ensure they
 295 * serialize access to the HW.
 296 *
 297 * Returns: 0 on success, negative value on failure.
 298 */
 299int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
 300                             u16 reg, u16 *val)
 301{
 302        int ret;
 303        __be16 v;
 304
 305        ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
 306                               reg, NULL, 0, (u8 *)&v, 2);
 307        *val = be16_to_cpu(v);
 308
 309        return ret;
 310}
 311EXPORT_SYMBOL(mma9551_read_config_word);
 312
 313/**
 314 * mma9551_write_config_word() - write 1 config word
 315 * @client:     I2C client
 316 * @app_id:     Application ID
 317 * @reg:        Application register
 318 * @val:        Value to write
 319 *
 320 * Write one configuration word from the device using MMA955xL command format.
 321 * Commands to the MMA955xL platform consist of a write followed by one or
 322 * more reads.
 323 *
 324 * Locking note: This function must be called with the device lock held.
 325 * Locking is not handled inside the function. Callers should ensure they
 326 * serialize access to the HW.
 327 *
 328 * Returns: 0 on success, negative value on failure.
 329 */
 330int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
 331                              u16 reg, u16 val)
 332{
 333        __be16 v = cpu_to_be16(val);
 334
 335        return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
 336                                (u8 *)&v, 2, NULL, 0);
 337}
 338EXPORT_SYMBOL(mma9551_write_config_word);
 339
 340/**
 341 * mma9551_read_status_word() - read 1 status word
 342 * @client:     I2C client
 343 * @app_id:     Application ID
 344 * @reg:        Application register
 345 * @val:        Pointer to store value read
 346 *
 347 * Read one status word from the device using MMA955xL command format.
 348 * Commands to the MMA955xL platform consist of a write followed by one or
 349 * more reads.
 350 *
 351 * Locking note: This function must be called with the device lock held.
 352 * Locking is not handled inside the function. Callers should ensure they
 353 * serialize access to the HW.
 354 *
 355 * Returns: 0 on success, negative value on failure.
 356 */
 357int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
 358                             u16 reg, u16 *val)
 359{
 360        int ret;
 361        __be16 v;
 362
 363        ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
 364                               reg, NULL, 0, (u8 *)&v, 2);
 365        *val = be16_to_cpu(v);
 366
 367        return ret;
 368}
 369EXPORT_SYMBOL(mma9551_read_status_word);
 370
 371/**
 372 * mma9551_read_config_words() - read multiple config words
 373 * @client:     I2C client
 374 * @app_id:     Application ID
 375 * @reg:        Application register
 376 * @len:        Length of array to read (in words)
 377 * @buf:        Array of words to read
 378 *
 379 * Read multiple configuration registers (word-sized registers).
 380 *
 381 * Locking note: This function must be called with the device lock held.
 382 * Locking is not handled inside the function. Callers should ensure they
 383 * serialize access to the HW.
 384 *
 385 * Returns: 0 on success, negative value on failure.
 386 */
 387int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
 388                              u16 reg, u8 len, u16 *buf)
 389{
 390        int ret, i;
 391        __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
 392
 393        if (len > ARRAY_SIZE(be_buf)) {
 394                dev_err(&client->dev, "Invalid buffer size %d\n", len);
 395                return -EINVAL;
 396        }
 397
 398        ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
 399                               reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
 400        if (ret < 0)
 401                return ret;
 402
 403        for (i = 0; i < len; i++)
 404                buf[i] = be16_to_cpu(be_buf[i]);
 405
 406        return 0;
 407}
 408EXPORT_SYMBOL(mma9551_read_config_words);
 409
 410/**
 411 * mma9551_read_status_words() - read multiple status words
 412 * @client:     I2C client
 413 * @app_id:     Application ID
 414 * @reg:        Application register
 415 * @len:        Length of array to read (in words)
 416 * @buf:        Array of words to read
 417 *
 418 * Read multiple status registers (word-sized registers).
 419 *
 420 * Locking note: This function must be called with the device lock held.
 421 * Locking is not handled inside the function. Callers should ensure they
 422 * serialize access to the HW.
 423 *
 424 * Returns: 0 on success, negative value on failure.
 425 */
 426int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
 427                              u16 reg, u8 len, u16 *buf)
 428{
 429        int ret, i;
 430        __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
 431
 432        if (len > ARRAY_SIZE(be_buf)) {
 433                dev_err(&client->dev, "Invalid buffer size %d\n", len);
 434                return -EINVAL;
 435        }
 436
 437        ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
 438                               reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
 439        if (ret < 0)
 440                return ret;
 441
 442        for (i = 0; i < len; i++)
 443                buf[i] = be16_to_cpu(be_buf[i]);
 444
 445        return 0;
 446}
 447EXPORT_SYMBOL(mma9551_read_status_words);
 448
 449/**
 450 * mma9551_write_config_words() - write multiple config words
 451 * @client:     I2C client
 452 * @app_id:     Application ID
 453 * @reg:        Application register
 454 * @len:        Length of array to write (in words)
 455 * @buf:        Array of words to write
 456 *
 457 * Write multiple configuration registers (word-sized registers).
 458 *
 459 * Locking note: This function must be called with the device lock held.
 460 * Locking is not handled inside the function. Callers should ensure they
 461 * serialize access to the HW.
 462 *
 463 * Returns: 0 on success, negative value on failure.
 464 */
 465int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
 466                               u16 reg, u8 len, u16 *buf)
 467{
 468        int i;
 469        __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
 470
 471        if (len > ARRAY_SIZE(be_buf)) {
 472                dev_err(&client->dev, "Invalid buffer size %d\n", len);
 473                return -EINVAL;
 474        }
 475
 476        for (i = 0; i < len; i++)
 477                be_buf[i] = cpu_to_be16(buf[i]);
 478
 479        return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
 480                                reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);
 481}
 482EXPORT_SYMBOL(mma9551_write_config_words);
 483
 484/**
 485 * mma9551_update_config_bits() - update bits in register
 486 * @client:     I2C client
 487 * @app_id:     Application ID
 488 * @reg:        Application register
 489 * @mask:       Mask for the bits to update
 490 * @val:        Value of the bits to update
 491 *
 492 * Update bits in the given register using a bit mask.
 493 *
 494 * Locking note: This function must be called with the device lock held.
 495 * Locking is not handled inside the function. Callers should ensure they
 496 * serialize access to the HW.
 497 *
 498 * Returns: 0 on success, negative value on failure.
 499 */
 500int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
 501                               u16 reg, u8 mask, u8 val)
 502{
 503        int ret;
 504        u8 tmp, orig;
 505
 506        ret = mma9551_read_config_byte(client, app_id, reg, &orig);
 507        if (ret < 0)
 508                return ret;
 509
 510        tmp = orig & ~mask;
 511        tmp |= val & mask;
 512
 513        if (tmp == orig)
 514                return 0;
 515
 516        return mma9551_write_config_byte(client, app_id, reg, tmp);
 517}
 518EXPORT_SYMBOL(mma9551_update_config_bits);
 519
 520/**
 521 * mma9551_gpio_config() - configure gpio
 522 * @client:     I2C client
 523 * @pin:        GPIO pin to configure
 524 * @app_id:     Application ID
 525 * @bitnum:     Bit number of status register being assigned to the GPIO pin.
 526 * @polarity:   The polarity parameter is described in section 6.2.2, page 66,
 527 *              of the Software Reference Manual.  Basically, polarity=0 means
 528 *              the interrupt line has the same value as the selected bit,
 529 *              while polarity=1 means the line is inverted.
 530 *
 531 * Assign a bit from an application’s status register to a specific GPIO pin.
 532 *
 533 * Locking note: This function must be called with the device lock held.
 534 * Locking is not handled inside the function. Callers should ensure they
 535 * serialize access to the HW.
 536 *
 537 * Returns: 0 on success, negative value on failure.
 538 */
 539int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
 540                        u8 app_id, u8 bitnum, int polarity)
 541{
 542        u8 reg, pol_mask, pol_val;
 543        int ret;
 544
 545        if (pin > mma9551_gpio_max) {
 546                dev_err(&client->dev, "bad GPIO pin\n");
 547                return -EINVAL;
 548        }
 549
 550        /*
 551         * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and
 552         * 0x03, and so on.
 553         */
 554        reg = pin * 2;
 555
 556        ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
 557                                        reg, app_id);
 558        if (ret < 0) {
 559                dev_err(&client->dev, "error setting GPIO app_id\n");
 560                return ret;
 561        }
 562
 563        ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
 564                                        reg + 1, bitnum);
 565        if (ret < 0) {
 566                dev_err(&client->dev, "error setting GPIO bit number\n");
 567                return ret;
 568        }
 569
 570        switch (pin) {
 571        case mma9551_gpio6:
 572                reg = MMA9551_GPIO_POL_LSB;
 573                pol_mask = 1 << 6;
 574                break;
 575        case mma9551_gpio7:
 576                reg = MMA9551_GPIO_POL_LSB;
 577                pol_mask = 1 << 7;
 578                break;
 579        case mma9551_gpio8:
 580                reg = MMA9551_GPIO_POL_MSB;
 581                pol_mask = 1 << 0;
 582                break;
 583        case mma9551_gpio9:
 584                reg = MMA9551_GPIO_POL_MSB;
 585                pol_mask = 1 << 1;
 586                break;
 587        }
 588        pol_val = polarity ? pol_mask : 0;
 589
 590        ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg,
 591                                         pol_mask, pol_val);
 592        if (ret < 0)
 593                dev_err(&client->dev, "error setting GPIO polarity\n");
 594
 595        return ret;
 596}
 597EXPORT_SYMBOL(mma9551_gpio_config);
 598
 599/**
 600 * mma9551_read_version() - read device version information
 601 * @client:     I2C client
 602 *
 603 * Read version information and print device id and firmware version.
 604 *
 605 * Locking note: This function must be called with the device lock held.
 606 * Locking is not handled inside the function. Callers should ensure they
 607 * serialize access to the HW.
 608 *
 609 * Returns: 0 on success, negative value on failure.
 610 */
 611int mma9551_read_version(struct i2c_client *client)
 612{
 613        struct mma9551_version_info info;
 614        int ret;
 615
 616        ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00,
 617                               NULL, 0, (u8 *)&info, sizeof(info));
 618        if (ret < 0)
 619                return ret;
 620
 621        dev_info(&client->dev, "device ID 0x%x, firmware version %02x.%02x\n",
 622                 be32_to_cpu(info.device_id), info.fw_version[0],
 623                 info.fw_version[1]);
 624
 625        return 0;
 626}
 627EXPORT_SYMBOL(mma9551_read_version);
 628
 629/**
 630 * mma9551_set_device_state() - sets HW power mode
 631 * @client:     I2C client
 632 * @enable:     Use true to power on device, false to cause the device
 633 *              to enter sleep.
 634 *
 635 * Set power on/off for device using the Sleep/Wake Application.
 636 * When enable is true, power on chip and enable doze mode.
 637 * When enable is false, enter sleep mode (device remains in the
 638 * lowest-power mode).
 639 *
 640 * Locking note: This function must be called with the device lock held.
 641 * Locking is not handled inside the function. Callers should ensure they
 642 * serialize access to the HW.
 643 *
 644 * Returns: 0 on success, negative value on failure.
 645 */
 646int mma9551_set_device_state(struct i2c_client *client, bool enable)
 647{
 648        return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE,
 649                                          MMA9551_SLEEP_CFG,
 650                                          MMA9551_SLEEP_CFG_SNCEN |
 651                                          MMA9551_SLEEP_CFG_FLEEN |
 652                                          MMA9551_SLEEP_CFG_SCHEN,
 653                                          enable ? MMA9551_SLEEP_CFG_SCHEN |
 654                                          MMA9551_SLEEP_CFG_FLEEN :
 655                                          MMA9551_SLEEP_CFG_SNCEN);
 656}
 657EXPORT_SYMBOL(mma9551_set_device_state);
 658
 659/**
 660 * mma9551_set_power_state() - sets runtime PM state
 661 * @client:     I2C client
 662 * @on:         Use true to power on device, false to power off
 663 *
 664 * Resume or suspend the device using Runtime PM.
 665 * The device will suspend after the autosuspend delay.
 666 *
 667 * Returns: 0 on success, negative value on failure.
 668 */
 669int mma9551_set_power_state(struct i2c_client *client, bool on)
 670{
 671#ifdef CONFIG_PM
 672        int ret;
 673
 674        if (on)
 675                ret = pm_runtime_get_sync(&client->dev);
 676        else {
 677                pm_runtime_mark_last_busy(&client->dev);
 678                ret = pm_runtime_put_autosuspend(&client->dev);
 679        }
 680
 681        if (ret < 0) {
 682                dev_err(&client->dev,
 683                        "failed to change power state to %d\n", on);
 684                if (on)
 685                        pm_runtime_put_noidle(&client->dev);
 686
 687                return ret;
 688        }
 689#endif
 690
 691        return 0;
 692}
 693EXPORT_SYMBOL(mma9551_set_power_state);
 694
 695/**
 696 * mma9551_sleep() - sleep
 697 * @freq:       Application frequency
 698 *
 699 * Firmware applications run at a certain frequency on the
 700 * device. Sleep for one application cycle to make sure the
 701 * application had time to run once and initialize set values.
 702 */
 703void mma9551_sleep(int freq)
 704{
 705        int sleep_val = 1000 / freq;
 706
 707        if (sleep_val < 20)
 708                usleep_range(sleep_val * 1000, 20000);
 709        else
 710                msleep_interruptible(sleep_val);
 711}
 712EXPORT_SYMBOL(mma9551_sleep);
 713
 714/**
 715 * mma9551_read_accel_chan() - read accelerometer channel
 716 * @client:     I2C client
 717 * @chan:       IIO channel
 718 * @val:        Pointer to the accelerometer value read
 719 * @val2:       Unused
 720 *
 721 * Read accelerometer value for the specified channel.
 722 *
 723 * Locking note: This function must be called with the device lock held.
 724 * Locking is not handled inside the function. Callers should ensure they
 725 * serialize access to the HW.
 726 *
 727 * Returns: IIO_VAL_INT on success, negative value on failure.
 728 */
 729int mma9551_read_accel_chan(struct i2c_client *client,
 730                            const struct iio_chan_spec *chan,
 731                            int *val, int *val2)
 732{
 733        u16 reg_addr;
 734        s16 raw_accel;
 735        int ret;
 736
 737        switch (chan->channel2) {
 738        case IIO_MOD_X:
 739                reg_addr = MMA9551_AFE_X_ACCEL_REG;
 740                break;
 741        case IIO_MOD_Y:
 742                reg_addr = MMA9551_AFE_Y_ACCEL_REG;
 743                break;
 744        case IIO_MOD_Z:
 745                reg_addr = MMA9551_AFE_Z_ACCEL_REG;
 746                break;
 747        default:
 748                return -EINVAL;
 749        }
 750
 751        ret = mma9551_set_power_state(client, true);
 752        if (ret < 0)
 753                return ret;
 754
 755        ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,
 756                                       reg_addr, &raw_accel);
 757        if (ret < 0)
 758                goto out_poweroff;
 759
 760        *val = raw_accel;
 761
 762        ret = IIO_VAL_INT;
 763
 764out_poweroff:
 765        mma9551_set_power_state(client, false);
 766        return ret;
 767}
 768EXPORT_SYMBOL(mma9551_read_accel_chan);
 769
 770/**
 771 * mma9551_read_accel_scale() - read accelerometer scale
 772 * @val:        Pointer to the accelerometer scale (int value)
 773 * @val2:       Pointer to the accelerometer scale (micro value)
 774 *
 775 * Read accelerometer scale.
 776 *
 777 * Returns: IIO_VAL_INT_PLUS_MICRO.
 778 */
 779int mma9551_read_accel_scale(int *val, int *val2)
 780{
 781        *val = 0;
 782        *val2 = 2440;
 783
 784        return IIO_VAL_INT_PLUS_MICRO;
 785}
 786EXPORT_SYMBOL(mma9551_read_accel_scale);
 787
 788/**
 789 * mma9551_app_reset() - reset application
 790 * @client:     I2C client
 791 * @app_mask:   Application to reset
 792 *
 793 * Reset the given application (using the Reset/Suspend/Clear
 794 * Control Application)
 795 *
 796 * Returns: 0 on success, negative value on failure.
 797 */
 798int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
 799{
 800        return mma9551_write_config_byte(client, MMA9551_APPID_RSC,
 801                                         MMA9551_RSC_RESET +
 802                                         MMA9551_RSC_OFFSET(app_mask),
 803                                         MMA9551_RSC_VAL(app_mask));
 804}
 805EXPORT_SYMBOL(mma9551_app_reset);
 806
 807MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
 808MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
 809MODULE_LICENSE("GPL v2");
 810MODULE_DESCRIPTION("MMA955xL sensors core");
 811