import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / in_pocket_sensor / in_pocket.c
1 #include "in_pocket.h"
2
3 static struct inpk_context *inpk_context_obj = NULL;
4
5 static struct inpk_init_info* in_pocket_init= {0}; //modified
6 static void inpk_early_suspend(struct early_suspend *h);
7 static void inpk_late_resume(struct early_suspend *h);
8
9 static int resume_enable_status = 0;
10
11 static struct inpk_context *inpk_context_alloc_object(void)
12 {
13 struct inpk_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
14 INPK_LOG("inpk_context_alloc_object++++\n");
15 if(!obj)
16 {
17 INPK_ERR("Alloc inpk object error!\n");
18 return NULL;
19 }
20 atomic_set(&obj->wake, 0);
21 mutex_init(&obj->inpk_op_mutex);
22
23 INPK_LOG("inpk_context_alloc_object----\n");
24 return obj;
25 }
26
27 int inpk_notify()
28 {
29 int err=0;
30 int value=0;
31 struct inpk_context *cxt = NULL;
32 cxt = inpk_context_obj;
33 INPK_LOG("inpk_notify++++\n");
34
35 value =1;
36 input_report_rel(cxt->idev, EVENT_TYPE_INPK_VALUE, value);
37 input_sync(cxt->idev);
38
39 return err;
40 }
41
42 static int inpk_real_enable(int enable)
43 {
44 int err =0;
45 struct inpk_context *cxt = NULL;
46 cxt = inpk_context_obj;
47
48 if(INPK_RESUME == enable)
49 {
50 enable = resume_enable_status;
51 }
52
53 if(1==enable)
54 {
55 resume_enable_status = 1;
56 if(atomic_read(&(inpk_context_obj->early_suspend))) //not allow to enable under suspend
57 {
58 return 0;
59 }
60 if(false==cxt->is_active_data)
61 {
62 err = cxt->inpk_ctl.open_report_data(1);
63 if(err)
64 {
65 err = cxt->inpk_ctl.open_report_data(1);
66 if(err)
67 {
68 err = cxt->inpk_ctl.open_report_data(1);
69 if(err)
70 {
71 INPK_ERR("enable_in_pocket enable(%d) err 3 timers = %d\n", enable, err);
72 return err;
73 }
74 }
75 }
76 cxt->is_active_data = true;
77 INPK_LOG("enable_in_pocket real enable \n" );
78 }
79 }
80 else if((0==enable) || (INPK_SUSPEND == enable))
81 {
82 if(0==enable)
83 resume_enable_status = 0;
84 if(true==cxt->is_active_data)
85 {
86 err = cxt->inpk_ctl.open_report_data(0);
87 if(err)
88 {
89 INPK_ERR("enable_in_pocketenable(%d) err = %d\n", enable, err);
90 }
91 cxt->is_active_data =false;
92 INPK_LOG("enable_in_pocket real disable \n" );
93 }
94 }
95 return err;
96 }
97
98 int inpk_enable_nodata(int enable)
99 {
100 struct inpk_context *cxt = NULL;
101 cxt = inpk_context_obj;
102 if(NULL == cxt->inpk_ctl.open_report_data)
103 {
104 INPK_ERR("inpk_enable_nodata:inpk ctl path is NULL\n");
105 return -1;
106 }
107
108 if(1 == enable)
109 {
110 cxt->is_active_nodata = true;
111 }
112 if(0 == enable)
113 {
114 cxt->is_active_nodata = false;
115 }
116 inpk_real_enable(enable);
117 return 0;
118 }
119
120 static ssize_t inpk_show_enable_nodata(struct device* dev,
121 struct device_attribute *attr, char *buf)
122 {
123 struct inpk_context *cxt = NULL;
124 cxt = inpk_context_obj;
125
126 INPK_LOG("inpk active: %d\n", cxt->is_active_nodata);
127 return snprintf(buf, PAGE_SIZE, "%d\n", cxt->is_active_nodata);
128 }
129
130 static ssize_t inpk_store_enable_nodata(struct device* dev, struct device_attribute *attr,
131 const char *buf, size_t count)
132 {
133 struct inpk_context *cxt = NULL;
134 INPK_LOG("inpk_store_enable nodata buf=%s\n",buf);
135 mutex_lock(&inpk_context_obj->inpk_op_mutex);
136 cxt = inpk_context_obj;
137 if(NULL == cxt->inpk_ctl.open_report_data)
138 {
139 INPK_LOG("inpk_ctl enable nodata NULL\n");
140 mutex_unlock(&inpk_context_obj->inpk_op_mutex);
141 return count;
142 }
143 if (!strncmp(buf, "1", 1))
144 {
145 inpk_enable_nodata(1);
146 }
147 else if (!strncmp(buf, "0", 1))
148 {
149 inpk_enable_nodata(0);
150 }
151 else
152 {
153 INPK_ERR(" inpk_store enable nodata cmd error !!\n");
154 }
155 mutex_unlock(&inpk_context_obj->inpk_op_mutex);
156 return count;
157 }
158
159 static ssize_t inpk_store_active(struct device* dev, struct device_attribute *attr,
160 const char *buf, size_t count)
161 {
162 struct inpk_context *cxt = NULL;
163 int res =0;
164 int en=0;
165 INPK_LOG("inpk_store_active buf=%s\n",buf);
166 mutex_lock(&inpk_context_obj->inpk_op_mutex);
167
168 cxt = inpk_context_obj;
169 if((res = sscanf(buf, "%d", &en))!=1)
170 {
171 INPK_LOG(" inpk_store_active param error: res = %d\n", res);
172 }
173 INPK_LOG(" inpk_store_active en=%d\n",en);
174 if(1 == en)
175 {
176 inpk_real_enable(1);
177 }
178 else if(0 == en)
179 {
180 inpk_real_enable(0);
181 }
182 else
183 {
184 INPK_ERR(" inpk_store_active error !!\n");
185 }
186 mutex_unlock(&inpk_context_obj->inpk_op_mutex);
187 INPK_LOG(" inpk_store_active done\n");
188 return count;
189 }
190 /*----------------------------------------------------------------------------*/
191 static ssize_t inpk_show_active(struct device* dev,
192 struct device_attribute *attr, char *buf)
193 {
194 struct inpk_context *cxt = NULL;
195 cxt = inpk_context_obj;
196
197 INPK_LOG("inpk active: %d\n", cxt->is_active_data);
198 return snprintf(buf, PAGE_SIZE, "%d\n", cxt->is_active_data);
199 }
200
201 static ssize_t inpk_store_delay(struct device* dev,
202 struct device_attribute *attr, char *buf)
203 {
204 int len = 0;
205 INPK_LOG(" not support now\n");
206 return len;
207 }
208
209
210 static ssize_t inpk_show_delay(struct device* dev,
211 struct device_attribute *attr, char *buf)
212 {
213 int len = 0;
214 INPK_LOG(" not support now\n");
215 return len;
216 }
217
218
219 static ssize_t inpk_store_batch(struct device* dev, struct device_attribute *attr,
220 const char *buf, size_t count)
221 {
222 int len = 0;
223 INPK_LOG(" not support now\n");
224 return len;
225 }
226
227 static ssize_t inpk_show_batch(struct device* dev,
228 struct device_attribute *attr, char *buf)
229 {
230 int len = 0;
231 INPK_LOG(" not support now\n");
232 return len;
233 }
234
235 static ssize_t inpk_store_flush(struct device* dev, struct device_attribute *attr,
236 const char *buf, size_t count)
237 {
238 int len = 0;
239 INPK_LOG(" not support now\n");
240 return len;
241 }
242
243 static ssize_t inpk_show_flush(struct device* dev,
244 struct device_attribute *attr, char *buf)
245 {
246 int len = 0;
247 INPK_LOG(" not support now\n");
248 return len;
249 }
250
251 static ssize_t inpk_show_devnum(struct device* dev,
252 struct device_attribute *attr, char *buf)
253 {
254 char *devname = NULL;
255 devname = dev_name(&inpk_context_obj->idev->dev);
256 return snprintf(buf, PAGE_SIZE, "%s\n", devname+5); //TODO: why +5?
257 }
258 static int in_pocket_remove(struct platform_device *pdev)
259 {
260 INPK_LOG("in_pocket_remove\n");
261 return 0;
262 }
263
264 static int in_pocket_probe(struct platform_device *pdev)
265 {
266 INPK_LOG("in_pocket_probe\n");
267 return 0;
268 }
269
270 #ifdef CONFIG_OF
271 static const struct of_device_id in_pocket_of_match[] = {
272 { .compatible = "mediatek,in_pocket", },
273 {},
274 };
275 #endif
276
277 static struct platform_driver in_pocket_driver = {
278 .probe = in_pocket_probe,
279 .remove = in_pocket_remove,
280 .driver =
281 {
282 .name = "in_pocket",
283 #ifdef CONFIG_OF
284 .of_match_table = in_pocket_of_match,
285 #endif
286 }
287 };
288
289 static int inpk_real_driver_init(void)
290 {
291 int err=0;
292 INPK_LOG(" inpk_real_driver_init +\n");
293 if(0 != in_pocket_init)
294 {
295 INPK_LOG(" inpk try to init driver %s\n", in_pocket_init->name);
296 err = in_pocket_init->init();
297 if(0 == err)
298 {
299 INPK_LOG(" inpk real driver %s probe ok\n", in_pocket_init->name);
300 }
301 }
302 return err;
303 }
304
305 int inpk_driver_add(struct inpk_init_info* obj)
306 {
307 int err=0;
308
309 INPK_FUN();
310 INPK_LOG("register in_pocket driver for the first time\n");
311 if(platform_driver_register(&in_pocket_driver))
312 {
313 INPK_ERR("failed to register gensor driver already exist\n");
314 }
315 if(NULL == in_pocket_init)
316 {
317 obj->platform_diver_addr = &in_pocket_driver;
318 in_pocket_init = obj;
319 }
320
321 if(NULL==in_pocket_init)
322 {
323 INPK_ERR("INPK driver add err \n");
324 err=-1;
325 }
326
327 return err;
328 }
329 EXPORT_SYMBOL_GPL(inpk_driver_add);
330
331 static int inpk_misc_init(struct inpk_context *cxt)
332 {
333 int err=0;
334 cxt->mdev.minor = MISC_DYNAMIC_MINOR;
335 cxt->mdev.name = INPK_MISC_DEV_NAME;
336 if((err = misc_register(&cxt->mdev)))
337 {
338 INPK_ERR("unable to register inpk misc device!!\n");
339 }
340 return err;
341 }
342
343 static void inpk_input_destroy(struct inpk_context *cxt)
344 {
345 struct input_dev *dev = cxt->idev;
346
347 input_unregister_device(dev);
348 input_free_device(dev);
349 }
350
351 static int inpk_input_init(struct inpk_context *cxt)
352 {
353 struct input_dev *dev;
354 int err = 0;
355
356 dev = input_allocate_device();
357 if (NULL == dev)
358 return -ENOMEM;
359
360 dev->name = INPK_INPUTDEV_NAME;
361 input_set_capability(dev, EV_REL, EVENT_TYPE_INPK_VALUE);
362
363 input_set_drvdata(dev, cxt);
364 set_bit(EV_REL, dev->evbit);
365 err = input_register_device(dev);
366 if (err < 0) {
367 input_free_device(dev);
368 return err;
369 }
370 cxt->idev= dev;
371
372 return 0;
373 }
374
375 DEVICE_ATTR(inpkenablenodata, S_IWUSR | S_IRUGO, inpk_show_enable_nodata, inpk_store_enable_nodata);
376 DEVICE_ATTR(inpkactive, S_IWUSR | S_IRUGO, inpk_show_active, inpk_store_active);
377 DEVICE_ATTR(inpkdelay, S_IWUSR | S_IRUGO, inpk_show_delay, inpk_store_delay);
378 DEVICE_ATTR(inpkbatch, S_IWUSR | S_IRUGO, inpk_show_batch, inpk_store_batch);
379 DEVICE_ATTR(inpkflush, S_IWUSR | S_IRUGO, inpk_show_flush, inpk_store_flush);
380 DEVICE_ATTR(inpkdevnum, S_IWUSR | S_IRUGO, inpk_show_devnum, NULL);
381
382
383 static struct attribute *inpk_attributes[] = {
384 &dev_attr_inpkenablenodata.attr,
385 &dev_attr_inpkactive.attr,
386 &dev_attr_inpkdelay.attr,
387 &dev_attr_inpkbatch.attr,
388 &dev_attr_inpkflush.attr,
389 &dev_attr_inpkdevnum.attr,
390 NULL
391 };
392
393 static struct attribute_group inpk_attribute_group = {
394 .attrs = inpk_attributes
395 };
396
397 int inpk_register_data_path(struct inpk_data_path *data)
398 {
399 struct inpk_context *cxt = NULL;
400 cxt = inpk_context_obj;
401 cxt->inpk_data.get_data = data->get_data;
402 if(NULL == cxt->inpk_data.get_data)
403 {
404 INPK_LOG("inpk register data path fail \n");
405 return -1;
406 }
407 return 0;
408 }
409
410 int inpk_register_control_path(struct inpk_control_path *ctl)
411 {
412 struct inpk_context *cxt = NULL;
413 int err =0;
414 cxt = inpk_context_obj;
415 // cxt->inpk_ctl.enable = ctl->enable;
416 // cxt->inpk_ctl.enable_nodata = ctl->enable_nodata;
417 cxt->inpk_ctl.open_report_data = ctl->open_report_data;
418
419 if(NULL==cxt->inpk_ctl.open_report_data)
420 {
421 INPK_LOG("inpk register control path fail \n");
422 return -1;
423 }
424
425 //add misc dev for sensor hal control cmd
426 err = inpk_misc_init(inpk_context_obj);
427 if(err)
428 {
429 INPK_ERR("unable to register inpk misc device!!\n");
430 return -2;
431 }
432 err = sysfs_create_group(&inpk_context_obj->mdev.this_device->kobj,
433 &inpk_attribute_group);
434 if (err < 0)
435 {
436 INPK_ERR("unable to create inpk attribute file\n");
437 return -3;
438 }
439 kobject_uevent(&inpk_context_obj->mdev.this_device->kobj, KOBJ_ADD);
440 return 0;
441 }
442
443 static int inpk_probe(struct platform_device *pdev)
444 {
445 int err;
446 INPK_LOG("+++++++++++++inpk_probe!!\n");
447
448 inpk_context_obj = inpk_context_alloc_object();
449 if (!inpk_context_obj)
450 {
451 err = -ENOMEM;
452 INPK_ERR("unable to allocate devobj!\n");
453 goto exit_alloc_data_failed;
454 }
455 //init real inpk driver
456 err = inpk_real_driver_init();
457 if(err)
458 {
459 INPK_ERR("inpk real driver init fail\n");
460 goto real_driver_init_fail;
461 }
462
463 //init input dev
464 err = inpk_input_init(inpk_context_obj);
465 if(err)
466 {
467 INPK_ERR("unable to register inpk input device!\n");
468 goto exit_alloc_input_dev_failed;
469 }
470
471 #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_EARLYSUSPEND)
472 atomic_set(&(inpk_context_obj->early_suspend), 0);
473 inpk_context_obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1,
474 inpk_context_obj->early_drv.suspend = inpk_early_suspend,
475 inpk_context_obj->early_drv.resume = inpk_late_resume,
476 register_early_suspend(&inpk_context_obj->early_drv);
477 #endif //#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_EARLYSUSPEND)
478
479 INPK_LOG("----inpk_probe OK !!\n");
480 return 0;
481
482
483 if (err)
484 {
485 INPK_ERR("sysfs node creation error \n");
486 inpk_input_destroy(inpk_context_obj);
487 }
488 real_driver_init_fail:
489 exit_alloc_input_dev_failed:
490 kfree(inpk_context_obj);
491 exit_alloc_data_failed:
492 INPK_LOG("----inpk_probe fail !!!\n");
493 return err;
494 }
495
496 static int inpk_remove(struct platform_device *pdev)
497 {
498 int err=0;
499 INPK_FUN(f);
500 input_unregister_device(inpk_context_obj->idev);
501 sysfs_remove_group(&inpk_context_obj->idev->dev.kobj,
502 &inpk_attribute_group);
503
504 if((err = misc_deregister(&inpk_context_obj->mdev)))
505 {
506 INPK_ERR("misc_deregister fail: %d\n", err);
507 }
508 kfree(inpk_context_obj);
509 return 0;
510 }
511
512 static void inpk_early_suspend(struct early_suspend *h)
513 {
514 atomic_set(&(inpk_context_obj->early_suspend), 1);
515 if(!atomic_read(&inpk_context_obj->wake)) //not wake up, disable in early suspend
516 {
517 inpk_real_enable(INPK_SUSPEND);
518 }
519 INPK_LOG(" inpk_early_suspend ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(inpk_context_obj->early_suspend)));
520 return ;
521 }
522 /*----------------------------------------------------------------------------*/
523 static void inpk_late_resume(struct early_suspend *h)
524 {
525 atomic_set(&(inpk_context_obj->early_suspend), 0);
526 if(!atomic_read(&inpk_context_obj->wake) && resume_enable_status) //not wake up, disable in early suspend
527 {
528 inpk_real_enable(INPK_RESUME);
529 }
530 INPK_LOG(" inpk_late_resume ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(inpk_context_obj->early_suspend)));
531 return ;
532 }
533
534 #if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(USE_EARLY_SUSPEND)
535 static int inpk_suspend(struct platform_device *dev, pm_message_t state)
536 {
537 atomic_set(&(inpk_context_obj->suspend), 1);
538 if(!atomic_read(&inpk_context_obj->wake)) //not wake up, disable in early suspend
539 {
540 inpk_real_enable(INPK_SUSPEND);
541 }
542 INPK_LOG(" inpk_suspend ok------->hwm_obj->suspend=%d \n",atomic_read(&(inpk_context_obj->suspend)));
543 return 0;
544 }
545 /*----------------------------------------------------------------------------*/
546 static int inpk_resume(struct platform_device *dev)
547 {
548 atomic_set(&(inpk_context_obj->suspend), 0);
549 if(!atomic_read(&inpk_context_obj->wake) && resume_enable_status) //not wake up, disable in early suspend
550 {
551 inpk_real_enable(INPK_RESUME);
552 }
553 INPK_LOG(" inpk_resume ok------->hwm_obj->suspend=%d \n",atomic_read(&(inpk_context_obj->suspend)));
554 return 0;
555 }
556 #endif //#if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(USE_EARLY_SUSPEND)
557
558 #ifdef CONFIG_OF
559 static const struct of_device_id m_inpk_pl_of_match[] = {
560 { .compatible = "mediatek,m_inpk_pl", },
561 {},
562 };
563 #endif
564
565 static struct platform_driver inpk_driver =
566 {
567 .probe = inpk_probe,
568 .remove = inpk_remove,
569 #if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(USE_EARLY_SUSPEND)
570 .suspend = inpk_suspend,
571 .resume = inpk_resume,
572 #endif
573 .driver =
574 {
575 .name = INPK_PL_DEV_NAME,
576 #ifdef CONFIG_OF
577 .of_match_table = m_inpk_pl_of_match,
578 #endif
579 }
580 };
581
582 static int __init inpk_init(void)
583 {
584 INPK_FUN();
585
586 if(platform_driver_register(&inpk_driver))
587 {
588 INPK_ERR("failed to register inpk driver\n");
589 return -ENODEV;
590 }
591
592 return 0;
593 }
594
595 static void __exit inpk_exit(void)
596 {
597 platform_driver_unregister(&inpk_driver);
598 platform_driver_unregister(&in_pocket_driver);
599 }
600
601 late_initcall(inpk_init);
602 //module_init(inpk_init);
603 //module_exit(inpk_exit);
604 MODULE_LICENSE("GPL");
605 MODULE_DESCRIPTION("INPK device driver");
606 MODULE_AUTHOR("Mediatek");
607