mma8452.c 27.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 * mma8452.c - Support for Freescale MMA8452Q 3-axis 12-bit accelerometer
 *
 * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net>
 *
 * This file is subject to the terms and conditions of version 2 of
 * the GNU General Public License.  See the file COPYING in the main
 * directory of this archive for more details.
 *
 * 7-bit I2C slave address 0x1c/0x1d (pin selectable)
 *
12
 * TODO: orientation / freefall events, autosleep
13 14 15 16 17 18 19
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
20 21
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
22
#include <linux/iio/triggered_buffer.h>
23
#include <linux/iio/events.h>
24
#include <linux/delay.h>
25
#include <linux/of_device.h>
26

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
#define MMA8452_STATUS				0x00
#define  MMA8452_STATUS_DRDY			(BIT(2) | BIT(1) | BIT(0))
#define MMA8452_OUT_X				0x01 /* MSB first, 12-bit  */
#define MMA8452_OUT_Y				0x03
#define MMA8452_OUT_Z				0x05
#define MMA8452_INT_SRC				0x0c
#define MMA8452_WHO_AM_I			0x0d
#define MMA8452_DATA_CFG			0x0e
#define  MMA8452_DATA_CFG_FS_MASK		GENMASK(1, 0)
#define  MMA8452_DATA_CFG_FS_2G			0
#define  MMA8452_DATA_CFG_FS_4G			1
#define  MMA8452_DATA_CFG_FS_8G			2
#define  MMA8452_DATA_CFG_HPF_MASK		BIT(4)
#define MMA8452_HP_FILTER_CUTOFF		0x0f
#define  MMA8452_HP_FILTER_CUTOFF_SEL_MASK	GENMASK(1, 0)
#define MMA8452_TRANSIENT_CFG			0x1d
#define  MMA8452_TRANSIENT_CFG_HPF_BYP		BIT(0)
#define  MMA8452_TRANSIENT_CFG_CHAN(chan)	BIT(chan + 1)
#define  MMA8452_TRANSIENT_CFG_ELE		BIT(4)
#define MMA8452_TRANSIENT_SRC			0x1e
#define  MMA8452_TRANSIENT_SRC_XTRANSE		BIT(1)
#define  MMA8452_TRANSIENT_SRC_YTRANSE		BIT(3)
#define  MMA8452_TRANSIENT_SRC_ZTRANSE		BIT(5)
#define MMA8452_TRANSIENT_THS			0x1f
#define  MMA8452_TRANSIENT_THS_MASK		GENMASK(6, 0)
#define MMA8452_TRANSIENT_COUNT			0x20
#define MMA8452_CTRL_REG1			0x2a
#define  MMA8452_CTRL_ACTIVE			BIT(0)
#define  MMA8452_CTRL_DR_MASK			GENMASK(5, 3)
#define  MMA8452_CTRL_DR_SHIFT			3
#define  MMA8452_CTRL_DR_DEFAULT		0x4 /* 50 Hz sample frequency */
#define MMA8452_CTRL_REG2			0x2b
#define  MMA8452_CTRL_REG2_RST			BIT(6)
#define MMA8452_CTRL_REG4			0x2d
#define MMA8452_CTRL_REG5			0x2e
#define MMA8452_OFF_X				0x2f
#define MMA8452_OFF_Y				0x30
#define MMA8452_OFF_Z				0x31
65

66
#define MMA8452_MAX_REG				0x31
67

68 69
#define  MMA8452_INT_DRDY			BIT(0)
#define  MMA8452_INT_TRANS			BIT(5)
70

71
#define  MMA8452_DEVICE_ID			0x2a
72 73 74 75 76 77

struct mma8452_data {
	struct i2c_client *client;
	struct mutex lock;
	u8 ctrl_reg1;
	u8 data_cfg;
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
	const struct mma_chip_info *chip_info;
};

/**
 * struct mma_chip_info - chip specific data for Freescale's accelerometers
 * @chip_id:			WHO_AM_I register's value
 * @channels:			struct iio_chan_spec matching the device's
 *				capabilities
 * @num_channels:		number of channels
 * @mma_scales:			scale factors for converting register values
 *				to m/s^2; 3 modes: 2g, 4g, 8g; 2 integers
 *				per mode: m/s^2 and micro m/s^2
 * @ev_cfg:			event config register address
 * @ev_cfg_ele:			latch bit in event config register
 * @ev_cfg_chan_shift:		number of the bit to enable events in X
 *				direction; in event config register
 * @ev_src:			event source register address
 * @ev_src_xe:			bit in event source register that indicates
 *				an event in X direction
 * @ev_src_ye:			bit in event source register that indicates
 *				an event in Y direction
 * @ev_src_ze:			bit in event source register that indicates
 *				an event in Z direction
 * @ev_ths:			event threshold register address
 * @ev_ths_mask:		mask for the threshold value
 * @ev_count:			event count (period) register address
 *
 * Since not all chips supported by the driver support comparing high pass
 * filtered data for events (interrupts), different interrupt sources are
 * used for different chips and the relevant registers are included here.
 */
