root/drivers/iio/accel/mma9551_core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mma9551_transfer
  2. mma9551_read_config_byte
  3. mma9551_write_config_byte
  4. mma9551_read_status_byte
  5. mma9551_read_config_word
  6. mma9551_write_config_word
  7. mma9551_read_status_word
  8. mma9551_read_config_words
  9. mma9551_read_status_words
  10. mma9551_write_config_words
  11. mma9551_update_config_bits
  12. mma9551_gpio_config
  13. mma9551_read_version
  14. mma9551_set_device_state
  15. mma9551_set_power_state
  16. mma9551_sleep
  17. mma9551_read_accel_chan
  18. mma9551_read_accel_scale
  19. mma9551_app_reset

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

/* [<][>][^][v][top][bottom][index][help] */