mma9551.c (6da93a6710a3b1eb3d15b88bf96efaac322c893f) | mma9551.c (d5b97f5c7dfcad98927fb4f3b2e99d4c3beeec9a) |
---|---|
1/* 2 * Freescale MMA9551L Intelligent Motion-Sensing Platform driver 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 unchanged lines hidden (view full) --- 18#include <linux/slab.h> 19#include <linux/acpi.h> 20#include <linux/delay.h> 21#include <linux/gpio/consumer.h> 22#include <linux/iio/iio.h> 23#include <linux/iio/sysfs.h> 24#include <linux/iio/events.h> 25#include <linux/pm_runtime.h> | 1/* 2 * Freescale MMA9551L Intelligent Motion-Sensing Platform driver 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 unchanged lines hidden (view full) --- 18#include <linux/slab.h> 19#include <linux/acpi.h> 20#include <linux/delay.h> 21#include <linux/gpio/consumer.h> 22#include <linux/iio/iio.h> 23#include <linux/iio/sysfs.h> 24#include <linux/iio/events.h> 25#include <linux/pm_runtime.h> |
26#include "mma9551_core.h" |
|
26 27#define MMA9551_DRV_NAME "mma9551" 28#define MMA9551_IRQ_NAME "mma9551_event" 29#define MMA9551_GPIO_NAME "mma9551_int" 30#define MMA9551_GPIO_COUNT 4 31 | 27 28#define MMA9551_DRV_NAME "mma9551" 29#define MMA9551_IRQ_NAME "mma9551_event" 30#define MMA9551_GPIO_NAME "mma9551_int" 31#define MMA9551_GPIO_COUNT 4 32 |
32/* Applications IDs */ 33#define MMA9551_APPID_VERSION 0x00 34#define MMA9551_APPID_GPIO 0x03 35#define MMA9551_APPID_AFE 0x06 36#define MMA9551_APPID_TILT 0x0B 37#define MMA9551_APPID_SLEEP_WAKE 0x12 38#define MMA9551_APPID_RESET 0x17 39#define MMA9551_APPID_NONE 0xff 40 41/* Command masks for mailbox write command */ 42#define MMA9551_CMD_READ_VERSION_INFO 0x00 43#define MMA9551_CMD_READ_CONFIG 0x10 44#define MMA9551_CMD_WRITE_CONFIG 0x20 45#define MMA9551_CMD_READ_STATUS 0x30 46 47enum mma9551_gpio_pin { 48 mma9551_gpio6 = 0, 49 mma9551_gpio7, 50 mma9551_gpio8, 51 mma9551_gpio9, 52 mma9551_gpio_max = mma9551_gpio9, 53}; 54 55/* Mailbox read command */ 56#define MMA9551_RESPONSE_COCO BIT(7) 57 58/* Error-Status codes returned in mailbox read command */ 59#define MMA9551_MCI_ERROR_NONE 0x00 60#define MMA9551_MCI_ERROR_PARAM 0x04 61#define MMA9551_MCI_INVALID_COUNT 0x19 62#define MMA9551_MCI_ERROR_COMMAND 0x1C 63#define MMA9551_MCI_ERROR_INVALID_LENGTH 0x21 64#define MMA9551_MCI_ERROR_FIFO_BUSY 0x22 65#define MMA9551_MCI_ERROR_FIFO_ALLOCATED 0x23 66#define MMA9551_MCI_ERROR_FIFO_OVERSIZE 0x24 67 68/* GPIO Application */ 69#define MMA9551_GPIO_POL_MSB 0x08 70#define MMA9551_GPIO_POL_LSB 0x09 71 72/* Sleep/Wake application */ 73#define MMA9551_SLEEP_CFG 0x06 74#define MMA9551_SLEEP_CFG_SNCEN BIT(0) 75#define MMA9551_SLEEP_CFG_FLEEN BIT(1) 76#define MMA9551_SLEEP_CFG_SCHEN BIT(2) 77 78/* AFE application */ 79#define MMA9551_AFE_X_ACCEL_REG 0x00 80#define MMA9551_AFE_Y_ACCEL_REG 0x02 81#define MMA9551_AFE_Z_ACCEL_REG 0x04 82 | |
83/* Tilt application (inclination in IIO terms). */ 84#define MMA9551_TILT_XZ_ANG_REG 0x00 85#define MMA9551_TILT_YZ_ANG_REG 0x01 86#define MMA9551_TILT_XY_ANG_REG 0x02 87#define MMA9551_TILT_ANGFLG BIT(7) 88#define MMA9551_TILT_QUAD_REG 0x03 89#define MMA9551_TILT_XY_QUAD_SHIFT 0 90#define MMA9551_TILT_YZ_QUAD_SHIFT 2 91#define MMA9551_TILT_XZ_QUAD_SHIFT 4 92#define MMA9551_TILT_CFG_REG 0x01 93#define MMA9551_TILT_ANG_THRESH_MASK GENMASK(3, 0) 94 | 33/* Tilt application (inclination in IIO terms). */ 34#define MMA9551_TILT_XZ_ANG_REG 0x00 35#define MMA9551_TILT_YZ_ANG_REG 0x01 36#define MMA9551_TILT_XY_ANG_REG 0x02 37#define MMA9551_TILT_ANGFLG BIT(7) 38#define MMA9551_TILT_QUAD_REG 0x03 39#define MMA9551_TILT_XY_QUAD_SHIFT 0 40#define MMA9551_TILT_YZ_QUAD_SHIFT 2 41#define MMA9551_TILT_XZ_QUAD_SHIFT 4 42#define MMA9551_TILT_CFG_REG 0x01 43#define MMA9551_TILT_ANG_THRESH_MASK GENMASK(3, 0) 44 |
45#define MMA9551_DEFAULT_SAMPLE_RATE 122 /* Hz */ 46 |
|
95/* Tilt events are mapped to the first three GPIO pins. */ 96enum mma9551_tilt_axis { 97 mma9551_x = 0, 98 mma9551_y, 99 mma9551_z, 100}; 101 | 47/* Tilt events are mapped to the first three GPIO pins. */ 48enum mma9551_tilt_axis { 49 mma9551_x = 0, 50 mma9551_y, 51 mma9551_z, 52}; 53 |
102/* 103 * A response is composed of: 104 * - control registers: MB0-3 105 * - data registers: MB4-31 106 * 107 * A request is composed of: 108 * - mbox to write to (always 0) 109 * - control registers: MB1-4 110 * - data registers: MB5-31 111 */ 112#define MMA9551_MAILBOX_CTRL_REGS 4 113#define MMA9551_MAX_MAILBOX_DATA_REGS 28 114#define MMA9551_MAILBOX_REGS 32 115 116#define MMA9551_I2C_READ_RETRIES 5 117#define MMA9551_I2C_READ_DELAY 50 /* us */ 118 119#define MMA9551_DEFAULT_SAMPLE_RATE 122 /* Hz */ 120#define MMA9551_AUTO_SUSPEND_DELAY_MS 2000 121 122struct mma9551_mbox_request { 123 u8 start_mbox; /* Always 0. */ 124 u8 app_id; 125 /* 126 * See Section 5.3.1 of the MMA955xL Software Reference Manual. 127 * 128 * Bit 7: reserved, always 0 129 * Bits 6-4: command 130 * Bits 3-0: upper bits of register offset 131 */ 132 u8 cmd_off; 133 u8 lower_off; 134 u8 nbytes; 135 u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS - 1]; 136} __packed; 137 138struct mma9551_mbox_response { 139 u8 app_id; 140 /* 141 * See Section 5.3.3 of the MMA955xL Software Reference Manual. 142 * 143 * Bit 7: COCO 144 * Bits 6-0: Error code. 145 */ 146 u8 coco_err; 147 u8 nbytes; 148 u8 req_bytes; 149 u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS]; 150} __packed; 151 152struct mma9551_version_info { 153 __be32 device_id; 154 u8 rom_version[2]; 155 u8 fw_version[2]; 156 u8 hw_version[2]; 157 u8 fw_build[2]; 158}; 159 | |
160struct mma9551_data { 161 struct i2c_client *client; 162 struct mutex mutex; 163 int event_enabled[3]; 164 int irqs[MMA9551_GPIO_COUNT]; 165}; 166 | 54struct mma9551_data { 55 struct i2c_client *client; 56 struct mutex mutex; 57 int event_enabled[3]; 58 int irqs[MMA9551_GPIO_COUNT]; 59}; 60 |
167static int mma9551_transfer(struct i2c_client *client, 168 u8 app_id, u8 command, u16 offset, 169 u8 *inbytes, int num_inbytes, 170 u8 *outbytes, int num_outbytes) 171{ 172 struct mma9551_mbox_request req; 173 struct mma9551_mbox_response rsp; 174 struct i2c_msg in, out; 175 u8 req_len, err_code; 176 int ret, retries; 177 178 if (offset >= 1 << 12) { 179 dev_err(&client->dev, "register offset too large\n"); 180 return -EINVAL; 181 } 182 183 req_len = 1 + MMA9551_MAILBOX_CTRL_REGS + num_inbytes; 184 req.start_mbox = 0; 185 req.app_id = app_id; 186 req.cmd_off = command | (offset >> 8); 187 req.lower_off = offset; 188 189 if (command == MMA9551_CMD_WRITE_CONFIG) 190 req.nbytes = num_inbytes; 191 else 192 req.nbytes = num_outbytes; 193 if (num_inbytes) 194 memcpy(req.buf, inbytes, num_inbytes); 195 196 out.addr = client->addr; 197 out.flags = 0; 198 out.len = req_len; 199 out.buf = (u8 *)&req; 200 201 ret = i2c_transfer(client->adapter, &out, 1); 202 if (ret < 0) { 203 dev_err(&client->dev, "i2c write failed\n"); 204 return ret; 205 } 206 207 retries = MMA9551_I2C_READ_RETRIES; 208 do { 209 udelay(MMA9551_I2C_READ_DELAY); 210 211 in.addr = client->addr; 212 in.flags = I2C_M_RD; 213 in.len = sizeof(rsp); 214 in.buf = (u8 *)&rsp; 215 216 ret = i2c_transfer(client->adapter, &in, 1); 217 if (ret < 0) { 218 dev_err(&client->dev, "i2c read failed\n"); 219 return ret; 220 } 221 222 if (rsp.coco_err & MMA9551_RESPONSE_COCO) 223 break; 224 } while (--retries > 0); 225 226 if (retries == 0) { 227 dev_err(&client->dev, 228 "timed out while waiting for command response\n"); 229 return -ETIMEDOUT; 230 } 231 232 if (rsp.app_id != app_id) { 233 dev_err(&client->dev, 234 "app_id mismatch in response got %02x expected %02x\n", 235 rsp.app_id, app_id); 236 return -EINVAL; 237 } 238 239 err_code = rsp.coco_err & ~MMA9551_RESPONSE_COCO; 240 if (err_code != MMA9551_MCI_ERROR_NONE) { 241 dev_err(&client->dev, "read returned error %x\n", err_code); 242 return -EINVAL; 243 } 244 245 if (rsp.nbytes != rsp.req_bytes) { 246 dev_err(&client->dev, 247 "output length mismatch got %d expected %d\n", 248 rsp.nbytes, rsp.req_bytes); 249 return -EINVAL; 250 } 251 252 if (num_outbytes) 253 memcpy(outbytes, rsp.buf, num_outbytes); 254 255 return 0; 256} 257 258static int mma9551_read_config_byte(struct i2c_client *client, u8 app_id, 259 u16 reg, u8 *val) 260{ 261 return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, 262 reg, NULL, 0, val, 1); 263} 264 265static int mma9551_write_config_byte(struct i2c_client *client, u8 app_id, 266 u16 reg, u8 val) 267{ 268 return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg, 269 &val, 1, NULL, 0); 270} 271 272static int mma9551_read_status_byte(struct i2c_client *client, u8 app_id, 273 u16 reg, u8 *val) 274{ 275 return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, 276 reg, NULL, 0, val, 1); 277} 278 279static int mma9551_read_status_word(struct i2c_client *client, u8 app_id, 280 u16 reg, u16 *val) 281{ 282 int ret; 283 __be16 v; 284 285 ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, 286 reg, NULL, 0, (u8 *)&v, 2); 287 *val = be16_to_cpu(v); 288 289 return ret; 290} 291 292static int mma9551_update_config_bits(struct i2c_client *client, u8 app_id, 293 u16 reg, u8 mask, u8 val) 294{ 295 int ret; 296 u8 tmp, orig; 297 298 ret = mma9551_read_config_byte(client, app_id, reg, &orig); 299 if (ret < 0) 300 return ret; 301 302 tmp = orig & ~mask; 303 tmp |= val & mask; 304 305 if (tmp == orig) 306 return 0; 307 308 return mma9551_write_config_byte(client, app_id, reg, tmp); 309} 310 311/* 312 * The polarity parameter is described in section 6.2.2, page 66, of the 313 * Software Reference Manual. Basically, polarity=0 means the interrupt 314 * line has the same value as the selected bit, while polarity=1 means 315 * the line is inverted. 316 */ 317static int mma9551_gpio_config(struct i2c_client *client, 318 enum mma9551_gpio_pin pin, 319 u8 app_id, u8 bitnum, int polarity) 320{ 321 u8 reg, pol_mask, pol_val; 322 int ret; 323 324 if (pin > mma9551_gpio_max) { 325 dev_err(&client->dev, "bad GPIO pin\n"); 326 return -EINVAL; 327 } 328 329 /* 330 * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and 331 * 0x03, and so on. 332 */ 333 reg = pin * 2; 334 335 ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO, 336 reg, app_id); 337 if (ret < 0) { 338 dev_err(&client->dev, "error setting GPIO app_id\n"); 339 return ret; 340 } 341 342 ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO, 343 reg + 1, bitnum); 344 if (ret < 0) { 345 dev_err(&client->dev, "error setting GPIO bit number\n"); 346 return ret; 347 } 348 349 switch (pin) { 350 case mma9551_gpio6: 351 reg = MMA9551_GPIO_POL_LSB; 352 pol_mask = 1 << 6; 353 break; 354 case mma9551_gpio7: 355 reg = MMA9551_GPIO_POL_LSB; 356 pol_mask = 1 << 7; 357 break; 358 case mma9551_gpio8: 359 reg = MMA9551_GPIO_POL_MSB; 360 pol_mask = 1 << 0; 361 break; 362 case mma9551_gpio9: 363 reg = MMA9551_GPIO_POL_MSB; 364 pol_mask = 1 << 1; 365 break; 366 } 367 pol_val = polarity ? pol_mask : 0; 368 369 ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg, 370 pol_mask, pol_val); 371 if (ret < 0) 372 dev_err(&client->dev, "error setting GPIO polarity\n"); 373 374 return ret; 375} 376 377static int mma9551_read_version(struct i2c_client *client) 378{ 379 struct mma9551_version_info info; 380 int ret; 381 382 ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00, 383 NULL, 0, (u8 *)&info, sizeof(info)); 384 if (ret < 0) 385 return ret; 386 387 dev_info(&client->dev, "Device ID 0x%x, firmware version %02x.%02x\n", 388 be32_to_cpu(info.device_id), info.fw_version[0], 389 info.fw_version[1]); 390 391 return 0; 392} 393 394/* 395 * Power on chip and enable doze mode. 396 * Use 'false' as the second parameter to cause the device to enter 397 * sleep. 398 */ 399static int mma9551_set_device_state(struct i2c_client *client, bool enable) 400{ 401 return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE, 402 MMA9551_SLEEP_CFG, 403 MMA9551_SLEEP_CFG_SNCEN | 404 MMA9551_SLEEP_CFG_FLEEN | 405 MMA9551_SLEEP_CFG_SCHEN, 406 enable ? MMA9551_SLEEP_CFG_SCHEN | 407 MMA9551_SLEEP_CFG_FLEEN : 408 MMA9551_SLEEP_CFG_SNCEN); 409} 410 411static int mma9551_set_power_state(struct i2c_client *client, bool on) 412{ 413#ifdef CONFIG_PM 414 int ret; 415 416 if (on) 417 ret = pm_runtime_get_sync(&client->dev); 418 else { 419 pm_runtime_mark_last_busy(&client->dev); 420 ret = pm_runtime_put_autosuspend(&client->dev); 421 } 422 423 if (ret < 0) { 424 dev_err(&client->dev, 425 "failed to change power state to %d\n", on); 426 if (on) 427 pm_runtime_put_noidle(&client->dev); 428 429 return ret; 430 } 431#endif 432 433 return 0; 434} 435 436static void mma9551_sleep(int freq) 437{ 438 int sleep_val = 1000 / freq; 439 440 if (sleep_val < 20) 441 usleep_range(sleep_val * 1000, 20000); 442 else 443 msleep_interruptible(sleep_val); 444} 445 | |
446static int mma9551_read_incli_chan(struct i2c_client *client, 447 const struct iio_chan_spec *chan, 448 int *val) 449{ 450 u8 quad_shift, angle, quadrant; 451 u16 reg_addr; 452 int ret; 453 --- 38 unchanged lines hidden (view full) --- 492 493 ret = IIO_VAL_INT; 494 495out_poweroff: 496 mma9551_set_power_state(client, false); 497 return ret; 498} 499 | 61static int mma9551_read_incli_chan(struct i2c_client *client, 62 const struct iio_chan_spec *chan, 63 int *val) 64{ 65 u8 quad_shift, angle, quadrant; 66 u16 reg_addr; 67 int ret; 68 --- 38 unchanged lines hidden (view full) --- 107 108 ret = IIO_VAL_INT; 109 110out_poweroff: 111 mma9551_set_power_state(client, false); 112 return ret; 113} 114 |
500static int mma9551_read_accel_chan(struct i2c_client *client, 501 const struct iio_chan_spec *chan, 502 int *val, int *val2) 503{ 504 u16 reg_addr; 505 s16 raw_accel; 506 int ret; 507 508 switch (chan->channel2) { 509 case IIO_MOD_X: 510 reg_addr = MMA9551_AFE_X_ACCEL_REG; 511 break; 512 case IIO_MOD_Y: 513 reg_addr = MMA9551_AFE_Y_ACCEL_REG; 514 break; 515 case IIO_MOD_Z: 516 reg_addr = MMA9551_AFE_Z_ACCEL_REG; 517 break; 518 default: 519 return -EINVAL; 520 } 521 522 ret = mma9551_set_power_state(client, true); 523 if (ret < 0) 524 return ret; 525 526 ret = mma9551_read_status_word(client, MMA9551_APPID_AFE, 527 reg_addr, &raw_accel); 528 if (ret < 0) 529 goto out_poweroff; 530 531 *val = raw_accel; 532 533 ret = IIO_VAL_INT; 534 535out_poweroff: 536 mma9551_set_power_state(client, false); 537 return ret; 538} 539 | |
540static int mma9551_read_raw(struct iio_dev *indio_dev, 541 struct iio_chan_spec const *chan, 542 int *val, int *val2, long mask) 543{ 544 struct mma9551_data *data = iio_priv(indio_dev); 545 int ret; 546 547 switch (mask) { --- 16 unchanged lines hidden (view full) --- 564 mutex_unlock(&data->mutex); 565 return ret; 566 default: 567 return -EINVAL; 568 } 569 case IIO_CHAN_INFO_SCALE: 570 switch (chan->type) { 571 case IIO_ACCEL: | 115static int mma9551_read_raw(struct iio_dev *indio_dev, 116 struct iio_chan_spec const *chan, 117 int *val, int *val2, long mask) 118{ 119 struct mma9551_data *data = iio_priv(indio_dev); 120 int ret; 121 122 switch (mask) { --- 16 unchanged lines hidden (view full) --- 139 mutex_unlock(&data->mutex); 140 return ret; 141 default: 142 return -EINVAL; 143 } 144 case IIO_CHAN_INFO_SCALE: 145 switch (chan->type) { 146 case IIO_ACCEL: |
572 *val = 0; 573 *val2 = 2440; 574 return IIO_VAL_INT_PLUS_MICRO; | 147 return mma9551_read_accel_scale(val, val2); |
575 default: 576 return -EINVAL; 577 } 578 default: 579 return -EINVAL; 580 } 581} 582 --- 152 unchanged lines hidden (view full) --- 735 736static const struct iio_event_spec mma9551_incli_event = { 737 .type = IIO_EV_TYPE_ROC, 738 .dir = IIO_EV_DIR_RISING, 739 .mask_separate = BIT(IIO_EV_INFO_ENABLE), 740 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE), 741}; 742 | 148 default: 149 return -EINVAL; 150 } 151 default: 152 return -EINVAL; 153 } 154} 155 --- 152 unchanged lines hidden (view full) --- 308 309static const struct iio_event_spec mma9551_incli_event = { 310 .type = IIO_EV_TYPE_ROC, 311 .dir = IIO_EV_DIR_RISING, 312 .mask_separate = BIT(IIO_EV_INFO_ENABLE), 313 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE), 314}; 315 |
743#define MMA9551_ACCEL_CHANNEL(axis) { \ 744 .type = IIO_ACCEL, \ 745 .modified = 1, \ 746 .channel2 = axis, \ 747 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 748 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 749} 750 | |
751#define MMA9551_INCLI_CHANNEL(axis) { \ 752 .type = IIO_INCLI, \ 753 .modified = 1, \ 754 .channel2 = axis, \ 755 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ 756 .event_spec = &mma9551_incli_event, \ 757 .num_event_specs = 1, \ 758} --- 314 unchanged lines hidden --- | 316#define MMA9551_INCLI_CHANNEL(axis) { \ 317 .type = IIO_INCLI, \ 318 .modified = 1, \ 319 .channel2 = axis, \ 320 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ 321 .event_spec = &mma9551_incli_event, \ 322 .num_event_specs = 1, \ 323} --- 314 unchanged lines hidden --- |