struct mma_chip_info {
	u8 chip_id;
	const struct iio_chan_spec *channels;
	int num_channels;
	const int mma_scales[3][2];
	u8 ev_cfg;
	u8 ev_cfg_ele;
	u8 ev_cfg_chan_shift;
	u8 ev_src;
	u8 ev_src_xe;
	u8 ev_src_ye;
	u8 ev_src_ze;
	u8 ev_ths;
	u8 ev_ths_mask;
	u8 ev_count;
124 125 126 127 128 129 130 131 132 133 134 135 136
};

static int mma8452_drdy(struct mma8452_data *data)
{
	int tries = 150;

	while (tries-- > 0) {
		int ret = i2c_smbus_read_byte_data(data->client,
			MMA8452_STATUS);
		if (ret < 0)
			return ret;
		if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
			return 0;
137

138 139 140 141
		msleep(20);
	}

	dev_err(&data->client->dev, "data not ready\n");
142

143 144 145 146 147 148
	return -EIO;
}

static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
{
	int ret = mma8452_drdy(data);
149

150 151
	if (ret < 0)
		return ret;
152 153 154

	return i2c_smbus_read_i2c_block_data(data->client, MMA8452_OUT_X,
					     3 * sizeof(__be16), (u8 *)buf);
155 156
}

157 158
static ssize_t mma8452_show_int_plus_micros(char *buf, const int (*vals)[2],
					    int n)
159 160 161 162
{
	size_t len = 0;

	while (n-- > 0)
163 164
		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
				 vals[n][0], vals[n][1]);
165 166 167 168 169 170 171 172

	/* replace trailing space by newline */
	buf[len - 1] = '\n';

	return len;
}

static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
173
					     int val, int val2)
174 175 176 177 178 179 180 181
{
	while (n-- > 0)
		if (val == vals[n][0] && val2 == vals[n][1])
			return n;

	return -EINVAL;
}

182 183 184 185 186 187
static int mma8452_get_odr_index(struct mma8452_data *data)
{
	return (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >>
			MMA8452_CTRL_DR_SHIFT;
}

188 189 190 191 192
static const int mma8452_samp_freq[8][2] = {
	{800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000},
	{6, 250000}, {1, 560000}
};

193 194 195 196 197 198 199 200 201 202 203 204
/* Datasheet table 35  (step time vs sample frequency) */
static const int mma8452_transient_time_step_us[8] = {
	1250,
	2500,
	5000,
	10000,
	20000,
	20000,
	20000,
	20000
};

205 206 207 208 209 210 211 212 213 214 215 216
/* Datasheet table 18 (normal mode) */
static const int mma8452_hp_filter_cutoff[8][4][2] = {
	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },		/* 800 Hz sample */
	{ {16, 0}, {8, 0}, {4, 0}, {2, 0} },		/* 400 Hz sample */
	{ {8, 0}, {4, 0}, {2, 0}, {1, 0} },		/* 200 Hz sample */
	{ {4, 0}, {2, 0}, {1, 0}, {0, 500000} },	/* 100 Hz sample */
	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },	/* 50 Hz sample */
	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },	/* 12.5 Hz sample */
	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} },	/* 6.25 Hz sample */
	{ {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }	/* 1.56 Hz sample */
};

217
static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
218 219
					    struct device_attribute *attr,
					    char *buf)
220 221
{
	return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
222
					    ARRAY_SIZE(mma8452_samp_freq));
223 224 225
}

static ssize_t mma8452_show_scale_avail(struct device *dev,
226 227
					struct device_attribute *attr,
					char *buf)
228
{
229 230 231 232 233
	struct mma8452_data *data = iio_priv(i2c_get_clientdata(
					     to_i2c_client(dev)));

	return mma8452_show_int_plus_micros(buf, data->chip_info->mma_scales,
		ARRAY_SIZE(data->chip_info->mma_scales));
234 235
}

236 237 238 239 240 241 242 243 244 245 246 247
static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev,
					    struct device_attribute *attr,
					    char *buf)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct mma8452_data *data = iio_priv(indio_dev);
	int i = mma8452_get_odr_index(data);

	return mma8452_show_int_plus_micros(buf, mma8452_hp_filter_cutoff[i],
		ARRAY_SIZE(mma8452_hp_filter_cutoff[0]));
}

