61dceedc4798b79e477dfa376e781e4d7c6bbfa3
[firefly-linux-kernel-4.4.55.git] / drivers / input / gsensor / mma7660.c
1 /* drivers/i2c/chips/mma7660.c - mma7660 compass driver
2  *
3  * Copyright (C) 2007-2008 HTC Corporation.
4  * Author: Hou-Kun Chen <houkun.chen@gmail.com>
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/interrupt.h>
18 #include <linux/i2c.h>
19 #include <linux/slab.h>
20 #include <linux/irq.h>
21 #include <linux/miscdevice.h>
22 #include <linux/gpio.h>
23 #include <asm/uaccess.h>
24 #include <linux/delay.h>
25 #include <linux/input.h>
26 #include <linux/workqueue.h>
27 #include <linux/freezer.h>
28 #include <linux/mma7660.h>
29 #include <mach/gpio.h>
30 #ifdef CONFIG_ANDROID_POWER
31 #include <linux/android_power.h>
32 #endif
33
34 //#define RK28_PRINT
35 //#include <asm/arch/rk28_debug.h>
36
37 #define rk28printk(x...) printk(x)
38
39 static int  mma7660_probe(struct i2c_client *client, const struct i2c_device_id *id);
40
41
42 #define MMA7660_GPIO_INT     RK2818_PIN_PE3
43
44 /* Addresses to scan -- protected by sense_data_mutex */
45 static char sense_data[RBUFF_SIZE + 1];
46 static struct i2c_client *this_client;
47
48 static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq);
49 static atomic_t data_ready;
50 #ifdef CONFIG_ANDROID_POWER
51 static android_early_suspend_t mma7660_early_suspend;
52 #endif
53 static int revision = -1;
54 /* AKM HW info */
55 static ssize_t gsensor_vendor_show(struct device *dev,
56                 struct device_attribute *attr, char *buf)
57 {
58         ssize_t ret = 0;
59
60         sprintf(buf, "%#x\n", revision);
61         ret = strlen(buf) + 1;
62
63         return ret;
64 }
65
66 static DEVICE_ATTR(vendor, 0444, gsensor_vendor_show, NULL);
67
68 static struct kobject *android_gsensor_kobj;
69
70 static int gsensor_sysfs_init(void)
71 {
72         int ret ;
73
74         android_gsensor_kobj = kobject_create_and_add("android_gsensor", NULL);
75         if (android_gsensor_kobj == NULL) {
76                 rk28printk(KERN_ERR
77                        "MMA7660 gsensor_sysfs_init:"\
78                        "subsystem_register failed\n");
79                 ret = -ENOMEM;
80                 goto err;
81         }
82
83         ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr);
84         if (ret) {
85                 rk28printk(KERN_ERR
86                        "MMA7660 gsensor_sysfs_init:"\
87                        "sysfs_create_group failed\n");
88                 goto err4;
89         }
90
91         return 0 ;
92 err4:
93         kobject_del(android_gsensor_kobj);
94 err:
95         return ret ;
96 }
97
98 static int mma7660_rx_data(char *rxData, int length)
99 {
100 #if 0
101         struct i2c_msg msgs[] = {
102                 {
103                  .addr = this_client->addr,
104                  .flags = 1,
105                  .len = length,
106                  .buf = rxData,
107                  },
108         };
109
110         if (i2c_transfer(this_client->adapter, msgs, 1) < 0) {
111                 rk28printk(KERN_ERR "MMA7660 mma7660_rx_data: transfer error\n");
112                 return -EIO;
113         } else
114                 return 0;
115 #else
116     int ret;
117         struct i2c_adapter *adap = this_client->adapter;
118         struct i2c_msg msgs[2];
119
120         msgs[0].addr = this_client->addr;
121         msgs[0].buf = (char *)rxData;
122         msgs[0].flags = this_client->flags;
123         msgs[0].len = 1;
124         msgs[0].scl_rate = 200*1000;
125
126         msgs[1].addr = this_client->addr;
127         msgs[1].buf = (char *)rxData;
128         msgs[1].flags = this_client->flags | I2C_M_RD;
129         msgs[1].len = 3;
130         msgs[1].scl_rate = 200*1000;
131
132         ret = i2c_transfer(adap, msgs, 2);
133
134         return ret;
135 #endif
136 }
137
138 static int mma7660_tx_data(char *txData, int length)
139 {
140 #if 0
141         struct i2c_msg msg[] = {
142                 {
143                  .addr = this_client->addr,
144                  .flags = 0,
145                  .len = length,
146                  .buf = txData,
147                  },
148         };
149         if (i2c_transfer(this_client->adapter, msg, 1) < 0) {
150                 rk28printk(KERN_ERR "MMA7660 mma7660_tx_data: transfer error\n");
151                 return -EIO;
152         } else
153                 return 0;
154 #else
155     int ret;
156         struct i2c_adapter *adap = this_client->adapter;
157         struct i2c_msg msg;
158
159         msg.addr = this_client->addr;
160         msg.buf = txData;
161         msg.len = length;
162         msg.flags = this_client->flags;
163         msg.scl_rate = 200*1000;
164     
165         ret = i2c_transfer(adap, &msg, 1);
166
167         return ret;
168 #endif
169 }
170
171 static int mma7660_set_rate(char rate)
172 {
173         char buffer[2];
174         int ret = 0;
175         int i;
176         
177         if (rate > 128)
178         return -EINVAL;
179
180     for (i = 0; i < 7; i++) {
181         if (rate & (0x1 << i))
182             break;
183     }   
184
185         buffer[0] = MMA7660_REG_SR;
186         buffer[1] = 0xf8 | (0x07 & (~i));
187
188         ret = mma7660_tx_data(&(buffer[0]), 2);
189
190         return ret;
191 }
192
193 static int mma7660_start_dev(char rate)
194 {
195         char buffer[MMA7660_REG_LEN];
196         int ret = 0;
197
198         buffer[0] = MMA7660_REG_INTSU;
199         buffer[1] = 0x10;       //0x10; modify by zhao
200         ret = mma7660_tx_data(&buffer[0], 2);
201
202         ret = mma7660_set_rate(rate);
203
204         buffer[0] = MMA7660_REG_MODE;
205         buffer[1] = 0x81;
206         ret = mma7660_tx_data(&buffer[0], 2);
207
208         rk28printk("\n----------------------------mma7660_start------------------------\n");
209         
210         return ret;
211 }
212
213 static int mma7660_start(char rate)
214
215     struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
216     
217     if (mma->status == MMA7660_OPEN) {
218         return 0;      
219     }
220     mma->status = MMA7660_OPEN;
221     return mma7660_start_dev(rate);
222 }
223
224 static int mma7660_close_dev(void)
225 {       
226         char buffer[2];
227                 
228         buffer[0] = MMA7660_REG_MODE;
229         buffer[1] = 0x00;
230         
231         return mma7660_tx_data(buffer, 2);
232 }
233
234 static int mma7660_close(void)
235 {
236     struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
237     
238     mma->status = MMA7660_CLOSE;
239     
240     return mma7660_close_dev();
241 }
242
243 static int mma7660_reset_rate(char rate)
244 {
245         int ret = 0;
246         
247     ret = mma7660_close_dev();
248     ret = mma7660_start_dev(rate);
249     
250         return ret ;
251 }
252
253 static inline int mma7660_convert_to_int(char value)
254 {
255     int result;
256
257     if (value < MMA7660_BOUNDARY) {
258        result = value * MMA7660_GRAVITY_STEP;
259     } else {
260        result = ~(((~value & 0x3f) + 1)* MMA7660_GRAVITY_STEP) + 1;
261     }
262
263     return result;
264 }
265
266 static void mma7660_report_value(short *rbuf)
267 {
268         struct mma7660_data *data = i2c_get_clientdata(this_client);
269     struct mma7660_axis *axis = (struct mma7660_axis *)rbuf;
270
271         /* Report acceleration sensor information */
272     input_report_abs(data->input_dev, ABS_X, axis->x);
273     input_report_abs(data->input_dev, ABS_Y, axis->y);
274     input_report_abs(data->input_dev, ABS_Z, axis->z);
275     input_sync(data->input_dev);
276     rk28printk("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
277 }
278
279 static int mma7660_get_data(void)
280 {
281         char buffer[3];
282         int ret;
283     struct mma7660_axis axis;
284
285         memset(buffer, 0, 3);
286         buffer[0] = MMA7660_REG_X_OUT;
287     ret = mma7660_rx_data(&buffer[0], 3);
288         //while(mma7660_rx_data(&buffer[0], 3));
289         /*
290     if (!ret) {
291         rk28printk( "%s: -------------------------------------------gsensor device register = [0]:%d  [1]:%d  [2]:%d  [3]:0x%x  [4]:0x%x  [5]:0x%x  [6]:0x%x  [7]:0x%x-----------------------------------------------\n",
292                __func__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); 
293     } 
294     */
295         if (ret < 0)
296                 return ret;
297
298         axis.x = mma7660_convert_to_int(buffer[MMA7660_REG_X_OUT]);
299         axis.y = -mma7660_convert_to_int(buffer[MMA7660_REG_Y_OUT]);
300         axis.z = -mma7660_convert_to_int(buffer[MMA7660_REG_Z_OUT]);
301
302     rk28printk( "%s: -------------------------------------------mma7660_GetData axis = %d  %d  %d-----------------------------------------------\n",
303            __func__, axis.x, axis.y, axis.z); 
304      
305     memcpy(sense_data, &axis, sizeof(axis));
306     mma7660_report_value(sense_data);
307         //atomic_set(&data_ready, 0);
308         //wake_up(&data_ready_wq);
309
310         return 0;
311 }
312
313 static int mma7660_trans_buff(char *rbuf, int size)
314 {
315         //wait_event_interruptible_timeout(data_ready_wq,
316         //                               atomic_read(&data_ready), 1000);
317         wait_event_interruptible(data_ready_wq,
318                                          atomic_read(&data_ready));
319
320         atomic_set(&data_ready, 0);
321         memcpy(rbuf, &sense_data[0], size);
322
323         return 0;
324 }
325
326 static int mma7660_open(struct inode *inode, struct file *file)
327 {
328         rk28printk("----------------------------mma7660_open------------------------\n");
329         return 0;//nonseekable_open(inode, file);
330 }
331
332 static int mma7660_release(struct inode *inode, struct file *file)
333 {
334         return 0;
335 }
336
337 static int mma7660_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
338            unsigned long arg)
339 {
340
341         void __user *argp = (void __user *)arg;
342         char msg[RBUFF_SIZE + 1];
343         int ret = -1;
344         char rate;
345
346         rk28printk("----------------------------mma7660_ioctl------------------------cmd: %d\n", cmd);
347
348         switch (cmd) {
349         case ECS_IOCTL_APP_SET_RATE:
350                 if (copy_from_user(&rate, argp, sizeof(rate)))
351                         return -EFAULT;
352                 break;
353         default:
354                 break;
355         }
356
357         switch (cmd) {
358         case ECS_IOCTL_START:
359                 ret = mma7660_start(MMA7660_RATE_32);
360                 if (ret < 0)
361                         return ret;
362                 break;
363         case ECS_IOCTL_CLOSE:
364                 ret = mma7660_close();
365                 if (ret < 0)
366                         return ret;
367                 break;
368         case ECS_IOCTL_APP_SET_RATE:
369                 ret = mma7660_reset_rate(rate);
370                 if (ret < 0)
371                         return ret;
372                 break;
373         case ECS_IOCTL_GETDATA:
374                 ret = mma7660_trans_buff(msg, RBUFF_SIZE);
375                 if (ret < 0)
376                         return ret;
377                 break;
378         default:
379                 return -ENOTTY;
380         }
381
382         switch (cmd) {
383         case ECS_IOCTL_GETDATA:
384                 if (copy_to_user(argp, &msg, sizeof(msg)))
385                         return -EFAULT;
386                 break;
387         default:
388                 break;
389         }
390
391         return 0;
392 }
393
394 static void mma7660_work_func(struct work_struct *work)
395 {
396         if (mma7660_get_data() < 0) 
397                 rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n");
398                 
399     //GPIOClrearInmarkIntr(MMA7660_GPIO_INT);
400         
401         rk28printk("---------------------------------------mma7660_work_func----------------------------------\n");
402 }
403
404 static void  mma7660_delaywork_func(struct work_struct  *work)
405 {
406         
407         if (mma7660_get_data() < 0) 
408                 rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n");
409                 
410         //GPIOClrearInmarkIntr(MMA7660_GPIO_INT);
411         
412         rk28printk("---------------------------------------mma7660_delaywork_func------------------------------\n");
413
414 }
415
416 static irqreturn_t mma7660_interrupt(int irq, void *dev_id)
417 {
418         struct mma7660_data *data = dev_id;
419
420         ///GPIOInmarkIntr(MMA7660_GPIO_INT);
421         //schedule_work(&data->work);
422         schedule_delayed_work(&data->delaywork,msecs_to_jiffies(30));
423         rk28printk("--------------------------------------mma7660_interrupt---------------------------------------\n");
424         
425         return IRQ_HANDLED;
426 }
427
428 static struct file_operations mma7660_fops = {
429         .owner = THIS_MODULE,
430         .open = mma7660_open,
431         .release = mma7660_release,
432         .ioctl = mma7660_ioctl,
433 };
434
435 static struct miscdevice mma7660_device = {
436         .minor = MISC_DYNAMIC_MINOR,
437         .name = "mma7660_daemon",
438         .fops = &mma7660_fops,
439 };
440
441 static int mma7660_remove(struct i2c_client *client)
442 {
443         struct mma7660_data *mma = i2c_get_clientdata(client);
444         
445     misc_deregister(&mma7660_device);
446     input_unregister_device(mma->input_dev);
447     input_free_device(mma->input_dev);
448     free_irq(client->irq, mma);
449     kfree(mma); 
450 #ifdef CONFIG_ANDROID_POWER
451     android_unregister_early_suspend(&mma7660_early_suspend);
452 #endif      
453     this_client = NULL;
454         return 0;
455 }
456
457 #ifdef CONFIG_ANDROID_POWER
458 static int mma7660_suspend(android_early_suspend_t *h)
459 {
460         rk28printk("Gsensor mma7760 enter suspend\n");
461         return mma7660_close_dev();
462 }
463
464 static int mma7660_resume(android_early_suspend_t *h)
465 {
466     struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
467         rk28printk("Gsensor mma7760 resume!!\n");
468         return mma7660_start_dev(mma->curr_tate);
469 }
470 /*
471 static int suspend(struct i2c_client *client, pm_message_t mesg)
472 {
473         rk28printk("Gsensor mma7760 enter 2 level  suspend\n");
474         return mma7660_close_dev();
475 }
476 static int resume(struct i2c_client *client)
477 {
478         struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
479         rk28printk("Gsensor mma7760 2 level resume!!\n");
480         return mma7660_start_dev(mma->curr_tate);
481 }
482 */
483 #else
484 #define mma7660_suspend NULL
485 #define mma7660_resume NULL
486 #endif
487
488 static const struct i2c_device_id mma7660_id[] = {
489                 {"gs_mma7660", 0},
490                 { }
491 };
492
493 static struct i2c_driver mma7660_driver = {
494         .driver = {
495                 .name = "gs_mma7660",
496             },
497         .id_table       = mma7660_id,
498         .probe          = mma7660_probe,
499         .remove         = __devexit_p(mma7660_remove),
500         //.suspend = &suspend,
501         //.resume = &resume,
502 };
503
504
505 static int mma7660_init_client(struct i2c_client *client)
506 {
507         struct mma7660_data *data;
508         int ret;
509         data = i2c_get_clientdata(client);
510
511         rk28printk("gpio_to_irq(%d) is %d\n",client->irq,gpio_to_irq(client->irq));
512         if ( !gpio_is_valid(client->irq)) {
513                 rk28printk("+++++++++++gpio_is_invalid\n");
514                 return -EINVAL;
515         }
516         ret = gpio_request(client->irq, "mma7660_int");
517         if (ret) {
518                 rk28printk( "failed to request mma7990_trig GPIO%d\n",gpio_to_irq(client->irq));
519                 return ret;
520         }
521
522         client->irq = gpio_to_irq(client->irq);
523         ret = request_irq(client->irq, mma7660_interrupt, IRQF_TRIGGER_RISING, client->dev.driver->name, data);
524         rk28printk("request irq is %d,ret is  0x%x\n",client->irq,ret);
525         if (ret ) {
526                 rk28printk(KERN_ERR "mma7660_init_client: request irq failed,ret is %d\n",ret);
527         return ret;
528         }
529         init_waitqueue_head(&data_ready_wq);
530  
531         return 0;
532 }
533
534 static int  mma7660_probe(struct i2c_client *client, const struct i2c_device_id *id)
535 {
536         struct mma7660_data *mma;
537         int err;
538
539         mma = kzalloc(sizeof(struct mma7660_data), GFP_KERNEL);
540         if (!mma) {
541                 rk28printk("[mma7660]:alloc data failed.\n");
542                 err = -ENOMEM;
543                 goto exit_alloc_data_failed;
544         }
545
546         INIT_WORK(&mma->work, mma7660_work_func);
547         INIT_DELAYED_WORK(&mma->delaywork, mma7660_delaywork_func);
548
549         mma->client = client;
550         i2c_set_clientdata(client, mma);
551
552         this_client = client;
553
554         err = mma7660_init_client(client);
555         if (err < 0) {
556                 rk28printk(KERN_ERR
557                        "mma7660_probe: mma7660_init_client failed\n");
558                 goto exit_request_gpio_irq_failed;
559         }
560                 
561         mma->input_dev = input_allocate_device();
562         if (!mma->input_dev) {
563                 err = -ENOMEM;
564                 rk28printk(KERN_ERR
565                        "mma7660_probe: Failed to allocate input device\n");
566                 goto exit_input_allocate_device_failed;
567         }
568
569         set_bit(EV_ABS, mma->input_dev->evbit);
570
571         /* x-axis acceleration */
572         input_set_abs_params(mma->input_dev, ABS_X, -1500, 1500, 0, 0);
573         /* y-axis acceleration */
574         input_set_abs_params(mma->input_dev, ABS_Y, -1500, 1500, 0, 0);
575         /* z-axis acceleration */
576         input_set_abs_params(mma->input_dev, ABS_Z, -1500, 1500, 0, 0);
577
578         mma->input_dev->name = "compass";
579
580         err = input_register_device(mma->input_dev);
581         if (err < 0) {
582                 rk28printk(KERN_ERR
583                        "mma7660_probe: Unable to register input device: %s\n",
584                        mma->input_dev->name);
585                 goto exit_input_register_device_failed;
586         }
587
588         err = misc_register(&mma7660_device);
589         if (err < 0) {
590                 rk28printk(KERN_ERR
591                        "mma7660_probe: mmad_device register failed\n");
592                 goto exit_misc_device_register_mma7660_device_failed;
593         }
594
595         err = gsensor_sysfs_init();
596         if (err < 0) {
597                 rk28printk(KERN_ERR
598             "mma7660_probe: gsensor sysfs init failed\n");
599                 goto exit_gsensor_sysfs_init_failed;
600         }
601         
602 #ifdef CONFIG_ANDROID_POWER
603     mma7660_early_suspend.suspend = mma7660_suspend;
604     mma7660_early_suspend.resume = mma7660_resume;
605     mma7660_early_suspend.level = 0x2;
606     android_register_early_suspend(&mma7660_early_suspend);
607 #endif
608
609         return 0;
610
611 exit_gsensor_sysfs_init_failed:
612     misc_deregister(&mma7660_device);
613 exit_misc_device_register_mma7660_device_failed:
614     input_unregister_device(mma->input_dev);
615 exit_input_register_device_failed:
616         input_free_device(mma->input_dev);
617 exit_input_allocate_device_failed:
618     free_irq(client->irq, mma);
619 exit_request_gpio_irq_failed:
620         kfree(mma);     
621 exit_alloc_data_failed:
622     ;
623         return err;
624 }
625
626
627 static int __init mma7660_i2c_init(void)
628 {
629         return i2c_add_driver(&mma7660_driver);
630 }
631
632 static void __exit mma7660_i2c_exit(void)
633 {
634         i2c_del_driver(&mma7660_driver);
635 }
636
637 module_init(mma7660_i2c_init);
638 module_exit(mma7660_i2c_exit);
639
640
641