cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mma9551.c (14584B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Freescale MMA9551L Intelligent Motion-Sensing Platform driver
      4 * 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/delay.h>
     13#include <linux/gpio/consumer.h>
     14#include <linux/iio/iio.h>
     15#include <linux/iio/sysfs.h>
     16#include <linux/iio/events.h>
     17#include <linux/pm_runtime.h>
     18#include "mma9551_core.h"
     19
     20#define MMA9551_DRV_NAME		"mma9551"
     21#define MMA9551_IRQ_NAME		"mma9551_event"
     22#define MMA9551_GPIO_COUNT		4
     23
     24/* Tilt application (inclination in IIO terms). */
     25#define MMA9551_TILT_XZ_ANG_REG		0x00
     26#define MMA9551_TILT_YZ_ANG_REG		0x01
     27#define MMA9551_TILT_XY_ANG_REG		0x02
     28#define MMA9551_TILT_ANGFLG		BIT(7)
     29#define MMA9551_TILT_QUAD_REG		0x03
     30#define MMA9551_TILT_XY_QUAD_SHIFT	0
     31#define MMA9551_TILT_YZ_QUAD_SHIFT	2
     32#define MMA9551_TILT_XZ_QUAD_SHIFT	4
     33#define MMA9551_TILT_CFG_REG		0x01
     34#define MMA9551_TILT_ANG_THRESH_MASK	GENMASK(3, 0)
     35
     36#define MMA9551_DEFAULT_SAMPLE_RATE	122	/* Hz */
     37
     38/* Tilt events are mapped to the first three GPIO pins. */
     39enum mma9551_tilt_axis {
     40	mma9551_x = 0,
     41	mma9551_y,
     42	mma9551_z,
     43};
     44
     45struct mma9551_data {
     46	struct i2c_client *client;
     47	struct mutex mutex;
     48	int event_enabled[3];
     49	int irqs[MMA9551_GPIO_COUNT];
     50};
     51
     52static int mma9551_read_incli_chan(struct i2c_client *client,
     53				   const struct iio_chan_spec *chan,
     54				   int *val)
     55{
     56	u8 quad_shift, angle, quadrant;
     57	u16 reg_addr;
     58	int ret;
     59
     60	switch (chan->channel2) {
     61	case IIO_MOD_X:
     62		reg_addr = MMA9551_TILT_YZ_ANG_REG;
     63		quad_shift = MMA9551_TILT_YZ_QUAD_SHIFT;
     64		break;
     65	case IIO_MOD_Y:
     66		reg_addr = MMA9551_TILT_XZ_ANG_REG;
     67		quad_shift = MMA9551_TILT_XZ_QUAD_SHIFT;
     68		break;
     69	case IIO_MOD_Z:
     70		reg_addr = MMA9551_TILT_XY_ANG_REG;
     71		quad_shift = MMA9551_TILT_XY_QUAD_SHIFT;
     72		break;
     73	default:
     74		return -EINVAL;
     75	}
     76
     77	ret = mma9551_set_power_state(client, true);
     78	if (ret < 0)
     79		return ret;
     80
     81	ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
     82				       reg_addr, &angle);
     83	if (ret < 0)
     84		goto out_poweroff;
     85
     86	ret = mma9551_read_status_byte(client, MMA9551_APPID_TILT,
     87				       MMA9551_TILT_QUAD_REG, &quadrant);
     88	if (ret < 0)
     89		goto out_poweroff;
     90
     91	angle &= ~MMA9551_TILT_ANGFLG;
     92	quadrant = (quadrant >> quad_shift) & 0x03;
     93
     94	if (quadrant == 1 || quadrant == 3)
     95		*val = 90 * (quadrant + 1) - angle;
     96	else
     97		*val = angle + 90 * quadrant;
     98
     99	ret = IIO_VAL_INT;
    100
    101out_poweroff:
    102	mma9551_set_power_state(client, false);
    103	return ret;
    104}
    105
    106static int mma9551_read_raw(struct iio_dev *indio_dev,
    107			    struct iio_chan_spec const *chan,
    108			    int *val, int *val2, long mask)
    109{
    110	struct mma9551_data *data = iio_priv(indio_dev);
    111	int ret;
    112
    113	switch (mask) {
    114	case IIO_CHAN_INFO_PROCESSED:
    115		switch (chan->type) {
    116		case IIO_INCLI:
    117			mutex_lock(&data->mutex);
    118			ret = mma9551_read_incli_chan(data->client, chan, val);
    119			mutex_unlock(&data->mutex);
    120			return ret;
    121		default:
    122			return -EINVAL;
    123		}
    124	case IIO_CHAN_INFO_RAW:
    125		switch (chan->type) {
    126		case IIO_ACCEL:
    127			mutex_lock(&data->mutex);
    128			ret = mma9551_read_accel_chan(data->client,
    129						      chan, val, val2);
    130			mutex_unlock(&data->mutex);
    131			return ret;
    132		default:
    133			return -EINVAL;
    134		}
    135	case IIO_CHAN_INFO_SCALE:
    136		switch (chan->type) {
    137		case IIO_ACCEL:
    138			return mma9551_read_accel_scale(val, val2);
    139		default:
    140			return -EINVAL;
    141		}
    142	default:
    143		return -EINVAL;
    144	}
    145}
    146
    147static int mma9551_read_event_config(struct iio_dev *indio_dev,
    148				     const struct iio_chan_spec *chan,
    149				     enum iio_event_type type,
    150				     enum iio_event_direction dir)
    151{
    152	struct mma9551_data *data = iio_priv(indio_dev);
    153
    154	switch (chan->type) {
    155	case IIO_INCLI:
    156		/* IIO counts axes from 1, because IIO_NO_MOD is 0. */
    157		return data->event_enabled[chan->channel2 - 1];
    158	default:
    159		return -EINVAL;
    160	}
    161}
    162
    163static int mma9551_config_incli_event(struct iio_dev *indio_dev,
    164				      enum iio_modifier axis,
    165				      int state)
    166{
    167	struct mma9551_data *data = iio_priv(indio_dev);
    168	enum mma9551_tilt_axis mma_axis;
    169	int ret;
    170
    171	/* IIO counts axes from 1, because IIO_NO_MOD is 0. */
    172	mma_axis = axis - 1;
    173
    174	if (data->event_enabled[mma_axis] == state)
    175		return 0;
    176
    177	if (state == 0) {
    178		ret = mma9551_gpio_config(data->client,
    179					  (enum mma9551_gpio_pin)mma_axis,
    180					  MMA9551_APPID_NONE, 0, 0);
    181		if (ret < 0)
    182			return ret;
    183
    184		ret = mma9551_set_power_state(data->client, false);
    185		if (ret < 0)
    186			return ret;
    187	} else {
    188		int bitnum;
    189
    190		/* Bit 7 of each angle register holds the angle flag. */
    191		switch (axis) {
    192		case IIO_MOD_X:
    193			bitnum = 7 + 8 * MMA9551_TILT_YZ_ANG_REG;
    194			break;
    195		case IIO_MOD_Y:
    196			bitnum = 7 + 8 * MMA9551_TILT_XZ_ANG_REG;
    197			break;
    198		case IIO_MOD_Z:
    199			bitnum = 7 + 8 * MMA9551_TILT_XY_ANG_REG;
    200			break;
    201		default:
    202			return -EINVAL;
    203		}
    204
    205
    206		ret = mma9551_set_power_state(data->client, true);
    207		if (ret < 0)
    208			return ret;
    209
    210		ret = mma9551_gpio_config(data->client,
    211					  (enum mma9551_gpio_pin)mma_axis,
    212					  MMA9551_APPID_TILT, bitnum, 0);
    213		if (ret < 0) {
    214			mma9551_set_power_state(data->client, false);
    215			return ret;
    216		}
    217	}
    218
    219	data->event_enabled[mma_axis] = state;
    220
    221	return ret;
    222}
    223
    224static int mma9551_write_event_config(struct iio_dev *indio_dev,
    225				      const struct iio_chan_spec *chan,
    226				      enum iio_event_type type,
    227				      enum iio_event_direction dir,
    228				      int state)
    229{
    230	struct mma9551_data *data = iio_priv(indio_dev);
    231	int ret;
    232
    233	switch (chan->type) {
    234	case IIO_INCLI:
    235		mutex_lock(&data->mutex);
    236		ret = mma9551_config_incli_event(indio_dev,
    237						 chan->channel2, state);
    238		mutex_unlock(&data->mutex);
    239		return ret;
    240	default:
    241		return -EINVAL;
    242	}
    243}
    244
    245static int mma9551_write_event_value(struct iio_dev *indio_dev,
    246				     const struct iio_chan_spec *chan,
    247				     enum iio_event_type type,
    248				     enum iio_event_direction dir,
    249				     enum iio_event_info info,
    250				     int val, int val2)
    251{
    252	struct mma9551_data *data = iio_priv(indio_dev);
    253	int ret;
    254
    255	switch (chan->type) {
    256	case IIO_INCLI:
    257		if (val2 != 0 || val < 1 || val > 10)
    258			return -EINVAL;
    259		mutex_lock(&data->mutex);
    260		ret = mma9551_update_config_bits(data->client,
    261						 MMA9551_APPID_TILT,
    262						 MMA9551_TILT_CFG_REG,
    263						 MMA9551_TILT_ANG_THRESH_MASK,
    264						 val);
    265		mutex_unlock(&data->mutex);
    266		return ret;
    267	default:
    268		return -EINVAL;
    269	}
    270}
    271
    272static int mma9551_read_event_value(struct iio_dev *indio_dev,
    273				    const struct iio_chan_spec *chan,
    274				    enum iio_event_type type,
    275				    enum iio_event_direction dir,
    276				    enum iio_event_info info,
    277				    int *val, int *val2)
    278{
    279	struct mma9551_data *data = iio_priv(indio_dev);
    280	int ret;
    281	u8 tmp;
    282
    283	switch (chan->type) {
    284	case IIO_INCLI:
    285		mutex_lock(&data->mutex);
    286		ret = mma9551_read_config_byte(data->client,
    287					       MMA9551_APPID_TILT,
    288					       MMA9551_TILT_CFG_REG, &tmp);
    289		mutex_unlock(&data->mutex);
    290		if (ret < 0)
    291			return ret;
    292		*val = tmp & MMA9551_TILT_ANG_THRESH_MASK;
    293		*val2 = 0;
    294		return IIO_VAL_INT;
    295	default:
    296		return -EINVAL;
    297	}
    298}
    299
    300static const struct iio_event_spec mma9551_incli_event = {
    301	.type = IIO_EV_TYPE_ROC,
    302	.dir = IIO_EV_DIR_RISING,
    303	.mask_separate = BIT(IIO_EV_INFO_ENABLE),
    304	.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
    305};
    306
    307#define MMA9551_INCLI_CHANNEL(axis) {				\
    308	.type = IIO_INCLI,					\
    309	.modified = 1,						\
    310	.channel2 = axis,					\
    311	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\
    312	.event_spec = &mma9551_incli_event,			\
    313	.num_event_specs = 1,					\
    314}
    315
    316static const struct iio_chan_spec mma9551_channels[] = {
    317	MMA9551_ACCEL_CHANNEL(IIO_MOD_X),
    318	MMA9551_ACCEL_CHANNEL(IIO_MOD_Y),
    319	MMA9551_ACCEL_CHANNEL(IIO_MOD_Z),
    320
    321	MMA9551_INCLI_CHANNEL(IIO_MOD_X),
    322	MMA9551_INCLI_CHANNEL(IIO_MOD_Y),
    323	MMA9551_INCLI_CHANNEL(IIO_MOD_Z),
    324};
    325
    326static const struct iio_info mma9551_info = {
    327	.read_raw = mma9551_read_raw,
    328	.read_event_config = mma9551_read_event_config,
    329	.write_event_config = mma9551_write_event_config,
    330	.read_event_value = mma9551_read_event_value,
    331	.write_event_value = mma9551_write_event_value,
    332};
    333
    334static irqreturn_t mma9551_event_handler(int irq, void *private)
    335{
    336	struct iio_dev *indio_dev = private;
    337	struct mma9551_data *data = iio_priv(indio_dev);
    338	int i, ret, mma_axis = -1;
    339	u16 reg;
    340	u8 val;
    341
    342	mutex_lock(&data->mutex);
    343
    344	for (i = 0; i < 3; i++)
    345		if (irq == data->irqs[i]) {
    346			mma_axis = i;
    347			break;
    348		}
    349
    350	if (mma_axis == -1) {
    351		/* IRQ was triggered on 4th line, which we don't use. */
    352		dev_warn(&data->client->dev,
    353			 "irq triggered on unused line %d\n", data->irqs[3]);
    354		goto out;
    355	}
    356
    357	switch (mma_axis) {
    358	case mma9551_x:
    359		reg = MMA9551_TILT_YZ_ANG_REG;
    360		break;
    361	case mma9551_y:
    362		reg = MMA9551_TILT_XZ_ANG_REG;
    363		break;
    364	case mma9551_z:
    365		reg = MMA9551_TILT_XY_ANG_REG;
    366		break;
    367	}
    368
    369	/*
    370	 * Read the angle even though we don't use it, otherwise we
    371	 * won't get any further interrupts.
    372	 */
    373	ret = mma9551_read_status_byte(data->client, MMA9551_APPID_TILT,
    374				       reg, &val);
    375	if (ret < 0) {
    376		dev_err(&data->client->dev,
    377			"error %d reading tilt register in IRQ\n", ret);
    378		goto out;
    379	}
    380
    381	iio_push_event(indio_dev,
    382		       IIO_MOD_EVENT_CODE(IIO_INCLI, 0, (mma_axis + 1),
    383					  IIO_EV_TYPE_ROC, IIO_EV_DIR_RISING),
    384		       iio_get_time_ns(indio_dev));
    385
    386out:
    387	mutex_unlock(&data->mutex);
    388
    389	return IRQ_HANDLED;
    390}
    391
    392static int mma9551_init(struct mma9551_data *data)
    393{
    394	int ret;
    395
    396	ret = mma9551_read_version(data->client);
    397	if (ret)
    398		return ret;
    399
    400	return mma9551_set_device_state(data->client, true);
    401}
    402
    403static int mma9551_gpio_probe(struct iio_dev *indio_dev)
    404{
    405	struct gpio_desc *gpio;
    406	int i, ret;
    407	struct mma9551_data *data = iio_priv(indio_dev);
    408	struct device *dev = &data->client->dev;
    409
    410	for (i = 0; i < MMA9551_GPIO_COUNT; i++) {
    411		gpio = devm_gpiod_get_index(dev, NULL, i, GPIOD_IN);
    412		if (IS_ERR(gpio)) {
    413			dev_err(dev, "acpi gpio get index failed\n");
    414			return PTR_ERR(gpio);
    415		}
    416
    417		ret = gpiod_to_irq(gpio);
    418		if (ret < 0)
    419			return ret;
    420
    421		data->irqs[i] = ret;
    422		ret = devm_request_threaded_irq(dev, data->irqs[i],
    423				NULL, mma9551_event_handler,
    424				IRQF_TRIGGER_RISING | IRQF_ONESHOT,
    425				MMA9551_IRQ_NAME, indio_dev);
    426		if (ret < 0) {
    427			dev_err(dev, "request irq %d failed\n", data->irqs[i]);
    428			return ret;
    429		}
    430
    431		dev_dbg(dev, "gpio resource, no:%d irq:%d\n",
    432			desc_to_gpio(gpio), data->irqs[i]);
    433	}
    434
    435	return 0;
    436}
    437
    438static const char *mma9551_match_acpi_device(struct device *dev)
    439{
    440	const struct acpi_device_id *id;
    441
    442	id = acpi_match_device(dev->driver->acpi_match_table, dev);
    443	if (!id)
    444		return NULL;
    445
    446	return dev_name(dev);
    447}
    448
    449static int mma9551_probe(struct i2c_client *client,
    450			 const struct i2c_device_id *id)
    451{
    452	struct mma9551_data *data;
    453	struct iio_dev *indio_dev;
    454	const char *name = NULL;
    455	int ret;
    456
    457	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
    458	if (!indio_dev)
    459		return -ENOMEM;
    460
    461	data = iio_priv(indio_dev);
    462	i2c_set_clientdata(client, indio_dev);
    463	data->client = client;
    464
    465	if (id)
    466		name = id->name;
    467	else if (ACPI_HANDLE(&client->dev))
    468		name = mma9551_match_acpi_device(&client->dev);
    469
    470	ret = mma9551_init(data);
    471	if (ret < 0)
    472		return ret;
    473
    474	mutex_init(&data->mutex);
    475
    476	indio_dev->channels = mma9551_channels;
    477	indio_dev->num_channels = ARRAY_SIZE(mma9551_channels);
    478	indio_dev->name = name;
    479	indio_dev->modes = INDIO_DIRECT_MODE;
    480	indio_dev->info = &mma9551_info;
    481
    482	ret = mma9551_gpio_probe(indio_dev);
    483	if (ret < 0)
    484		goto out_poweroff;
    485
    486	ret = pm_runtime_set_active(&client->dev);
    487	if (ret < 0)
    488		goto out_poweroff;
    489
    490	pm_runtime_enable(&client->dev);
    491	pm_runtime_set_autosuspend_delay(&client->dev,
    492					 MMA9551_AUTO_SUSPEND_DELAY_MS);
    493	pm_runtime_use_autosuspend(&client->dev);
    494
    495	ret = iio_device_register(indio_dev);
    496	if (ret < 0) {
    497		dev_err(&client->dev, "unable to register iio device\n");
    498		goto err_pm_cleanup;
    499	}
    500
    501	return 0;
    502
    503err_pm_cleanup:
    504	pm_runtime_dont_use_autosuspend(&client->dev);
    505	pm_runtime_disable(&client->dev);
    506out_poweroff:
    507	mma9551_set_device_state(client, false);
    508
    509	return ret;
    510}
    511
    512static int mma9551_remove(struct i2c_client *client)
    513{
    514	struct iio_dev *indio_dev = i2c_get_clientdata(client);
    515	struct mma9551_data *data = iio_priv(indio_dev);
    516
    517	iio_device_unregister(indio_dev);
    518
    519	pm_runtime_disable(&client->dev);
    520	pm_runtime_set_suspended(&client->dev);
    521
    522	mutex_lock(&data->mutex);
    523	mma9551_set_device_state(data->client, false);
    524	mutex_unlock(&data->mutex);
    525
    526	return 0;
    527}
    528
    529static int mma9551_runtime_suspend(struct device *dev)
    530{
    531	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
    532	struct mma9551_data *data = iio_priv(indio_dev);
    533	int ret;
    534
    535	mutex_lock(&data->mutex);
    536	ret = mma9551_set_device_state(data->client, false);
    537	mutex_unlock(&data->mutex);
    538	if (ret < 0) {
    539		dev_err(&data->client->dev, "powering off device failed\n");
    540		return -EAGAIN;
    541	}
    542
    543	return 0;
    544}
    545
    546static int mma9551_runtime_resume(struct device *dev)
    547{
    548	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
    549	struct mma9551_data *data = iio_priv(indio_dev);
    550	int ret;
    551
    552	ret = mma9551_set_device_state(data->client, true);
    553	if (ret < 0)
    554		return ret;
    555
    556	mma9551_sleep(MMA9551_DEFAULT_SAMPLE_RATE);
    557
    558	return 0;
    559}
    560
    561static int mma9551_suspend(struct device *dev)
    562{
    563	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
    564	struct mma9551_data *data = iio_priv(indio_dev);
    565	int ret;
    566
    567	mutex_lock(&data->mutex);
    568	ret = mma9551_set_device_state(data->client, false);
    569	mutex_unlock(&data->mutex);
    570
    571	return ret;
    572}
    573
    574static int mma9551_resume(struct device *dev)
    575{
    576	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
    577	struct mma9551_data *data = iio_priv(indio_dev);
    578	int ret;
    579
    580	mutex_lock(&data->mutex);
    581	ret = mma9551_set_device_state(data->client, true);
    582	mutex_unlock(&data->mutex);
    583
    584	return ret;
    585}
    586
    587static const struct dev_pm_ops mma9551_pm_ops = {
    588	SYSTEM_SLEEP_PM_OPS(mma9551_suspend, mma9551_resume)
    589	RUNTIME_PM_OPS(mma9551_runtime_suspend, mma9551_runtime_resume, NULL)
    590};
    591
    592static const struct acpi_device_id mma9551_acpi_match[] = {
    593	{"MMA9551", 0},
    594	{},
    595};
    596
    597MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
    598
    599static const struct i2c_device_id mma9551_id[] = {
    600	{"mma9551", 0},
    601	{}
    602};
    603
    604MODULE_DEVICE_TABLE(i2c, mma9551_id);
    605
    606static struct i2c_driver mma9551_driver = {
    607	.driver = {
    608		   .name = MMA9551_DRV_NAME,
    609		   .acpi_match_table = ACPI_PTR(mma9551_acpi_match),
    610		   .pm = pm_ptr(&mma9551_pm_ops),
    611		   },
    612	.probe = mma9551_probe,
    613	.remove = mma9551_remove,
    614	.id_table = mma9551_id,
    615};
    616
    617module_i2c_driver(mma9551_driver);
    618
    619MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
    620MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
    621MODULE_LICENSE("GPL v2");
    622MODULE_DESCRIPTION("MMA9551L motion-sensing platform driver");
    623MODULE_IMPORT_NS(IIO_MMA9551);