248 249
static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail);
static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
250
		       mma8452_show_scale_avail, NULL, 0);
251
static IIO_DEVICE_ATTR(in_accel_filter_high_pass_3db_frequency_available,
252
		       S_IRUGO, mma8452_show_hp_cutoff_avail, NULL, 0);
253 254

static int mma8452_get_samp_freq_index(struct mma8452_data *data,
255
				       int val, int val2)
256 257
{
	return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
258 259
						 ARRAY_SIZE(mma8452_samp_freq),
						 val, val2);
260 261
}

262
static int mma8452_get_scale_index(struct mma8452_data *data, int val, int val2)
263
{
264 265
	return mma8452_get_int_plus_micros_index(data->chip_info->mma_scales,
			ARRAY_SIZE(data->chip_info->mma_scales), val, val2);
266 267
}

268 269 270 271 272 273
static int mma8452_get_hp_filter_index(struct mma8452_data *data,
				       int val, int val2)
{
	int i = mma8452_get_odr_index(data);

	return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[i],
274
		ARRAY_SIZE(mma8452_hp_filter_cutoff[0]), val, val2);
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
}

static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz)
{
	int i, ret;

	ret = i2c_smbus_read_byte_data(data->client, MMA8452_HP_FILTER_CUTOFF);
	if (ret < 0)
		return ret;

	i = mma8452_get_odr_index(data);
	ret &= MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
	*hz = mma8452_hp_filter_cutoff[i][ret][0];
	*uHz = mma8452_hp_filter_cutoff[i][ret][1];

	return 0;
}

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
static int mma8452_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{
	struct mma8452_data *data = iio_priv(indio_dev);
	__be16 buffer[3];
	int i, ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (iio_buffer_enabled(indio_dev))
			return -EBUSY;

		mutex_lock(&data->lock);
		ret = mma8452_read(data, buffer);
		mutex_unlock(&data->lock);
		if (ret < 0)
			return ret;
311

312 313 314
		*val = sign_extend32(be16_to_cpu(
			buffer[chan->scan_index]) >> chan->scan_type.shift,
			chan->scan_type.realbits - 1);
315

316 317 318
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
319 320
		*val = data->chip_info->mma_scales[i][0];
		*val2 = data->chip_info->mma_scales[i][1];
321

322 323
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_SAMP_FREQ:
324
		i = mma8452_get_odr_index(data);
325 326
		*val = mma8452_samp_freq[i][0];
		*val2 = mma8452_samp_freq[i][1];
327

328 329
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_CALIBBIAS:
330 331
		ret = i2c_smbus_read_byte_data(data->client,
					      MMA8452_OFF_X + chan->scan_index);
332 333
		if (ret < 0)
			return ret;
334

335
		*val = sign_extend32(ret, 7);
336

337
		return IIO_VAL_INT;
338 339 340 341 342 343 344 345 346
	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
		if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) {
			ret = mma8452_read_hp_filter(data, val, val2);
			if (ret < 0)
				return ret;
		} else {
			*val = 0;
			*val2 = 0;
		}
347

348
		return IIO_VAL_INT_PLUS_MICRO;
349
	}
350

351 352 353 354 355 356
	return -EINVAL;
}

static int mma8452_standby(struct mma8452_data *data)
{
	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
357
					data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE);
358 359 360 361 362
}

static int mma8452_active(struct mma8452_data *data)
{
	return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
363
					 data->ctrl_reg1);
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
}

static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
{
	int ret;

	mutex_lock(&data->lock);

	/* config can only be changed when in standby */
	ret = mma8452_standby(data);
	if (ret < 0)
		goto fail;

	ret = i2c_smbus_write_byte_data(data->client, reg, val);
	if (ret < 0)
		goto fail;

	ret = mma8452_active(data);
	if (ret < 0)
		goto fail;

	ret = 0;
fail:
	mutex_unlock(&data->lock);
388

389 390 391
	return ret;
}

392 393 394 395 396 397 398
static int mma8452_set_hp_filter_frequency(struct mma8452_data *data,
					   int val, int val2)
{
	int i, reg;

	i = mma8452_get_hp_filter_index(data, val, val2);
	if (i < 0)
399
		return i;
400 401 402 403 404

	reg = i2c_smbus_read_byte_data(data->client,
				       MMA8452_HP_FILTER_CUTOFF);
	if (reg < 0)
		return reg;
405

406 407 408 409 410 411
	reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
	reg |= i;

	return mma8452_change_config(data, MMA8452_HP_FILTER_CUTOFF, reg);
}

