807 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Common code for Freescale MMA955x Intelligent Sensor Platform drivers4 * 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 0x0016#define MMA9551_CMD_READ_CONFIG 0x1017#define MMA9551_CMD_WRITE_CONFIG 0x2018#define MMA9551_CMD_READ_STATUS 0x3019 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 0x0025#define MMA9551_MCI_ERROR_PARAM 0x0426#define MMA9551_MCI_INVALID_COUNT 0x1927#define MMA9551_MCI_ERROR_COMMAND 0x1C28#define MMA9551_MCI_ERROR_INVALID_LENGTH 0x2129#define MMA9551_MCI_ERROR_FIFO_BUSY 0x2230#define MMA9551_MCI_ERROR_FIFO_ALLOCATED 0x2331#define MMA9551_MCI_ERROR_FIFO_OVERSIZE 0x2432 33/* GPIO Application */34#define MMA9551_GPIO_POL_MSB 0x0835#define MMA9551_GPIO_POL_LSB 0x0936 37/* Sleep/Wake application */38#define MMA9551_SLEEP_CFG 0x0639#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 0x0045#define MMA9551_AFE_Y_ACCEL_REG 0x0246#define MMA9551_AFE_Z_ACCEL_REG 0x0447 48/* Reset/Suspend/Clear application */49#define MMA9551_RSC_RESET 0x0050#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-356 * - data registers: MB4-3157 *58 * A request is composed of:59 * - mbox to write to (always 0)60 * - control registers: MB1-461 * - data registers: MB5-3162 */63#define MMA9551_MAILBOX_CTRL_REGS 464#define MMA9551_MAX_MAILBOX_DATA_REGS 2865#define MMA9551_MAILBOX_REGS 3266 67#define MMA9551_I2C_READ_RETRIES 568#define MMA9551_I2C_READ_DELAY 50 /* us */69 70struct 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 077 * Bits 6-4: command78 * Bits 3-0: upper bits of register offset79 */80 u8 cmd_off;81 u8 lower_off;82 u8 nbytes;83 u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS - 1];84} __packed;85 86struct mma9551_mbox_response {87 u8 app_id;88 /*89 * See Section 5.3.3 of the MMA955xL Software Reference Manual.90 *91 * Bit 7: COCO92 * 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 100struct 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 108static 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 else133 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 byte201 * @client: I2C client202 * @app_id: Application ID203 * @reg: Application register204 * @val: Pointer to store value read205 *206 * Read one configuration byte from the device using MMA955xL command format.207 * Commands to the MMA955xL platform consist of a write followed208 * 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 they212 * serialize access to the HW.213 *214 * Returns: 0 on success, negative value on failure.215 */216int 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}222EXPORT_SYMBOL_NS(mma9551_read_config_byte, IIO_MMA9551);223 224/**225 * mma9551_write_config_byte() - write 1 configuration byte226 * @client: I2C client227 * @app_id: Application ID228 * @reg: Application register229 * @val: Value to write230 *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 or233 * 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 they237 * serialize access to the HW.238 *239 * Returns: 0 on success, negative value on failure.240 */241int 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}247EXPORT_SYMBOL_NS(mma9551_write_config_byte, IIO_MMA9551);248 249/**250 * mma9551_read_status_byte() - read 1 status byte251 * @client: I2C client252 * @app_id: Application ID253 * @reg: Application register254 * @val: Pointer to store value read255 *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 or258 * 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 they262 * serialize access to the HW.263 *264 * Returns: 0 on success, negative value on failure.265 */266int 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}272EXPORT_SYMBOL_NS(mma9551_read_status_byte, IIO_MMA9551);273 274/**275 * mma9551_read_config_word() - read 1 config word276 * @client: I2C client277 * @app_id: Application ID278 * @reg: Application register279 * @val: Pointer to store value read280 *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 or283 * 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 they287 * serialize access to the HW.288 *289 * Returns: 0 on success, negative value on failure.290 */291int 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 if (ret < 0)300 return ret;301 302 *val = be16_to_cpu(v);303 304 return 0;305}306EXPORT_SYMBOL_NS(mma9551_read_config_word, IIO_MMA9551);307 308/**309 * mma9551_write_config_word() - write 1 config word310 * @client: I2C client311 * @app_id: Application ID312 * @reg: Application register313 * @val: Value to write314 *315 * Write one configuration word from the device using MMA955xL command format.316 * Commands to the MMA955xL platform consist of a write followed by one or317 * more reads.318 *319 * Locking note: This function must be called with the device lock held.320 * Locking is not handled inside the function. Callers should ensure they321 * serialize access to the HW.322 *323 * Returns: 0 on success, negative value on failure.324 */325int mma9551_write_config_word(struct i2c_client *client, u8 app_id,326 u16 reg, u16 val)327{328 __be16 v = cpu_to_be16(val);329 330 return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,331 (u8 *)&v, 2, NULL, 0);332}333EXPORT_SYMBOL_NS(mma9551_write_config_word, IIO_MMA9551);334 335/**336 * mma9551_read_status_word() - read 1 status word337 * @client: I2C client338 * @app_id: Application ID339 * @reg: Application register340 * @val: Pointer to store value read341 *342 * Read one status word from the device using MMA955xL command format.343 * Commands to the MMA955xL platform consist of a write followed by one or344 * more reads.345 *346 * Locking note: This function must be called with the device lock held.347 * Locking is not handled inside the function. Callers should ensure they348 * serialize access to the HW.349 *350 * Returns: 0 on success, negative value on failure.351 */352int mma9551_read_status_word(struct i2c_client *client, u8 app_id,353 u16 reg, u16 *val)354{355 int ret;356 __be16 v;357 358 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,359 reg, NULL, 0, (u8 *)&v, 2);360 if (ret < 0)361 return ret;362 363 *val = be16_to_cpu(v);364 365 return 0;366}367EXPORT_SYMBOL_NS(mma9551_read_status_word, IIO_MMA9551);368 369/**370 * mma9551_read_config_words() - read multiple config words371 * @client: I2C client372 * @app_id: Application ID373 * @reg: Application register374 * @len: Length of array to read (in words)375 * @buf: Array of words to read376 *377 * Read multiple configuration registers (word-sized registers).378 *379 * Locking note: This function must be called with the device lock held.380 * Locking is not handled inside the function. Callers should ensure they381 * serialize access to the HW.382 *383 * Returns: 0 on success, negative value on failure.384 */385int mma9551_read_config_words(struct i2c_client *client, u8 app_id,386 u16 reg, u8 len, u16 *buf)387{388 int ret, i;389 __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];390 391 if (len > ARRAY_SIZE(be_buf)) {392 dev_err(&client->dev, "Invalid buffer size %d\n", len);393 return -EINVAL;394 }395 396 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,397 reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));398 if (ret < 0)399 return ret;400 401 for (i = 0; i < len; i++)402 buf[i] = be16_to_cpu(be_buf[i]);403 404 return 0;405}406EXPORT_SYMBOL_NS(mma9551_read_config_words, IIO_MMA9551);407 408/**409 * mma9551_read_status_words() - read multiple status words410 * @client: I2C client411 * @app_id: Application ID412 * @reg: Application register413 * @len: Length of array to read (in words)414 * @buf: Array of words to read415 *416 * Read multiple status registers (word-sized registers).417 *418 * Locking note: This function must be called with the device lock held.419 * Locking is not handled inside the function. Callers should ensure they420 * serialize access to the HW.421 *422 * Returns: 0 on success, negative value on failure.423 */424int mma9551_read_status_words(struct i2c_client *client, u8 app_id,425 u16 reg, u8 len, u16 *buf)426{427 int ret, i;428 __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];429 430 if (len > ARRAY_SIZE(be_buf)) {431 dev_err(&client->dev, "Invalid buffer size %d\n", len);432 return -EINVAL;433 }434 435 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,436 reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));437 if (ret < 0)438 return ret;439 440 for (i = 0; i < len; i++)441 buf[i] = be16_to_cpu(be_buf[i]);442 443 return 0;444}445EXPORT_SYMBOL_NS(mma9551_read_status_words, IIO_MMA9551);446 447/**448 * mma9551_write_config_words() - write multiple config words449 * @client: I2C client450 * @app_id: Application ID451 * @reg: Application register452 * @len: Length of array to write (in words)453 * @buf: Array of words to write454 *455 * Write multiple configuration registers (word-sized registers).456 *457 * Locking note: This function must be called with the device lock held.458 * Locking is not handled inside the function. Callers should ensure they459 * serialize access to the HW.460 *461 * Returns: 0 on success, negative value on failure.462 */463int mma9551_write_config_words(struct i2c_client *client, u8 app_id,464 u16 reg, u8 len, u16 *buf)465{466 int i;467 __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];468 469 if (len > ARRAY_SIZE(be_buf)) {470 dev_err(&client->dev, "Invalid buffer size %d\n", len);471 return -EINVAL;472 }473 474 for (i = 0; i < len; i++)475 be_buf[i] = cpu_to_be16(buf[i]);476 477 return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,478 reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);479}480EXPORT_SYMBOL_NS(mma9551_write_config_words, IIO_MMA9551);481 482/**483 * mma9551_update_config_bits() - update bits in register484 * @client: I2C client485 * @app_id: Application ID486 * @reg: Application register487 * @mask: Mask for the bits to update488 * @val: Value of the bits to update489 *490 * Update bits in the given register using a bit mask.491 *492 * Locking note: This function must be called with the device lock held.493 * Locking is not handled inside the function. Callers should ensure they494 * serialize access to the HW.495 *496 * Returns: 0 on success, negative value on failure.497 */498int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,499 u16 reg, u8 mask, u8 val)500{501 int ret;502 u8 tmp, orig;503 504 ret = mma9551_read_config_byte(client, app_id, reg, &orig);505 if (ret < 0)506 return ret;507 508 tmp = orig & ~mask;509 tmp |= val & mask;510 511 if (tmp == orig)512 return 0;513 514 return mma9551_write_config_byte(client, app_id, reg, tmp);515}516EXPORT_SYMBOL_NS(mma9551_update_config_bits, IIO_MMA9551);517 518/**519 * mma9551_gpio_config() - configure gpio520 * @client: I2C client521 * @pin: GPIO pin to configure522 * @app_id: Application ID523 * @bitnum: Bit number of status register being assigned to the GPIO pin.524 * @polarity: The polarity parameter is described in section 6.2.2, page 66,525 * of the Software Reference Manual. Basically, polarity=0 means526 * the interrupt line has the same value as the selected bit,527 * while polarity=1 means the line is inverted.528 *529 * Assign a bit from an application’s status register to a specific GPIO pin.530 *531 * Locking note: This function must be called with the device lock held.532 * Locking is not handled inside the function. Callers should ensure they533 * serialize access to the HW.534 *535 * Returns: 0 on success, negative value on failure.536 */537int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,538 u8 app_id, u8 bitnum, int polarity)539{540 u8 reg, pol_mask, pol_val;541 int ret;542 543 if (pin > mma9551_gpio_max) {544 dev_err(&client->dev, "bad GPIO pin\n");545 return -EINVAL;546 }547 548 /*549 * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and550 * 0x03, and so on.551 */552 reg = pin * 2;553 554 ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,555 reg, app_id);556 if (ret < 0) {557 dev_err(&client->dev, "error setting GPIO app_id\n");558 return ret;559 }560 561 ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,562 reg + 1, bitnum);563 if (ret < 0) {564 dev_err(&client->dev, "error setting GPIO bit number\n");565 return ret;566 }567 568 switch (pin) {569 case mma9551_gpio6:570 reg = MMA9551_GPIO_POL_LSB;571 pol_mask = 1 << 6;572 break;573 case mma9551_gpio7:574 reg = MMA9551_GPIO_POL_LSB;575 pol_mask = 1 << 7;576 break;577 case mma9551_gpio8:578 reg = MMA9551_GPIO_POL_MSB;579 pol_mask = 1 << 0;580 break;581 case mma9551_gpio9:582 reg = MMA9551_GPIO_POL_MSB;583 pol_mask = 1 << 1;584 break;585 }586 pol_val = polarity ? pol_mask : 0;587 588 ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg,589 pol_mask, pol_val);590 if (ret < 0)591 dev_err(&client->dev, "error setting GPIO polarity\n");592 593 return ret;594}595EXPORT_SYMBOL_NS(mma9551_gpio_config, IIO_MMA9551);596 597/**598 * mma9551_read_version() - read device version information599 * @client: I2C client600 *601 * Read version information and print device id and firmware version.602 *603 * Locking note: This function must be called with the device lock held.604 * Locking is not handled inside the function. Callers should ensure they605 * serialize access to the HW.606 *607 * Returns: 0 on success, negative value on failure.608 */609int mma9551_read_version(struct i2c_client *client)610{611 struct mma9551_version_info info;612 int ret;613 614 ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00,615 NULL, 0, (u8 *)&info, sizeof(info));616 if (ret < 0)617 return ret;618 619 dev_info(&client->dev, "device ID 0x%x, firmware version %02x.%02x\n",620 be32_to_cpu(info.device_id), info.fw_version[0],621 info.fw_version[1]);622 623 return 0;624}625EXPORT_SYMBOL_NS(mma9551_read_version, IIO_MMA9551);626 627/**628 * mma9551_set_device_state() - sets HW power mode629 * @client: I2C client630 * @enable: Use true to power on device, false to cause the device631 * to enter sleep.632 *633 * Set power on/off for device using the Sleep/Wake Application.634 * When enable is true, power on chip and enable doze mode.635 * When enable is false, enter sleep mode (device remains in the636 * lowest-power mode).637 *638 * Locking note: This function must be called with the device lock held.639 * Locking is not handled inside the function. Callers should ensure they640 * serialize access to the HW.641 *642 * Returns: 0 on success, negative value on failure.643 */644int mma9551_set_device_state(struct i2c_client *client, bool enable)645{646 return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE,647 MMA9551_SLEEP_CFG,648 MMA9551_SLEEP_CFG_SNCEN |649 MMA9551_SLEEP_CFG_FLEEN |650 MMA9551_SLEEP_CFG_SCHEN,651 enable ? MMA9551_SLEEP_CFG_SCHEN |652 MMA9551_SLEEP_CFG_FLEEN :653 MMA9551_SLEEP_CFG_SNCEN);654}655EXPORT_SYMBOL_NS(mma9551_set_device_state, IIO_MMA9551);656 657/**658 * mma9551_set_power_state() - sets runtime PM state659 * @client: I2C client660 * @on: Use true to power on device, false to power off661 *662 * Resume or suspend the device using Runtime PM.663 * The device will suspend after the autosuspend delay.664 *665 * Returns: 0 on success, negative value on failure.666 */667int mma9551_set_power_state(struct i2c_client *client, bool on)668{669#ifdef CONFIG_PM670 int ret;671 672 if (on)673 ret = pm_runtime_resume_and_get(&client->dev);674 else {675 pm_runtime_mark_last_busy(&client->dev);676 ret = pm_runtime_put_autosuspend(&client->dev);677 }678 679 if (ret < 0) {680 dev_err(&client->dev,681 "failed to change power state to %d\n", on);682 683 return ret;684 }685#endif686 687 return 0;688}689EXPORT_SYMBOL_NS(mma9551_set_power_state, IIO_MMA9551);690 691/**692 * mma9551_sleep() - sleep693 * @freq: Application frequency694 *695 * Firmware applications run at a certain frequency on the696 * device. Sleep for one application cycle to make sure the697 * application had time to run once and initialize set values.698 */699void mma9551_sleep(int freq)700{701 int sleep_val = 1000 / freq;702 703 if (sleep_val < 20)704 usleep_range(sleep_val * 1000, 20000);705 else706 msleep_interruptible(sleep_val);707}708EXPORT_SYMBOL_NS(mma9551_sleep, IIO_MMA9551);709 710/**711 * mma9551_read_accel_chan() - read accelerometer channel712 * @client: I2C client713 * @chan: IIO channel714 * @val: Pointer to the accelerometer value read715 * @val2: Unused716 *717 * Read accelerometer value for the specified channel.718 *719 * Locking note: This function must be called with the device lock held.720 * Locking is not handled inside the function. Callers should ensure they721 * serialize access to the HW.722 *723 * Returns: IIO_VAL_INT on success, negative value on failure.724 */725int mma9551_read_accel_chan(struct i2c_client *client,726 const struct iio_chan_spec *chan,727 int *val, int *val2)728{729 u16 reg_addr;730 s16 raw_accel;731 int ret;732 733 switch (chan->channel2) {734 case IIO_MOD_X:735 reg_addr = MMA9551_AFE_X_ACCEL_REG;736 break;737 case IIO_MOD_Y:738 reg_addr = MMA9551_AFE_Y_ACCEL_REG;739 break;740 case IIO_MOD_Z:741 reg_addr = MMA9551_AFE_Z_ACCEL_REG;742 break;743 default:744 return -EINVAL;745 }746 747 ret = mma9551_set_power_state(client, true);748 if (ret < 0)749 return ret;750 751 ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,752 reg_addr, &raw_accel);753 if (ret < 0)754 goto out_poweroff;755 756 *val = raw_accel;757 758 ret = IIO_VAL_INT;759 760out_poweroff:761 mma9551_set_power_state(client, false);762 return ret;763}764EXPORT_SYMBOL_NS(mma9551_read_accel_chan, IIO_MMA9551);765 766/**767 * mma9551_read_accel_scale() - read accelerometer scale768 * @val: Pointer to the accelerometer scale (int value)769 * @val2: Pointer to the accelerometer scale (micro value)770 *771 * Read accelerometer scale.772 *773 * Returns: IIO_VAL_INT_PLUS_MICRO.774 */775int mma9551_read_accel_scale(int *val, int *val2)776{777 *val = 0;778 *val2 = 2440;779 780 return IIO_VAL_INT_PLUS_MICRO;781}782EXPORT_SYMBOL_NS(mma9551_read_accel_scale, IIO_MMA9551);783 784/**785 * mma9551_app_reset() - reset application786 * @client: I2C client787 * @app_mask: Application to reset788 *789 * Reset the given application (using the Reset/Suspend/Clear790 * Control Application)791 *792 * Returns: 0 on success, negative value on failure.793 */794int mma9551_app_reset(struct i2c_client *client, u32 app_mask)795{796 return mma9551_write_config_byte(client, MMA9551_APPID_RSC,797 MMA9551_RSC_RESET +798 MMA9551_RSC_OFFSET(app_mask),799 MMA9551_RSC_VAL(app_mask));800}801EXPORT_SYMBOL_NS(mma9551_app_reset, IIO_MMA9551);802 803MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");804MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");805MODULE_LICENSE("GPL v2");806MODULE_DESCRIPTION("MMA955xL sensors core");807