blob: 8a0d4ab9672ca6cb403d513b350a332511c65331 [file] [log] [blame]
Yan Zhang7d417c62013-02-01 11:15:51 +08001/*
2 * mma8x5x.c - Linux kernel modules for 3-Axis Orientation/Motion
3 * Detection Sensor MMA8451/MMA8452/MMA8453
4 *
5 * Copyright (C) 2010-2011 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/hwmon.h>
34#include <linux/input-polldev.h>
Richard Liu1d49d4a2013-04-14 17:01:26 -070035#include <linux/regulator/consumer.h>
Yan Zhang7d417c62013-02-01 11:15:51 +080036
37#define MMA8X5X_I2C_ADDR 0x1D
38#define MMA8451_ID 0x1A
39#define MMA8452_ID 0x2A
40#define MMA8453_ID 0x3A
41#define MMA8652_ID 0x4A
42#define MMA8653_ID 0x5A
43
44
45#define POLL_INTERVAL_MIN 1
46#define POLL_INTERVAL_MAX 500
47#define POLL_INTERVAL 100 /* msecs */
48
49/* if sensor is standby ,set POLL_STOP_TIME to slow down the poll */
50#define POLL_STOP_TIME 200
51#define INPUT_FUZZ 32
52#define INPUT_FLAT 32
53#define MODE_CHANGE_DELAY_MS 100
54
55#define MMA8X5X_STATUS_ZYXDR 0x08
56#define MMA8X5X_BUF_SIZE 7
Richard Liu1d49d4a2013-04-14 17:01:26 -070057
58struct sensor_regulator {
59 struct regulator *vreg;
60 const char *name;
61 u32 min_uV;
62 u32 max_uV;
63};
64
65static struct sensor_regulator mma_vreg[] = {
66 {NULL, "vdd", 2850000, 2850000},
67 {NULL, "vio", 1800000, 1800000},
68};
69
Yan Zhang7d417c62013-02-01 11:15:51 +080070/* register enum for mma8x5x registers */
71enum {
72 MMA8X5X_STATUS = 0x00,
73 MMA8X5X_OUT_X_MSB,
74 MMA8X5X_OUT_X_LSB,
75 MMA8X5X_OUT_Y_MSB,
76 MMA8X5X_OUT_Y_LSB,
77 MMA8X5X_OUT_Z_MSB,
78 MMA8X5X_OUT_Z_LSB,
79
80 MMA8X5X_F_SETUP = 0x09,
81 MMA8X5X_TRIG_CFG,
82 MMA8X5X_SYSMOD,
83 MMA8X5X_INT_SOURCE,
84 MMA8X5X_WHO_AM_I,
85 MMA8X5X_XYZ_DATA_CFG,
86 MMA8X5X_HP_FILTER_CUTOFF,
87
88 MMA8X5X_PL_STATUS,
89 MMA8X5X_PL_CFG,
90 MMA8X5X_PL_COUNT,
91 MMA8X5X_PL_BF_ZCOMP,
92 MMA8X5X_P_L_THS_REG,
93
94 MMA8X5X_FF_MT_CFG,
95 MMA8X5X_FF_MT_SRC,
96 MMA8X5X_FF_MT_THS,
97 MMA8X5X_FF_MT_COUNT,
98
99 MMA8X5X_TRANSIENT_CFG = 0x1D,
100 MMA8X5X_TRANSIENT_SRC,
101 MMA8X5X_TRANSIENT_THS,
102 MMA8X5X_TRANSIENT_COUNT,
103
104 MMA8X5X_PULSE_CFG,
105 MMA8X5X_PULSE_SRC,
106 MMA8X5X_PULSE_THSX,
107 MMA8X5X_PULSE_THSY,
108 MMA8X5X_PULSE_THSZ,
109 MMA8X5X_PULSE_TMLT,
110 MMA8X5X_PULSE_LTCY,
111 MMA8X5X_PULSE_WIND,
112
113 MMA8X5X_ASLP_COUNT,
114 MMA8X5X_CTRL_REG1,
115 MMA8X5X_CTRL_REG2,
116 MMA8X5X_CTRL_REG3,
117 MMA8X5X_CTRL_REG4,
118 MMA8X5X_CTRL_REG5,
119
120 MMA8X5X_OFF_X,
121 MMA8X5X_OFF_Y,
122 MMA8X5X_OFF_Z,
123
124 MMA8X5X_REG_END,
125};
126
127/* The sensitivity is represented in counts/g. In 2g mode the
128sensitivity is 1024 counts/g. In 4g mode the sensitivity is 512
129counts/g and in 8g mode the sensitivity is 256 counts/g.
130 */
131enum {
132 MODE_2G = 0,
133 MODE_4G,
134 MODE_8G,
135};
136
137enum {
138 MMA_STANDBY = 0,
139 MMA_ACTIVED,
140};
141struct mma8x5x_data_axis {
142 short x;
143 short y;
144 short z;
145};
146struct mma8x5x_data {
147 struct i2c_client *client;
148 struct input_polled_dev *poll_dev;
149 struct mutex data_lock;
150 int active;
151 int position;
152 u8 chip_id;
153 int mode;
154};
155/* Addresses scanned */
156static const unsigned short normal_i2c[] = {0x1c, 0x1d, I2C_CLIENT_END};
157
158static int mma8x5x_chip_id[] = {
159 MMA8451_ID,
160 MMA8452_ID,
161 MMA8453_ID,
162 MMA8652_ID,
163 MMA8653_ID,
164};
165static char *mma8x5x_names[] = {
166 "mma8451",
167 "mma8452",
168 "mma8453",
169 "mma8652",
170 "mma8653",
171};
172static int mma8x5x_position_setting[8][3][3] = {
173 {{ 0, -1, 0}, { 1, 0, 0}, {0, 0, 1} },
174 {{-1, 0, 0}, { 0, -1, 0}, {0, 0, 1} },
175 {{ 0, 1, 0}, {-1, 0, 0}, {0, 0, 1} },
176 {{ 1, 0, 0}, { 0, 1, 0}, {0, 0, 1} },
177 {{ 0, -1, 0}, {-1, 0, 0}, {0, 0, -1} },
178 {{-1, 0, 0}, { 0, 1, 0}, {0, 0, -1} },
179 {{ 0, 1, 0}, { 1, 0, 0}, {0, 0, -1} },
180 {{ 1, 0, 0}, { 0, -1, 0}, {0, 0, -1} },
181};
182
Richard Liu1d49d4a2013-04-14 17:01:26 -0700183static int mma8x5x_config_regulator(struct i2c_client *client, bool on)
184{
185 int rc = 0, i;
186 int num_vreg = sizeof(mma_vreg)/sizeof(struct sensor_regulator);
187
188 if (on) {
189 for (i = 0; i < num_vreg; i++) {
190 mma_vreg[i].vreg = regulator_get(&client->dev,
191 mma_vreg[i].name);
192 if (IS_ERR(mma_vreg[i].vreg)) {
193 rc = PTR_ERR(mma_vreg[i].vreg);
194 dev_err(&client->dev, "%s:regulator get failed rc=%d\n",
195 __func__, rc);
196 mma_vreg[i].vreg = NULL;
197 goto error_vdd;
198 }
199 if (regulator_count_voltages(mma_vreg[i].vreg) > 0) {
200 rc = regulator_set_voltage(mma_vreg[i].vreg,
201 mma_vreg[i].min_uV, mma_vreg[i].max_uV);
202 if (rc) {
203 dev_err(&client->dev, "%s:set_voltage failed rc=%d\n",
204 __func__, rc);
205 regulator_put(mma_vreg[i].vreg);
206 mma_vreg[i].vreg = NULL;
207 goto error_vdd;
208 }
209 }
210 rc = regulator_enable(mma_vreg[i].vreg);
211 if (rc) {
212 dev_err(&client->dev, "%s: regulator_enable failed rc =%d\n",
213 __func__, rc);
214 if (regulator_count_voltages(mma_vreg[i].vreg)
215 > 0) {
216 regulator_set_voltage(mma_vreg[i].vreg,
217 0, mma_vreg[i].max_uV);
218 }
219 regulator_put(mma_vreg[i].vreg);
220 mma_vreg[i].vreg = NULL;
221 goto error_vdd;
222 }
223 }
224 return rc;
225 } else {
226 i = num_vreg;
227 }
228error_vdd:
229 while (--i >= 0) {
230 if (!IS_ERR_OR_NULL(mma_vreg[i].vreg)) {
231 if (regulator_count_voltages(
232 mma_vreg[i].vreg) > 0) {
233 regulator_set_voltage(mma_vreg[i].vreg, 0,
234 mma_vreg[i].max_uV);
235 }
236 regulator_disable(mma_vreg[i].vreg);
237 regulator_put(mma_vreg[i].vreg);
238 mma_vreg[i].vreg = NULL;
239 }
240 }
241 return rc;
242}
243
Yan Zhang7d417c62013-02-01 11:15:51 +0800244static int mma8x5x_data_convert(struct mma8x5x_data *pdata,
245 struct mma8x5x_data_axis *axis_data)
246{
247 short rawdata[3], data[3];
248 int i, j;
249 int position = pdata->position ;
250 if (position < 0 || position > 7)
251 position = 0;
252 rawdata[0] = axis_data->x;
253 rawdata[1] = axis_data->y;
254 rawdata[2] = axis_data->z;
255 for (i = 0; i < 3 ; i++) {
256 data[i] = 0;
257 for (j = 0; j < 3; j++)
258 data[i] += rawdata[j] *
259 mma8x5x_position_setting[position][i][j];
260 }
261 axis_data->x = data[0];
262 axis_data->y = data[1];
263 axis_data->z = data[2];
264 return 0;
265}
266static int mma8x5x_check_id(int id)
267{
268 int i = 0;
269 for (i = 0; i < sizeof(mma8x5x_chip_id)/sizeof(mma8x5x_chip_id[0]);
270 i++)
271 if (id == mma8x5x_chip_id[i])
272 return 1;
273 return 0;
274}
275static char *mma8x5x_id2name(u8 id)
276{
277 return mma8x5x_names[(id >> 4)-1];
278}
279static int mma8x5x_device_init(struct i2c_client *client)
280{
281 int result;
282 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
283 result = i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, 0);
284 if (result < 0)
285 goto out;
286
287 result = i2c_smbus_write_byte_data(client, MMA8X5X_XYZ_DATA_CFG,
288 pdata->mode);
289 if (result < 0)
290 goto out;
291 pdata->active = MMA_STANDBY;
292 msleep(MODE_CHANGE_DELAY_MS);
293 return 0;
294out:
295 dev_err(&client->dev, "error when init mma8x5x:(%d)", result);
296 return result;
297}
298static int mma8x5x_device_stop(struct i2c_client *client)
299{
300 u8 val;
301 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
302 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val & 0xfe);
303 return 0;
304}
305
306static int mma8x5x_read_data(struct i2c_client *client,
307 struct mma8x5x_data_axis *data)
308{
309 u8 tmp_data[MMA8X5X_BUF_SIZE];
310 int ret;
311
312 ret = i2c_smbus_read_i2c_block_data(client,
313 MMA8X5X_OUT_X_MSB, 7, tmp_data);
314 if (ret < MMA8X5X_BUF_SIZE) {
315 dev_err(&client->dev, "i2c block read failed\n");
316 return -EIO;
317 }
318 data->x = ((tmp_data[0] << 8) & 0xff00) | tmp_data[1];
319 data->y = ((tmp_data[2] << 8) & 0xff00) | tmp_data[3];
320 data->z = ((tmp_data[4] << 8) & 0xff00) | tmp_data[5];
321 return 0;
322}
323
324static void mma8x5x_report_data(struct mma8x5x_data *pdata)
325{
326 struct input_polled_dev *poll_dev = pdata->poll_dev;
327 struct mma8x5x_data_axis data;
328 mutex_lock(&pdata->data_lock);
329 if (pdata->active == MMA_STANDBY) {
330 poll_dev->poll_interval = POLL_STOP_TIME;
331 /* if standby ,set as 10s to slow the poll. */
332 goto out;
333 } else {
334 if (poll_dev->poll_interval == POLL_STOP_TIME)
335 poll_dev->poll_interval = POLL_INTERVAL;
336 }
337 if (mma8x5x_read_data(pdata->client, &data) != 0)
338 goto out;
339 mma8x5x_data_convert(pdata, &data);
340 input_report_abs(poll_dev->input, ABS_X, data.x);
341 input_report_abs(poll_dev->input, ABS_Y, data.y);
342 input_report_abs(poll_dev->input, ABS_Z, data.z);
343 input_sync(poll_dev->input);
344out:
345 mutex_unlock(&pdata->data_lock);
346}
347
348static void mma8x5x_dev_poll(struct input_polled_dev *dev)
349{
350 struct mma8x5x_data *pdata = (struct mma8x5x_data *)dev->private;
351 mma8x5x_report_data(pdata);
352}
353
354static ssize_t mma8x5x_enable_show(struct device *dev,
355 struct device_attribute *attr, char *buf)
356{
357 struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
358 struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
359 struct i2c_client *client = pdata->client;
360 u8 val;
361 int enable;
362
363 mutex_lock(&pdata->data_lock);
364 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
365 if ((val & 0x01) && pdata->active == MMA_ACTIVED)
366 enable = 1;
367 else
368 enable = 0;
369 mutex_unlock(&pdata->data_lock);
370 return snprintf(buf, PAGE_SIZE, "%d\n", enable);
371}
372
373static ssize_t mma8x5x_enable_store(struct device *dev,
374 struct device_attribute *attr,
375 const char *buf, size_t count)
376{
377 struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
378 struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
379 struct i2c_client *client = pdata->client;
380 int ret;
381 unsigned long enable;
382 u8 val = 0;
383 ret = kstrtoul(buf, 10, &enable);
384 if (ret)
385 return ret;
386 mutex_lock(&pdata->data_lock);
387 enable = (enable > 0) ? 1 : 0;
388 if (enable && pdata->active == MMA_STANDBY) {
389 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
390 ret = i2c_smbus_write_byte_data(client,
391 MMA8X5X_CTRL_REG1, val|0x01);
392 if (!ret) {
393 pdata->active = MMA_ACTIVED;
394 printk(KERN_INFO "mma enable setting active\n");
395 }
396 } else if (enable == 0 && pdata->active == MMA_ACTIVED) {
397 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
398 ret = i2c_smbus_write_byte_data(client,
399 MMA8X5X_CTRL_REG1, val & 0xFE);
400 if (!ret) {
401 pdata->active = MMA_STANDBY;
402 printk(KERN_INFO "mma enable setting inactive\n");
403 }
404 }
405 mutex_unlock(&pdata->data_lock);
406 return count;
407}
408static ssize_t mma8x5x_position_show(struct device *dev,
409 struct device_attribute *attr, char *buf)
410{
411 struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
412 struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
413 int position = 0;
414 mutex_lock(&pdata->data_lock);
415 position = pdata->position ;
416 mutex_unlock(&pdata->data_lock);
417 return snprintf(buf, PAGE_SIZE, "%d\n", position);
418}
419
420static ssize_t mma8x5x_position_store(struct device *dev,
421 struct device_attribute *attr,
422 const char *buf, size_t count)
423{
424 struct input_polled_dev *poll_dev = dev_get_drvdata(dev);
425 struct mma8x5x_data *pdata = (struct mma8x5x_data *)(poll_dev->private);
426 int position;
427 int ret;
428 ret = kstrtoint(buf, 10, &position);
429 if (ret)
430 return ret;
431 mutex_lock(&pdata->data_lock);
432 pdata->position = position;
433 mutex_unlock(&pdata->data_lock);
434 return count;
435}
436
437static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
438 mma8x5x_enable_show, mma8x5x_enable_store);
439static DEVICE_ATTR(position, S_IWUSR | S_IRUGO,
440 mma8x5x_position_show, mma8x5x_position_store);
441
442static struct attribute *mma8x5x_attributes[] = {
443 &dev_attr_enable.attr,
444 &dev_attr_position.attr,
445 NULL
446};
447
448static const struct attribute_group mma8x5x_attr_group = {
449 .attrs = mma8x5x_attributes,
450};
451static int mma8x5x_detect(struct i2c_client *client,
452 struct i2c_board_info *info)
453{
454 struct i2c_adapter *adapter = client->adapter;
455 int chip_id;
456 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA))
457 return -ENODEV;
458 chip_id = i2c_smbus_read_byte_data(client, MMA8X5X_WHO_AM_I);
459 if (!mma8x5x_check_id(chip_id))
460 return -ENODEV;
461 printk(KERN_INFO "check %s i2c address 0x%x\n",
462 mma8x5x_id2name(chip_id), client->addr);
463 strlcpy(info->type, "mma8x5x", I2C_NAME_SIZE);
464 return 0;
465}
466static int __devinit mma8x5x_probe(struct i2c_client *client,
467 const struct i2c_device_id *id)
468{
469 int result, chip_id;
470 struct input_dev *idev;
471 struct mma8x5x_data *pdata;
472 struct i2c_adapter *adapter;
473 struct input_polled_dev *poll_dev;
474 adapter = to_i2c_adapter(client->dev.parent);
Richard Liu1d49d4a2013-04-14 17:01:26 -0700475 /* power on the device */
476 result = mma8x5x_config_regulator(client, 1);
477 if (result)
478 goto err_power_on;
479
Yan Zhang7d417c62013-02-01 11:15:51 +0800480 result = i2c_check_functionality(adapter,
481 I2C_FUNC_SMBUS_BYTE |
482 I2C_FUNC_SMBUS_BYTE_DATA);
483 if (!result)
484 goto err_out;
485
486 chip_id = i2c_smbus_read_byte_data(client, MMA8X5X_WHO_AM_I);
487
488 if (!mma8x5x_check_id(chip_id)) {
489 dev_err(&client->dev,
490 "read chip ID 0x%x is not equal to 0x%x,0x%x,0x%x,0x%x,0x%x!\n",
491 chip_id, MMA8451_ID, MMA8452_ID, MMA8453_ID,
492 MMA8652_ID, MMA8653_ID);
493 result = -EINVAL;
494 goto err_out;
495 }
Richard Liu1d49d4a2013-04-14 17:01:26 -0700496 /* set the private data */
Yan Zhang7d417c62013-02-01 11:15:51 +0800497 pdata = kzalloc(sizeof(struct mma8x5x_data), GFP_KERNEL);
498 if (!pdata) {
499 result = -ENOMEM;
500 dev_err(&client->dev, "alloc data memory error!\n");
501 goto err_out;
502 }
503 /* Initialize the MMA8X5X chip */
504 pdata->client = client;
505 pdata->chip_id = chip_id;
506 pdata->mode = MODE_2G;
507 pdata->position = CONFIG_SENSORS_MMA_POSITION;
508 mutex_init(&pdata->data_lock);
509 i2c_set_clientdata(client, pdata);
Richard Liu1d49d4a2013-04-14 17:01:26 -0700510 /* Initialize the MMA8X5X chip */
Yan Zhang7d417c62013-02-01 11:15:51 +0800511 mma8x5x_device_init(client);
Richard Liu1d49d4a2013-04-14 17:01:26 -0700512 /* create the input poll device */
Yan Zhang7d417c62013-02-01 11:15:51 +0800513 poll_dev = input_allocate_polled_device();
514 if (!poll_dev) {
515 result = -ENOMEM;
516 dev_err(&client->dev, "alloc poll device failed!\n");
517 goto err_alloc_poll_device;
518 }
519 poll_dev->poll = mma8x5x_dev_poll;
520 poll_dev->poll_interval = POLL_STOP_TIME;
521 poll_dev->poll_interval_min = POLL_INTERVAL_MIN;
522 poll_dev->poll_interval_max = POLL_INTERVAL_MAX;
523 poll_dev->private = pdata;
524 idev = poll_dev->input;
525 idev->name = "accelerometer";
526 idev->uniq = mma8x5x_id2name(pdata->chip_id);
527 idev->id.bustype = BUS_I2C;
528 idev->evbit[0] = BIT_MASK(EV_ABS);
529 input_set_abs_params(idev, ABS_X, -0x7fff, 0x7fff, 0, 0);
530 input_set_abs_params(idev, ABS_Y, -0x7fff, 0x7fff, 0, 0);
531 input_set_abs_params(idev, ABS_Z, -0x7fff, 0x7fff, 0, 0);
532 pdata->poll_dev = poll_dev;
533 result = input_register_polled_device(pdata->poll_dev);
534 if (result) {
535 dev_err(&client->dev, "register poll device failed!\n");
536 goto err_register_polled_device;
537 }
538 result = sysfs_create_group(&idev->dev.kobj, &mma8x5x_attr_group);
539 if (result) {
540 dev_err(&client->dev, "create device file failed!\n");
541 result = -EINVAL;
542 goto err_create_sysfs;
543 }
544 printk(KERN_INFO "mma8x5x device driver probe successfully\n");
545 return 0;
546err_create_sysfs:
547 input_unregister_polled_device(pdata->poll_dev);
548err_register_polled_device:
549 input_free_polled_device(poll_dev);
550err_alloc_poll_device:
551 kfree(pdata);
552err_out:
Richard Liu1d49d4a2013-04-14 17:01:26 -0700553 mma8x5x_config_regulator(client, 0);
554err_power_on:
Yan Zhang7d417c62013-02-01 11:15:51 +0800555 return result;
556}
557static int __devexit mma8x5x_remove(struct i2c_client *client)
558{
559 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
Richard Liu1d49d4a2013-04-14 17:01:26 -0700560 struct input_polled_dev *poll_dev;
Yan Zhang7d417c62013-02-01 11:15:51 +0800561 mma8x5x_device_stop(client);
562 if (pdata) {
Richard Liu1d49d4a2013-04-14 17:01:26 -0700563 poll_dev = pdata->poll_dev;
Yan Zhang7d417c62013-02-01 11:15:51 +0800564 input_unregister_polled_device(poll_dev);
565 input_free_polled_device(poll_dev);
566 kfree(pdata);
567 }
568 return 0;
569}
570
571#ifdef CONFIG_PM_SLEEP
572static int mma8x5x_suspend(struct device *dev)
573{
574 struct i2c_client *client = to_i2c_client(dev);
575 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
576 if (pdata->active == MMA_ACTIVED)
577 mma8x5x_device_stop(client);
578 return 0;
579}
580
581static int mma8x5x_resume(struct device *dev)
582{
583 int val = 0;
584 struct i2c_client *client = to_i2c_client(dev);
585 struct mma8x5x_data *pdata = i2c_get_clientdata(client);
586 if (pdata->active == MMA_ACTIVED) {
587 val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
588 i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val|0x01);
589 }
590 return 0;
591
592}
593#endif
594
595static const struct i2c_device_id mma8x5x_id[] = {
596 {"mma8x5x", 0},
597 { }
598};
599MODULE_DEVICE_TABLE(i2c, mma8x5x_id);
600
Richard Liu1d49d4a2013-04-14 17:01:26 -0700601static const struct of_device_id mma8x5x_of_match[] = {
602 { .compatible = "fsl,mma8x5x", },
603 { },
604};
605
Yan Zhang7d417c62013-02-01 11:15:51 +0800606static SIMPLE_DEV_PM_OPS(mma8x5x_pm_ops, mma8x5x_suspend, mma8x5x_resume);
607static struct i2c_driver mma8x5x_driver = {
608 .class = I2C_CLASS_HWMON,
609 .driver = {
Richard Liu1d49d4a2013-04-14 17:01:26 -0700610 .name = "mma8x5x",
611 .owner = THIS_MODULE,
612 .pm = &mma8x5x_pm_ops,
613 .of_match_table = mma8x5x_of_match,
614 },
Yan Zhang7d417c62013-02-01 11:15:51 +0800615 .probe = mma8x5x_probe,
616 .remove = __devexit_p(mma8x5x_remove),
617 .id_table = mma8x5x_id,
618 .detect = mma8x5x_detect,
619 .address_list = normal_i2c,
620};
621
622static int __init mma8x5x_init(void)
623{
624 /* register driver */
625 int res;
626
627 res = i2c_add_driver(&mma8x5x_driver);
628 if (res < 0) {
629 printk(KERN_INFO "add mma8x5x i2c driver failed\n");
630 return -ENODEV;
631 }
632 return res;
633}
634
635static void __exit mma8x5x_exit(void)
636{
637 i2c_del_driver(&mma8x5x_driver);
638}
639
640MODULE_AUTHOR("Freescale Semiconductor, Inc.");
641MODULE_DESCRIPTION("MMA8X5X 3-Axis Orientation/Motion Detection Sensor driver");
642MODULE_LICENSE("GPL");
643
644module_init(mma8x5x_init);
645module_exit(mma8x5x_exit);