412 413 414 415 416
static int mma8452_write_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int val, int val2, long mask)
{
	struct mma8452_data *data = iio_priv(indio_dev);
417
	int i, ret;
418 419 420 421 422 423 424 425

	if (iio_buffer_enabled(indio_dev))
		return -EBUSY;

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		i = mma8452_get_samp_freq_index(data, val, val2);
		if (i < 0)
426
			return i;
427 428 429

		data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
		data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
430

431
		return mma8452_change_config(data, MMA8452_CTRL_REG1,
432
					     data->ctrl_reg1);
433 434 435
	case IIO_CHAN_INFO_SCALE:
		i = mma8452_get_scale_index(data, val, val2);
		if (i < 0)
436
			return i;
437

438 439
		data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
		data->data_cfg |= i;
440

441
		return mma8452_change_config(data, MMA8452_DATA_CFG,
442
					     data->data_cfg);
443 444 445
	case IIO_CHAN_INFO_CALIBBIAS:
		if (val < -128 || val > 127)
			return -EINVAL;
446 447 448 449

		return mma8452_change_config(data,
					     MMA8452_OFF_X + chan->scan_index,
					     val);
450 451 452 453 454 455 456 457 458 459

	case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
		if (val == 0 && val2 == 0) {
			data->data_cfg &= ~MMA8452_DATA_CFG_HPF_MASK;
		} else {
			data->data_cfg |= MMA8452_DATA_CFG_HPF_MASK;
			ret = mma8452_set_hp_filter_frequency(data, val, val2);
			if (ret < 0)
				return ret;
		}
460

461
		return mma8452_change_config(data, MMA8452_DATA_CFG,
462
					     data->data_cfg);
463

464 465 466 467 468
	default:
		return -EINVAL;
	}
}

469 470 471 472 473 474 475 476
static int mma8452_read_thresh(struct iio_dev *indio_dev,
			       const struct iio_chan_spec *chan,
			       enum iio_event_type type,
			       enum iio_event_direction dir,
			       enum iio_event_info info,
			       int *val, int *val2)
{
	struct mma8452_data *data = iio_priv(indio_dev);
477
	int ret, us;
478

479 480 481
	switch (info) {
	case IIO_EV_INFO_VALUE:
		ret = i2c_smbus_read_byte_data(data->client,
482
					       data->chip_info->ev_ths);
483 484 485
		if (ret < 0)
			return ret;

486
		*val = ret & data->chip_info->ev_ths_mask;
487

488
		return IIO_VAL_INT;
489

490 491
	case IIO_EV_INFO_PERIOD:
		ret = i2c_smbus_read_byte_data(data->client,
492
					       data->chip_info->ev_count);
493 494 495 496 497 498 499
		if (ret < 0)
			return ret;

		us = ret * mma8452_transient_time_step_us[
				mma8452_get_odr_index(data)];
		*val = us / USEC_PER_SEC;
		*val2 = us % USEC_PER_SEC;
500

501
		return IIO_VAL_INT_PLUS_MICRO;
502

503 504 505 506 507 508 509 510 511 512 513 514 515 516
	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
		ret = i2c_smbus_read_byte_data(data->client,
					       MMA8452_TRANSIENT_CFG);
		if (ret < 0)
			return ret;

		if (ret & MMA8452_TRANSIENT_CFG_HPF_BYP) {
			*val = 0;
			*val2 = 0;
		} else {
			ret = mma8452_read_hp_filter(data, val, val2);
			if (ret < 0)
				return ret;
		}
517

518 519
		return IIO_VAL_INT_PLUS_MICRO;

520 521 522
	default:
		return -EINVAL;
	}
523 524 525 526 527 528 529 530 531 532
}

static int mma8452_write_thresh(struct iio_dev *indio_dev,
				const struct iio_chan_spec *chan,
				enum iio_event_type type,
				enum iio_event_direction dir,
				enum iio_event_info info,
				int val, int val2)
{
	struct mma8452_data *data = iio_priv(indio_dev);
533
	int ret, reg, steps;
534

535 536
	switch (info) {
	case IIO_EV_INFO_VALUE:
537 538 539
		if (val < 0 || val > MMA8452_TRANSIENT_THS_MASK)
			return -EINVAL;

540 541
		return mma8452_change_config(data, data->chip_info->ev_ths,
					     val);
542 543 544 545 546 547

	case IIO_EV_INFO_PERIOD:
		steps = (val * USEC_PER_SEC + val2) /
				mma8452_transient_time_step_us[
					mma8452_get_odr_index(data)];

548
		if (steps < 0 || steps > 0xff)
549 550
			return -EINVAL;

551
		return mma8452_change_config(data, data->chip_info->ev_count,
552
					     steps);
553

554 555 556 557 558 559 560 561 562 563 564 565 566 567
	case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
		reg = i2c_smbus_read_byte_data(data->client,
					       MMA8452_TRANSIENT_CFG);
		if (reg < 0)
			return reg;

		if (val == 0 && val2 == 0) {
			reg |= MMA8452_TRANSIENT_CFG_HPF_BYP;
		} else {
			reg &= ~MMA8452_TRANSIENT_CFG_HPF_BYP;
			ret = mma8452_set_hp_filter_frequency(data, val, val2);
			if (ret < 0)
				return ret;
		}
568

569 570
		return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg);

571 572 573
	default:
		return -EINVAL;
	}
