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