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