574 575 576 577 578 579 580 581
}

static int mma8452_read_event_config(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan,
				     enum iio_event_type type,
				     enum iio_event_direction dir)
{
	struct mma8452_data *data = iio_priv(indio_dev);
582
	const struct mma_chip_info *chip = data->chip_info;
583 584
	int ret;

585 586
	ret = i2c_smbus_read_byte_data(data->client,
				       data->chip_info->ev_cfg);
587 588 589
	if (ret < 0)
		return ret;

590
	return !!(ret & BIT(chan->scan_index + chip->ev_cfg_chan_shift));
591 592 593 594 595 596 597 598 599
}

static int mma8452_write_event_config(struct iio_dev *indio_dev,
				      const struct iio_chan_spec *chan,
				      enum iio_event_type type,
				      enum iio_event_direction dir,
				      int state)
{
	struct mma8452_data *data = iio_priv(indio_dev);
600
	const struct mma_chip_info *chip = data->chip_info;
601 602
	int val;

603
	val = i2c_smbus_read_byte_data(data->client, chip->ev_cfg);
604 605 606 607
	if (val < 0)
		return val;

	if (state)
608
		val |= BIT(chan->scan_index + chip->ev_cfg_chan_shift);
609
	else
610
		val &= ~BIT(chan->scan_index + chip->ev_cfg_chan_shift);
611 612 613

	val |= MMA8452_TRANSIENT_CFG_ELE;

614
	return mma8452_change_config(data, chip->ev_cfg, val);
615 616 617 618 619 620 621 622
}

static void mma8452_transient_interrupt(struct iio_dev *indio_dev)
{
	struct mma8452_data *data = iio_priv(indio_dev);
	s64 ts = iio_get_time_ns();
	int src;

623
	src = i2c_smbus_read_byte_data(data->client, data->chip_info->ev_src);
624 625 626
	if (src < 0)
		return;

627
	if (src & data->chip_info->ev_src_xe)
628 629
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X,
630
						  IIO_EV_TYPE_MAG,
631 632 633
						  IIO_EV_DIR_RISING),
			       ts);

634
	if (src & data->chip_info->ev_src_ye)
635 636
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Y,
637
						  IIO_EV_TYPE_MAG,
638 639 640
						  IIO_EV_DIR_RISING),
			       ts);

641
	if (src & data->chip_info->ev_src_ze)
642 643
		iio_push_event(indio_dev,
			       IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Z,
644
						  IIO_EV_TYPE_MAG,
645 646 647 648 649 650 651 652
						  IIO_EV_DIR_RISING),
			       ts);
}

static irqreturn_t mma8452_interrupt(int irq, void *p)
{
	struct iio_dev *indio_dev = p;
	struct mma8452_data *data = iio_priv(indio_dev);
653
	int ret = IRQ_NONE;
654 655 656 657 658 659
	int src;

	src = i2c_smbus_read_byte_data(data->client, MMA8452_INT_SRC);
	if (src < 0)
		return IRQ_NONE;

660 661 662 663 664
	if (src & MMA8452_INT_DRDY) {
		iio_trigger_poll_chained(indio_dev->trig);
		ret = IRQ_HANDLED;
	}

665 666
	if (src & MMA8452_INT_TRANS) {
		mma8452_transient_interrupt(indio_dev);
667
		ret = IRQ_HANDLED;
668 669
	}

670
	return ret;
671 672
}

673 674 675 676 677 678 679 680
static irqreturn_t mma8452_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct mma8452_data *data = iio_priv(indio_dev);
	u8 buffer[16]; /* 3 16-bit channels + padding + ts */
	int ret;

681
	ret = mma8452_read(data, (__be16 *)buffer);
682 683 684 685
	if (ret < 0)
		goto done;

	iio_push_to_buffers_with_timestamp(indio_dev, buffer,
686
					   iio_get_time_ns());
