1 /* For RockChip android platform.
2 *
3 * mir3da.c - Linux kernel modules for 3-Axis Accelerometer
4 *
5 * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18 #include <linux/interrupt.h>
19 #include <linux/i2c.h>
20 #include <linux/slab.h>
21 #include <linux/irq.h>
22 #include <linux/miscdevice.h>
23 #include <linux/gpio.h>
24 #include <linux/uaccess.h>
25 #include <asm/atomic.h>
26 #include <linux/delay.h>
27 #include <linux/input.h>
28 #include <linux/workqueue.h>
29 #include <linux/freezer.h>
30 #ifdef CONFIG_HAS_EARLYSUSPEND
31 #include <linux/earlysuspend.h>
32 #endif
33 #include <linux/sensor-dev.h>
34 #include <linux/syscalls.h>
35 #include <linux/fs.h>
36
37 #include "da223_core.h"
38 #include "da223_cust.h"
39 /******************************************************************************/
40 #define GSENSOR_MIN 2
41 #define MIR3DA_PRECISION 11
42 #define MIR3DA_RANGE 16384
43 #define DA311_BOUNDARY (0x1 << (MIR3DA_PRECISION - 1))
44 #define DA311_GRAVITY_STEP (MIR3DA_RANGE/DA311_BOUNDARY)
45 /******************************************************************************/
46 #define MIR3DA_DRV_NAME "mir3da"
47 #define MIR3DA_INPUT_DEV_NAME MIR3DA_DRV_NAME
48 /******************************************************************************/
49 static MIR_HANDLE mir_handle;
50 static int is_init =0;
51 /******************************************************************************/
52 #define MI_DATA(format, ...) if(DEBUG_DATA&mir3da_Log_level){printk(KERN_ERR MI_TAG format "\n", ## __VA_ARGS__);}
53 #define MI_MSG(format, ...) if(DEBUG_MSG&mir3da_Log_level){printk(KERN_ERR MI_TAG format "\n", ## __VA_ARGS__);}
54 #define MI_ERR(format, ...) if(DEBUG_ERR&mir3da_Log_level){printk(KERN_ERR MI_TAG format "\n", ## __VA_ARGS__);}
55 #define MI_FUN if(DEBUG_FUNC&mir3da_Log_level){printk(KERN_ERR MI_TAG "%s is called, line: %d\n", __FUNCTION__,__LINE__);}
56 #define MI_ASSERT(expr) \
57 if (!(expr)) {\
58 printk(KERN_ERR "Assertion failed! %s,%d,%s,%s\n",\
59 __FILE__, __LINE__, __func__, #expr);\
60 }
61 /******************************************************************************/
62 #if MIR3DA_OFFSET_TEMP_SOLUTION
63 static char OffsetFileName[] = "/data/misc/miraGSensorOffset.txt";
64 static char OffsetFolerName[] = "/data/misc/";
65 #define OFFSET_STRING_LEN 26
66 struct work_info
67 {
68 char tst1[20];
69 char tst2[20];
70 char buffer[OFFSET_STRING_LEN];
71 struct workqueue_struct *wq;
72 struct delayed_work read_work;
73 struct delayed_work write_work;
74 struct completion completion;
75 int len;
76 int rst;
77 };
78
79 static struct work_info m_work_info = {{0}};
80 /******************************************************************************/
sensor_write_work(struct work_struct * work)81 static void sensor_write_work( struct work_struct *work )
82 {
83 struct work_info* pWorkInfo;
84 struct file *filep;
85 mm_segment_t orgfs;
86 int ret;
87
88 orgfs = get_fs();
89 set_fs(KERNEL_DS);
90
91 pWorkInfo = container_of((struct delayed_work*)work, struct work_info, write_work);
92 if (pWorkInfo == NULL){
93 MI_ERR("get pWorkInfo failed!");
94 return;
95 }
96
97 filep = filp_open(OffsetFileName, O_RDWR|O_CREAT, 0600);
98 if (IS_ERR(filep)){
99 MI_ERR("write, sys_open %s error!!.\n", OffsetFileName);
100 ret = -1;
101 }
102 else
103 {
104 filep->f_op->write(filep, pWorkInfo->buffer, pWorkInfo->len, &filep->f_pos);
105 filp_close(filep, NULL);
106 ret = 0;
107
108 set_fs(orgfs);
109 pWorkInfo->rst = ret;
110 complete( &pWorkInfo->completion );
111 }
112 /******************************************************************************/
113 static void sensor_read_work( struct work_struct *work )
114 {
115 mm_segment_t orgfs;
116 struct file *filep;
117 int ret;
118 struct work_info* pWorkInfo;
119
120 orgfs = get_fs();
121 set_fs(KERNEL_DS);
122
123 pWorkInfo = container_of((struct delayed_work*)work, struct work_info, read_work);
124 if (pWorkInfo == NULL){
125 MI_ERR("get pWorkInfo failed!");
126 return;
127 }
128
129 filep = filp_open(OffsetFileName, O_RDONLY, 0600);
130 if (IS_ERR(filep)){
131 MI_ERR("read, sys_open %s error!!.\n",OffsetFileName);
132 set_fs(orgfs);
133 ret = -1;
134 }
135 else{
136 filep->f_op->read(filep, pWorkInfo->buffer, sizeof(pWorkInfo->buffer), &filep->f_pos);
137 filp_close(filep, NULL);
138 set_fs(orgfs);
139 ret = 0;
140 }
141
142 pWorkInfo->rst = ret;
143 complete( &(pWorkInfo->completion) );
144 }
145 /******************************************************************************/
146 static int sensor_sync_read(u8* offset)
147 {
148 int err;
149 int off[MIR3DA_OFFSET_LEN] = {0};
150 struct work_info* pWorkInfo = &m_work_info;
151
152 init_completion( &pWorkInfo->completion );
153 queue_delayed_work( pWorkInfo->wq, &pWorkInfo->read_work, msecs_to_jiffies(0) );
154 err = wait_for_completion_timeout( &pWorkInfo->completion, msecs_to_jiffies( 2000 ) );
155 if ( err == 0 ){
156 MI_ERR("wait_for_completion_timeout TIMEOUT");
157 return -1;
158 }
159
160 if (pWorkInfo->rst != 0){
161 MI_ERR("work_info.rst not equal 0");
162 return pWorkInfo->rst;
163 }
164
165 sscanf(m_work_info.buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%x", &off[0], &off[1], &off[2], &off[3], &off[4], &off[5],&off[6], &off[7], &off[8]);
166
167 offset[0] = (u8)off[0];
168 offset[1] = (u8)off[1];
169 offset[2] = (u8)off[2];
170 offset[3] = (u8)off[3];
171 offset[4] = (u8)off[4];
172 offset[5] = (u8)off[5];
173 offset[6] = (u8)off[6];
174 offset[7] = (u8)off[7];
175 offset[8] = (u8)off[8];
176
177 return 0;
178 }
179 /******************************************************************************/
180 static int sensor_sync_write(u8* off)
181 {
182 int err = 0;
183 struct work_info* pWorkInfo = &m_work_info;
184
185 init_completion( &pWorkInfo->completion );
186
187 sprintf(m_work_info.buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%x\n", off[0],off[1],off[2],off[3],off[4],off[5],off[6],off[7],off[8]);
188
189 pWorkInfo->len = sizeof(m_work_info.buffer);
190
191 queue_delayed_work( pWorkInfo->wq, &pWorkInfo->write_work, msecs_to_jiffies(0) );
192 err = wait_for_completion_timeout( &pWorkInfo->completion, msecs_to_jiffies( 2000 ) );
193 if ( err == 0 ){
194 MI_ERR("wait_for_completion_timeout TIMEOUT");
195 return -1;
196 }
197
198 if (pWorkInfo->rst != 0){
199 MI_ERR("work_info.rst not equal 0");
200 return pWorkInfo->rst;
201 }
202
203 return 0;
204 }
205 /******************************************************************************/
206 static int check_califolder_exist(void)
207 {
208 mm_segment_t orgfs;
209 struct file *filep;
210
211 orgfs = get_fs();
212 set_fs(KERNEL_DS);
213
214 filep = filp_open(OffsetFolerName, O_RDONLY, 0600);
215 if (IS_ERR(filep)) {
216 MI_ERR("%s read, sys_open %s error!!.\n",__func__,OffsetFolerName);
217 set_fs(orgfs);
218 return 0;
219 }
220
221 filp_close(filep, NULL);
222 set_fs(orgfs);
223
224 return 1;
225 }
226 /******************************************************************************/
227 static int support_fast_auto_cali(void)
228 {
229 #if MIR3DA_SUPPORT_FAST_AUTO_CALI
230 return 1;
231 #else
232 return 0;
233 #endif
234 }
235 #endif
236 /******************************************************************************/
237 static int get_address(PLAT_HANDLE handle)
238 {
239 if(NULL == handle){
240 MI_ERR("chip init failed !\n");
241 return -1;
242 }
243
244 return ((struct i2c_client *)handle)->addr;
245 }
246 /******************************************************************************/
247 static int i2c_smbus_read(PLAT_HANDLE handle, u8 addr, u8 *data)
248 {
249 int res = 0;
250 struct i2c_client *client = (struct i2c_client*)handle;
251
252 *data = i2c_smbus_read_byte_data(client, addr);
253
254 return res;
255 }
256 /******************************************************************************/
257 static int i2c_smbus_read_block(PLAT_HANDLE handle, u8 addr, u8 count, u8 *data)
258 {
259 int res = 0;
260 struct i2c_client *client = (struct i2c_client*)handle;
261
262 res = i2c_smbus_read_i2c_block_data(client, addr, count, data);
263
264 return res;
265 }
266 /******************************************************************************/
267 static int i2c_smbus_write(PLAT_HANDLE handle, u8 addr, u8 data)
268 {
269 int res = 0;
270 struct i2c_client *client = (struct i2c_client*)handle;
271
272 res = i2c_smbus_write_byte_data(client, addr, data);
273
274 return res;
275 }
276 /******************************************************************************/
277 static void msdelay(int ms)
278 {
279 mdelay(ms);
280 }
281 /******************************************************************************/
282
283 #if MIR3DA_OFFSET_TEMP_SOLUTION
284 static MIR_GENERAL_OPS_DECLARE(ops_handle, i2c_smbus_read, i2c_smbus_read_block, i2c_smbus_write, sensor_sync_write, sensor_sync_read, check_califolder_exist,get_address,support_fast_auto_cali,msdelay, printk, sprintf);
285 #else
286 static MIR_GENERAL_OPS_DECLARE(ops_handle, i2c_smbus_read, i2c_smbus_read_block, i2c_smbus_write, NULL, NULL, NULL,get_address,NULL,msdelay, printk, sprintf);
287 #endif
288
289 /******************************************************************************/
290 static ssize_t enable_show(struct device *dev,
291 struct device_attribute *attr, char *buf)
292 {
293 int ret;
294 char bEnable;
295
296 MI_FUN;
297
298 ret = mir3da_get_enable(mir_handle, &bEnable);
299 if (ret < 0){
300 ret = -EINVAL;
301 }
302 else{
303 ret = sprintf(buf, "%d\n", bEnable);
304 }
305
306 return ret;
307 }
308 /******************************************************************************/
309 static ssize_t enable_store(struct device *dev,
310 struct device_attribute *attr,
311 const char *buf, size_t count)
312 {
313 int ret;
314 bool bEnable;
315 unsigned long enable;
316
317 if (buf == NULL){
318 return -1;
319 }
320
321 enable = simple_strtoul(buf, NULL, 10);
322 bEnable = (enable > 0) ? true : false;
323
324 MI_MSG("%s:enable=%d\n",__func__,bEnable);
325
326 ret = mir3da_set_enable (mir_handle, bEnable);
327 if (ret < 0){
328 ret = -EINVAL;
329 }
330 else{
331 ret = count;
332 }
333
334 return ret;
335 }
336 /******************************************************************************/
337 static ssize_t axis_data_show(struct device *dev,
338 struct device_attribute *attr, char *buf)
339 {
340 int result;
341 short x,y,z;
342 int count = 0;
343
344 result = mir3da_read_data(mir_handle, &x, &y, &z);
345 if (result == 0)
346 count += sprintf(buf+count, "x= %d;y=%d;z=%d\n", x,y,z);
347 else
348 count += sprintf(buf+count, "reading failed!");
349
350 return count;
351 }
352 /******************************************************************************/
353 static ssize_t reg_data_store(struct device *dev,
354 struct device_attribute *attr, const char *buf, size_t count)
355 {
356 int addr, data;
357 int result;
358
359 sscanf(buf, "0x%x, 0x%x\n", &addr, &data);
360
361 result = mir3da_register_write(mir_handle, addr, data);
362
363 MI_ASSERT(result==0);
364
365 return count;
366 }
367 /******************************************************************************/
368 static ssize_t reg_data_show(struct device *dev,
369 struct device_attribute *attr, char *buf)
370 {
371 MIR_HANDLE handle = mir_handle;
372
373 return mir3da_get_reg_data(handle, buf);
374 }
375 /******************************************************************************/
376
377 #if MIR3DA_OFFSET_TEMP_SOLUTION
378 static ssize_t offset_show(struct device *dev, struct device_attribute *attr, char *buf)
379 {
380 ssize_t count = 0;
381
382 if(bLoad==FILE_EXIST)
383 count += sprintf(buf,"%s",m_work_info.buffer);
384 else
385 count += sprintf(buf,"%s","Calibration file not exist!\n");
386
387 return count;
388 }
389 #endif
390 /******************************************************************************/
391 #if FILTER_AVERAGE_ENHANCE
392 static ssize_t average_enhance_show(struct device *dev,
393 struct device_attribute *attr, char *buf)
394 {
395 int ret = 0;
396 struct mir3da_filter_param_s param = {0};
397
398 ret = mir3da_get_filter_param(¶m);
399 ret |= sprintf(buf, "%d %d %d\n", param.filter_param_l, param.filter_param_h, param.filter_threhold);
400
401 return ret;
402 }
403 /******************************************************************************/
404 static ssize_t average_enhance_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
405 {
406 int ret = 0;
407 struct mir3da_filter_param_s param = {0};
408
409 sscanf(buf, "%d %d %d\n", ¶m.filter_param_l, ¶m.filter_param_h, ¶m.filter_threhold);
410
411 ret = mir3da_set_filter_param(¶m);
412
413 return count;
414 }
415 #endif
416 /******************************************************************************/
417 #if MIR3DA_OFFSET_TEMP_SOLUTION
418 static int bCaliResult = -1;
419 static ssize_t calibrate_miraGSensor_show(struct device *dev,struct device_attribute *attr,char *buf)
420 {
421 int ret;
422
423 ret = sprintf(buf, "%d\n", bCaliResult);
424 return ret;
425 }
426 /******************************************************************************/
427 static ssize_t calibrate_miraGSensor_store(struct device *dev,
428 struct device_attribute *attr,
429 const char *buf, size_t count)
430 {
431 s8 z_dir = 0;
432 MIR_HANDLE handle = mir_handle;
433
434 z_dir = simple_strtol(buf, NULL, 10);
435 bCaliResult = mir3da_calibrate(handle,z_dir);
436
437 return count;
438 }
439 #endif
440 /******************************************************************************/
441 static ssize_t log_level_show(struct device *dev,
442 struct device_attribute *attr, char *buf)
443 {
444 int ret;
445
446 ret = sprintf(buf, "%d\n", mir3da_Log_level);
447
448 return ret;
449 }
450 /******************************************************************************/
451 static ssize_t log_level_store(struct device *dev,
452 struct device_attribute *attr,
453 const char *buf, size_t count)
454 {
455 mir3da_Log_level = simple_strtoul(buf, NULL, 10);
456
457 return count;
458 }
459 /******************************************************************************/
460 static ssize_t primary_offset_show(struct device *dev,
461 struct device_attribute *attr, char *buf){
462 MIR_HANDLE handle = mir_handle;
463 int x=0,y=0,z=0;
464
465 mir3da_get_primary_offset(handle,&x,&y,&z);
466
467 return sprintf(buf, "x=%d ,y=%d ,z=%d\n",x,y,z);
468 }
469 /******************************************************************************/
470 static ssize_t version_show(struct device *dev,
471 struct device_attribute *attr, char *buf){
472
473 return sprintf(buf, "%s_%s\n", DRI_VER, CORE_VER);
474 }
475 /******************************************************************************/
476 static ssize_t vendor_show(struct device *dev,
477 struct device_attribute *attr, char *buf){
478 return sprintf(buf, "%s\n", "MiraMEMS");
479 }
480 /******************************************************************************/
481 static DEVICE_ATTR_RW(enable);
482 static DEVICE_ATTR_RO(axis_data);
483 static DEVICE_ATTR_RW(reg_data);
484 static DEVICE_ATTR_RW(log_level);
485 #if MIR3DA_OFFSET_TEMP_SOLUTION
486 static DEVICE_ATTR_RO(offset);
487 static DEVICE_ATTR_RW(calibrate_miraGSensor);
488 #endif
489 #if FILTER_AVERAGE_ENHANCE
490 static DEVICE_ATTR_RW(average_enhance);
491 #endif
492 static DEVICE_ATTR_RO(primary_offset);
493 static DEVICE_ATTR_RO(version);
494 static DEVICE_ATTR_RO(vendor);
495
496 /******************************************************************************/
497 static struct attribute *mir3da_attributes[] = {
498 &dev_attr_enable.attr,
499 &dev_attr_axis_data.attr,
500 &dev_attr_reg_data.attr,
501 &dev_attr_log_level.attr,
502 #if MIR3DA_OFFSET_TEMP_SOLUTION
503 &dev_attr_offset.attr,
504 &dev_attr_calibrate_miraGSensor.attr,
505 #endif
506 #if FILTER_AVERAGE_ENHANCE
507 &dev_attr_average_enhance.attr,
508 #endif
509 &dev_attr_primary_offset.attr,
510 &dev_attr_version.attr,
511 &dev_attr_vendor.attr,
512 NULL
513 };
514
515 static const struct attribute_group mir3da_attr_group = {
516 .attrs = mir3da_attributes,
517 };
518 /******************************************************************************/
519 static int sensor_init(struct i2c_client *client)
520 {
521 int ret = 0;
522 static int withSysAttr = 1;
523 unsigned char chip_id=0;
524 unsigned char i=0;
525
526 struct sensor_private_data *sensor =(struct sensor_private_data *) i2c_get_clientdata(client);
527
528 MI_FUN;
529
530 if(is_init)
531 return 0;
532
533 sensor->status_cur = SENSOR_OFF;
534
535 if(mir3da_install_general_ops(&ops_handle)){
536 MI_ERR("Install ops failed !\n");
537 return -1;
538 }
539
540 #if MIR3DA_OFFSET_TEMP_SOLUTION
541 m_work_info.wq = create_singlethread_workqueue( "oo" );
542 if(NULL==m_work_info.wq) {
543 MI_ERR("Failed to create workqueue !");
544 return -1;
545 }
546
547 INIT_DELAYED_WORK( &m_work_info.read_work, sensor_read_work );
548 INIT_DELAYED_WORK( &m_work_info.write_work, sensor_write_work );
549 #endif
550 i2c_smbus_read((PLAT_HANDLE) client, NSA_REG_WHO_AM_I, &chip_id);
551 if(chip_id != 0x13){
552 for(i=0;i<5;i++){
553 mdelay(5);
554 i2c_smbus_read((PLAT_HANDLE) client, NSA_REG_WHO_AM_I, &chip_id);
555 if(chip_id == 0x13)
556 break;
557 }
558 if(i == 5)
559 client->addr = 0x27;
560 }
561
562 mir_handle = mir3da_core_init(client);
563 if(NULL == mir_handle){
564 MI_ERR("chip init failed !\n");
565 return -1;
566 }
567
568 if(withSysAttr)
569 {
570 struct input_dev* pInputDev;
571 pInputDev = input_allocate_device();
572 if (!pInputDev) {
573 MI_ERR("Failed to allocate input device %s\n", sensor->input_dev->name);
574 return -ENOMEM;
575 }
576
577 pInputDev->name = MIR3DA_INPUT_DEV_NAME;
578 set_bit(EV_ABS, pInputDev->evbit);
579
580 /* x-axis acceleration */
581 input_set_abs_params(pInputDev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
582 /* y-axis acceleration */
583 input_set_abs_params(pInputDev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
584 /* z-axis acceleration */
585 input_set_abs_params(pInputDev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
586
587 ret = input_register_device(pInputDev);
588 if (ret) {
589 MI_ERR("Unable to register input device %s\n", pInputDev->name);
590 return -ENOMEM;
591 }
592 MI_MSG("Sys Attribute Register here %s is called for MIR3DA.\n", __func__);
593
594 ret = sysfs_create_group(&pInputDev->dev.kobj, &mir3da_attr_group);
595 if (ret) {
596 MI_ERR("mir3da_attr_group create Error err=%d..", ret);
597 ret = -EINVAL;
598 }
599
600 withSysAttr = 0;
601 }
602
603 is_init =1;
604
605 return ret;
606 }
607 /******************************************************************************/
608 static int sensor_active(struct i2c_client *client, int enable, int rate)
609 {
610 int result = 0;
611
612 MI_MSG("%s. enable=%d.\n", __func__,enable);
613
614 if(!is_init)
615 return -1;
616
617 mdelay(10);
618 if(enable){
619 /* result = mir3da_chip_resume(client);
620 if(result) {
621 MI_ERR("sensor_active chip resume fail!!\n");
622 return result;
623 }
624 */
625 result = mir3da_set_enable(client, true);
626 if(result){
627 MI_ERR("sensor_active enable fail!!\n");
628 return result;
629 }
630 }
631 else{
632 result = mir3da_set_enable(client, false);
633 if(result){
634 MI_ERR("sensor_active disable fail!!\n");
635 return result;
636 }
637 }
638 mdelay(10);
639
640 return result;
641 }
642 /******************************************************************************/
643 static int sensor_report_value(struct i2c_client *client)
644 {
645 struct sensor_private_data *sensor = (struct sensor_private_data *) i2c_get_clientdata(client);
646 struct sensor_platform_data *pdata = sensor->pdata;
647 struct sensor_axis axis;
648 int ret = 0;
649 short x=0,y=0,z=0;
650 int tmp_x=0,tmp_y=0,tmp_z=0;
651 static struct sensor_axis last_axis;
652 static int flag;
653
654 if(!is_init)
655 return -1;
656
657 ret = mir3da_read_data (client,&x, &y, &z);
658 if (ret){
659 MI_ERR("read data failed!");
660 return ret;
661 }
662
663 //MI_DATA(" x = %d, y = %d, z = %d\n", x, y, z);
664
665 tmp_x = x*DA311_GRAVITY_STEP;
666 tmp_y = y*DA311_GRAVITY_STEP;
667 tmp_z = z*DA311_GRAVITY_STEP;
668
669 //MI_DATA(" tmp_x = %d, tmp_y = %d, tmp_z = %d\n", tmp_x, tmp_y, tmp_z);
670
671 axis.x = (pdata->orientation[0])*tmp_x + (pdata->orientation[1])*tmp_y + (pdata->orientation[2])*tmp_z;
672 axis.y = (pdata->orientation[3])*tmp_x + (pdata->orientation[4])*tmp_y + (pdata->orientation[5])*tmp_z;
673 #if MIR3DA_STK_TEMP_SOLUTION
674 axis.z = (pdata->orientation[6])*tmp_x + (pdata->orientation[7])*tmp_y + (bzstk?1:(pdata->orientation[8]))*tmp_z;
675 #else
676 axis.z = (pdata->orientation[6])*tmp_x + (pdata->orientation[7])*tmp_y + (pdata->orientation[8])*tmp_z;
677 #endif
678 //MI_DATA( "map: axis = %d %d %d \n", axis.x, axis.y, axis.z);
679 #if 0
680 if (axis.x == last_axis.x && axis.y == last_axis.y && axis.z == last_axis.z)
681 axis.x += 1;
682 #else
683 if ((sensor->axis.x == axis.x) && (sensor->axis.y == axis.y) && (sensor->axis.z == axis.z)) {
684 if (flag) {
685 flag = 0;
686 axis.x += 1;
687 axis.y += 1;
688 axis.z += 1;
689 } else {
690 flag = 1;
691 axis.x -= 1;
692 axis.y -= 1;
693 axis.z -= 1;
694 }
695 }
696 #endif
697 // if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
698 {
699
700 /* RK3326 platform board */
701 #if defined (CONFIG_BOARD_RK3326_AK47)
702 input_report_abs(sensor->input_dev, ABS_X, -(axis.y/64));
703 input_report_abs(sensor->input_dev, ABS_Y, -(axis.x/64));
704 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
705 #elif defined (CONFIG_BOARD_RK3326_TH700)
706 input_report_abs(sensor->input_dev, ABS_X, -(axis.y/64));
707 input_report_abs(sensor->input_dev, ABS_Y, -(axis.x/64));
708 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
709 #elif defined(CONFIG_BOARD_RK3326_TH863B_10)
710 input_report_abs(sensor->input_dev, ABS_X, -(axis.x/64));
711 input_report_abs(sensor->input_dev, ABS_Y, (axis.y/64));
712 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
713 #elif defined(CONFIG_BOARD_RK3326_TH863B_7)
714 input_report_abs(sensor->input_dev, ABS_X, -(axis.x/64));
715 input_report_abs(sensor->input_dev, ABS_Y, (axis.y/64));
716 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
717 #elif defined(CONFIG_BOARD_RK3326_TH863B_V31_7)
718 input_report_abs(sensor->input_dev, ABS_X, -(axis.x/64));
719 input_report_abs(sensor->input_dev, ABS_Y, (axis.y/64));
720 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
721 #elif defined(CONFIG_BOARD_RK3326_TH863B_8)
722 input_report_abs(sensor->input_dev, ABS_X, (axis.y/64));
723 input_report_abs(sensor->input_dev, ABS_Y, (axis.x/64));
724 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
725 #elif defined(CONFIG_BOARD_RK3326_TH7926_7)
726 input_report_abs(sensor->input_dev, ABS_X, -(axis.y/64));
727 input_report_abs(sensor->input_dev, ABS_Y, -(axis.x/64));
728 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
729 #elif defined(CONFIG_BOARD_RK3326_TH7926_9)
730 input_report_abs(sensor->input_dev, ABS_X, -(axis.y/64));
731 input_report_abs(sensor->input_dev, ABS_Y, -(axis.x/64));
732 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
733 #elif defined(CONFIG_BOARD_RK3326_MT1011)
734 input_report_abs(sensor->input_dev, ABS_X, (axis.y/64));
735 input_report_abs(sensor->input_dev, ABS_Y, (axis.x/64));
736 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
737 #elif defined(CONFIG_BOARD_RK3326_M1011QR)
738 input_report_abs(sensor->input_dev, ABS_X, (axis.y/64));
739 input_report_abs(sensor->input_dev, ABS_Y, (axis.x/64));
740 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
741 #elif defined(CONFIG_BOARD_RK3326_TH1021DN)
742 input_report_abs(sensor->input_dev, ABS_X, -(axis.x/64));
743 input_report_abs(sensor->input_dev, ABS_Y, (axis.y/64));
744 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
745 #elif defined(CONFIG_BOARD_RK3326_TH1021DN_V20)
746 input_report_abs(sensor->input_dev, ABS_X, -(axis.x/64));
747 input_report_abs(sensor->input_dev, ABS_Y, (axis.y/64));
748 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
749
750 /* RK3126C platform board */
751 #elif defined(CONFIG_BOARD_RK3126C_AK47)
752 input_report_abs(sensor->input_dev, ABS_X, (axis.y/64));
753 input_report_abs(sensor->input_dev, ABS_Y, (axis.x/64));
754 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
755 #elif defined(CONFIG_BOARD_RK3126C_TH1021DN)
756 input_report_abs(sensor->input_dev, ABS_X, (axis.x/64));
757 input_report_abs(sensor->input_dev, ABS_Y, -(axis.y/64));
758 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
759 #elif defined(CONFIG_BOARD_RK3126C_TH863_7)
760 input_report_abs(sensor->input_dev, ABS_X, -(axis.x/64));
761 input_report_abs(sensor->input_dev, ABS_Y, (axis.y/64));
762 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
763 #elif defined(CONFIG_BOARD_RK3126C_TH863_8)
764 input_report_abs(sensor->input_dev, ABS_X, (axis.y/64));
765 input_report_abs(sensor->input_dev, ABS_Y, (axis.x/64));
766 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
767 #elif defined(CONFIG_BOARD_RK3126C_TH98V)
768 input_report_abs(sensor->input_dev, ABS_X, (axis.y/64));
769 input_report_abs(sensor->input_dev, ABS_Y, (axis.x/64));
770 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
771
772 /* RK3368 platform board */
773 #elif defined(CONFIG_BOARD_RK3368_TH863C_10)
774 input_report_abs(sensor->input_dev, ABS_X, -(axis.x/64));
775 input_report_abs(sensor->input_dev, ABS_Y, (axis.y/64));
776 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z/64));
777 #else
778 input_report_abs(sensor->input_dev, ABS_X, -(axis.x));
779 input_report_abs(sensor->input_dev, ABS_Y, (axis.y));
780 input_report_abs(sensor->input_dev, ABS_Z, -(axis.z));
781 #endif
782
783 input_sync(sensor->input_dev);
784 last_axis = axis;
785
786 mutex_lock(&(sensor->data_mutex) );
787 sensor->axis = axis;
788 mutex_unlock(&(sensor->data_mutex) );
789 }
790
791 return ret;
792 }
793 /******************************************************************************/
794 static int sensor_suspend(struct i2c_client *client)
795 {
796 int result = 0;
797
798 MI_FUN;
799
800 mdelay(10);
801
802 result = mir3da_set_enable(client, false);
803 if (result) {
804 MI_ERR("sensor_suspend disable fail!!\n");
805 return result;
806 }
807
808 mdelay(10);
809
810 return result;
811 }
812
813 /******************************************************************************/
814 static int sensor_resume(struct i2c_client *client)
815 {
816 int result = 0;
817
818 MI_FUN;
819
820 mdelay(10);
821
822 /*
823 * result = mir3da_chip_resume(client);
824 * if(result) {
825 * MI_ERR("sensor_resume chip resume fail!!\n");
826 * return result;
827 * }
828 */
829 result = mir3da_set_enable(client, true);
830 if (result) {
831 MI_ERR("sensor_resume enable fail!!\n");
832 return result;
833 }
834
835 mdelay(10);
836
837 return result;
838 }
839
840 /******************************************************************************/
841 static struct sensor_operate gsensor_ops = {
842 .name = MIR3DA_DRV_NAME,
843 .type = SENSOR_TYPE_ACCEL,
844 .id_i2c = ACCEL_ID_MIR3DA,
845 .read_reg = -1,
846 .read_len = 0,
847 .id_reg = -1,
848 .id_data = 0,
849 .precision = MIR3DA_PRECISION,
850 .ctrl_reg = -1,
851 .int_status_reg = 0x00,
852 .range = {-MIR3DA_RANGE, MIR3DA_RANGE},
853 .trig = IRQF_TRIGGER_LOW | IRQF_ONESHOT,
854 .active = sensor_active,
855 .init = sensor_init,
856 .report = sensor_report_value,
857 .suspend = sensor_suspend,
858 .resume = sensor_resume,
859 };
860
861 /******************************************************************************/
862 static int gsensor_mir3da_probe(struct i2c_client *client,
863 const struct i2c_device_id *devid)
864 {
865 MI_FUN;
866
867 return sensor_register_device(client, NULL, devid, &gsensor_ops);
868 }
869 /******************************************************************************/
870 static int gsensor_mir3da_remove(struct i2c_client *client)
871 {
872 MI_FUN;
873
874 return sensor_unregister_device(client, NULL, &gsensor_ops);
875 }
876 /******************************************************************************/
877 static const struct i2c_device_id gsensor_mir3da_id[] = {
878 {"gs_da223", ACCEL_ID_MIR3DA},
879 {}
880 };
881
882 static struct i2c_driver gsensor_mir3da_driver = {
883 .probe = gsensor_mir3da_probe,
884 .remove = gsensor_mir3da_remove,
885 .shutdown = sensor_shutdown,
886 .id_table = gsensor_mir3da_id,
887 .driver = {
888 .name = "gsensor_mir3da",
889 #ifdef CONFIG_PM
890 .pm = &sensor_pm_ops,
891 #endif
892 },
893 };
894
895 module_i2c_driver(gsensor_mir3da_driver);
896
897 MODULE_DESCRIPTION("mir3da 3-Axis accelerometer driver");
898 MODULE_LICENSE("GPL");
899