touchscreen && spi
[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 #if 0
37 #define rk28printk(x...) printk(x)
38 #else
39 #define rk28printk(x...)
40 #endif
41 static int  mma7660_probe(struct i2c_client *client, const struct i2c_device_id *id);
42
43 #define MMA7660_SPEED           200 * 1000
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         int ret = 0;
102         char reg = rxData[0];
103         ret = i2c_master_reg8_recv(this_client, reg, rxData, length, MMA7660_SPEED);
104         return (ret > 0)? 0 : ret;
105 }
106
107 static int mma7660_tx_data(char *txData, int length)
108 {
109         int ret = 0;
110         char reg = txData[0];
111         ret = i2c_master_reg8_send(this_client, reg, &txData[1], length-1, MMA7660_SPEED);
112         return (ret > 0)? 0 : ret;
113 }
114
115 static int mma7660_set_rate(char rate)
116 {
117         char buffer[2];
118         int ret = 0;
119         int i;
120         
121         if (rate > 128)
122         return -EINVAL;
123
124     for (i = 0; i < 7; i++) {
125         if (rate & (0x1 << i))
126             break;
127     }   
128
129         buffer[0] = MMA7660_REG_SR;
130         buffer[1] = 0xf8 | (0x07 & (~i));
131
132         ret = mma7660_tx_data(&(buffer[0]), 2);
133         ret = mma7660_rx_data(&(buffer[0]), 1);
134
135         return ret;
136 }
137
138 static int mma7660_start_dev(char rate)
139 {
140         char buffer[MMA7660_REG_LEN];
141         int ret = 0;
142
143         buffer[0] = MMA7660_REG_INTSU;
144         buffer[1] = 0x10;       //0x10; modify by zhao
145         ret = mma7660_tx_data(&buffer[0], 2);
146         ret = mma7660_rx_data(&buffer[0], 1);
147
148         ret = mma7660_set_rate(rate);
149
150         buffer[0] = MMA7660_REG_MODE;
151         buffer[1] = 0x81;
152         ret = mma7660_tx_data(&buffer[0], 2);
153         ret = mma7660_rx_data(&buffer[0], 1);
154
155         enable_irq(this_client->irq);
156         rk28printk("\n----------------------------mma7660_start------------------------\n");
157         
158         return ret;
159 }
160
161 static int mma7660_start(char rate)
162
163     struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
164     
165     if (mma->status == MMA7660_OPEN) {
166         return 0;      
167     }
168     mma->status = MMA7660_OPEN;
169     return mma7660_start_dev(rate);
170 }
171
172 static int mma7660_close_dev(void)
173 {       
174         char buffer[2];
175                 
176         buffer[0] = MMA7660_REG_MODE;
177         buffer[1] = 0x00;
178         
179         return mma7660_tx_data(buffer, 2);
180 }
181
182 static int mma7660_close(void)
183 {
184     struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
185     
186     mma->status = MMA7660_CLOSE;
187     
188     return mma7660_close_dev();
189 }
190
191 static int mma7660_reset_rate(char rate)
192 {
193         int ret = 0;
194         
195     ret = mma7660_close_dev();
196     ret = mma7660_start_dev(rate);
197     
198         return ret ;
199 }
200
201 static inline int mma7660_convert_to_int(char value)
202 {
203     int result;
204
205     if (value < MMA7660_BOUNDARY) {
206        result = value * MMA7660_GRAVITY_STEP;
207     } else {
208        result = ~(((~value & 0x3f) + 1)* MMA7660_GRAVITY_STEP) + 1;
209     }
210
211     return result;
212 }
213
214 static void mma7660_report_value(short *rbuf)
215 {
216         struct mma7660_data *data = i2c_get_clientdata(this_client);
217     struct mma7660_axis *axis = (struct mma7660_axis *)rbuf;
218
219         /* Report acceleration sensor information */
220     input_report_abs(data->input_dev, ABS_X, axis->x);
221     input_report_abs(data->input_dev, ABS_Y, axis->y);
222     input_report_abs(data->input_dev, ABS_Z, axis->z);
223     input_sync(data->input_dev);
224     rk28printk("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
225 }
226
227 static int mma7660_get_data(void)
228 {
229         char buffer[3];
230         int ret;
231     struct mma7660_axis axis;
232
233         memset(buffer, 0, 3);
234         buffer[0] = MMA7660_REG_X_OUT;
235     ret = mma7660_rx_data(&buffer[0], 3);
236         //while(mma7660_rx_data(&buffer[0], 3));
237         /*
238     if (!ret) {
239         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",
240                __func__, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); 
241     } 
242     */
243         if (ret < 0)
244                 return ret;
245
246         axis.x = mma7660_convert_to_int(buffer[MMA7660_REG_X_OUT]);
247         axis.y = -mma7660_convert_to_int(buffer[MMA7660_REG_Y_OUT]);
248         axis.z = -mma7660_convert_to_int(buffer[MMA7660_REG_Z_OUT]);
249
250     rk28printk( "%s: -------------------------------------------mma7660_GetData axis = %d  %d  %d-----------------------------------------------\n",
251            __func__, axis.x, axis.y, axis.z); 
252      
253     memcpy(sense_data, &axis, sizeof(axis));
254     mma7660_report_value(sense_data);
255         //atomic_set(&data_ready, 0);
256         //wake_up(&data_ready_wq);
257
258         return 0;
259 }
260
261 static int mma7660_trans_buff(char *rbuf, int size)
262 {
263         //wait_event_interruptible_timeout(data_ready_wq,
264         //                               atomic_read(&data_ready), 1000);
265         wait_event_interruptible(data_ready_wq,
266                                          atomic_read(&data_ready));
267
268         atomic_set(&data_ready, 0);
269         memcpy(rbuf, &sense_data[0], size);
270
271         return 0;
272 }
273
274 static int mma7660_open(struct inode *inode, struct file *file)
275 {
276         rk28printk("----------------------------mma7660_open------------------------\n");
277         return 0;//nonseekable_open(inode, file);
278 }
279
280 static int mma7660_release(struct inode *inode, struct file *file)
281 {
282         return 0;
283 }
284
285 static int mma7660_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
286            unsigned long arg)
287 {
288
289         void __user *argp = (void __user *)arg;
290         char msg[RBUFF_SIZE + 1];
291         int ret = -1;
292         char rate;
293
294         rk28printk("----------------------------mma7660_ioctl------------------------cmd: %d\n", cmd);
295
296         switch (cmd) {
297         case ECS_IOCTL_APP_SET_RATE:
298                 if (copy_from_user(&rate, argp, sizeof(rate)))
299                         return -EFAULT;
300                 break;
301         default:
302                 break;
303         }
304
305         switch (cmd) {
306         case ECS_IOCTL_START:
307                 ret = mma7660_start(MMA7660_RATE_32);
308                 if (ret < 0)
309                         return ret;
310                 break;
311         case ECS_IOCTL_CLOSE:
312                 ret = mma7660_close();
313                 if (ret < 0)
314                         return ret;
315                 break;
316         case ECS_IOCTL_APP_SET_RATE:
317                 ret = mma7660_reset_rate(rate);
318                 if (ret < 0)
319                         return ret;
320                 break;
321         case ECS_IOCTL_GETDATA:
322                 ret = mma7660_trans_buff(msg, RBUFF_SIZE);
323                 if (ret < 0)
324                         return ret;
325                 break;
326         default:
327                 return -ENOTTY;
328         }
329
330         switch (cmd) {
331         case ECS_IOCTL_GETDATA:
332                 if (copy_to_user(argp, &msg, sizeof(msg)))
333                         return -EFAULT;
334                 break;
335         default:
336                 break;
337         }
338
339         return 0;
340 }
341
342 static void mma7660_work_func(struct work_struct *work)
343 {
344         if (mma7660_get_data() < 0) 
345                 rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n");
346                 
347         enable_irq(this_client->irq);           
348         rk28printk("---------------------------------------mma7660_work_func----------------------------------\n");
349 }
350
351 static void  mma7660_delaywork_func(struct work_struct  *work)
352 {
353         
354         if (mma7660_get_data() < 0) 
355                 rk28printk(KERN_ERR "MMA7660 mma_work_func: Get data failed\n");
356         enable_irq(this_client->irq);           
357         rk28printk("---------------------------------------mma7660_delaywork_func------------------------------\n");
358
359 }
360
361 static irqreturn_t mma7660_interrupt(int irq, void *dev_id)
362 {
363         struct mma7660_data *data = dev_id;
364         disable_irq_nosync(this_client->irq);
365         schedule_delayed_work(&data->delaywork,msecs_to_jiffies(30));
366         rk28printk("--------------------------------------mma7660_interrupt---------------------------------------\n");
367         
368         return IRQ_HANDLED;
369 }
370
371 static struct file_operations mma7660_fops = {
372         .owner = THIS_MODULE,
373         .open = mma7660_open,
374         .release = mma7660_release,
375         .ioctl = mma7660_ioctl,
376 };
377
378 static struct miscdevice mma7660_device = {
379         .minor = MISC_DYNAMIC_MINOR,
380         .name = "mma7660_daemon",
381         .fops = &mma7660_fops,
382 };
383
384 static int mma7660_remove(struct i2c_client *client)
385 {
386         struct mma7660_data *mma = i2c_get_clientdata(client);
387         
388     misc_deregister(&mma7660_device);
389     input_unregister_device(mma->input_dev);
390     input_free_device(mma->input_dev);
391     free_irq(client->irq, mma);
392     kfree(mma); 
393 #ifdef CONFIG_ANDROID_POWER
394     android_unregister_early_suspend(&mma7660_early_suspend);
395 #endif      
396     this_client = NULL;
397         return 0;
398 }
399
400 #ifdef CONFIG_ANDROID_POWER
401 static int mma7660_suspend(android_early_suspend_t *h)
402 {
403         rk28printk("Gsensor mma7760 enter suspend\n");
404         return mma7660_close_dev();
405 }
406
407 static int mma7660_resume(android_early_suspend_t *h)
408 {
409     struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
410         rk28printk("Gsensor mma7760 resume!!\n");
411         return mma7660_start_dev(mma->curr_tate);
412 }
413 /*
414 static int suspend(struct i2c_client *client, pm_message_t mesg)
415 {
416         rk28printk("Gsensor mma7760 enter 2 level  suspend\n");
417         return mma7660_close_dev();
418 }
419 static int resume(struct i2c_client *client)
420 {
421         struct mma7660_data *mma = (struct mma7660_data *)i2c_get_clientdata(this_client);
422         rk28printk("Gsensor mma7760 2 level resume!!\n");
423         return mma7660_start_dev(mma->curr_tate);
424 }
425 */
426 #else
427 #define mma7660_suspend NULL
428 #define mma7660_resume NULL
429 #endif
430
431 static const struct i2c_device_id mma7660_id[] = {
432                 {"gs_mma7660", 0},
433                 { }
434 };
435
436 static struct i2c_driver mma7660_driver = {
437         .driver = {
438                 .name = "gs_mma7660",
439             },
440         .id_table       = mma7660_id,
441         .probe          = mma7660_probe,
442         .remove         = __devexit_p(mma7660_remove),
443         //.suspend = &suspend,
444         //.resume = &resume,
445 };
446
447
448 static int mma7660_init_client(struct i2c_client *client)
449 {
450         struct mma7660_data *data;
451         int ret;
452         data = i2c_get_clientdata(client);
453         rk28printk("gpio_to_irq(%d) is %d\n",client->irq,gpio_to_irq(client->irq));
454         if ( !gpio_is_valid(client->irq)) {
455                 rk28printk("+++++++++++gpio_is_invalid\n");
456                 return -EINVAL;
457         }
458         ret = gpio_request(client->irq, "mma7660_int");
459         if (ret) {
460                 rk28printk( "failed to request mma7990_trig GPIO%d\n",gpio_to_irq(client->irq));
461                 return ret;
462         }
463         client->irq = gpio_to_irq(client->irq);
464         ret = request_irq(client->irq, mma7660_interrupt, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, client->dev.driver->name, data);
465         rk28printk("request irq is %d,ret is  0x%x\n",client->irq,ret);
466         if (ret ) {
467                 rk28printk(KERN_ERR "mma7660_init_client: request irq failed,ret is %d\n",ret);
468         return ret;
469         }
470         disable_irq(client->irq);
471         init_waitqueue_head(&data_ready_wq);
472  
473         return 0;
474 }
475
476 static int  mma7660_probe(struct i2c_client *client, const struct i2c_device_id *id)
477 {
478         struct mma7660_data *mma;
479         int err;
480
481         mma = kzalloc(sizeof(struct mma7660_data), GFP_KERNEL);
482         if (!mma) {
483                 rk28printk("[mma7660]:alloc data failed.\n");
484                 err = -ENOMEM;
485                 goto exit_alloc_data_failed;
486         }
487
488         INIT_WORK(&mma->work, mma7660_work_func);
489         INIT_DELAYED_WORK(&mma->delaywork, mma7660_delaywork_func);
490
491         mma->client = client;
492         i2c_set_clientdata(client, mma);
493
494         this_client = client;
495
496         err = mma7660_init_client(client);
497         if (err < 0) {
498                 rk28printk(KERN_ERR
499                        "mma7660_probe: mma7660_init_client failed\n");
500                 goto exit_request_gpio_irq_failed;
501         }
502                 
503         mma->input_dev = input_allocate_device();
504         if (!mma->input_dev) {
505                 err = -ENOMEM;
506                 rk28printk(KERN_ERR
507                        "mma7660_probe: Failed to allocate input device\n");
508                 goto exit_input_allocate_device_failed;
509         }
510
511         set_bit(EV_ABS, mma->input_dev->evbit);
512
513         /* x-axis acceleration */
514         input_set_abs_params(mma->input_dev, ABS_X, -1500, 1500, 0, 0);
515         /* y-axis acceleration */
516         input_set_abs_params(mma->input_dev, ABS_Y, -1500, 1500, 0, 0);
517         /* z-axis acceleration */
518         input_set_abs_params(mma->input_dev, ABS_Z, -1500, 1500, 0, 0);
519
520         mma->input_dev->name = "compass";
521
522         err = input_register_device(mma->input_dev);
523         if (err < 0) {
524                 rk28printk(KERN_ERR
525                        "mma7660_probe: Unable to register input device: %s\n",
526                        mma->input_dev->name);
527                 goto exit_input_register_device_failed;
528         }
529
530         err = misc_register(&mma7660_device);
531         if (err < 0) {
532                 rk28printk(KERN_ERR
533                        "mma7660_probe: mmad_device register failed\n");
534                 goto exit_misc_device_register_mma7660_device_failed;
535         }
536
537         err = gsensor_sysfs_init();
538         if (err < 0) {
539                 rk28printk(KERN_ERR
540             "mma7660_probe: gsensor sysfs init failed\n");
541                 goto exit_gsensor_sysfs_init_failed;
542         }
543         
544 #ifdef CONFIG_ANDROID_POWER
545     mma7660_early_suspend.suspend = mma7660_suspend;
546     mma7660_early_suspend.resume = mma7660_resume;
547     mma7660_early_suspend.level = 0x2;
548     android_register_early_suspend(&mma7660_early_suspend);
549 #endif
550         rk28printk(KERN_INFO "mma7660 probe ok\n");
551         mma->status = -1;
552         mma7660_start(MMA7660_RATE_32);
553         return 0;
554
555 exit_gsensor_sysfs_init_failed:
556     misc_deregister(&mma7660_device);
557 exit_misc_device_register_mma7660_device_failed:
558     input_unregister_device(mma->input_dev);
559 exit_input_register_device_failed:
560         input_free_device(mma->input_dev);
561 exit_input_allocate_device_failed:
562     free_irq(client->irq, mma);
563 exit_request_gpio_irq_failed:
564         kfree(mma);     
565 exit_alloc_data_failed:
566     ;
567         return err;
568 }
569
570
571 static int __init mma7660_i2c_init(void)
572 {
573         return i2c_add_driver(&mma7660_driver);
574 }
575
576 static void __exit mma7660_i2c_exit(void)
577 {
578         i2c_del_driver(&mma7660_driver);
579 }
580
581 module_init(mma7660_i2c_init);
582 module_exit(mma7660_i2c_exit);
583
584
585