687 688 689

done:
	iio_trigger_notify_done(indio_dev->trig);
690

691 692 693
	return IRQ_HANDLED;
}

694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
static int mma8452_reg_access_dbg(struct iio_dev *indio_dev,
				  unsigned reg, unsigned writeval,
				  unsigned *readval)
{
	int ret;
	struct mma8452_data *data = iio_priv(indio_dev);

	if (reg > MMA8452_MAX_REG)
		return -EINVAL;

	if (!readval)
		return mma8452_change_config(data, reg, writeval);

	ret = i2c_smbus_read_byte_data(data->client, reg);
	if (ret < 0)
		return ret;

	*readval = ret;

	return 0;
}

716 717
static const struct iio_event_spec mma8452_transient_event[] = {
	{
718
		.type = IIO_EV_TYPE_MAG,
719 720
		.dir = IIO_EV_DIR_RISING,
		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
721
		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
722 723
					BIT(IIO_EV_INFO_PERIOD) |
					BIT(IIO_EV_INFO_HIGH_PASS_FILTER_3DB)
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
	},
};

/*
 * Threshold is configured in fixed 8G/127 steps regardless of
 * currently selected scale for measurement.
 */
static IIO_CONST_ATTR_NAMED(accel_transient_scale, in_accel_scale, "0.617742");

static struct attribute *mma8452_event_attributes[] = {
	&iio_const_attr_accel_transient_scale.dev_attr.attr,
	NULL,
};

static struct attribute_group mma8452_event_attribute_group = {
	.attrs = mma8452_event_attributes,
	.name = "events",
};

743
#define MMA8452_CHANNEL(axis, idx, bits) { \
744 745 746 747
	.type = IIO_ACCEL, \
	.modified = 1, \
	.channel2 = IIO_MOD_##axis, \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
748
			      BIT(IIO_CHAN_INFO_CALIBBIAS), \
749
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
750 751
			BIT(IIO_CHAN_INFO_SCALE) | \
			BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
752 753 754
	.scan_index = idx, \
	.scan_type = { \
		.sign = 's', \
755
		.realbits = (bits), \
756
		.storagebits = 16, \
757
		.shift = 16 - (bits), \
758 759
		.endianness = IIO_BE, \
	}, \
760 761
	.event_spec = mma8452_transient_event, \
	.num_event_specs = ARRAY_SIZE(mma8452_transient_event), \
762 763 764
}

static const struct iio_chan_spec mma8452_channels[] = {
765 766 767
	MMA8452_CHANNEL(X, 0, 12),
	MMA8452_CHANNEL(Y, 1, 12),
	MMA8452_CHANNEL(Z, 2, 12),
768 769 770
	IIO_CHAN_SOFT_TIMESTAMP(3),
};

771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800
enum {
	mma8452,
};

static const struct mma_chip_info mma_chip_info_table[] = {
	[mma8452] = {
		.chip_id = MMA8452_DEVICE_ID,
		.channels = mma8452_channels,
		.num_channels = ARRAY_SIZE(mma8452_channels),
		/*
		 * Hardware has fullscale of -2G, -4G, -8G corresponding to
		 * raw value -2048 for 12 bit or -512 for 10 bit.
		 * The userspace interface uses m/s^2 and we declare micro units
		 * So scale factor for 12 bit here is given by:
		 *	g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665
		 */
		.mma_scales = { {0, 9577}, {0, 19154}, {0, 38307} },
		.ev_cfg = MMA8452_TRANSIENT_CFG,
		.ev_cfg_ele = MMA8452_TRANSIENT_CFG_ELE,
		.ev_cfg_chan_shift = 1,
		.ev_src = MMA8452_TRANSIENT_SRC,
		.ev_src_xe = MMA8452_TRANSIENT_SRC_XTRANSE,
		.ev_src_ye = MMA8452_TRANSIENT_SRC_YTRANSE,
		.ev_src_ze = MMA8452_TRANSIENT_SRC_ZTRANSE,
		.ev_ths = MMA8452_TRANSIENT_THS,
		.ev_ths_mask = MMA8452_TRANSIENT_THS_MASK,
		.ev_count = MMA8452_TRANSIENT_COUNT,
	},
};

801 802 803
static struct attribute *mma8452_attributes[] = {
	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
804
	&iio_dev_attr_in_accel_filter_high_pass_3db_frequency_available.dev_attr.attr,
805 806 807 808 809 810 811 812 813 814 815
	NULL
};

static const struct attribute_group mma8452_group = {
	.attrs = mma8452_attributes,
};

