brintos

brintos / linux-shallow public Read only

0
0
Text · 31.8 KiB · 86543f3 Raw
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