1260 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Freescale MMA9553L Intelligent Pedometer driver4 * Copyright (c) 2014, Intel Corporation.5 */6 7#include <linux/module.h>8#include <linux/i2c.h>9#include <linux/interrupt.h>10#include <linux/slab.h>11#include <linux/acpi.h>12#include <linux/iio/iio.h>13#include <linux/iio/sysfs.h>14#include <linux/iio/events.h>15#include <linux/pm_runtime.h>16#include "mma9551_core.h"17 18#define MMA9553_DRV_NAME "mma9553"19#define MMA9553_IRQ_NAME "mma9553_event"20 21/* Pedometer configuration registers (R/W) */22#define MMA9553_REG_CONF_SLEEPMIN 0x0023#define MMA9553_REG_CONF_SLEEPMAX 0x0224#define MMA9553_REG_CONF_SLEEPTHD 0x0425#define MMA9553_MASK_CONF_WORD GENMASK(15, 0)26 27#define MMA9553_REG_CONF_CONF_STEPLEN 0x0628#define MMA9553_MASK_CONF_CONFIG BIT(15)29#define MMA9553_MASK_CONF_ACT_DBCNTM BIT(14)30#define MMA9553_MASK_CONF_SLP_DBCNTM BIT(13)31#define MMA9553_MASK_CONF_STEPLEN GENMASK(7, 0)32 33#define MMA9553_REG_CONF_HEIGHT_WEIGHT 0x0834#define MMA9553_MASK_CONF_HEIGHT GENMASK(15, 8)35#define MMA9553_MASK_CONF_WEIGHT GENMASK(7, 0)36 37#define MMA9553_REG_CONF_FILTER 0x0A38#define MMA9553_MASK_CONF_FILTSTEP GENMASK(15, 8)39#define MMA9553_MASK_CONF_MALE BIT(7)40#define MMA9553_MASK_CONF_FILTTIME GENMASK(6, 0)41 42#define MMA9553_REG_CONF_SPEED_STEP 0x0C43#define MMA9553_MASK_CONF_SPDPRD GENMASK(15, 8)44#define MMA9553_MASK_CONF_STEPCOALESCE GENMASK(7, 0)45 46#define MMA9553_REG_CONF_ACTTHD 0x0E47#define MMA9553_MAX_ACTTHD GENMASK(15, 0)48 49/* Pedometer status registers (R-only) */50#define MMA9553_REG_STATUS 0x0051#define MMA9553_MASK_STATUS_MRGFL BIT(15)52#define MMA9553_MASK_STATUS_SUSPCHG BIT(14)53#define MMA9553_MASK_STATUS_STEPCHG BIT(13)54#define MMA9553_MASK_STATUS_ACTCHG BIT(12)55#define MMA9553_MASK_STATUS_SUSP BIT(11)56#define MMA9553_MASK_STATUS_ACTIVITY GENMASK(10, 8)57#define MMA9553_MASK_STATUS_VERSION GENMASK(7, 0)58 59#define MMA9553_REG_STEPCNT 0x0260#define MMA9553_REG_DISTANCE 0x0461#define MMA9553_REG_SPEED 0x0662#define MMA9553_REG_CALORIES 0x0863#define MMA9553_REG_SLEEPCNT 0x0A64 65/* Pedometer events are always mapped to this pin. */66#define MMA9553_DEFAULT_GPIO_PIN mma9551_gpio667#define MMA9553_DEFAULT_GPIO_POLARITY 068 69/* Bitnum used for GPIO configuration = bit number in high status byte */70#define MMA9553_STATUS_TO_BITNUM(bit) (ffs(bit) - 9)71#define MMA9553_MAX_BITNUM MMA9553_STATUS_TO_BITNUM(BIT(16))72 73#define MMA9553_DEFAULT_SAMPLE_RATE 30 /* Hz */74 75/*76 * The internal activity level must be stable for ACTTHD samples before77 * ACTIVITY is updated. The ACTIVITY variable contains the current activity78 * level and is updated every time a step is detected or once a second79 * if there are no steps.80 */81#define MMA9553_ACTIVITY_THD_TO_SEC(thd) ((thd) / MMA9553_DEFAULT_SAMPLE_RATE)82#define MMA9553_ACTIVITY_SEC_TO_THD(sec) ((sec) * MMA9553_DEFAULT_SAMPLE_RATE)83 84/*85 * Autonomously suspend pedometer if acceleration vector magnitude86 * is near 1g (4096 at 0.244 mg/LSB resolution) for 30 seconds.87 */88#define MMA9553_DEFAULT_SLEEPMIN 3688 /* 0,9 g */89#define MMA9553_DEFAULT_SLEEPMAX 4508 /* 1,1 g */90#define MMA9553_DEFAULT_SLEEPTHD (MMA9553_DEFAULT_SAMPLE_RATE * 30)91 92#define MMA9553_CONFIG_RETRIES 293 94/* Status register - activity field */95enum activity_level {96 ACTIVITY_UNKNOWN,97 ACTIVITY_REST,98 ACTIVITY_WALKING,99 ACTIVITY_JOGGING,100 ACTIVITY_RUNNING,101};102 103static struct mma9553_event_info {104 enum iio_chan_type type;105 enum iio_modifier mod;106 enum iio_event_direction dir;107} mma9553_events_info[] = {108 {109 .type = IIO_STEPS,110 .mod = IIO_NO_MOD,111 .dir = IIO_EV_DIR_NONE,112 },113 {114 .type = IIO_ACTIVITY,115 .mod = IIO_MOD_STILL,116 .dir = IIO_EV_DIR_RISING,117 },118 {119 .type = IIO_ACTIVITY,120 .mod = IIO_MOD_STILL,121 .dir = IIO_EV_DIR_FALLING,122 },123 {124 .type = IIO_ACTIVITY,125 .mod = IIO_MOD_WALKING,126 .dir = IIO_EV_DIR_RISING,127 },128 {129 .type = IIO_ACTIVITY,130 .mod = IIO_MOD_WALKING,131 .dir = IIO_EV_DIR_FALLING,132 },133 {134 .type = IIO_ACTIVITY,135 .mod = IIO_MOD_JOGGING,136 .dir = IIO_EV_DIR_RISING,137 },138 {139 .type = IIO_ACTIVITY,140 .mod = IIO_MOD_JOGGING,141 .dir = IIO_EV_DIR_FALLING,142 },143 {144 .type = IIO_ACTIVITY,145 .mod = IIO_MOD_RUNNING,146 .dir = IIO_EV_DIR_RISING,147 },148 {149 .type = IIO_ACTIVITY,150 .mod = IIO_MOD_RUNNING,151 .dir = IIO_EV_DIR_FALLING,152 },153};154 155#define MMA9553_EVENTS_INFO_SIZE ARRAY_SIZE(mma9553_events_info)156 157struct mma9553_event {158 struct mma9553_event_info *info;159 bool enabled;160};161 162struct mma9553_conf_regs {163 u16 sleepmin;164 u16 sleepmax;165 u16 sleepthd;166 u16 config;167 u16 height_weight;168 u16 filter;169 u16 speed_step;170 u16 actthd;171} __packed;172 173struct mma9553_data {174 struct i2c_client *client;175 /*176 * 1. Serialize access to HW (requested by mma9551_core API).177 * 2. Serialize sequences that power on/off the device and access HW.178 */179 struct mutex mutex;180 struct mma9553_conf_regs conf;181 struct mma9553_event events[MMA9553_EVENTS_INFO_SIZE];182 int num_events;183 u8 gpio_bitnum;184 /*185 * This is used for all features that depend on step count:186 * step count, distance, speed, calories.187 */188 bool stepcnt_enabled;189 u16 stepcnt;190 u8 activity;191 s64 timestamp;192};193 194static u8 mma9553_get_bits(u16 val, u16 mask)195{196 return (val & mask) >> (ffs(mask) - 1);197}198 199static u16 mma9553_set_bits(u16 current_val, u16 val, u16 mask)200{201 return (current_val & ~mask) | (val << (ffs(mask) - 1));202}203 204static enum iio_modifier mma9553_activity_to_mod(enum activity_level activity)205{206 switch (activity) {207 case ACTIVITY_RUNNING:208 return IIO_MOD_RUNNING;209 case ACTIVITY_JOGGING:210 return IIO_MOD_JOGGING;211 case ACTIVITY_WALKING:212 return IIO_MOD_WALKING;213 case ACTIVITY_REST:214 return IIO_MOD_STILL;215 case ACTIVITY_UNKNOWN:216 default:217 return IIO_NO_MOD;218 }219}220 221static void mma9553_init_events(struct mma9553_data *data)222{223 int i;224 225 data->num_events = MMA9553_EVENTS_INFO_SIZE;226 for (i = 0; i < data->num_events; i++) {227 data->events[i].info = &mma9553_events_info[i];228 data->events[i].enabled = false;229 }230}231 232static struct mma9553_event *mma9553_get_event(struct mma9553_data *data,233 enum iio_chan_type type,234 enum iio_modifier mod,235 enum iio_event_direction dir)236{237 int i;238 239 for (i = 0; i < data->num_events; i++)240 if (data->events[i].info->type == type &&241 data->events[i].info->mod == mod &&242 data->events[i].info->dir == dir)243 return &data->events[i];244 245 return NULL;246}247 248static bool mma9553_is_any_event_enabled(struct mma9553_data *data,249 bool check_type,250 enum iio_chan_type type)251{252 int i;253 254 for (i = 0; i < data->num_events; i++)255 if ((check_type && data->events[i].info->type == type &&256 data->events[i].enabled) ||257 (!check_type && data->events[i].enabled))258 return true;259 260 return false;261}262 263static int mma9553_set_config(struct mma9553_data *data, u16 reg,264 u16 *p_reg_val, u16 val, u16 mask)265{266 int ret, retries;267 u16 reg_val, config;268 269 reg_val = *p_reg_val;270 if (val == mma9553_get_bits(reg_val, mask))271 return 0;272 273 reg_val = mma9553_set_bits(reg_val, val, mask);274 ret = mma9551_write_config_word(data->client, MMA9551_APPID_PEDOMETER,275 reg, reg_val);276 if (ret < 0) {277 dev_err(&data->client->dev,278 "error writing config register 0x%x\n", reg);279 return ret;280 }281 282 *p_reg_val = reg_val;283 284 /* Reinitializes the pedometer with current configuration values */285 config = mma9553_set_bits(data->conf.config, 1,286 MMA9553_MASK_CONF_CONFIG);287 288 ret = mma9551_write_config_word(data->client, MMA9551_APPID_PEDOMETER,289 MMA9553_REG_CONF_CONF_STEPLEN, config);290 if (ret < 0) {291 dev_err(&data->client->dev,292 "error writing config register 0x%x\n",293 MMA9553_REG_CONF_CONF_STEPLEN);294 return ret;295 }296 297 retries = MMA9553_CONFIG_RETRIES;298 do {299 mma9551_sleep(MMA9553_DEFAULT_SAMPLE_RATE);300 ret = mma9551_read_config_word(data->client,301 MMA9551_APPID_PEDOMETER,302 MMA9553_REG_CONF_CONF_STEPLEN,303 &config);304 if (ret < 0)305 return ret;306 } while (mma9553_get_bits(config, MMA9553_MASK_CONF_CONFIG) &&307 --retries > 0);308 309 return 0;310}311 312static int mma9553_read_activity_stepcnt(struct mma9553_data *data,313 u8 *activity, u16 *stepcnt)314{315 u16 buf[2];316 int ret;317 318 ret = mma9551_read_status_words(data->client, MMA9551_APPID_PEDOMETER,319 MMA9553_REG_STATUS, ARRAY_SIZE(buf),320 buf);321 if (ret < 0) {322 dev_err(&data->client->dev,323 "error reading status and stepcnt\n");324 return ret;325 }326 327 *activity = mma9553_get_bits(buf[0], MMA9553_MASK_STATUS_ACTIVITY);328 *stepcnt = buf[1];329 330 return 0;331}332 333static int mma9553_conf_gpio(struct mma9553_data *data)334{335 u8 bitnum = 0, appid = MMA9551_APPID_PEDOMETER;336 int ret;337 struct mma9553_event *ev_step_detect;338 bool activity_enabled;339 340 activity_enabled = mma9553_is_any_event_enabled(data, true,341 IIO_ACTIVITY);342 ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,343 IIO_EV_DIR_NONE);344 345 /*346 * If both step detector and activity are enabled, use the MRGFL bit.347 * This bit is the logical OR of the SUSPCHG, STEPCHG, and ACTCHG flags.348 */349 if (activity_enabled && ev_step_detect->enabled)350 bitnum = MMA9553_STATUS_TO_BITNUM(MMA9553_MASK_STATUS_MRGFL);351 else if (ev_step_detect->enabled)352 bitnum = MMA9553_STATUS_TO_BITNUM(MMA9553_MASK_STATUS_STEPCHG);353 else if (activity_enabled)354 bitnum = MMA9553_STATUS_TO_BITNUM(MMA9553_MASK_STATUS_ACTCHG);355 else /* Reset */356 appid = MMA9551_APPID_NONE;357 358 if (data->gpio_bitnum == bitnum)359 return 0;360 361 /* Save initial values for activity and stepcnt */362 if (activity_enabled || ev_step_detect->enabled) {363 ret = mma9553_read_activity_stepcnt(data, &data->activity,364 &data->stepcnt);365 if (ret < 0)366 return ret;367 }368 369 ret = mma9551_gpio_config(data->client, MMA9553_DEFAULT_GPIO_PIN, appid,370 bitnum, MMA9553_DEFAULT_GPIO_POLARITY);371 if (ret < 0)372 return ret;373 data->gpio_bitnum = bitnum;374 375 return 0;376}377 378static int mma9553_init(struct mma9553_data *data)379{380 int ret;381 382 ret = mma9551_read_version(data->client);383 if (ret)384 return ret;385 386 /*387 * Read all the pedometer configuration registers. This is used as388 * a device identification command to differentiate the MMA9553L389 * from the MMA9550L.390 */391 ret = mma9551_read_config_words(data->client, MMA9551_APPID_PEDOMETER,392 MMA9553_REG_CONF_SLEEPMIN,393 sizeof(data->conf) / sizeof(u16),394 (u16 *)&data->conf);395 if (ret < 0) {396 dev_err(&data->client->dev,397 "failed to read configuration registers\n");398 return ret;399 }400 401 /* Reset GPIO */402 data->gpio_bitnum = MMA9553_MAX_BITNUM;403 ret = mma9553_conf_gpio(data);404 if (ret < 0)405 return ret;406 407 ret = mma9551_app_reset(data->client, MMA9551_RSC_PED);408 if (ret < 0)409 return ret;410 411 /* Init config registers */412 data->conf.sleepmin = MMA9553_DEFAULT_SLEEPMIN;413 data->conf.sleepmax = MMA9553_DEFAULT_SLEEPMAX;414 data->conf.sleepthd = MMA9553_DEFAULT_SLEEPTHD;415 data->conf.config = mma9553_set_bits(data->conf.config, 1,416 MMA9553_MASK_CONF_CONFIG);417 /*418 * Clear the activity debounce counter when the activity level changes,419 * so that the confidence level applies for any activity level.420 */421 data->conf.config = mma9553_set_bits(data->conf.config, 1,422 MMA9553_MASK_CONF_ACT_DBCNTM);423 ret = mma9551_write_config_words(data->client, MMA9551_APPID_PEDOMETER,424 MMA9553_REG_CONF_SLEEPMIN,425 sizeof(data->conf) / sizeof(u16),426 (u16 *)&data->conf);427 if (ret < 0) {428 dev_err(&data->client->dev,429 "failed to write configuration registers\n");430 return ret;431 }432 433 return mma9551_set_device_state(data->client, true);434}435 436static int mma9553_read_status_word(struct mma9553_data *data, u16 reg,437 u16 *tmp)438{439 bool powered_on;440 int ret;441 442 /*443 * The HW only counts steps and other dependent444 * parameters (speed, distance, calories, activity)445 * if power is on (from enabling an event or the446 * step counter).447 */448 powered_on = mma9553_is_any_event_enabled(data, false, 0) ||449 data->stepcnt_enabled;450 if (!powered_on) {451 dev_err(&data->client->dev, "No channels enabled\n");452 return -EINVAL;453 }454 455 mutex_lock(&data->mutex);456 ret = mma9551_read_status_word(data->client, MMA9551_APPID_PEDOMETER,457 reg, tmp);458 mutex_unlock(&data->mutex);459 return ret;460}461 462static int mma9553_read_raw(struct iio_dev *indio_dev,463 struct iio_chan_spec const *chan,464 int *val, int *val2, long mask)465{466 struct mma9553_data *data = iio_priv(indio_dev);467 int ret;468 u16 tmp;469 u8 activity;470 471 switch (mask) {472 case IIO_CHAN_INFO_PROCESSED:473 switch (chan->type) {474 case IIO_STEPS:475 ret = mma9553_read_status_word(data,476 MMA9553_REG_STEPCNT,477 &tmp);478 if (ret < 0)479 return ret;480 *val = tmp;481 return IIO_VAL_INT;482 case IIO_DISTANCE:483 ret = mma9553_read_status_word(data,484 MMA9553_REG_DISTANCE,485 &tmp);486 if (ret < 0)487 return ret;488 *val = tmp;489 return IIO_VAL_INT;490 case IIO_ACTIVITY:491 ret = mma9553_read_status_word(data,492 MMA9553_REG_STATUS,493 &tmp);494 if (ret < 0)495 return ret;496 497 activity =498 mma9553_get_bits(tmp, MMA9553_MASK_STATUS_ACTIVITY);499 500 /*501 * The device does not support confidence value levels,502 * so we will always have 100% for current activity and503 * 0% for the others.504 */505 if (chan->channel2 == mma9553_activity_to_mod(activity))506 *val = 100;507 else508 *val = 0;509 return IIO_VAL_INT;510 default:511 return -EINVAL;512 }513 case IIO_CHAN_INFO_RAW:514 switch (chan->type) {515 case IIO_VELOCITY: /* m/h */516 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)517 return -EINVAL;518 ret = mma9553_read_status_word(data,519 MMA9553_REG_SPEED,520 &tmp);521 if (ret < 0)522 return ret;523 *val = tmp;524 return IIO_VAL_INT;525 case IIO_ENERGY: /* Cal or kcal */526 ret = mma9553_read_status_word(data,527 MMA9553_REG_CALORIES,528 &tmp);529 if (ret < 0)530 return ret;531 *val = tmp;532 return IIO_VAL_INT;533 case IIO_ACCEL:534 mutex_lock(&data->mutex);535 ret = mma9551_read_accel_chan(data->client,536 chan, val, val2);537 mutex_unlock(&data->mutex);538 return ret;539 default:540 return -EINVAL;541 }542 case IIO_CHAN_INFO_SCALE:543 switch (chan->type) {544 case IIO_VELOCITY: /* m/h to m/s */545 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)546 return -EINVAL;547 *val = 0;548 *val2 = 277; /* 0.000277 */549 return IIO_VAL_INT_PLUS_MICRO;550 case IIO_ENERGY: /* Cal or kcal to J */551 *val = 4184;552 return IIO_VAL_INT;553 case IIO_ACCEL:554 return mma9551_read_accel_scale(val, val2);555 default:556 return -EINVAL;557 }558 case IIO_CHAN_INFO_ENABLE:559 *val = data->stepcnt_enabled;560 return IIO_VAL_INT;561 case IIO_CHAN_INFO_CALIBHEIGHT:562 tmp = mma9553_get_bits(data->conf.height_weight,563 MMA9553_MASK_CONF_HEIGHT);564 *val = tmp / 100; /* cm to m */565 *val2 = (tmp % 100) * 10000;566 return IIO_VAL_INT_PLUS_MICRO;567 case IIO_CHAN_INFO_CALIBWEIGHT:568 *val = mma9553_get_bits(data->conf.height_weight,569 MMA9553_MASK_CONF_WEIGHT);570 return IIO_VAL_INT;571 case IIO_CHAN_INFO_DEBOUNCE_COUNT:572 switch (chan->type) {573 case IIO_STEPS:574 *val = mma9553_get_bits(data->conf.filter,575 MMA9553_MASK_CONF_FILTSTEP);576 return IIO_VAL_INT;577 default:578 return -EINVAL;579 }580 case IIO_CHAN_INFO_DEBOUNCE_TIME:581 switch (chan->type) {582 case IIO_STEPS:583 *val = mma9553_get_bits(data->conf.filter,584 MMA9553_MASK_CONF_FILTTIME);585 return IIO_VAL_INT;586 default:587 return -EINVAL;588 }589 case IIO_CHAN_INFO_INT_TIME:590 switch (chan->type) {591 case IIO_VELOCITY:592 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)593 return -EINVAL;594 *val = mma9553_get_bits(data->conf.speed_step,595 MMA9553_MASK_CONF_SPDPRD);596 return IIO_VAL_INT;597 default:598 return -EINVAL;599 }600 default:601 return -EINVAL;602 }603}604 605static int mma9553_write_raw(struct iio_dev *indio_dev,606 struct iio_chan_spec const *chan,607 int val, int val2, long mask)608{609 struct mma9553_data *data = iio_priv(indio_dev);610 int ret, tmp;611 612 switch (mask) {613 case IIO_CHAN_INFO_ENABLE:614 if (data->stepcnt_enabled == !!val)615 return 0;616 mutex_lock(&data->mutex);617 ret = mma9551_set_power_state(data->client, val);618 if (ret < 0) {619 mutex_unlock(&data->mutex);620 return ret;621 }622 data->stepcnt_enabled = val;623 mutex_unlock(&data->mutex);624 return 0;625 case IIO_CHAN_INFO_CALIBHEIGHT:626 /* m to cm */627 tmp = val * 100 + val2 / 10000;628 if (tmp < 0 || tmp > 255)629 return -EINVAL;630 mutex_lock(&data->mutex);631 ret = mma9553_set_config(data,632 MMA9553_REG_CONF_HEIGHT_WEIGHT,633 &data->conf.height_weight,634 tmp, MMA9553_MASK_CONF_HEIGHT);635 mutex_unlock(&data->mutex);636 return ret;637 case IIO_CHAN_INFO_CALIBWEIGHT:638 if (val < 0 || val > 255)639 return -EINVAL;640 mutex_lock(&data->mutex);641 ret = mma9553_set_config(data,642 MMA9553_REG_CONF_HEIGHT_WEIGHT,643 &data->conf.height_weight,644 val, MMA9553_MASK_CONF_WEIGHT);645 mutex_unlock(&data->mutex);646 return ret;647 case IIO_CHAN_INFO_DEBOUNCE_COUNT:648 switch (chan->type) {649 case IIO_STEPS:650 /*651 * Set to 0 to disable step filtering. If the value652 * specified is greater than 6, then 6 will be used.653 */654 if (val < 0)655 return -EINVAL;656 if (val > 6)657 val = 6;658 mutex_lock(&data->mutex);659 ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,660 &data->conf.filter, val,661 MMA9553_MASK_CONF_FILTSTEP);662 mutex_unlock(&data->mutex);663 return ret;664 default:665 return -EINVAL;666 }667 case IIO_CHAN_INFO_DEBOUNCE_TIME:668 switch (chan->type) {669 case IIO_STEPS:670 if (val < 0 || val > 127)671 return -EINVAL;672 mutex_lock(&data->mutex);673 ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,674 &data->conf.filter, val,675 MMA9553_MASK_CONF_FILTTIME);676 mutex_unlock(&data->mutex);677 return ret;678 default:679 return -EINVAL;680 }681 case IIO_CHAN_INFO_INT_TIME:682 switch (chan->type) {683 case IIO_VELOCITY:684 if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)685 return -EINVAL;686 /*687 * If set to a value greater than 5, then 5 will be688 * used. Warning: Do not set SPDPRD to 0 or 1 as689 * this may cause undesirable behavior.690 */691 if (val < 2)692 return -EINVAL;693 if (val > 5)694 val = 5;695 mutex_lock(&data->mutex);696 ret = mma9553_set_config(data,697 MMA9553_REG_CONF_SPEED_STEP,698 &data->conf.speed_step, val,699 MMA9553_MASK_CONF_SPDPRD);700 mutex_unlock(&data->mutex);701 return ret;702 default:703 return -EINVAL;704 }705 default:706 return -EINVAL;707 }708}709 710static int mma9553_read_event_config(struct iio_dev *indio_dev,711 const struct iio_chan_spec *chan,712 enum iio_event_type type,713 enum iio_event_direction dir)714{715 struct mma9553_data *data = iio_priv(indio_dev);716 struct mma9553_event *event;717 718 event = mma9553_get_event(data, chan->type, chan->channel2, dir);719 if (!event)720 return -EINVAL;721 722 return event->enabled;723}724 725static int mma9553_write_event_config(struct iio_dev *indio_dev,726 const struct iio_chan_spec *chan,727 enum iio_event_type type,728 enum iio_event_direction dir, int state)729{730 struct mma9553_data *data = iio_priv(indio_dev);731 struct mma9553_event *event;732 int ret;733 734 event = mma9553_get_event(data, chan->type, chan->channel2, dir);735 if (!event)736 return -EINVAL;737 738 if (event->enabled == state)739 return 0;740 741 mutex_lock(&data->mutex);742 743 ret = mma9551_set_power_state(data->client, state);744 if (ret < 0)745 goto err_out;746 event->enabled = state;747 748 ret = mma9553_conf_gpio(data);749 if (ret < 0)750 goto err_conf_gpio;751 752 mutex_unlock(&data->mutex);753 754 return 0;755 756err_conf_gpio:757 if (state) {758 event->enabled = false;759 mma9551_set_power_state(data->client, false);760 }761err_out:762 mutex_unlock(&data->mutex);763 return ret;764}765 766static int mma9553_read_event_value(struct iio_dev *indio_dev,767 const struct iio_chan_spec *chan,768 enum iio_event_type type,769 enum iio_event_direction dir,770 enum iio_event_info info,771 int *val, int *val2)772{773 struct mma9553_data *data = iio_priv(indio_dev);774 775 *val2 = 0;776 switch (info) {777 case IIO_EV_INFO_VALUE:778 switch (chan->type) {779 case IIO_STEPS:780 *val = mma9553_get_bits(data->conf.speed_step,781 MMA9553_MASK_CONF_STEPCOALESCE);782 return IIO_VAL_INT;783 case IIO_ACTIVITY:784 /*785 * The device does not support confidence value levels.786 * We set an average of 50%.787 */788 *val = 50;789 return IIO_VAL_INT;790 default:791 return -EINVAL;792 }793 case IIO_EV_INFO_PERIOD:794 switch (chan->type) {795 case IIO_ACTIVITY:796 *val = MMA9553_ACTIVITY_THD_TO_SEC(data->conf.actthd);797 return IIO_VAL_INT;798 default:799 return -EINVAL;800 }801 default:802 return -EINVAL;803 }804}805 806static int mma9553_write_event_value(struct iio_dev *indio_dev,807 const struct iio_chan_spec *chan,808 enum iio_event_type type,809 enum iio_event_direction dir,810 enum iio_event_info info,811 int val, int val2)812{813 struct mma9553_data *data = iio_priv(indio_dev);814 int ret;815 816 switch (info) {817 case IIO_EV_INFO_VALUE:818 switch (chan->type) {819 case IIO_STEPS:820 if (val < 0 || val > 255)821 return -EINVAL;822 mutex_lock(&data->mutex);823 ret = mma9553_set_config(data,824 MMA9553_REG_CONF_SPEED_STEP,825 &data->conf.speed_step, val,826 MMA9553_MASK_CONF_STEPCOALESCE);827 mutex_unlock(&data->mutex);828 return ret;829 default:830 return -EINVAL;831 }832 case IIO_EV_INFO_PERIOD:833 switch (chan->type) {834 case IIO_ACTIVITY:835 if (val < 0 || val > MMA9553_ACTIVITY_THD_TO_SEC(836 MMA9553_MAX_ACTTHD))837 return -EINVAL;838 mutex_lock(&data->mutex);839 ret = mma9553_set_config(data, MMA9553_REG_CONF_ACTTHD,840 &data->conf.actthd,841 MMA9553_ACTIVITY_SEC_TO_THD842 (val), MMA9553_MASK_CONF_WORD);843 mutex_unlock(&data->mutex);844 return ret;845 default:846 return -EINVAL;847 }848 default:849 return -EINVAL;850 }851}852 853static int mma9553_get_calibgender_mode(struct iio_dev *indio_dev,854 const struct iio_chan_spec *chan)855{856 struct mma9553_data *data = iio_priv(indio_dev);857 u8 gender;858 859 gender = mma9553_get_bits(data->conf.filter, MMA9553_MASK_CONF_MALE);860 /*861 * HW expects 0 for female and 1 for male,862 * while iio index is 0 for male and 1 for female.863 */864 return !gender;865}866 867static int mma9553_set_calibgender_mode(struct iio_dev *indio_dev,868 const struct iio_chan_spec *chan,869 unsigned int mode)870{871 struct mma9553_data *data = iio_priv(indio_dev);872 u8 gender = !mode;873 int ret;874 875 if ((mode != 0) && (mode != 1))876 return -EINVAL;877 mutex_lock(&data->mutex);878 ret = mma9553_set_config(data, MMA9553_REG_CONF_FILTER,879 &data->conf.filter, gender,880 MMA9553_MASK_CONF_MALE);881 mutex_unlock(&data->mutex);882 883 return ret;884}885 886static const struct iio_event_spec mma9553_step_event = {887 .type = IIO_EV_TYPE_CHANGE,888 .dir = IIO_EV_DIR_NONE,889 .mask_separate = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_VALUE),890};891 892static const struct iio_event_spec mma9553_activity_events[] = {893 {894 .type = IIO_EV_TYPE_THRESH,895 .dir = IIO_EV_DIR_RISING,896 .mask_separate = BIT(IIO_EV_INFO_ENABLE) |897 BIT(IIO_EV_INFO_VALUE) |898 BIT(IIO_EV_INFO_PERIOD),899 },900 {901 .type = IIO_EV_TYPE_THRESH,902 .dir = IIO_EV_DIR_FALLING,903 .mask_separate = BIT(IIO_EV_INFO_ENABLE) |904 BIT(IIO_EV_INFO_VALUE) |905 BIT(IIO_EV_INFO_PERIOD),906 },907};908 909static const char * const mma9553_calibgender_modes[] = { "male", "female" };910 911static const struct iio_enum mma9553_calibgender_enum = {912 .items = mma9553_calibgender_modes,913 .num_items = ARRAY_SIZE(mma9553_calibgender_modes),914 .get = mma9553_get_calibgender_mode,915 .set = mma9553_set_calibgender_mode,916};917 918static const struct iio_chan_spec_ext_info mma9553_ext_info[] = {919 IIO_ENUM("calibgender", IIO_SHARED_BY_TYPE, &mma9553_calibgender_enum),920 IIO_ENUM_AVAILABLE("calibgender", IIO_SHARED_BY_TYPE, &mma9553_calibgender_enum),921 {},922};923 924#define MMA9553_PEDOMETER_CHANNEL(_type, _mask) { \925 .type = _type, \926 .info_mask_separate = BIT(IIO_CHAN_INFO_ENABLE) | \927 BIT(IIO_CHAN_INFO_CALIBHEIGHT) | \928 _mask, \929 .ext_info = mma9553_ext_info, \930}931 932#define MMA9553_ACTIVITY_CHANNEL(_chan2) { \933 .type = IIO_ACTIVITY, \934 .modified = 1, \935 .channel2 = _chan2, \936 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \937 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT) | \938 BIT(IIO_CHAN_INFO_ENABLE), \939 .event_spec = mma9553_activity_events, \940 .num_event_specs = ARRAY_SIZE(mma9553_activity_events), \941 .ext_info = mma9553_ext_info, \942}943 944static const struct iio_chan_spec mma9553_channels[] = {945 MMA9551_ACCEL_CHANNEL(IIO_MOD_X),946 MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),947 MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),948 949 {950 .type = IIO_STEPS,951 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |952 BIT(IIO_CHAN_INFO_ENABLE) |953 BIT(IIO_CHAN_INFO_DEBOUNCE_COUNT) |954 BIT(IIO_CHAN_INFO_DEBOUNCE_TIME),955 .event_spec = &mma9553_step_event,956 .num_event_specs = 1,957 },958 959 MMA9553_PEDOMETER_CHANNEL(IIO_DISTANCE, BIT(IIO_CHAN_INFO_PROCESSED)),960 {961 .type = IIO_VELOCITY,962 .modified = 1,963 .channel2 = IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z,964 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |965 BIT(IIO_CHAN_INFO_SCALE) |966 BIT(IIO_CHAN_INFO_INT_TIME) |967 BIT(IIO_CHAN_INFO_ENABLE),968 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBHEIGHT),969 .ext_info = mma9553_ext_info,970 },971 MMA9553_PEDOMETER_CHANNEL(IIO_ENERGY, BIT(IIO_CHAN_INFO_RAW) |972 BIT(IIO_CHAN_INFO_SCALE) |973 BIT(IIO_CHAN_INFO_CALIBWEIGHT)),974 975 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_RUNNING),976 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_JOGGING),977 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_WALKING),978 MMA9553_ACTIVITY_CHANNEL(IIO_MOD_STILL),979};980 981static const struct iio_info mma9553_info = {982 .read_raw = mma9553_read_raw,983 .write_raw = mma9553_write_raw,984 .read_event_config = mma9553_read_event_config,985 .write_event_config = mma9553_write_event_config,986 .read_event_value = mma9553_read_event_value,987 .write_event_value = mma9553_write_event_value,988};989 990static irqreturn_t mma9553_irq_handler(int irq, void *private)991{992 struct iio_dev *indio_dev = private;993 struct mma9553_data *data = iio_priv(indio_dev);994 995 data->timestamp = iio_get_time_ns(indio_dev);996 /*997 * Since we only configure the interrupt pin when an998 * event is enabled, we are sure we have at least999 * one event enabled at this point.1000 */1001 return IRQ_WAKE_THREAD;1002}1003 1004static irqreturn_t mma9553_event_handler(int irq, void *private)1005{1006 struct iio_dev *indio_dev = private;1007 struct mma9553_data *data = iio_priv(indio_dev);1008 u16 stepcnt;1009 u8 activity;1010 struct mma9553_event *ev_activity, *ev_prev_activity, *ev_step_detect;1011 int ret;1012 1013 mutex_lock(&data->mutex);1014 ret = mma9553_read_activity_stepcnt(data, &activity, &stepcnt);1015 if (ret < 0) {1016 mutex_unlock(&data->mutex);1017 return IRQ_HANDLED;1018 }1019 1020 ev_prev_activity = mma9553_get_event(data, IIO_ACTIVITY,1021 mma9553_activity_to_mod(1022 data->activity),1023 IIO_EV_DIR_FALLING);1024 ev_activity = mma9553_get_event(data, IIO_ACTIVITY,1025 mma9553_activity_to_mod(activity),1026 IIO_EV_DIR_RISING);1027 ev_step_detect = mma9553_get_event(data, IIO_STEPS, IIO_NO_MOD,1028 IIO_EV_DIR_NONE);1029 1030 if (ev_step_detect->enabled && (stepcnt != data->stepcnt)) {1031 data->stepcnt = stepcnt;1032 iio_push_event(indio_dev,1033 IIO_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD,1034 IIO_EV_DIR_NONE,1035 IIO_EV_TYPE_CHANGE, 0, 0, 0),1036 data->timestamp);1037 }1038 1039 if (activity != data->activity) {1040 data->activity = activity;1041 /* ev_activity can be NULL if activity == ACTIVITY_UNKNOWN */1042 if (ev_prev_activity && ev_prev_activity->enabled)1043 iio_push_event(indio_dev,1044 IIO_EVENT_CODE(IIO_ACTIVITY, 0,1045 ev_prev_activity->info->mod,1046 IIO_EV_DIR_FALLING,1047 IIO_EV_TYPE_THRESH, 0, 0,1048 0),1049 data->timestamp);1050 1051 if (ev_activity && ev_activity->enabled)1052 iio_push_event(indio_dev,1053 IIO_EVENT_CODE(IIO_ACTIVITY, 0,1054 ev_activity->info->mod,1055 IIO_EV_DIR_RISING,1056 IIO_EV_TYPE_THRESH, 0, 0,1057 0),1058 data->timestamp);1059 }1060 mutex_unlock(&data->mutex);1061 1062 return IRQ_HANDLED;1063}1064 1065static const char *mma9553_match_acpi_device(struct device *dev)1066{1067 const struct acpi_device_id *id;1068 1069 id = acpi_match_device(dev->driver->acpi_match_table, dev);1070 if (!id)1071 return NULL;1072 1073 return dev_name(dev);1074}1075 1076static int mma9553_probe(struct i2c_client *client)1077{1078 const struct i2c_device_id *id = i2c_client_get_device_id(client);1079 struct mma9553_data *data;1080 struct iio_dev *indio_dev;1081 const char *name = NULL;1082 int ret;1083 1084 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));1085 if (!indio_dev)1086 return -ENOMEM;1087 1088 data = iio_priv(indio_dev);1089 i2c_set_clientdata(client, indio_dev);1090 data->client = client;1091 1092 if (id)1093 name = id->name;1094 else if (ACPI_HANDLE(&client->dev))1095 name = mma9553_match_acpi_device(&client->dev);1096 else1097 return -ENOSYS;1098 1099 mutex_init(&data->mutex);1100 mma9553_init_events(data);1101 1102 ret = mma9553_init(data);1103 if (ret < 0)1104 return ret;1105 1106 indio_dev->channels = mma9553_channels;1107 indio_dev->num_channels = ARRAY_SIZE(mma9553_channels);1108 indio_dev->name = name;1109 indio_dev->modes = INDIO_DIRECT_MODE;1110 indio_dev->info = &mma9553_info;1111 1112 if (client->irq > 0) {1113 ret = devm_request_threaded_irq(&client->dev, client->irq,1114 mma9553_irq_handler,1115 mma9553_event_handler,1116 IRQF_TRIGGER_RISING,1117 MMA9553_IRQ_NAME, indio_dev);1118 if (ret < 0) {1119 dev_err(&client->dev, "request irq %d failed\n",1120 client->irq);1121 goto out_poweroff;1122 }1123 }1124 1125 ret = pm_runtime_set_active(&client->dev);1126 if (ret < 0)1127 goto out_poweroff;1128 1129 pm_runtime_enable(&client->dev);1130 pm_runtime_set_autosuspend_delay(&client->dev,1131 MMA9551_AUTO_SUSPEND_DELAY_MS);1132 pm_runtime_use_autosuspend(&client->dev);1133 1134 ret = iio_device_register(indio_dev);1135 if (ret < 0) {1136 dev_err(&client->dev, "unable to register iio device\n");1137 goto err_pm_cleanup;1138 }1139 1140 dev_dbg(&indio_dev->dev, "Registered device %s\n", name);1141 return 0;1142 1143err_pm_cleanup:1144 pm_runtime_dont_use_autosuspend(&client->dev);1145 pm_runtime_disable(&client->dev);1146out_poweroff:1147 mma9551_set_device_state(client, false);1148 return ret;1149}1150 1151static void mma9553_remove(struct i2c_client *client)1152{1153 struct iio_dev *indio_dev = i2c_get_clientdata(client);1154 struct mma9553_data *data = iio_priv(indio_dev);1155 1156 iio_device_unregister(indio_dev);1157 1158 pm_runtime_disable(&client->dev);1159 pm_runtime_set_suspended(&client->dev);1160 1161 mutex_lock(&data->mutex);1162 mma9551_set_device_state(data->client, false);1163 mutex_unlock(&data->mutex);1164}1165 1166static int mma9553_runtime_suspend(struct device *dev)1167{1168 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));1169 struct mma9553_data *data = iio_priv(indio_dev);1170 int ret;1171 1172 mutex_lock(&data->mutex);1173 ret = mma9551_set_device_state(data->client, false);1174 mutex_unlock(&data->mutex);1175 if (ret < 0) {1176 dev_err(&data->client->dev, "powering off device failed\n");1177 return -EAGAIN;1178 }1179 1180 return 0;1181}1182 1183static int mma9553_runtime_resume(struct device *dev)1184{1185 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));1186 struct mma9553_data *data = iio_priv(indio_dev);1187 int ret;1188 1189 ret = mma9551_set_device_state(data->client, true);1190 if (ret < 0)1191 return ret;1192 1193 mma9551_sleep(MMA9553_DEFAULT_SAMPLE_RATE);1194 1195 return 0;1196}1197 1198static int mma9553_suspend(struct device *dev)1199{1200 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));1201 struct mma9553_data *data = iio_priv(indio_dev);1202 int ret;1203 1204 mutex_lock(&data->mutex);1205 ret = mma9551_set_device_state(data->client, false);1206 mutex_unlock(&data->mutex);1207 1208 return ret;1209}1210 1211static int mma9553_resume(struct device *dev)1212{1213 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));1214 struct mma9553_data *data = iio_priv(indio_dev);1215 int ret;1216 1217 mutex_lock(&data->mutex);1218 ret = mma9551_set_device_state(data->client, true);1219 mutex_unlock(&data->mutex);1220 1221 return ret;1222}1223 1224static const struct dev_pm_ops mma9553_pm_ops = {1225 SYSTEM_SLEEP_PM_OPS(mma9553_suspend, mma9553_resume)1226 RUNTIME_PM_OPS(mma9553_runtime_suspend, mma9553_runtime_resume, NULL)1227};1228 1229static const struct acpi_device_id mma9553_acpi_match[] = {1230 {"MMA9553", 0},1231 {},1232};1233 1234MODULE_DEVICE_TABLE(acpi, mma9553_acpi_match);1235 1236static const struct i2c_device_id mma9553_id[] = {1237 { "mma9553" },1238 {}1239};1240 1241MODULE_DEVICE_TABLE(i2c, mma9553_id);1242 1243static struct i2c_driver mma9553_driver = {1244 .driver = {1245 .name = MMA9553_DRV_NAME,1246 .acpi_match_table = mma9553_acpi_match,1247 .pm = pm_ptr(&mma9553_pm_ops),1248 },1249 .probe = mma9553_probe,1250 .remove = mma9553_remove,1251 .id_table = mma9553_id,1252};1253 1254module_i2c_driver(mma9553_driver);1255 1256MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");1257MODULE_LICENSE("GPL v2");1258MODULE_DESCRIPTION("MMA9553L pedometer platform driver");1259MODULE_IMPORT_NS(IIO_MMA9551);1260