static const struct iio_info mma8452_info = {
	.attrs = &mma8452_group,
	.read_raw = &mma8452_read_raw,
	.write_raw = &mma8452_write_raw,
816 817 818 819 820
	.event_attrs = &mma8452_event_attribute_group,
	.read_event_value = &mma8452_read_thresh,
	.write_event_value = &mma8452_write_thresh,
	.read_event_config = &mma8452_read_event_config,
	.write_event_config = &mma8452_write_event_config,
821
	.debugfs_reg_access = &mma8452_reg_access_dbg,
822 823 824 825 826
	.driver_module = THIS_MODULE,
};

static const unsigned long mma8452_scan_masks[] = {0x7, 0};

827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
static int mma8452_data_rdy_trigger_set_state(struct iio_trigger *trig,
					      bool state)
{
	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
	struct mma8452_data *data = iio_priv(indio_dev);
	int reg;

	reg = i2c_smbus_read_byte_data(data->client, MMA8452_CTRL_REG4);
	if (reg < 0)
		return reg;

	if (state)
		reg |= MMA8452_INT_DRDY;
	else
		reg &= ~MMA8452_INT_DRDY;

	return mma8452_change_config(data, MMA8452_CTRL_REG4, reg);
}

static int mma8452_validate_device(struct iio_trigger *trig,
				   struct iio_dev *indio_dev)
{
	struct iio_dev *indio = iio_trigger_get_drvdata(trig);

	if (indio != indio_dev)
		return -EINVAL;

	return 0;
}

static const struct iio_trigger_ops mma8452_trigger_ops = {
	.set_trigger_state = mma8452_data_rdy_trigger_set_state,
	.validate_device = mma8452_validate_device,
	.owner = THIS_MODULE,
};

static int mma8452_trigger_setup(struct iio_dev *indio_dev)
{
	struct mma8452_data *data = iio_priv(indio_dev);
	struct iio_trigger *trig;
	int ret;

	trig = devm_iio_trigger_alloc(&data->client->dev, "%s-dev%d",
				      indio_dev->name,
				      indio_dev->id);
	if (!trig)
		return -ENOMEM;

	trig->dev.parent = &data->client->dev;
	trig->ops = &mma8452_trigger_ops;
	iio_trigger_set_drvdata(trig, indio_dev);

	ret = iio_trigger_register(trig);
	if (ret)
		return ret;

	indio_dev->trig = trig;
884

885 886 887 888 889 890 891 892 893
	return 0;
}

static void mma8452_trigger_cleanup(struct iio_dev *indio_dev)
{
	if (indio_dev->trig)
		iio_trigger_unregister(indio_dev->trig);
}

894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917
static int mma8452_reset(struct i2c_client *client)
{
	int i;
	int ret;

	ret = i2c_smbus_write_byte_data(client,	MMA8452_CTRL_REG2,
					MMA8452_CTRL_REG2_RST);
	if (ret < 0)
		return ret;

	for (i = 0; i < 10; i++) {
		usleep_range(100, 200);
		ret = i2c_smbus_read_byte_data(client, MMA8452_CTRL_REG2);
		if (ret == -EIO)
			continue; /* I2C comm reset */
		if (ret < 0)
			return ret;
		if (!(ret & MMA8452_CTRL_REG2_RST))
			return 0;
	}

	return -ETIMEDOUT;
}

918 919 920 921 922 923
static const struct of_device_id mma8452_dt_ids[] = {
	{ .compatible = "fsl,mma8452", .data = &mma_chip_info_table[mma8452] },
	{ }
};
MODULE_DEVICE_TABLE(of, mma8452_dt_ids);

924 925 926 927 928 929
static int mma8452_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct mma8452_data *data;
	struct iio_dev *indio_dev;
	int ret;
930
	const struct of_device_id *match;
931 932 933 934 935 936 937

	ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);
	if (ret < 0)
		return ret;
	if (ret != MMA8452_DEVICE_ID)
		return -ENODEV;

938 939 940 941 942 943
	match = of_match_device(mma8452_dt_ids, &client->dev);
	if (!match) {
		dev_err(&client->dev, "unknown device model\n");
		return -ENODEV;
	}

944 945 946 947 948 949 950
	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
	if (!indio_dev)
		return -ENOMEM;

	data = iio_priv(indio_dev);
	data->client = client;
	mutex_init(&data->lock);
951 952 953 954
	data->chip_info = match->data;

	dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n",
		 match->compatible, data->chip_info->chip_id);
955 956 957 958 959 960

	i2c_set_clientdata(client, indio_dev);
	indio_dev->info = &mma8452_info;
	indio_dev->name = id->name;
	indio_dev->dev.parent = &client->dev;
	indio_dev->modes = INDIO_DIRECT_MODE;
