aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluweizhou <b45643@freescale.com>2014-06-26 20:23:35 -0400
committerluweizhou <b45643@freescale.com>2014-06-26 21:15:47 -0400
commit97083f8b86a037c032520ce28562b2b14baf1f66 (patch)
treeec4ae05ae4d916f152eca4268afac04ed529e5e4
parent7db52dbac37e7f0d6c963d1b768581d6b1e3dc54 (diff)
ENGR00320098 hwmon: mma8451: Add a new mma8451 driver from android team update
The android app has its own interface for mma8451 data. The inerface isn't a regular input dev interface. Since it is difficult to maintain the code within one file, one new file and configure will be added. It would not be compiled in the default config. If want to use this driver, need to follow: *Disable the CONFIG_MXC_MMA8451. *Enable the CONFIG_MXC_MMA8x5x and make. The code is from branch imx_3.10.y_android. The main modification is : *Using device to pass into parameters related with platform not hard code. *Codeing style issues Signed-off-by: Luwei Zhou <b45643@freescale.com> (cherry picked from commit e3faf9d404fcd3663c47cd1183e01a71c53b9eb8)
-rw-r--r--drivers/hwmon/Kconfig6
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/mma8x5x.c1036
3 files changed, 1043 insertions, 0 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 981a22f0812e..54192aacf45b 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1579,4 +1579,10 @@ config MXC_MMA8451
1579 depends on I2C 1579 depends on I2C
1580 default y 1580 default y
1581 1581
1582config MXC_MMA8x5x
1583 tristate "MMA8x5x device driver"
1584 depends on I2C && SYSFS
1585 default n
1586 help
1587 This configure is used by android sensor driver.
1582endif # HWMON 1588endif # HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 43fe743901ee..4fcafff867c3 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -143,6 +143,7 @@ obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o
143obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o 143obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o
144obj-$(CONFIG_SENSORS_MAG3110) += mag3110.o 144obj-$(CONFIG_SENSORS_MAG3110) += mag3110.o
145obj-$(CONFIG_MXC_MMA8451) += mxc_mma8451.o 145obj-$(CONFIG_MXC_MMA8451) += mxc_mma8451.o
146obj-$(CONFIG_MXC_MMA8x5x) += mma8x5x.o
146 147
147obj-$(CONFIG_PMBUS) += pmbus/ 148obj-$(CONFIG_PMBUS) += pmbus/
148 149
diff --git a/drivers/hwmon/mma8x5x.c b/drivers/hwmon/mma8x5x.c
new file mode 100644
index 000000000000..d77dc515043f
--- /dev/null
+++ b/drivers/hwmon/mma8x5x.c
@@ -0,0 +1,1036 @@
1/*
2 * mma8x5x.c - Linux kernel modules for 3-Axis Orientation/Motion
3 * Detection Sensor MMA8451/MMA8452/MMA8453/MMA8652/MMA8653
4 *
5 * Copyright (C) 2012-2014 Freescale Semiconductor, Inc. All Rights Reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/i2c.h>
26#include <linux/pm.h>
27#include <linux/mutex.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h>
30#include <linux/irq.h>
31#include <linux/hwmon-sysfs.h>
32#include <linux/err.h>
33#include <linux/poll.h>
34#include <linux/hwmon.h>
35#include <linux/input.h>
36#include <linux/miscdevice.h>
37#include <linux/regulator/consumer.h>
38
39#define MMA8X5X_I2C_ADDR 0x1D
40#define MMA8451_ID 0x1A
41#define MMA8452_ID 0x2A
42#define MMA8453_ID 0x3A
43#define MMA8652_ID 0x4A
44#define MMA8653_ID 0x5A
45
46
47#define POLL_INTERVAL_MIN 1
48#define POLL_INTERVAL_MAX 500
49#define POLL_INTERVAL 100 /* msecs */
50
51/* if sensor is standby ,set POLL_STOP_TIME to slow down the poll */
52#define POLL_STOP_TIME 200
53#define INPUT_FUZZ 32
54#define INPUT_FLAT 32
55#define MODE_CHANGE_DELAY_MS 100
56
57#define MMA8X5X_STATUS_ZYXDR 0x08
58#define MMA8X5X_BUF_SIZE 6
59
60#define MMA8X5X_FIFO_SIZE 32
61/* register enum for mma8x5x registers */
62enum {
63 MMA8X5X_STATUS = 0x00,
64 MMA8X5X_OUT_X_MSB,
65 MMA8X5X_OUT_X_LSB,
66 MMA8X5X_OUT_Y_MSB,
67 MMA8X5X_OUT_Y_LSB,
68 MMA8X5X_OUT_Z_MSB,
69 MMA8X5X_OUT_Z_LSB,
70
71 MMA8X5X_F_SETUP = 0x09,
72 MMA8X5X_TRIG_CFG,
73 MMA8X5X_SYSMOD,
74 MMA8X5X_INT_SOURCE,
75 MMA8X5X_WHO_AM_I,
76 MMA8X5X_XYZ_DATA_CFG,
77 MMA8X5X_HP_FILTER_CUTOFF,
78
79 MMA8X5X_PL_STATUS,
80 MMA8X5X_PL_CFG,
81 MMA8X5X_PL_COUNT,
82 MMA8X5X_PL_BF_ZCOMP,
83 MMA8X5X_P_L_THS_REG,
84
85 MMA8X5X_FF_MT_CFG,
86 MMA8X5X_FF_MT_SRC,
87 MMA8X5X_FF_MT_THS,
88 MMA8X5X_FF_MT_COUNT,
89
90 MMA8X5X_TRANSIENT_CFG = 0x1D,
91 MMA8X5X_TRANSIENT_SRC,
92 MMA8X5X_TRANSIENT_THS,
93 MMA8X5X_TRANSIENT_COUNT,
94
95 MMA8X5X_PULSE_CFG,
96 MMA8X5X_PULSE_SRC,
97 MMA8X5X_PULSE_THSX,
98 MMA8X5X_PULSE_THSY,
99 MMA8X5X_PULSE_THSZ,
100 MMA8X5X_PULSE_TMLT,
101 MMA8X5X_PULSE_LTCY,
102 MMA8X5X_PULSE_WIND,
103
104 MMA8X5X_ASLP_COUNT,
105 MMA8X5X_CTRL_REG1,
106 MMA8X5X_CTRL_REG2,
107 MMA8X5X_CTRL_REG3,
108 MMA8X5X_CTRL_REG4,
109 MMA8X5X_CTRL_REG5,
110
111 MMA8X5X_OFF_X,
112 MMA8X5X_OFF_Y,
113 MMA8X5X_OFF_Z,
114
115 MMA8X5X_REG_END,
116};
117
118/* The sensitivity is represented in counts/g. In 2g mode the
119 sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
120 counts/g and in 8g mode the sensitivity is 256 counts/g.
121 */
122enum {
123 MODE_2G = 0,
124 MODE_4G,
125 MODE_8G,
126};
127
128enum {
129 MMA_STANDBY = 0,
130 MMA_ACTIVED,
131};
132#pragma pack(1)
133struct mma8x5x_data_axis {
134 short x;
135 short y;
136 short z;
137};
138struct mma8x5x_fifo{
139 int count;
140 s64 period;
141 s64 timestamp;
142 struct mma8x5x_data_axis fifo_data[MMA8X5X_FIFO_SIZE];
143};
144#pragma pack()
145
146struct mma8x5x_data {
147 struct i2c_client *client;
148 struct input_dev *idev;
149 struct delayed_work work;
150 struct mutex data_lock;
151 struct mma8x5x_fifo fifo;
152 wait_queue_head_t fifo_wq;
153 atomic_t fifo_ready;
154 int active;
155 int delay;
156 int position;
157 u8 chip_id;
158 int mode;
159 int awaken;
160 s64 period_rel;
161 int fifo_wakeup;
162 int fifo_timeout;
163 u32 int_pin;
164};
165
166static struct mma8x5x_data *p_mma8x5x_data;
167
168/* Addresses scanned */
169static const unsigned short normal_i2c[] = { 0x1c, 0x1d, I2C_CLIENT_END };
170
171static int mma8x5x_chip_id[] = {
172 MMA8451_ID,
173 MMA8452_ID,
174 MMA8453_ID,
175 MMA8652_ID,
176 MMA8653_ID,
177};
178static char *mma8x5x_names[] = {
179 "mma8451",
180 "mma8452",
181 "mma8453",
182 "mma8652",
183 "mma8653",
184};
185static int mma8x5x_position_setting[8][3][3] = {
186 { { 0, -1, 0 }, { 1, 0, 0 }, { 0, 0, 1 } },
187 { { -1, 0, 0 }, { 0, -1, 0 }, { 0, 0, 1 } },
188 { { 0, 1, 0 }, { -1, 0, 0 }, { 0, 0, 1 } },
189 { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } },
190
191 { { 0, -1, 0 }, { -1, 0, 0 }, { 0, 0, -1 } },
192 { { -1, 0, 0 }, { 0, 1, 0 }, { 0, 0, -1 } },
193 { { 0, 1, 0 }, { 1, 0, 0 }, { 0, 0, -1 } },
194 { { 1, 0, 0 }, { 0, -1, 0 }, { 0, 0, -1 } },
195};
196static int mma8x5x_data_convert(struct mma8x5x_data *pdata,
197 struct mma8x5x_data_axis *axis_data)
198{
199 short rawdata[3], data[3];
200 int i, j;
201 int position = pdata->position;
202
203 if (position < 0 || position > 7)
204 position = 0;
205 rawdata[0] = axis_data->x;
206 rawdata[1] = axis_data->y;
207 rawdata[2] = axis_data->z;
208 for (i = 0; i < 3; i++) {
209 data[i] = 0;
210 for (j = 0; j < 3; j++)
211 data[i] += rawdata[j] *
212 mma8x5x_position_setting[position][i][j];
213 }
214 axis_data->x = data[0];
215 axis_data->y = data[1];
216 axis_data->z = data[2];
217 return 0;
218}
219static int mma8x5x_check_id(int id)
220{
221 int i = 0;
222
223 for (i = 0; i < sizeof(mma8x5x_chip_id) /
224 sizeof(mma8x5x_chip_id[0]); i++)
225 if (id == mma8x5x_chip_id[i])
226 return 1;
227 return 0;
228}
229static char *mma8x5x_id2name(u8 id)
230{
231 return mma8x5x_names[(id >> 4) - 1];
232}
233
234static int mma8x5x_i2c_read_fifo(struct i2c_client *client,
235 u8 reg, char *buf, int len)
236{
237 char send_buf[] = {reg};
238 struct i2c_msg msgs[] = {
239 {
240 .addr = client->addr,
241 .flags = 0,
242 .len = 1,
243 .buf = send_buf,
244 },
245 {
246 .addr = client->addr,
247 .flags = I2C_M_RD,
248 .len = len,
249 .buf = buf,
250 },
251 };
252 if (i2c_transfer(client->adapter, msgs, 2) < 0) {
253 printk(KERN_ERR "mma8x5x: transfer error\n");
254 return -EIO;
255 } else
256 return len;
257}
258
259/*period is ms, return the real period per event*/
260static s64 mma8x5x_odr_set(struct i2c_client *client, int period)
261{
262 u8 odr;
263 u8 val;
264 s64 period_rel;
265 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
266 /*Standby*/
267 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val & (~0x01));
268 val &= ~(0x07 << 3);
269 if (period >= 640) {
270 /*1.56HZ*/
271 odr = 0x7;
272 period_rel = 640 * NSEC_PER_MSEC;
273 } else if (period >= 160) {
274 /*6.25HZ*/
275 odr = 0x06;
276 period_rel = 160 * NSEC_PER_MSEC;
277 } else if (period >= 80) {
278 /*12.5HZ*/
279 odr = 0x05;
280 period_rel = 80 * NSEC_PER_MSEC;
281 } else if (period >= 20) {
282 /*50HZ*/
283 odr = 0x04;
284 period_rel = 20 * NSEC_PER_MSEC;
285 } else if (period >= 10) {
286 /*100HZ*/
287 odr = 0x03;
288 period_rel = 10 * NSEC_PER_MSEC;
289 } else if (period >= 5) {
290 /*200HZ*/
291 odr = 0x02;
292 period_rel = 5 * NSEC_PER_MSEC;
293 } else if ((period * 2) >= 5) {
294 /*400HZ*/
295 odr = 0x01;
296 period_rel = 2500 * NSEC_PER_USEC;
297 } else {
298 /*800HZ*/
299 odr = 0x00;
300 period_rel = 1250 * NSEC_PER_USEC;
301 }
302 val |= (odr << 3);
303 /*Standby*/
304 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val);
305 return period_rel;
306}
307static int mma8x5x_device_init(struct i2c_client *client)
308{
309 int result;
310 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
311
312 result = i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, 0);
313 if (result < 0)
314 goto out;
315
316 result = i2c_smbus_write_byte_data(client, MMA8X5X_XYZ_DATA_CFG,
317 pdata->mode);
318 if (result < 0)
319 goto out;
320 pdata->active = MMA_STANDBY;
321 msleep(MODE_CHANGE_DELAY_MS);
322 return 0;
323out:
324 dev_err(&client->dev, "error when init mma8x5x:(%d)", result);
325 return result;
326}
327static int mma8x5x_device_stop(struct i2c_client *client)
328{
329 u8 val;
330
331 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
332 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val & 0xfe);
333 return 0;
334}
335static int mma8x5x_read_data(struct i2c_client *client,
336 struct mma8x5x_data_axis *data)
337{
338 u8 tmp_data[MMA8X5X_BUF_SIZE];
339 int ret;
340
341 ret = i2c_smbus_read_i2c_block_data(client,
342 MMA8X5X_OUT_X_MSB,
343 MMA8X5X_BUF_SIZE, tmp_data);
344 if (ret < MMA8X5X_BUF_SIZE) {
345 dev_err(&client->dev, "i2c block read failed\n");
346 return -EIO;
347 }
348 data->x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
349 data->y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
350 data->z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
351 return 0;
352}
353
354static int mma8x5x_fifo_interrupt(struct i2c_client *client, int enable)
355{
356 u8 val, sys_mode;
357 sys_mode = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
358 /*standby*/
359 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1,
360 (sys_mode & (~0x01)));
361 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG4);
362 val &= ~(0x01 << 6);
363 if (enable)
364 val |= (0x01 << 6);
365 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG4, val);
366 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, sys_mode);
367 return 0;
368}
369
370static int mma8x5x_fifo_setting(struct mma8x5x_data *pdata,
371 int time_out, int is_overwrite)
372{
373 u8 val, sys_mode, pin_cfg;
374 struct i2c_client *client = pdata->client;
375 sys_mode = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
376 /*standby*/
377 i2c_smbus_write_byte_data(client,
378 MMA8X5X_CTRL_REG1,
379 (sys_mode & (~0x01)));
380 pin_cfg = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG5);
381 val = i2c_smbus_read_byte_data(client, MMA8X5X_F_SETUP);
382 val &= ~(0x03 << 6);
383 if (time_out > 0) {
384 if (is_overwrite)
385 val |= (0x01 << 6);
386 else
387 val |= (0x02 << 6);
388 }
389 i2c_smbus_write_byte_data(client, MMA8X5X_F_SETUP, val);
390 /*route to pin 1*/
391 if (pdata->int_pin == 1)
392 i2c_smbus_write_byte_data(client,
393 MMA8X5X_CTRL_REG5,
394 pin_cfg | (0x01 << 6));
395 /*route to pin 1*/
396 else
397 i2c_smbus_write_byte_data(client,
398 MMA8X5X_CTRL_REG5,
399 pin_cfg & ~(0x01 << 6));
400
401 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, sys_mode);
402
403 if (time_out > 0) {
404 /*fifo len is 32*/
405 pdata->period_rel = mma8x5x_odr_set(client, time_out/32);
406 }
407 return 0;
408}
409static int mma8x5x_read_fifo_data(struct mma8x5x_data *pdata)
410{
411 int count, cnt;
412 u8 buf[256], val;
413 int i, index;
414 struct i2c_client *client = pdata->client;
415 struct mma8x5x_fifo *pfifo = &pdata->fifo;
416 struct timespec ts;
417 val = i2c_smbus_read_byte_data(client, MMA8X5X_STATUS);
418 /*FIFO overflow*/
419 if (val & (0x01 << 7)) {
420 cnt = (val & 0x3f);
421 count = mma8x5x_i2c_read_fifo(client, MMA8X5X_OUT_X_MSB,
422 buf, MMA8X5X_BUF_SIZE * cnt);
423 if (count > 0) {
424 ktime_get_ts(&ts);
425 for (i = 0; i < count/MMA8X5X_BUF_SIZE ; i++) {
426 index = MMA8X5X_BUF_SIZE * i;
427 pfifo->fifo_data[i].x =
428 ((buf[index] << 8) & 0xff00) | buf[index + 1];
429 pfifo->fifo_data[i].y =
430 ((buf[index + 2] << 8) & 0xff00) | buf[index + 3];
431 pfifo->fifo_data[i].z =
432 ((buf[index + 4] << 8) & 0xff00) | buf[index + 5];
433 mma8x5x_data_convert(pdata,
434 &pfifo->fifo_data[i]);
435 }
436 pfifo->period = pdata->period_rel;
437 pfifo->count = count / MMA8X5X_BUF_SIZE;
438 pfifo->timestamp = ((s64)ts.tv_sec) * NSEC_PER_SEC
439 + ts.tv_nsec;
440 return 0;
441 }
442 }
443 return -1;
444}
445
446static void mma8x5x_report_data(struct mma8x5x_data *pdata)
447{
448 struct mma8x5x_data_axis data;
449 int ret;
450 ret = mma8x5x_read_data(pdata->client, &data);
451 if (!ret) {
452 mma8x5x_data_convert(pdata, &data);
453 input_report_abs(pdata->idev, ABS_X, data.x);
454 input_report_abs(pdata->idev, ABS_Y, data.y);
455 input_report_abs(pdata->idev, ABS_Z, data.z);
456 input_sync(pdata->idev);
457 }
458}
459static void mma8x5x_work(struct mma8x5x_data *pdata)
460{
461 int delay;
462 if (pdata->active == MMA_ACTIVED) {
463 delay = msecs_to_jiffies(pdata->delay);
464 if (delay >= HZ)
465 delay = round_jiffies_relative(delay);
466 schedule_delayed_work(&pdata->work, delay);
467 }
468}
469static void mma8x5x_dev_poll(struct work_struct *work)
470{
471 struct mma8x5x_data *pdata = container_of(work,
472 struct mma8x5x_data,
473 work.work);
474 mma8x5x_report_data(pdata);
475 mma8x5x_work(pdata);
476}
477static irqreturn_t mma8x5x_irq_handler(int irq, void *dev)
478{
479 int ret;
480 u8 int_src;
481 struct mma8x5x_data *pdata = (struct mma8x5x_data *)dev;
482 int_src = i2c_smbus_read_byte_data(pdata->client, MMA8X5X_INT_SOURCE);
483 if (int_src & (0x01 << 6)) {
484 ret = mma8x5x_read_fifo_data(pdata);
485 if (!ret) {
486 atomic_set(&pdata->fifo_ready, 1);
487 wake_up(&pdata->fifo_wq);
488 }
489 /*is just awken from suspend*/
490 if (pdata->awaken) {
491 /*10s timeout*/
492 mma8x5x_fifo_setting(pdata, pdata->fifo_timeout, 0);
493 mma8x5x_fifo_interrupt(pdata->client, 1);
494 pdata->awaken = 0;
495 }
496 }
497 return IRQ_HANDLED;
498}
499
500static ssize_t mma8x5x_enable_show(struct device *dev,
501 struct device_attribute *attr, char *buf)
502{
503 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
504 struct i2c_client *client = pdata->client;
505 u8 val;
506 int enable;
507
508 mutex_lock(&pdata->data_lock);
509 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
510 if ((val & 0x01) && pdata->active == MMA_ACTIVED)
511 enable = 1;
512 else
513 enable = 0;
514 mutex_unlock(&pdata->data_lock);
515 return sprintf(buf, "%d\n", enable);
516}
517
518static ssize_t mma8x5x_enable_store(struct device *dev,
519 struct device_attribute *attr,
520 const char *buf, size_t count)
521{
522 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
523 struct i2c_client *client = pdata->client;
524 int ret;
525 unsigned long enable;
526 u8 val = 0;
527
528 ret = strict_strtol(buf, 10, &enable);
529 if (ret) {
530 dev_err(dev, "string to long error\n");
531 return ret;
532 }
533 mutex_lock(&pdata->data_lock);
534 enable = (enable > 0) ? 1 : 0;
535 if (enable && pdata->active == MMA_STANDBY) {
536 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
537 ret = i2c_smbus_write_byte_data(client,
538 MMA8X5X_CTRL_REG1,
539 val | 0x01);
540 if (!ret) {
541 pdata->active = MMA_ACTIVED;
542 /*continuous mode*/
543 if (pdata->fifo_timeout <= 0)
544 mma8x5x_work(pdata);
545 else {
546 /*fifo mode*/
547 mma8x5x_fifo_setting(pdata,
548 pdata->fifo_timeout, 0);
549 mma8x5x_fifo_interrupt(client, 1);
550 }
551 printk(KERN_INFO"mma enable setting active\n");
552 }
553 } else if (enable == 0 && pdata->active == MMA_ACTIVED) {
554 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
555 ret = i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1,
556 val & 0xFE);
557 if (!ret) {
558 pdata->active = MMA_STANDBY;
559 if (pdata->fifo_timeout <= 0)
560 /*continuous mode*/
561 cancel_delayed_work_sync(&pdata->work);
562 else {
563 /*fifo mode*/
564 mma8x5x_fifo_setting(pdata, 0, 0);
565 mma8x5x_fifo_interrupt(client, 0);
566 }
567 printk(KERN_INFO"mma enable setting inactive\n");
568 }
569 }
570 mutex_unlock(&pdata->data_lock);
571 return count;
572}
573
574static ssize_t mma8x5x_delay_show(struct device *dev,
575 struct device_attribute *attr, char *buf)
576{
577 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
578 int delay;
579 mutex_lock(&pdata->data_lock);
580 delay = pdata->delay;
581 mutex_unlock(&pdata->data_lock);
582 return sprintf(buf, "%d\n", delay);
583}
584
585static ssize_t mma8x5x_delay_store(struct device *dev,
586 struct device_attribute *attr,
587 const char *buf, size_t count)
588{
589 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
590 struct i2c_client *client = pdata->client;
591 int ret;
592 long delay;
593 ret = strict_strtol(buf, 10, &delay);
594 if (ret) {
595 dev_err(dev, "string to long error\n");
596 return ret;
597 }
598
599 mutex_lock(&pdata->data_lock);
600 cancel_delayed_work_sync(&pdata->work);
601 pdata->delay = (int)delay;
602 if (pdata->active == MMA_ACTIVED && pdata->fifo_timeout <= 0) {
603 mma8x5x_odr_set(client, (int)delay);
604 mma8x5x_work(pdata);
605 }
606 mutex_unlock(&pdata->data_lock);
607 return count;
608}
609
610static ssize_t mma8x5x_fifo_show(struct device *dev,
611 struct device_attribute *attr, char *buf)
612{
613 int count = 0;
614 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
615 mutex_lock(&pdata->data_lock);
616 count = sprintf(&buf[count], "period poll :%d ms\n", pdata->delay);
617 count += sprintf(&buf[count], "period fifo :%lld ns\n",
618 pdata->period_rel);
619 count += sprintf(&buf[count], "timeout :%d ms\n", pdata->fifo_timeout);
620 /*is the interrupt enable*/
621 count += sprintf(&buf[count], "interrupt wake up: %s\n",
622 (pdata->fifo_wakeup ? "yes" : "no"));
623 mutex_unlock(&pdata->data_lock);
624 return count;
625}
626
627static ssize_t mma8x5x_fifo_store(struct device *dev,
628 struct device_attribute *attr,
629 const char *buf, size_t count)
630{
631 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
632 struct i2c_client *client = pdata->client;
633 int period, timeout, wakeup;
634 sscanf(buf, "%d,%d,%d", &period, &timeout, &wakeup);
635 printk(KERN_INFO"period %d ,timeout is %d, wake up is :%d\n",
636 period, timeout, wakeup);
637 if (timeout > 0) {
638 mutex_lock(&pdata->data_lock);
639 cancel_delayed_work_sync(&pdata->work);
640 pdata->delay = period;
641 mutex_unlock(&pdata->data_lock);
642 /*no overwirte fifo*/
643 mma8x5x_fifo_setting(pdata, timeout, 0);
644 mma8x5x_fifo_interrupt(client, 1);
645 pdata->fifo_timeout = timeout;
646 pdata->fifo_wakeup = wakeup;
647 } else {
648 /*no overwirte fifo*/
649 mma8x5x_fifo_setting(pdata, timeout, 0);
650 mma8x5x_fifo_interrupt(client, 0);
651 pdata->fifo_timeout = timeout;
652 pdata->fifo_wakeup = wakeup;
653 mutex_lock(&pdata->data_lock);
654 pdata->delay = period;
655 if (pdata->active == MMA_ACTIVED)
656 mma8x5x_work(pdata);
657 mutex_unlock(&pdata->data_lock);
658 }
659 return count;
660}
661
662static ssize_t mma8x5x_position_show(struct device *dev,
663 struct device_attribute *attr, char *buf)
664{
665 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
666 int position = 0;
667 mutex_lock(&pdata->data_lock);
668 position = pdata->position;
669 mutex_unlock(&pdata->data_lock);
670 return sprintf(buf, "%d\n", position);
671}
672
673static ssize_t mma8x5x_position_store(struct device *dev,
674 struct device_attribute *attr,
675 const char *buf, size_t count)
676{
677 struct mma8x5x_data *pdata = dev_get_drvdata(dev);
678 int ret;
679 long position;
680 ret = strict_strtol(buf, 10, &position);
681 if (ret) {
682 dev_err(dev, "string to long error\n");
683 return ret;
684 }
685 mutex_lock(&pdata->data_lock);
686 pdata->position = (int)position;
687 mutex_unlock(&pdata->data_lock);
688 return count;
689}
690
691static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
692 mma8x5x_enable_show, mma8x5x_enable_store);
693static DEVICE_ATTR(poll_delay, S_IWUSR | S_IRUGO,
694 mma8x5x_delay_show, mma8x5x_delay_store);
695
696static DEVICE_ATTR(fifo, S_IWUSR | S_IRUGO,
697 mma8x5x_fifo_show, mma8x5x_fifo_store);
698static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
699 mma8x5x_position_show, mma8x5x_position_store);
700
701static struct attribute *mma8x5x_attributes[] = {
702 &dev_attr_enable.attr,
703 &dev_attr_poll_delay.attr,
704 &dev_attr_fifo.attr,
705 &dev_attr_position.attr,
706 NULL
707};
708
709static const struct attribute_group mma8x5x_attr_group = {
710 .attrs = mma8x5x_attributes,
711};
712static int mma8x5x_detect(struct i2c_client *client,
713 struct i2c_board_info *info)
714{
715 struct i2c_adapter *adapter = client->adapter;
716 int chip_id;
717
718 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
719 return -ENODEV;
720 chip_id = i2c_smbus_read_byte_data(client, MMA8X5X_WHO_AM_I);
721 if (!mma8x5x_check_id(chip_id))
722 return -ENODEV;
723 printk(KERN_INFO"check %s i2c address 0x%x\n",
724 mma8x5x_id2name(chip_id), client->addr);
725 strlcpy(info->type, "mma8x5x", I2C_NAME_SIZE);
726 return 0;
727}
728static int mma8x5x_open(struct inode *inode, struct file *file)
729{
730 int err;
731 err = nonseekable_open(inode, file);
732 if (err)
733 return err;
734 file->private_data = p_mma8x5x_data;
735 return 0;
736}
737static ssize_t mma8x5x_read(struct file *file,
738 char __user *buf,
739 size_t size, loff_t *ppos)
740{
741 struct mma8x5x_data *pdata = file->private_data;
742 int ret = 0;
743 if (!(file->f_flags & O_NONBLOCK)) {
744 ret = wait_event_interruptible(pdata->fifo_wq,
745 (atomic_read(&pdata->fifo_ready) != 0));
746 if (ret)
747 return ret;
748 }
749 if (!atomic_read(&pdata->fifo_ready))
750 return -ENODEV;
751 if (size < sizeof(struct mma8x5x_fifo)) {
752 printk(KERN_ERR"the buffer leght less than need\n");
753 return -ENOMEM;
754 }
755 if (!copy_to_user(buf, &pdata->fifo, sizeof(struct mma8x5x_fifo))) {
756 atomic_set(&pdata->fifo_ready, 0);
757 return size;
758 }
759 return -ENOMEM ;
760}
761static unsigned int mma8x5x_poll(struct file *file,
762 struct poll_table_struct *wait)
763{
764 struct mma8x5x_data *pdata = file->private_data;
765 poll_wait(file, &pdata->fifo_wq, wait);
766 if (atomic_read(&pdata->fifo_ready))
767 return POLLIN | POLLRDNORM;
768 return 0;
769}
770
771static const struct file_operations mma8x5x_fops = {
772 .owner = THIS_MODULE,
773 .open = mma8x5x_open,
774 .read = mma8x5x_read,
775 .poll = mma8x5x_poll,
776};
777
778static struct miscdevice mma8x5x_dev = {
779 .minor = MISC_DYNAMIC_MINOR,
780 .name = "mma8x5x",
781 .fops = &mma8x5x_fops,
782};
783
784static int mma8x5x_probe(struct i2c_client *client,
785 const struct i2c_device_id *id)
786{
787 int result, chip_id;
788 struct input_dev *idev;
789 struct mma8x5x_data *pdata;
790 struct i2c_adapter *adapter;
791 struct device_node *of_node = client->dev.of_node;
792 u32 pos = 0;
793 struct regulator *vdd, *vdd_io;
794 u32 irq_flag;
795 struct irq_data *irq_data;
796
797 vdd = devm_regulator_get(&client->dev, "vdd");
798 if (!IS_ERR(vdd)) {
799 result = regulator_enable(vdd);
800 if (result) {
801 dev_err(&client->dev, "vdd set voltage error\n");
802 return result;
803 }
804 }
805
806 vdd_io = devm_regulator_get(&client->dev, "vddio");
807 if (!IS_ERR(vdd_io)) {
808 result = regulator_enable(vdd_io);
809 if (result) {
810 dev_err(&client->dev, "vddio set voltage error\n");
811 return result;
812 }
813 }
814 adapter = to_i2c_adapter(client->dev.parent);
815 result = i2c_check_functionality(adapter,
816 I2C_FUNC_SMBUS_BYTE |
817 I2C_FUNC_SMBUS_BYTE_DATA);
818 if (!result)
819 goto err_out;
820
821 chip_id = i2c_smbus_read_byte_data(client, MMA8X5X_WHO_AM_I);
822
823 if (!mma8x5x_check_id(chip_id)) {
824 dev_err(&client->dev,
825 "read chip ID 0x%x is not equal to 0x%x,0x%x,0x%x,0x%x,0x%x!\n",
826 chip_id, MMA8451_ID, MMA8452_ID,
827 MMA8453_ID, MMA8652_ID, MMA8653_ID);
828 result = -EINVAL;
829 goto err_out;
830 }
831 pdata = kzalloc(sizeof(struct mma8x5x_data), GFP_KERNEL);
832 if (!pdata) {
833 result = -ENOMEM;
834 dev_err(&client->dev, "alloc data memory error!\n");
835 goto err_out;
836 }
837
838 /* Initialize the MMA8X5X chip */
839 memset(pdata, 0, sizeof(struct mma8x5x_data));
840 pdata->client = client;
841 pdata->chip_id = chip_id;
842 pdata->mode = MODE_2G;
843 pdata->fifo_wakeup = 0;
844 pdata->fifo_timeout = 0;
845
846 result = of_property_read_u32(of_node, "position", &pos);
847 if (result)
848 pos = 1;
849 pdata->position = (int)pos;
850 p_mma8x5x_data = pdata;
851 mutex_init(&pdata->data_lock);
852 i2c_set_clientdata(client, pdata);
853
854 mma8x5x_device_init(client);
855
856 idev = input_allocate_device();
857 if (!idev) {
858 result = -ENOMEM;
859 dev_err(&client->dev, "alloc input device failed!\n");
860 goto err_alloc_input_device;
861 }
862 idev->name = "FreescaleAccelerometer";
863 idev->uniq = mma8x5x_id2name(pdata->chip_id);
864 idev->id.bustype = BUS_I2C;
865 idev->evbit[0] = BIT_MASK(EV_ABS);
866 input_set_abs_params(idev, ABS_X, -0x7fff, 0x7fff, 0, 0);
867 input_set_abs_params(idev, ABS_Y, -0x7fff, 0x7fff, 0, 0);
868 input_set_abs_params(idev, ABS_Z, -0x7fff, 0x7fff, 0, 0);
869 dev_set_drvdata(&idev->dev, pdata);
870 pdata->idev = idev;
871 result = input_register_device(pdata->idev);
872 if (result) {
873 dev_err(&client->dev, "register input device failed!\n");
874 goto err_register_input_device;
875 }
876 pdata->delay = POLL_INTERVAL;
877 INIT_DELAYED_WORK(&pdata->work, mma8x5x_dev_poll);
878 result = sysfs_create_group(&idev->dev.kobj, &mma8x5x_attr_group);
879 if (result) {
880 dev_err(&client->dev, "create device file failed!\n");
881 result = -EINVAL;
882 goto err_create_sysfs;
883 }
884 init_waitqueue_head(&pdata->fifo_wq);
885
886 if (client->irq) {
887 irq_data = irq_get_irq_data(client->irq);
888 irq_flag = irqd_get_trigger_type(irq_data);
889 irq_flag |= IRQF_ONESHOT;
890 result = request_threaded_irq(client->irq, NULL,
891 mma8x5x_irq_handler,
892 irq_flag,
893 client->dev.driver->name,
894 pdata);
895 if (result < 0) {
896 dev_err(&client->dev,
897 "failed to register MMA8x5x irq %d!\n",
898 client->irq);
899 goto err_register_irq;
900 } else {
901 result = misc_register(&mma8x5x_dev);
902 if (result) {
903 dev_err(&client->dev,
904 "register fifo device error\n");
905 goto err_reigster_dev;
906 }
907 }
908
909 result = of_property_read_u32(of_node,
910 "interrupt-route",
911 &pdata->int_pin);
912 if (result) {
913 result = -EINVAL;
914 dev_err(&client->dev,
915 "Can't find interrupt-pin value\n");
916 goto err_reigster_dev;
917
918 }
919 if (pdata->int_pin == 0 || pdata->int_pin > 2) {
920 result = -EINVAL;
921 dev_err(&client->dev,
922 "The interrupt-pin value is invalid\n");
923 goto err_reigster_dev;
924 }
925 }
926 printk(KERN_INFO"mma8x5x device driver probe successfully\n");
927 return 0;
928err_reigster_dev:
929 free_irq(client->irq, pdata);
930err_register_irq:
931 sysfs_remove_group(&idev->dev.kobj, &mma8x5x_attr_group);
932err_create_sysfs:
933 input_unregister_device(pdata->idev);
934err_register_input_device:
935 input_free_device(idev);
936err_alloc_input_device:
937 kfree(pdata);
938err_out:
939 return result;
940}
941
942static int mma8x5x_remove(struct i2c_client *client)
943{
944 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
945 struct input_dev *idev = pdata->idev;
946 mma8x5x_device_stop(client);
947 if (pdata) {
948 sysfs_remove_group(&idev->dev.kobj, &mma8x5x_attr_group);
949 input_unregister_device(pdata->idev);
950 input_free_device(pdata->idev);
951 kfree(pdata);
952 }
953 return 0;
954}
955
956#ifdef CONFIG_PM_SLEEP
957static int mma8x5x_suspend(struct device *dev)
958{
959 struct i2c_client *client = to_i2c_client(dev);
960 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
961 if (pdata->fifo_timeout <= 0) {
962 if (pdata->active == MMA_ACTIVED)
963 mma8x5x_device_stop(client);
964 } else {
965 if (pdata->active == MMA_ACTIVED) {
966 if (pdata->fifo_wakeup) {
967 /*10s timeout , overwrite*/
968 mma8x5x_fifo_setting(pdata, 10000, 0);
969 mma8x5x_fifo_interrupt(client, 1);
970 } else {
971 mma8x5x_fifo_interrupt(client, 0);
972 /*10s timeout , overwrite*/
973 mma8x5x_fifo_setting(pdata, 10000, 1);
974 }
975 }
976 }
977 return 0;
978}
979
980static int mma8x5x_resume(struct device *dev)
981{
982 int val = 0;
983 struct i2c_client *client = to_i2c_client(dev);
984 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
985 if (pdata->fifo_timeout <= 0) {
986 if (pdata->active == MMA_ACTIVED) {
987 val = i2c_smbus_read_byte_data(client,
988 MMA8X5X_CTRL_REG1);
989 i2c_smbus_write_byte_data(client,
990 MMA8X5X_CTRL_REG1, val | 0x01);
991 }
992 } else {
993 if (pdata->active == MMA_ACTIVED) {
994 mma8x5x_fifo_interrupt(client, 1);
995 /*Awake from suspend*/
996 pdata->awaken = 1;
997 }
998 }
999 return 0;
1000
1001}
1002#endif
1003
1004static const struct i2c_device_id mma8x5x_id[] = {
1005 {"mma8451", 0},
1006 {"mma8452", 0},
1007 {"mma8453", 0},
1008 {"mma8652", 0},
1009 {"mma8653", 0},
1010 {}
1011};
1012
1013MODULE_DEVICE_TABLE(i2c, mma8x5x_id);
1014
1015static SIMPLE_DEV_PM_OPS(mma8x5x_pm_ops, mma8x5x_suspend, mma8x5x_resume);
1016static struct i2c_driver mma8x5x_driver = {
1017 .class = I2C_CLASS_HWMON,
1018 .driver = {
1019 .name = "mma8x5x",
1020 .owner = THIS_MODULE,
1021 .pm = &mma8x5x_pm_ops,
1022 },
1023 .probe = mma8x5x_probe,
1024 .remove = mma8x5x_remove,
1025 .id_table = mma8x5x_id,
1026 .detect = mma8x5x_detect,
1027 .address_list = normal_i2c,
1028};
1029
1030
1031module_i2c_driver(mma8x5x_driver);
1032
1033MODULE_AUTHOR("Freescale Semiconductor, Inc.");
1034MODULE_DESCRIPTION("MMA8X5X 3-Axis Orientation/Motion Detection Sensor driver");
1035MODULE_LICENSE("GPL");
1036