]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/iio/accel/mma8452.c
iio:accel:mma8452: check values to be written
[mirror_ubuntu-zesty-kernel.git] / drivers / iio / accel / mma8452.c
CommitLineData
c7eeea93
PM
1/*
2 * mma8452.c - Support for Freescale MMA8452Q 3-axis 12-bit accelerometer
3 *
4 * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net>
5 *
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
9 *
10 * 7-bit I2C slave address 0x1c/0x1d (pin selectable)
11 *
28e34278 12 * TODO: orientation / freefall events, autosleep
c7eeea93
PM
13 */
14
15#include <linux/module.h>
16#include <linux/i2c.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/sysfs.h>
c7eeea93 19#include <linux/iio/buffer.h>
ae6d9ce0
MF
20#include <linux/iio/trigger.h>
21#include <linux/iio/trigger_consumer.h>
c7eeea93 22#include <linux/iio/triggered_buffer.h>
28e34278 23#include <linux/iio/events.h>
c7eeea93
PM
24#include <linux/delay.h>
25
26#define MMA8452_STATUS 0x00
27#define MMA8452_OUT_X 0x01 /* MSB first, 12-bit */
28#define MMA8452_OUT_Y 0x03
29#define MMA8452_OUT_Z 0x05
28e34278 30#define MMA8452_INT_SRC 0x0c
c7eeea93
PM
31#define MMA8452_WHO_AM_I 0x0d
32#define MMA8452_DATA_CFG 0x0e
1e79841a
MF
33#define MMA8452_HP_FILTER_CUTOFF 0x0f
34#define MMA8452_HP_FILTER_CUTOFF_SEL_MASK (BIT(0) | BIT(1))
28e34278
MF
35#define MMA8452_TRANSIENT_CFG 0x1d
36#define MMA8452_TRANSIENT_CFG_ELE BIT(4)
37#define MMA8452_TRANSIENT_CFG_CHAN(chan) BIT(chan + 1)
1e79841a 38#define MMA8452_TRANSIENT_CFG_HPF_BYP BIT(0)
28e34278
MF
39#define MMA8452_TRANSIENT_SRC 0x1e
40#define MMA8452_TRANSIENT_SRC_XTRANSE BIT(1)
41#define MMA8452_TRANSIENT_SRC_YTRANSE BIT(3)
42#define MMA8452_TRANSIENT_SRC_ZTRANSE BIT(5)
43#define MMA8452_TRANSIENT_THS 0x1f
44#define MMA8452_TRANSIENT_THS_MASK 0x7f
5dbbd19f 45#define MMA8452_TRANSIENT_COUNT 0x20
c7eeea93
PM
46#define MMA8452_OFF_X 0x2f
47#define MMA8452_OFF_Y 0x30
48#define MMA8452_OFF_Z 0x31
49#define MMA8452_CTRL_REG1 0x2a
50#define MMA8452_CTRL_REG2 0x2b
ecabae71 51#define MMA8452_CTRL_REG2_RST BIT(6)
28e34278
MF
52#define MMA8452_CTRL_REG4 0x2d
53#define MMA8452_CTRL_REG5 0x2e
c7eeea93 54
2a17698c
MF
55#define MMA8452_MAX_REG 0x31
56
c7eeea93
PM
57#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
58
59#define MMA8452_CTRL_DR_MASK (BIT(5) | BIT(4) | BIT(3))
60#define MMA8452_CTRL_DR_SHIFT 3
61#define MMA8452_CTRL_DR_DEFAULT 0x4 /* 50 Hz sample frequency */
62#define MMA8452_CTRL_ACTIVE BIT(0)
63
64#define MMA8452_DATA_CFG_FS_MASK (BIT(1) | BIT(0))
65#define MMA8452_DATA_CFG_FS_2G 0
66#define MMA8452_DATA_CFG_FS_4G 1
67#define MMA8452_DATA_CFG_FS_8G 2
1e79841a 68#define MMA8452_DATA_CFG_HPF_MASK BIT(4)
c7eeea93 69
ae6d9ce0 70#define MMA8452_INT_DRDY BIT(0)
28e34278
MF
71#define MMA8452_INT_TRANS BIT(5)
72
c7eeea93
PM
73#define MMA8452_DEVICE_ID 0x2a
74
75struct mma8452_data {
76 struct i2c_client *client;
77 struct mutex lock;
78 u8 ctrl_reg1;
79 u8 data_cfg;
80};
81
82static int mma8452_drdy(struct mma8452_data *data)
83{
84 int tries = 150;
85
86 while (tries-- > 0) {
87 int ret = i2c_smbus_read_byte_data(data->client,
88 MMA8452_STATUS);
89 if (ret < 0)
90 return ret;
91 if ((ret & MMA8452_STATUS_DRDY) == MMA8452_STATUS_DRDY)
92 return 0;
93 msleep(20);
94 }
95
96 dev_err(&data->client->dev, "data not ready\n");
97 return -EIO;
98}
99
100static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
101{
102 int ret = mma8452_drdy(data);
103 if (ret < 0)
104 return ret;
105 return i2c_smbus_read_i2c_block_data(data->client,
106 MMA8452_OUT_X, 3 * sizeof(__be16), (u8 *) buf);
107}
108
109static ssize_t mma8452_show_int_plus_micros(char *buf,
110 const int (*vals)[2], int n)
111{
112 size_t len = 0;
113
114 while (n-- > 0)
115 len += scnprintf(buf + len, PAGE_SIZE - len,
116 "%d.%06d ", vals[n][0], vals[n][1]);
117
118 /* replace trailing space by newline */
119 buf[len - 1] = '\n';
120
121 return len;
122}
123
124static int mma8452_get_int_plus_micros_index(const int (*vals)[2], int n,
125 int val, int val2)
126{
127 while (n-- > 0)
128 if (val == vals[n][0] && val2 == vals[n][1])
129 return n;
130
131 return -EINVAL;
132}
133
5dbbd19f
MF
134static int mma8452_get_odr_index(struct mma8452_data *data)
135{
136 return (data->ctrl_reg1 & MMA8452_CTRL_DR_MASK) >>
137 MMA8452_CTRL_DR_SHIFT;
138}
139
c7eeea93
PM
140static const int mma8452_samp_freq[8][2] = {
141 {800, 0}, {400, 0}, {200, 0}, {100, 0}, {50, 0}, {12, 500000},
142 {6, 250000}, {1, 560000}
143};
144
c876109e 145/*
71702e6e
MF
146 * Hardware has fullscale of -2G, -4G, -8G corresponding to raw value -2048
147 * The userspace interface uses m/s^2 and we declare micro units
148 * So scale factor is given by:
149 * g * N * 1000000 / 2048 for N = 2, 4, 8 and g=9.80665
150 */
c7eeea93 151static const int mma8452_scales[3][2] = {
71702e6e 152 {0, 9577}, {0, 19154}, {0, 38307}
c7eeea93
PM
153};
154
5dbbd19f
MF
155/* Datasheet table 35 (step time vs sample frequency) */
156static const int mma8452_transient_time_step_us[8] = {
157 1250,
158 2500,
159 5000,
160 10000,
161 20000,
162 20000,
163 20000,
164 20000
165};
166
1e79841a
MF
167/* Datasheet table 18 (normal mode) */
168static const int mma8452_hp_filter_cutoff[8][4][2] = {
169 { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, /* 800 Hz sample */
170 { {16, 0}, {8, 0}, {4, 0}, {2, 0} }, /* 400 Hz sample */
171 { {8, 0}, {4, 0}, {2, 0}, {1, 0} }, /* 200 Hz sample */
172 { {4, 0}, {2, 0}, {1, 0}, {0, 500000} }, /* 100 Hz sample */
173 { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, /* 50 Hz sample */
174 { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, /* 12.5 Hz sample */
175 { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} }, /* 6.25 Hz sample */
176 { {2, 0}, {1, 0}, {0, 500000}, {0, 250000} } /* 1.56 Hz sample */
177};
178
c7eeea93
PM
179static ssize_t mma8452_show_samp_freq_avail(struct device *dev,
180 struct device_attribute *attr, char *buf)
181{
182 return mma8452_show_int_plus_micros(buf, mma8452_samp_freq,
183 ARRAY_SIZE(mma8452_samp_freq));
184}
185
186static ssize_t mma8452_show_scale_avail(struct device *dev,
187 struct device_attribute *attr, char *buf)
188{
189 return mma8452_show_int_plus_micros(buf, mma8452_scales,
190 ARRAY_SIZE(mma8452_scales));
191}
192
1e79841a
MF
193static ssize_t mma8452_show_hp_cutoff_avail(struct device *dev,
194 struct device_attribute *attr,
195 char *buf)
196{
197 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
198 struct mma8452_data *data = iio_priv(indio_dev);
199 int i = mma8452_get_odr_index(data);
200
201 return mma8452_show_int_plus_micros(buf, mma8452_hp_filter_cutoff[i],
202 ARRAY_SIZE(mma8452_hp_filter_cutoff[0]));
203}
204
c7eeea93
PM
205static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(mma8452_show_samp_freq_avail);
206static IIO_DEVICE_ATTR(in_accel_scale_available, S_IRUGO,
207 mma8452_show_scale_avail, NULL, 0);
1e79841a
MF
208static IIO_DEVICE_ATTR(in_accel_filter_high_pass_3db_frequency_available,
209 S_IRUGO, mma8452_show_hp_cutoff_avail, NULL, 0);
c7eeea93
PM
210
211static int mma8452_get_samp_freq_index(struct mma8452_data *data,
212 int val, int val2)
213{
214 return mma8452_get_int_plus_micros_index(mma8452_samp_freq,
215 ARRAY_SIZE(mma8452_samp_freq), val, val2);
216}
217
218static int mma8452_get_scale_index(struct mma8452_data *data,
219 int val, int val2)
220{
221 return mma8452_get_int_plus_micros_index(mma8452_scales,
222 ARRAY_SIZE(mma8452_scales), val, val2);
223}
224
1e79841a
MF
225static int mma8452_get_hp_filter_index(struct mma8452_data *data,
226 int val, int val2)
227{
228 int i = mma8452_get_odr_index(data);
229
230 return mma8452_get_int_plus_micros_index(mma8452_hp_filter_cutoff[i],
001fceb9 231 ARRAY_SIZE(mma8452_hp_filter_cutoff[0]), val, val2);
1e79841a
MF
232}
233
234static int mma8452_read_hp_filter(struct mma8452_data *data, int *hz, int *uHz)
235{
236 int i, ret;
237
238 ret = i2c_smbus_read_byte_data(data->client, MMA8452_HP_FILTER_CUTOFF);
239 if (ret < 0)
240 return ret;
241
242 i = mma8452_get_odr_index(data);
243 ret &= MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
244 *hz = mma8452_hp_filter_cutoff[i][ret][0];
245 *uHz = mma8452_hp_filter_cutoff[i][ret][1];
246
247 return 0;
248}
249
c7eeea93
PM
250static int mma8452_read_raw(struct iio_dev *indio_dev,
251 struct iio_chan_spec const *chan,
252 int *val, int *val2, long mask)
253{
254 struct mma8452_data *data = iio_priv(indio_dev);
255 __be16 buffer[3];
256 int i, ret;
257
258 switch (mask) {
259 case IIO_CHAN_INFO_RAW:
260 if (iio_buffer_enabled(indio_dev))
261 return -EBUSY;
262
263 mutex_lock(&data->lock);
264 ret = mma8452_read(data, buffer);
265 mutex_unlock(&data->lock);
266 if (ret < 0)
267 return ret;
268 *val = sign_extend32(
269 be16_to_cpu(buffer[chan->scan_index]) >> 4, 11);
270 return IIO_VAL_INT;
271 case IIO_CHAN_INFO_SCALE:
272 i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
273 *val = mma8452_scales[i][0];
274 *val2 = mma8452_scales[i][1];
275 return IIO_VAL_INT_PLUS_MICRO;
276 case IIO_CHAN_INFO_SAMP_FREQ:
5dbbd19f 277 i = mma8452_get_odr_index(data);
c7eeea93
PM
278 *val = mma8452_samp_freq[i][0];
279 *val2 = mma8452_samp_freq[i][1];
280 return IIO_VAL_INT_PLUS_MICRO;
281 case IIO_CHAN_INFO_CALIBBIAS:
282 ret = i2c_smbus_read_byte_data(data->client, MMA8452_OFF_X +
283 chan->scan_index);
284 if (ret < 0)
285 return ret;
286 *val = sign_extend32(ret, 7);
287 return IIO_VAL_INT;
1e79841a
MF
288 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
289 if (data->data_cfg & MMA8452_DATA_CFG_HPF_MASK) {
290 ret = mma8452_read_hp_filter(data, val, val2);
291 if (ret < 0)
292 return ret;
293 } else {
294 *val = 0;
295 *val2 = 0;
296 }
297 return IIO_VAL_INT_PLUS_MICRO;
c7eeea93
PM
298 }
299 return -EINVAL;
300}
301
302static int mma8452_standby(struct mma8452_data *data)
303{
304 return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
305 data->ctrl_reg1 & ~MMA8452_CTRL_ACTIVE);
306}
307
308static int mma8452_active(struct mma8452_data *data)
309{
310 return i2c_smbus_write_byte_data(data->client, MMA8452_CTRL_REG1,
311 data->ctrl_reg1);
312}
313
314static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
315{
316 int ret;
317
318 mutex_lock(&data->lock);
319
320 /* config can only be changed when in standby */
321 ret = mma8452_standby(data);
322 if (ret < 0)
323 goto fail;
324
325 ret = i2c_smbus_write_byte_data(data->client, reg, val);
326 if (ret < 0)
327 goto fail;
328
329 ret = mma8452_active(data);
330 if (ret < 0)
331 goto fail;
332
333 ret = 0;
334fail:
335 mutex_unlock(&data->lock);
336 return ret;
337}
338
1e79841a
MF
339static int mma8452_set_hp_filter_frequency(struct mma8452_data *data,
340 int val, int val2)
341{
342 int i, reg;
343
344 i = mma8452_get_hp_filter_index(data, val, val2);
345 if (i < 0)
b9fddcdb 346 return i;
1e79841a
MF
347
348 reg = i2c_smbus_read_byte_data(data->client,
349 MMA8452_HP_FILTER_CUTOFF);
350 if (reg < 0)
351 return reg;
352 reg &= ~MMA8452_HP_FILTER_CUTOFF_SEL_MASK;
353 reg |= i;
354
355 return mma8452_change_config(data, MMA8452_HP_FILTER_CUTOFF, reg);
356}
357
c7eeea93
PM
358static int mma8452_write_raw(struct iio_dev *indio_dev,
359 struct iio_chan_spec const *chan,
360 int val, int val2, long mask)
361{
362 struct mma8452_data *data = iio_priv(indio_dev);
1e79841a 363 int i, ret;
c7eeea93
PM
364
365 if (iio_buffer_enabled(indio_dev))
366 return -EBUSY;
367
368 switch (mask) {
369 case IIO_CHAN_INFO_SAMP_FREQ:
370 i = mma8452_get_samp_freq_index(data, val, val2);
371 if (i < 0)
b9fddcdb 372 return i;
c7eeea93
PM
373
374 data->ctrl_reg1 &= ~MMA8452_CTRL_DR_MASK;
375 data->ctrl_reg1 |= i << MMA8452_CTRL_DR_SHIFT;
376 return mma8452_change_config(data, MMA8452_CTRL_REG1,
377 data->ctrl_reg1);
378 case IIO_CHAN_INFO_SCALE:
379 i = mma8452_get_scale_index(data, val, val2);
380 if (i < 0)
b9fddcdb 381 return i;
c7eeea93
PM
382 data->data_cfg &= ~MMA8452_DATA_CFG_FS_MASK;
383 data->data_cfg |= i;
384 return mma8452_change_config(data, MMA8452_DATA_CFG,
385 data->data_cfg);
386 case IIO_CHAN_INFO_CALIBBIAS:
387 if (val < -128 || val > 127)
388 return -EINVAL;
389 return mma8452_change_config(data, MMA8452_OFF_X +
390 chan->scan_index, val);
1e79841a
MF
391
392 case IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY:
393 if (val == 0 && val2 == 0) {
394 data->data_cfg &= ~MMA8452_DATA_CFG_HPF_MASK;
395 } else {
396 data->data_cfg |= MMA8452_DATA_CFG_HPF_MASK;
397 ret = mma8452_set_hp_filter_frequency(data, val, val2);
398 if (ret < 0)
399 return ret;
400 }
401 return mma8452_change_config(data, MMA8452_DATA_CFG,
402 data->data_cfg);
403
c7eeea93
PM
404 default:
405 return -EINVAL;
406 }
407}
408
28e34278
MF
409static int mma8452_read_thresh(struct iio_dev *indio_dev,
410 const struct iio_chan_spec *chan,
411 enum iio_event_type type,
412 enum iio_event_direction dir,
413 enum iio_event_info info,
414 int *val, int *val2)
415{
416 struct mma8452_data *data = iio_priv(indio_dev);
5dbbd19f 417 int ret, us;
28e34278 418
5dbbd19f
MF
419 switch (info) {
420 case IIO_EV_INFO_VALUE:
421 ret = i2c_smbus_read_byte_data(data->client,
422 MMA8452_TRANSIENT_THS);
423 if (ret < 0)
424 return ret;
425
426 *val = ret & MMA8452_TRANSIENT_THS_MASK;
427 return IIO_VAL_INT;
28e34278 428
5dbbd19f
MF
429 case IIO_EV_INFO_PERIOD:
430 ret = i2c_smbus_read_byte_data(data->client,
431 MMA8452_TRANSIENT_COUNT);
432 if (ret < 0)
433 return ret;
434
435 us = ret * mma8452_transient_time_step_us[
436 mma8452_get_odr_index(data)];
437 *val = us / USEC_PER_SEC;
438 *val2 = us % USEC_PER_SEC;
439 return IIO_VAL_INT_PLUS_MICRO;
28e34278 440
1e79841a
MF
441 case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
442 ret = i2c_smbus_read_byte_data(data->client,
443 MMA8452_TRANSIENT_CFG);
444 if (ret < 0)
445 return ret;
446
447 if (ret & MMA8452_TRANSIENT_CFG_HPF_BYP) {
448 *val = 0;
449 *val2 = 0;
450 } else {
451 ret = mma8452_read_hp_filter(data, val, val2);
452 if (ret < 0)
453 return ret;
454 }
455 return IIO_VAL_INT_PLUS_MICRO;
456
5dbbd19f
MF
457 default:
458 return -EINVAL;
459 }
28e34278
MF
460}
461
462static int mma8452_write_thresh(struct iio_dev *indio_dev,
463 const struct iio_chan_spec *chan,
464 enum iio_event_type type,
465 enum iio_event_direction dir,
466 enum iio_event_info info,
467 int val, int val2)
468{
469 struct mma8452_data *data = iio_priv(indio_dev);
1e79841a 470 int ret, reg, steps;
28e34278 471
5dbbd19f
MF
472 switch (info) {
473 case IIO_EV_INFO_VALUE:
11218226
HK
474 if (val < 0 || val > MMA8452_TRANSIENT_THS_MASK)
475 return -EINVAL;
476
477 return mma8452_change_config(data, MMA8452_TRANSIENT_THS, val);
5dbbd19f
MF
478
479 case IIO_EV_INFO_PERIOD:
480 steps = (val * USEC_PER_SEC + val2) /
481 mma8452_transient_time_step_us[
482 mma8452_get_odr_index(data)];
483
11218226 484 if (steps < 0 || steps > 0xff)
5dbbd19f
MF
485 return -EINVAL;
486
487 return mma8452_change_config(data, MMA8452_TRANSIENT_COUNT,
488 steps);
1e79841a
MF
489 case IIO_EV_INFO_HIGH_PASS_FILTER_3DB:
490 reg = i2c_smbus_read_byte_data(data->client,
491 MMA8452_TRANSIENT_CFG);
492 if (reg < 0)
493 return reg;
494
495 if (val == 0 && val2 == 0) {
496 reg |= MMA8452_TRANSIENT_CFG_HPF_BYP;
497 } else {
498 reg &= ~MMA8452_TRANSIENT_CFG_HPF_BYP;
499 ret = mma8452_set_hp_filter_frequency(data, val, val2);
500 if (ret < 0)
501 return ret;
502 }
503 return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, reg);
504
5dbbd19f
MF
505 default:
506 return -EINVAL;
507 }
28e34278
MF
508}
509
510static int mma8452_read_event_config(struct iio_dev *indio_dev,
511 const struct iio_chan_spec *chan,
512 enum iio_event_type type,
513 enum iio_event_direction dir)
514{
515 struct mma8452_data *data = iio_priv(indio_dev);
516 int ret;
517
518 ret = i2c_smbus_read_byte_data(data->client, MMA8452_TRANSIENT_CFG);
519 if (ret < 0)
520 return ret;
521
522 return ret & MMA8452_TRANSIENT_CFG_CHAN(chan->scan_index) ? 1 : 0;
523}
524
525static int mma8452_write_event_config(struct iio_dev *indio_dev,
526 const struct iio_chan_spec *chan,
527 enum iio_event_type type,
528 enum iio_event_direction dir,
529 int state)
530{
531 struct mma8452_data *data = iio_priv(indio_dev);
532 int val;
533
534 val = i2c_smbus_read_byte_data(data->client, MMA8452_TRANSIENT_CFG);
535 if (val < 0)
536 return val;
537
538 if (state)
539 val |= MMA8452_TRANSIENT_CFG_CHAN(chan->scan_index);
540 else
541 val &= ~MMA8452_TRANSIENT_CFG_CHAN(chan->scan_index);
542
543 val |= MMA8452_TRANSIENT_CFG_ELE;
544
545 return mma8452_change_config(data, MMA8452_TRANSIENT_CFG, val);
546}
547
548static void mma8452_transient_interrupt(struct iio_dev *indio_dev)
549{
550 struct mma8452_data *data = iio_priv(indio_dev);
551 s64 ts = iio_get_time_ns();
552 int src;
553
554 src = i2c_smbus_read_byte_data(data->client, MMA8452_TRANSIENT_SRC);
555 if (src < 0)
556 return;
557
558 if (src & MMA8452_TRANSIENT_SRC_XTRANSE)
559 iio_push_event(indio_dev,
560 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X,
561 IIO_EV_TYPE_THRESH,
562 IIO_EV_DIR_RISING),
563 ts);
564
565 if (src & MMA8452_TRANSIENT_SRC_YTRANSE)
566 iio_push_event(indio_dev,
567 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Y,
568 IIO_EV_TYPE_THRESH,
569 IIO_EV_DIR_RISING),
570 ts);
571
572 if (src & MMA8452_TRANSIENT_SRC_ZTRANSE)
573 iio_push_event(indio_dev,
574 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Z,
575 IIO_EV_TYPE_THRESH,
576 IIO_EV_DIR_RISING),
577 ts);
578}
579
580static irqreturn_t mma8452_interrupt(int irq, void *p)
581{
582 struct iio_dev *indio_dev = p;
583 struct mma8452_data *data = iio_priv(indio_dev);
ae6d9ce0 584 int ret = IRQ_NONE;
28e34278
MF
585 int src;
586
587 src = i2c_smbus_read_byte_data(data->client, MMA8452_INT_SRC);
588 if (src < 0)
589 return IRQ_NONE;
590
ae6d9ce0
MF
591 if (src & MMA8452_INT_DRDY) {
592 iio_trigger_poll_chained(indio_dev->trig);
593 ret = IRQ_HANDLED;
594 }
595
28e34278
MF
596 if (src & MMA8452_INT_TRANS) {
597 mma8452_transient_interrupt(indio_dev);
ae6d9ce0 598 ret = IRQ_HANDLED;
28e34278
MF
599 }
600
ae6d9ce0 601 return ret;
28e34278
MF
602}
603
c7eeea93
PM
604static irqreturn_t mma8452_trigger_handler(int irq, void *p)
605{
606 struct iio_poll_func *pf = p;
607 struct iio_dev *indio_dev = pf->indio_dev;
608 struct mma8452_data *data = iio_priv(indio_dev);
609 u8 buffer[16]; /* 3 16-bit channels + padding + ts */
610 int ret;
611
612 ret = mma8452_read(data, (__be16 *) buffer);
613 if (ret < 0)
614 goto done;
615
616 iio_push_to_buffers_with_timestamp(indio_dev, buffer,
617 iio_get_time_ns());
618
619done:
620 iio_trigger_notify_done(indio_dev->trig);
621 return IRQ_HANDLED;
622}
623
2a17698c
MF
624static int mma8452_reg_access_dbg(struct iio_dev *indio_dev,
625 unsigned reg, unsigned writeval,
626 unsigned *readval)
627{
628 int ret;
629 struct mma8452_data *data = iio_priv(indio_dev);
630
631 if (reg > MMA8452_MAX_REG)
632 return -EINVAL;
633
634 if (!readval)
635 return mma8452_change_config(data, reg, writeval);
636
637 ret = i2c_smbus_read_byte_data(data->client, reg);
638 if (ret < 0)
639 return ret;
640
641 *readval = ret;
642
643 return 0;
644}
645
28e34278
MF
646static const struct iio_event_spec mma8452_transient_event[] = {
647 {
648 .type = IIO_EV_TYPE_THRESH,
649 .dir = IIO_EV_DIR_RISING,
650 .mask_separate = BIT(IIO_EV_INFO_ENABLE),
5dbbd19f 651 .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) |
1e79841a
MF
652 BIT(IIO_EV_INFO_PERIOD) |
653 BIT(IIO_EV_INFO_HIGH_PASS_FILTER_3DB)
28e34278
MF
654 },
655};
656
657/*
658 * Threshold is configured in fixed 8G/127 steps regardless of
659 * currently selected scale for measurement.
660 */
661static IIO_CONST_ATTR_NAMED(accel_transient_scale, in_accel_scale, "0.617742");
662
663static struct attribute *mma8452_event_attributes[] = {
664 &iio_const_attr_accel_transient_scale.dev_attr.attr,
665 NULL,
666};
667
668static struct attribute_group mma8452_event_attribute_group = {
669 .attrs = mma8452_event_attributes,
670 .name = "events",
671};
672
c7eeea93
PM
673#define MMA8452_CHANNEL(axis, idx) { \
674 .type = IIO_ACCEL, \
675 .modified = 1, \
676 .channel2 = IIO_MOD_##axis, \
677 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
678 BIT(IIO_CHAN_INFO_CALIBBIAS), \
679 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
1e79841a
MF
680 BIT(IIO_CHAN_INFO_SCALE) | \
681 BIT(IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY), \
c7eeea93
PM
682 .scan_index = idx, \
683 .scan_type = { \
684 .sign = 's', \
685 .realbits = 12, \
686 .storagebits = 16, \
687 .shift = 4, \
688 .endianness = IIO_BE, \
689 }, \
28e34278
MF
690 .event_spec = mma8452_transient_event, \
691 .num_event_specs = ARRAY_SIZE(mma8452_transient_event), \
c7eeea93
PM
692}
693
694static const struct iio_chan_spec mma8452_channels[] = {
695 MMA8452_CHANNEL(X, 0),
696 MMA8452_CHANNEL(Y, 1),
697 MMA8452_CHANNEL(Z, 2),
698 IIO_CHAN_SOFT_TIMESTAMP(3),
699};
700
701static struct attribute *mma8452_attributes[] = {
702 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
703 &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1e79841a 704 &iio_dev_attr_in_accel_filter_high_pass_3db_frequency_available.dev_attr.attr,
c7eeea93
PM
705 NULL
706};
707
708static const struct attribute_group mma8452_group = {
709 .attrs = mma8452_attributes,
710};
711
712static const struct iio_info mma8452_info = {
713 .attrs = &mma8452_group,
714 .read_raw = &mma8452_read_raw,
715 .write_raw = &mma8452_write_raw,
28e34278
MF
716 .event_attrs = &mma8452_event_attribute_group,
717 .read_event_value = &mma8452_read_thresh,
718 .write_event_value = &mma8452_write_thresh,
719 .read_event_config = &mma8452_read_event_config,
720 .write_event_config = &mma8452_write_event_config,
2a17698c 721 .debugfs_reg_access = &mma8452_reg_access_dbg,
c7eeea93
PM
722 .driver_module = THIS_MODULE,
723};
724
725static const unsigned long mma8452_scan_masks[] = {0x7, 0};
726
ae6d9ce0
MF
727static int mma8452_data_rdy_trigger_set_state(struct iio_trigger *trig,
728 bool state)
729{
730 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
731 struct mma8452_data *data = iio_priv(indio_dev);
732 int reg;
733
734 reg = i2c_smbus_read_byte_data(data->client, MMA8452_CTRL_REG4);
735 if (reg < 0)
736 return reg;
737
738 if (state)
739 reg |= MMA8452_INT_DRDY;
740 else
741 reg &= ~MMA8452_INT_DRDY;
742
743 return mma8452_change_config(data, MMA8452_CTRL_REG4, reg);
744}
745
746static int mma8452_validate_device(struct iio_trigger *trig,
747 struct iio_dev *indio_dev)
748{
749 struct iio_dev *indio = iio_trigger_get_drvdata(trig);
750
751 if (indio != indio_dev)
752 return -EINVAL;
753
754 return 0;
755}
756
757static const struct iio_trigger_ops mma8452_trigger_ops = {
758 .set_trigger_state = mma8452_data_rdy_trigger_set_state,
759 .validate_device = mma8452_validate_device,
760 .owner = THIS_MODULE,
761};
762
763static int mma8452_trigger_setup(struct iio_dev *indio_dev)
764{
765 struct mma8452_data *data = iio_priv(indio_dev);
766 struct iio_trigger *trig;
767 int ret;
768
769 trig = devm_iio_trigger_alloc(&data->client->dev, "%s-dev%d",
770 indio_dev->name,
771 indio_dev->id);
772 if (!trig)
773 return -ENOMEM;
774
775 trig->dev.parent = &data->client->dev;
776 trig->ops = &mma8452_trigger_ops;
777 iio_trigger_set_drvdata(trig, indio_dev);
778
779 ret = iio_trigger_register(trig);
780 if (ret)
781 return ret;
782
783 indio_dev->trig = trig;
784 return 0;
785}
786
787static void mma8452_trigger_cleanup(struct iio_dev *indio_dev)
788{
789 if (indio_dev->trig)
790 iio_trigger_unregister(indio_dev->trig);
791}
792
ecabae71
MF
793static int mma8452_reset(struct i2c_client *client)
794{
795 int i;
796 int ret;
797
798 ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG2,
799 MMA8452_CTRL_REG2_RST);
800 if (ret < 0)
801 return ret;
802
803 for (i = 0; i < 10; i++) {
804 usleep_range(100, 200);
805 ret = i2c_smbus_read_byte_data(client, MMA8452_CTRL_REG2);
806 if (ret == -EIO)
807 continue; /* I2C comm reset */
808 if (ret < 0)
809 return ret;
810 if (!(ret & MMA8452_CTRL_REG2_RST))
811 return 0;
812 }
813
814 return -ETIMEDOUT;
815}
816
c7eeea93
PM
817static int mma8452_probe(struct i2c_client *client,
818 const struct i2c_device_id *id)
819{
820 struct mma8452_data *data;
821 struct iio_dev *indio_dev;
822 int ret;
823
824 ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);
825 if (ret < 0)
826 return ret;
827 if (ret != MMA8452_DEVICE_ID)
828 return -ENODEV;
829
830 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
831 if (!indio_dev)
832 return -ENOMEM;
833
834 data = iio_priv(indio_dev);
835 data->client = client;
836 mutex_init(&data->lock);
837
838 i2c_set_clientdata(client, indio_dev);
839 indio_dev->info = &mma8452_info;
840 indio_dev->name = id->name;
841 indio_dev->dev.parent = &client->dev;
842 indio_dev->modes = INDIO_DIRECT_MODE;
843 indio_dev->channels = mma8452_channels;
844 indio_dev->num_channels = ARRAY_SIZE(mma8452_channels);
845 indio_dev->available_scan_masks = mma8452_scan_masks;
846
ecabae71 847 ret = mma8452_reset(client);
c7eeea93
PM
848 if (ret < 0)
849 return ret;
850
851 data->data_cfg = MMA8452_DATA_CFG_FS_2G;
852 ret = i2c_smbus_write_byte_data(client, MMA8452_DATA_CFG,
853 data->data_cfg);
854 if (ret < 0)
855 return ret;
856
28e34278
MF
857 /*
858 * By default set transient threshold to max to avoid events if
859 * enabling without configuring threshold.
860 */
861 ret = i2c_smbus_write_byte_data(client, MMA8452_TRANSIENT_THS,
862 MMA8452_TRANSIENT_THS_MASK);
863 if (ret < 0)
864 return ret;
865
866 if (client->irq) {
867 /*
868 * Although we enable the transient interrupt source once and
869 * for all here the transient event detection itself is not
870 * enabled until userspace asks for it by
871 * mma8452_write_event_config()
872 */
ae6d9ce0
MF
873 int supported_interrupts = MMA8452_INT_DRDY | MMA8452_INT_TRANS;
874 int enabled_interrupts = MMA8452_INT_TRANS;
28e34278
MF
875
876 /* Assume wired to INT1 pin */
877 ret = i2c_smbus_write_byte_data(client,
878 MMA8452_CTRL_REG5,
879 supported_interrupts);
880 if (ret < 0)
881 return ret;
882
883 ret = i2c_smbus_write_byte_data(client,
884 MMA8452_CTRL_REG4,
ae6d9ce0
MF
885 enabled_interrupts);
886 if (ret < 0)
887 return ret;
888
889 ret = mma8452_trigger_setup(indio_dev);
28e34278
MF
890 if (ret < 0)
891 return ret;
892 }
893
ecabae71
MF
894 data->ctrl_reg1 = MMA8452_CTRL_ACTIVE |
895 (MMA8452_CTRL_DR_DEFAULT << MMA8452_CTRL_DR_SHIFT);
896 ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG1,
897 data->ctrl_reg1);
898 if (ret < 0)
ae6d9ce0 899 goto trigger_cleanup;
ecabae71 900
c7eeea93
PM
901 ret = iio_triggered_buffer_setup(indio_dev, NULL,
902 mma8452_trigger_handler, NULL);
903 if (ret < 0)
ae6d9ce0 904 goto trigger_cleanup;
c7eeea93 905
28e34278
MF
906 if (client->irq) {
907 ret = devm_request_threaded_irq(&client->dev,
908 client->irq,
909 NULL, mma8452_interrupt,
910 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
911 client->name, indio_dev);
912 if (ret)
913 goto buffer_cleanup;
914 }
915
c7eeea93
PM
916 ret = iio_device_register(indio_dev);
917 if (ret < 0)
918 goto buffer_cleanup;
28e34278 919
c7eeea93
PM
920 return 0;
921
922buffer_cleanup:
923 iio_triggered_buffer_cleanup(indio_dev);
ae6d9ce0
MF
924
925trigger_cleanup:
926 mma8452_trigger_cleanup(indio_dev);
927
c7eeea93
PM
928 return ret;
929}
930
931static int mma8452_remove(struct i2c_client *client)
932{
933 struct iio_dev *indio_dev = i2c_get_clientdata(client);
934
935 iio_device_unregister(indio_dev);
936 iio_triggered_buffer_cleanup(indio_dev);
ae6d9ce0 937 mma8452_trigger_cleanup(indio_dev);
c7eeea93
PM
938 mma8452_standby(iio_priv(indio_dev));
939
940 return 0;
941}
942
943#ifdef CONFIG_PM_SLEEP
944static int mma8452_suspend(struct device *dev)
945{
946 return mma8452_standby(iio_priv(i2c_get_clientdata(
947 to_i2c_client(dev))));
948}
949
950static int mma8452_resume(struct device *dev)
951{
952 return mma8452_active(iio_priv(i2c_get_clientdata(
953 to_i2c_client(dev))));
954}
955
956static SIMPLE_DEV_PM_OPS(mma8452_pm_ops, mma8452_suspend, mma8452_resume);
957#define MMA8452_PM_OPS (&mma8452_pm_ops)
958#else
959#define MMA8452_PM_OPS NULL
960#endif
961
962static const struct i2c_device_id mma8452_id[] = {
963 { "mma8452", 0 },
964 { }
965};
966MODULE_DEVICE_TABLE(i2c, mma8452_id);
967
a3fb96a8
MF
968static const struct of_device_id mma8452_dt_ids[] = {
969 { .compatible = "fsl,mma8452" },
970 { }
971};
119c4fce 972MODULE_DEVICE_TABLE(of, mma8452_dt_ids);
a3fb96a8 973
c7eeea93
PM
974static struct i2c_driver mma8452_driver = {
975 .driver = {
976 .name = "mma8452",
a3fb96a8 977 .of_match_table = of_match_ptr(mma8452_dt_ids),
c7eeea93
PM
978 .pm = MMA8452_PM_OPS,
979 },
980 .probe = mma8452_probe,
981 .remove = mma8452_remove,
982 .id_table = mma8452_id,
983};
984module_i2c_driver(mma8452_driver);
985
986MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
987MODULE_DESCRIPTION("Freescale MMA8452 accelerometer driver");
988MODULE_LICENSE("GPL");