961 962
	indio_dev->channels = data->chip_info->channels;
	indio_dev->num_channels = data->chip_info->num_channels;
963 964
	indio_dev->available_scan_masks = mma8452_scan_masks;

965
	ret = mma8452_reset(client);
966 967 968 969 970
	if (ret < 0)
		return ret;

	data->data_cfg = MMA8452_DATA_CFG_FS_2G;
	ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG,
971
					data->data_cfg);
972 973 974
	if (ret < 0)
		return ret;

975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990
	/*
	 * By default set transient threshold to max to avoid events if
	 * enabling without configuring threshold.
	 */
	ret = i2c_smbus_write_byte_data(client, MMA8452_TRANSIENT_THS,
					MMA8452_TRANSIENT_THS_MASK);
	if (ret < 0)
		return ret;

	if (client->irq) {
		/*
		 * Although we enable the transient interrupt source once and
		 * for all here the transient event detection itself is not
		 * enabled until userspace asks for it by
		 * mma8452_write_event_config()
		 */
991 992
		int supported_interrupts = MMA8452_INT_DRDY | MMA8452_INT_TRANS;
		int enabled_interrupts = MMA8452_INT_TRANS;
993 994 995 996 997 998 999 1000 1001 1002

		/* Assume wired to INT1 pin */
		ret = i2c_smbus_write_byte_data(client,
						MMA8452_CTRL_REG5,
						supported_interrupts);
		if (ret < 0)
			return ret;

		ret = i2c_smbus_write_byte_data(client,
						MMA8452_CTRL_REG4,
1003 1004 1005 1006 1007
						enabled_interrupts);
		if (ret < 0)
			return ret;

		ret = mma8452_trigger_setup(indio_dev);
1008 1009 1010 1011
		if (ret < 0)
			return ret;
	}

1012
	data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
1013
			  (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
1014 1015 1016
	ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
					data->ctrl_reg1);
	if (ret < 0)
1017
		goto trigger_cleanup;
1018

1019
	ret = iio_triggered_buffer_setup(indio_dev, NULL,
1020
					 mma8452_trigger_handler, NULL);
1021
	if (ret < 0)
1022
		goto trigger_cleanup;
1023

1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
	if (client->irq) {
		ret = devm_request_threaded_irq(&client->dev,
						client->irq,
						NULL, mma8452_interrupt,
						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
						client->name, indio_dev);
		if (ret)
			goto buffer_cleanup;
	}

1034 1035 1036
	ret = iio_device_register(indio_dev);
	if (ret < 0)
		goto buffer_cleanup;
1037

1038 1039 1040 1041
	return 0;

buffer_cleanup:
	iio_triggered_buffer_cleanup(indio_dev);
1042 1043 1044 1045

trigger_cleanup:
	mma8452_trigger_cleanup(indio_dev);

1046 1047 1048 1049 1050 1051 1052 1053 1054
	return ret;
}

static int mma8452_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);

	iio_device_unregister(indio_dev);
	iio_triggered_buffer_cleanup(indio_dev);
1055
	mma8452_trigger_cleanup(indio_dev);
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
	mma8452_standby(iio_priv(indio_dev));

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int mma8452_suspend(struct device *dev)
{
	return mma8452_standby(iio_priv(i2c_get_clientdata(
		to_i2c_client(dev))));
}

static int mma8452_resume(struct device *dev)
{
	return mma8452_active(iio_priv(i2c_get_clientdata(
		to_i2c_client(dev))));
}

static SIMPLE_DEV_PM_OPS(mma8452_pm_ops, mma8452_suspend, mma8452_resume);
#define MMA8452_PM_OPS (&mma8452_pm_ops)
#else
#define MMA8452_PM_OPS NULL
#endif

static const struct i2c_device_id mma8452_id[] = {
1081
	{ "mma8452", mma8452 },
1082 1083 1084 1085 1086 1087 1088
	{ }
};
MODULE_DEVICE_TABLE(i2c, mma8452_id);

static struct i2c_driver mma8452_driver = {
	.driver = {
		.name	= "mma8452",
M
Martin Fuzzey 已提交
1089
		.of_match_table = of_match_ptr(mma8452_dt_ids),
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
		.pm	= MMA8452_PM_OPS,
	},
	.probe = mma8452_probe,
	.remove = mma8452_remove,
	.id_table = mma8452_id,
};
module_i2c_driver(mma8452_driver);

MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
MODULE_DESCRIPTION("Freescale MMA8452 accelerometer driver");
MODULE_LICENSE("GPL");