import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / step_counter / step_counter.c
1
2 #include "step_counter.h"
3
4 static struct step_c_context *step_c_context_obj = NULL;
5
6
7 static struct step_c_init_info* step_counter_init_list[MAX_CHOOSE_STEP_C_NUM]= {0}; //modified
8 static void step_c_early_suspend(struct early_suspend *h);
9 static void step_c_late_resume(struct early_suspend *h);
10
11 static void step_c_work_func(struct work_struct *work)
12 {
13
14 struct step_c_context *cxt = NULL;
15 int out_size;
16 //hwm_sensor_data sensor_data;
17 int value,status,div;
18 int64_t nt;
19 struct timespec time;
20 int err, idx;
21
22 cxt = step_c_context_obj;
23
24 if(NULL == cxt->step_c_data.get_data)
25 {
26 STEP_C_LOG("step_c driver not register data path\n");
27 }
28
29
30 time.tv_sec = time.tv_nsec = 0;
31 time = get_monotonic_coarse();
32 nt = time.tv_sec*1000000000LL+time.tv_nsec;
33
34 //add wake lock to make sure data can be read before system suspend
35 err = cxt->step_c_data.get_data(&value,&status);
36
37 if(err)
38 {
39 STEP_C_ERR("get step_c data fails!!\n" );
40 goto step_c_loop;
41 }
42 else
43 {
44 {
45 cxt->drv_data.step_c_data.values[0] = value;
46 cxt->drv_data.step_c_data.status = status;
47 cxt->drv_data.step_c_data.time = nt;
48 }
49 }
50
51 if(true == cxt->is_first_data_after_enable)
52 {
53 cxt->is_first_data_after_enable = false;
54 //filter -1 value
55 if(STEP_C_INVALID_VALUE == cxt->drv_data.step_c_data.values[0])
56 {
57 STEP_C_LOG(" read invalid data \n");
58 goto step_c_loop;
59
60 }
61 }
62 //report data to input device
63 //printk("new step_c work run....\n");
64 STEP_C_LOG("step_c data[%d] \n" ,cxt->drv_data.step_c_data.values[0]);
65
66 step_c_data_report(cxt->idev,
67 cxt->drv_data.step_c_data.values[0],
68 cxt->drv_data.step_c_data.status);
69
70 step_c_loop:
71 if(true == cxt->is_polling_run)
72 {
73 {
74 mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
75 }
76 }
77 }
78
79 static void step_c_poll(unsigned long data)
80 {
81 struct step_c_context *obj = (struct step_c_context *)data;
82 if(obj != NULL)
83 {
84 schedule_work(&obj->report);
85 }
86 }
87
88 static struct step_c_context *step_c_context_alloc_object(void)
89 {
90
91 struct step_c_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
92 STEP_C_LOG("step_c_context_alloc_object++++\n");
93 if(!obj)
94 {
95 STEP_C_ERR("Alloc step_c object error!\n");
96 return NULL;
97 }
98 atomic_set(&obj->delay, 200); /*5Hz*/// set work queue delay time 200ms
99 atomic_set(&obj->wake, 0);
100 INIT_WORK(&obj->report, step_c_work_func);
101 init_timer(&obj->timer);
102 obj->timer.expires = jiffies + atomic_read(&obj->delay)/(1000/HZ);
103 obj->timer.function = step_c_poll;
104 obj->timer.data = (unsigned long)obj;
105 obj->is_first_data_after_enable = false;
106 obj->is_polling_run = false;
107 mutex_init(&obj->step_c_op_mutex);
108 obj->is_batch_enable = false;//for batch mode init
109
110 STEP_C_LOG("step_c_context_alloc_object----\n");
111 return obj;
112 }
113
114 int step_notify(STEP_NOTIFY_TYPE type)
115 {
116 int err=0;
117 int value=0;
118 struct step_c_context *cxt = NULL;
119 cxt = step_c_context_obj;
120 STEP_C_LOG("step_notify++++\n");
121
122 if(type == TYPE_STEP_DETECTOR)
123 {
124 STEP_C_LOG("fwq TYPE_STEP_DETECTOR notify\n");
125 //cxt->step_c_data.get_data_step_d(&value);
126 //step_c_data_report(cxt->idev,value,3);
127 value =1;
128 input_report_rel(cxt->idev, EVENT_TYPE_STEP_DETECTOR_VALUE, value);
129 input_sync(cxt->idev);
130
131 }
132 if(type == TYPE_SIGNIFICANT)
133 {
134 STEP_C_LOG("fwq TYPE_SIGNIFICANT notify\n");
135 //cxt->step_c_data.get_data_significant(&value);
136 value=1;
137 input_report_rel(cxt->idev, EVENT_TYPE_SIGNIFICANT_VALUE, value);
138 input_sync(cxt->idev);
139 }
140
141 return err;
142 }
143
144 static int step_d_real_enable(int enable)
145 {
146 int err =0;
147 struct step_c_context *cxt = NULL;
148 cxt = step_c_context_obj;
149 if(1==enable)
150 {
151
152
153 err = cxt->step_c_ctl.enable_step_detect(1);
154 if(err)
155 {
156 err = cxt->step_c_ctl.enable_step_detect(1);
157 if(err)
158 {
159 err = cxt->step_c_ctl.enable_step_detect(1);
160 if(err)
161 STEP_C_ERR("step_d enable(%d) err 3 timers = %d\n", enable, err);
162 }
163 }
164 STEP_C_LOG("step_d real enable \n" );
165 }
166
167
168 if(0==enable)
169 {
170
171 err = cxt->step_c_ctl.enable_nodata(0);
172 if(err)
173 {
174 STEP_C_ERR("step_d enable(%d) err = %d\n", enable, err);
175 }
176 STEP_C_LOG("step_d real disable \n" );
177
178 }
179
180 return err;
181 }
182
183 static int significant_real_enable(int enable)
184 {
185 int err =0;
186 struct step_c_context *cxt = NULL;
187 cxt = step_c_context_obj;
188 if(1==enable)
189 {
190
191
192 err = cxt->step_c_ctl.enable_significant(1);
193 if(err)
194 {
195 err = cxt->step_c_ctl.enable_significant(1);
196 if(err)
197 {
198 err = cxt->step_c_ctl.enable_significant(1);
199 if(err)
200 STEP_C_ERR("enable_significant enable(%d) err 3 timers = %d\n", enable, err);
201 }
202 }
203 STEP_C_LOG("enable_significant real enable \n" );
204 }
205
206
207 if(0==enable)
208 {
209
210 err = cxt->step_c_ctl.enable_significant(0);
211 if(err)
212 {
213 STEP_C_ERR("enable_significantenable(%d) err = %d\n", enable, err);
214 }
215 STEP_C_LOG("enable_significant real disable \n" );
216
217 }
218
219 return err;
220 }
221
222
223 static int step_c_real_enable(int enable)
224 {
225 int err =0;
226 struct step_c_context *cxt = NULL;
227 cxt = step_c_context_obj;
228 if(1==enable)
229 {
230
231 if(true==cxt->is_active_data || true ==cxt->is_active_nodata)
232 {
233 err = cxt->step_c_ctl.enable_nodata(1);
234 if(err)
235 {
236 err = cxt->step_c_ctl.enable_nodata(1);
237 if(err)
238 {
239 err = cxt->step_c_ctl.enable_nodata(1);
240 if(err)
241 STEP_C_ERR("step_c enable(%d) err 3 timers = %d\n", enable, err);
242 }
243 }
244 STEP_C_LOG("step_c real enable \n" );
245 }
246
247 }
248 if(0==enable)
249 {
250 if(false==cxt->is_active_data && false ==cxt->is_active_nodata)
251 {
252 err = cxt->step_c_ctl.enable_nodata(0);
253 if(err)
254 {
255 STEP_C_ERR("step_c enable(%d) err = %d\n", enable, err);
256 }
257 STEP_C_LOG("step_c real disable \n" );
258 }
259
260 }
261
262 return err;
263 }
264 static int step_c_enable_data(int enable)
265 {
266 struct step_c_context *cxt = NULL;
267 int err =0;
268 cxt = step_c_context_obj;
269 if(NULL == cxt->step_c_ctl.open_report_data)
270 {
271 STEP_C_ERR("no step_c control path\n");
272 return -1;
273 }
274
275 if(1 == enable)
276 {
277 STEP_C_LOG("STEP_C enable data\n");
278 cxt->is_active_data =true;
279 cxt->is_first_data_after_enable = true;
280 cxt->step_c_ctl.open_report_data(1);
281 if(false == cxt->is_polling_run && cxt->is_batch_enable == false)
282 {
283 if(false == cxt->step_c_ctl.is_report_input_direct)
284 {
285 mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
286 cxt->is_polling_run = true;
287 }
288 }
289 }
290 if(0 == enable)
291 {
292 STEP_C_LOG("STEP_C disable \n");
293 cxt->is_active_data =false;
294 cxt->step_c_ctl.open_report_data(0);
295 if(true == cxt->is_polling_run)
296 {
297 if(false == cxt->step_c_ctl.is_report_input_direct )
298 {
299 cxt->is_polling_run = false;
300 del_timer_sync(&cxt->timer);
301 cancel_work_sync(&cxt->report);
302 cxt->drv_data.step_c_data.values[0] = STEP_C_INVALID_VALUE;
303 }
304 }
305
306 }
307 step_c_real_enable(enable);
308 return 0;
309 }
310
311
312
313 int step_c_enable_nodata(int enable)
314 {
315 struct step_c_context *cxt = NULL;
316 int err =0;
317 cxt = step_c_context_obj;
318 if(NULL == cxt->step_c_ctl.enable_nodata)
319 {
320 STEP_C_ERR("step_c_enable_nodata:step_c ctl path is NULL\n");
321 return -1;
322 }
323
324 if(1 == enable)
325 {
326 cxt->is_active_nodata = true;
327 }
328
329 if(0 == enable)
330 {
331 cxt->is_active_nodata = false;
332 }
333 step_c_real_enable(enable);
334 return 0;
335 }
336
337
338 static ssize_t step_c_show_enable_nodata(struct device* dev,
339 struct device_attribute *attr, char *buf)
340 {
341 int len = 0;
342 STEP_C_LOG(" not support now\n");
343 return len;
344 }
345
346 static ssize_t step_c_store_enable_nodata(struct device* dev, struct device_attribute *attr,
347 const char *buf, size_t count)
348 {
349 STEP_C_LOG("step_c_store_enable nodata buf=%s\n",buf);
350 mutex_lock(&step_c_context_obj->step_c_op_mutex);
351 struct step_c_context *cxt = NULL;
352 int err =0;
353 cxt = step_c_context_obj;
354 if(NULL == cxt->step_c_ctl.enable_nodata)
355 {
356 STEP_C_LOG("step_c_ctl enable nodata NULL\n");
357 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
358 return count;
359 }
360 if (!strncmp(buf, "1", 1))
361 {
362 step_c_enable_nodata(1);
363 }
364 else if (!strncmp(buf, "0", 1))
365 {
366 step_c_enable_nodata(0);
367 }
368 else
369 {
370 STEP_C_ERR(" step_c_store enable nodata cmd error !!\n");
371 }
372 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
373 }
374
375 static ssize_t step_c_store_active(struct device* dev, struct device_attribute *attr,
376 const char *buf, size_t count)
377 {
378 STEP_C_LOG("step_c_store_active buf=%s\n",buf);
379 struct step_c_context *cxt = NULL;
380 int res =0;
381 int handle=0;
382 int en=0;
383 mutex_lock(&step_c_context_obj->step_c_op_mutex);
384
385 cxt = step_c_context_obj;
386 if(NULL == cxt->step_c_ctl.open_report_data)
387 {
388 STEP_C_LOG("step_c_ctl enable NULL\n");
389 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
390 return count;
391 }
392 if((res = sscanf(buf, "%d,%d", &handle, &en))!=2)
393 {
394 STEP_C_LOG(" step_store_active param error: res = %d\n", res);
395 }
396 STEP_C_LOG(" step_store_active handle=%d ,en=%d\n",handle,en);
397 switch(handle)
398 {
399 case ID_STEP_COUNTER:
400 if(1 == en)
401 {
402 step_c_enable_data(1);
403 }
404 else if(0 == en)
405 {
406 step_c_enable_data(0);
407 }
408 else
409 {
410 STEP_C_ERR(" step_c_store_active error !!\n");
411 }
412 break;
413 case ID_STEP_DETECTOR:
414 if(1 == en)
415 {
416 step_d_real_enable(1);
417 }
418 else if(0 == en)
419 {
420 step_d_real_enable(0);
421 }
422 else
423 {
424 STEP_C_ERR(" step_d_real_enable error !!\n");
425 }
426 break;
427 case ID_SIGNIFICANT_MOTION:
428 if(1 == en)
429 {
430 significant_real_enable(1);
431 }
432 else if(0 == en)
433 {
434 significant_real_enable(0);
435 }
436 else
437 {
438 STEP_C_ERR(" significant_real_enable error !!\n");
439 }
440 break;
441
442 }
443
444 /*
445 if (!strncmp(buf, "1", 1))
446 {
447 step_c_enable_data(1);
448 }
449 else if (!strncmp(buf, "0", 1))
450 {
451 step_c_enable_data(0);
452 }
453 else
454 {
455 STEP_C_ERR(" step_c_store_active error !!\n");
456 }
457 */
458 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
459 STEP_C_LOG(" step_c_store_active done\n");
460 return count;
461 }
462 /*----------------------------------------------------------------------------*/
463 static ssize_t step_c_show_active(struct device* dev,
464 struct device_attribute *attr, char *buf)
465 {
466 struct step_c_context *cxt = NULL;
467 cxt = step_c_context_obj;
468 int div=cxt->step_c_data.vender_div;
469 STEP_C_LOG("step_c vender_div value: %d\n", div);
470 return snprintf(buf, PAGE_SIZE, "%d\n", div);
471 }
472
473 static ssize_t step_c_store_delay(struct device* dev, struct device_attribute *attr,
474 const char *buf, size_t count)
475
476 {
477 mutex_lock(&step_c_context_obj->step_c_op_mutex);
478 struct step_c_context *devobj = (struct step_c_context*)dev_get_drvdata(dev);
479 int delay;
480 int mdelay=0;
481 struct step_c_context *cxt = NULL;
482 int err =0;
483 cxt = step_c_context_obj;
484 if(NULL == cxt->step_c_ctl.set_delay)
485 {
486 STEP_C_LOG("step_c_ctl set_delay NULL\n");
487 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
488 return count;
489 }
490
491 if (1 != sscanf(buf, "%d", &delay)) {
492 STEP_C_ERR("invalid format!!\n");
493 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
494 return count;
495 }
496
497 if(false == cxt->step_c_ctl.is_report_input_direct)
498 {
499 mdelay = (int)delay/1000/1000;
500 atomic_set(&step_c_context_obj->delay, mdelay);
501 }
502 cxt->step_c_ctl.set_delay(delay);
503 STEP_C_LOG(" step_c_delay %d ns\n",delay);
504 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
505 return count;
506
507 }
508
509 static ssize_t step_c_show_delay(struct device* dev,
510 struct device_attribute *attr, char *buf)
511 {
512 int len = 0;
513 STEP_C_LOG(" not support now\n");
514 return len;
515 }
516
517
518 static ssize_t step_c_store_batch(struct device* dev, struct device_attribute *attr,
519 const char *buf, size_t count)
520 {
521 STEP_C_LOG("step_c_store_batch buf=%s\n",buf);
522 mutex_lock(&step_c_context_obj->step_c_op_mutex);
523 struct step_c_context *cxt = NULL;
524 int err =0;
525 cxt = step_c_context_obj;
526
527 if (!strncmp(buf, "1", 1))
528 {
529 cxt->is_batch_enable = true;
530 if(true == cxt->is_polling_run)
531 {
532 cxt->is_polling_run = false;
533 del_timer_sync(&cxt->timer);
534 cancel_work_sync(&cxt->report);
535 cxt->drv_data.step_c_data.values[0] = STEP_C_INVALID_VALUE;
536 cxt->drv_data.step_c_data.values[1] = STEP_C_INVALID_VALUE;
537 cxt->drv_data.step_c_data.values[2] = STEP_C_INVALID_VALUE;
538 }
539 }
540 else if (!strncmp(buf, "0", 1))
541 {
542 cxt->is_batch_enable = false;
543 if(false == cxt->is_polling_run)
544 {
545 if(false == cxt->step_c_ctl.is_report_input_direct)
546 {
547 mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
548 cxt->is_polling_run = true;
549 }
550 }
551 }
552 else
553 {
554 STEP_C_ERR(" step_c_store_batch error !!\n");
555 }
556 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
557 STEP_C_LOG(" step_c_store_batch done: %d\n", cxt->is_batch_enable);
558 return count;
559
560 }
561
562 static ssize_t step_c_show_batch(struct device* dev,
563 struct device_attribute *attr, char *buf)
564 {
565 return snprintf(buf, PAGE_SIZE, "%d\n", 0);
566 }
567
568 static ssize_t step_c_store_flush(struct device* dev, struct device_attribute *attr,
569 const char *buf, size_t count)
570 {
571 mutex_lock(&step_c_context_obj->step_c_op_mutex);
572 struct step_c_context *devobj = (struct step_c_context*)dev_get_drvdata(dev);
573 //do read FIFO data function and report data immediately
574 mutex_unlock(&step_c_context_obj->step_c_op_mutex);
575 return count;
576 }
577
578 static ssize_t step_c_show_flush(struct device* dev,
579 struct device_attribute *attr, char *buf)
580 {
581 return snprintf(buf, PAGE_SIZE, "%d\n", 0);
582 }
583
584 static ssize_t step_c_show_devnum(struct device* dev,
585 struct device_attribute *attr, char *buf)
586 {
587 char *devname = NULL;
588 devname = dev_name(&step_c_context_obj->idev->dev);
589 return snprintf(buf, PAGE_SIZE, "%s\n", devname+5);
590 }
591 static int step_counter_remove(struct platform_device *pdev)
592 {
593 STEP_C_LOG("step_counter_remove\n");
594 return 0;
595 }
596
597 static int step_counter_probe(struct platform_device *pdev)
598 {
599 STEP_C_LOG("step_counter_probe\n");
600 return 0;
601 }
602
603 #ifdef CONFIG_OF
604 static const struct of_device_id step_counter_of_match[] = {
605 { .compatible = "mediatek,step_counter", },
606 {},
607 };
608 #endif
609
610 static struct platform_driver step_counter_driver = {
611 .probe = step_counter_probe,
612 .remove = step_counter_remove,
613 .driver =
614 {
615 .name = "step_counter",
616 #ifdef CONFIG_OF
617 .of_match_table = step_counter_of_match,
618 #endif
619 }
620 };
621
622 static int step_c_real_driver_init(void)
623 {
624 int i =0;
625 int err=0;
626 STEP_C_LOG(" step_c_real_driver_init +\n");
627 for(i = 0; i < MAX_CHOOSE_STEP_C_NUM; i++)
628 {
629 STEP_C_LOG(" i=%d\n",i);
630 if(0 != step_counter_init_list[i])
631 {
632 STEP_C_LOG(" step_c try to init driver %s\n", step_counter_init_list[i]->name);
633 err = step_counter_init_list[i]->init();
634 if(0 == err)
635 {
636 STEP_C_LOG(" step_c real driver %s probe ok\n", step_counter_init_list[i]->name);
637 break;
638 }
639 }
640 }
641
642 if(i == MAX_CHOOSE_STEP_C_NUM)
643 {
644 STEP_C_LOG(" step_c_real_driver_init fail\n");
645 err=-1;
646 }
647 return err;
648 }
649
650 int step_c_driver_add(struct step_c_init_info* obj)
651 {
652 int err=0;
653 int i =0;
654
655 STEP_C_FUN();
656
657
658 for(i =0; i < MAX_CHOOSE_STEP_C_NUM; i++ )
659 {
660 if(i == 0){
661 STEP_C_LOG("register step_counter driver for the first time\n");
662 if(platform_driver_register(&step_counter_driver))
663 {
664 STEP_C_ERR("failed to register gensor driver already exist\n");
665 }
666 }
667
668 if(NULL == step_counter_init_list[i])
669 {
670 obj->platform_diver_addr = &step_counter_driver;
671 step_counter_init_list[i] = obj;
672 break;
673 }
674 }
675 if(NULL==step_counter_init_list[i])
676 {
677 STEP_C_ERR("STEP_C driver add err \n");
678 err=-1;
679 }
680
681 return err;
682 }
683 EXPORT_SYMBOL_GPL(step_c_driver_add);
684
685 static int step_c_misc_init(struct step_c_context *cxt)
686 {
687
688 int err=0;
689 cxt->mdev.minor = MISC_DYNAMIC_MINOR;
690 cxt->mdev.name = STEP_C_MISC_DEV_NAME;
691 if((err = misc_register(&cxt->mdev)))
692 {
693 STEP_C_ERR("unable to register step_c misc device!!\n");
694 }
695 return err;
696 }
697
698 static void step_c_input_destroy(struct step_c_context *cxt)
699 {
700 struct input_dev *dev = cxt->idev;
701
702 input_unregister_device(dev);
703 input_free_device(dev);
704 }
705
706 static int step_c_input_init(struct step_c_context *cxt)
707 {
708 struct input_dev *dev;
709 int err = 0;
710
711 dev = input_allocate_device();
712 if (NULL == dev)
713 return -ENOMEM;
714
715 dev->name = STEP_C_INPUTDEV_NAME;
716 input_set_capability(dev, EV_REL, EVENT_TYPE_STEP_DETECTOR_VALUE);
717 input_set_capability(dev, EV_REL, EVENT_TYPE_SIGNIFICANT_VALUE);
718 input_set_capability(dev, EV_ABS, EVENT_TYPE_STEP_C_VALUE);
719 input_set_capability(dev, EV_ABS, EVENT_TYPE_STEP_C_STATUS);
720
721 input_set_abs_params(dev, EVENT_TYPE_STEP_C_VALUE, STEP_C_VALUE_MIN, STEP_C_VALUE_MAX, 0, 0);
722 input_set_abs_params(dev, EVENT_TYPE_STEP_C_STATUS, STEP_C_STATUS_MIN, STEP_C_STATUS_MAX, 0, 0);
723 input_set_drvdata(dev, cxt);
724 set_bit(EV_REL, dev->evbit);
725 err = input_register_device(dev);
726 if (err < 0) {
727 input_free_device(dev);
728 return err;
729 }
730 cxt->idev= dev;
731
732 return 0;
733 }
734
735 DEVICE_ATTR(step_cenablenodata, S_IWUSR | S_IRUGO, step_c_show_enable_nodata, step_c_store_enable_nodata);
736 DEVICE_ATTR(step_cactive, S_IWUSR | S_IRUGO, step_c_show_active, step_c_store_active);
737 DEVICE_ATTR(step_cdelay, S_IWUSR | S_IRUGO, step_c_show_delay, step_c_store_delay);
738 DEVICE_ATTR(step_cbatch, S_IWUSR | S_IRUGO, step_c_show_batch, step_c_store_batch);
739 DEVICE_ATTR(step_cflush, S_IWUSR | S_IRUGO, step_c_show_flush, step_c_store_flush);
740 DEVICE_ATTR(step_cdevnum, S_IWUSR | S_IRUGO, step_c_show_devnum, NULL);
741
742
743 static struct attribute *step_c_attributes[] = {
744 &dev_attr_step_cenablenodata.attr,
745 &dev_attr_step_cactive.attr,
746 &dev_attr_step_cdelay.attr,
747 &dev_attr_step_cbatch.attr,
748 &dev_attr_step_cflush.attr,
749 &dev_attr_step_cdevnum.attr,
750 NULL
751 };
752
753 static struct attribute_group step_c_attribute_group = {
754 .attrs = step_c_attributes
755 };
756
757 int step_c_register_data_path(struct step_c_data_path *data)
758 {
759 struct step_c_context *cxt = NULL;
760 int err =0;
761 cxt = step_c_context_obj;
762 cxt->step_c_data.get_data = data->get_data;
763 cxt->step_c_data.vender_div = data->vender_div;
764 cxt->step_c_data.get_data_significant = data->get_data_significant;
765 cxt->step_c_data.get_data_step_d = data->get_data_step_d;
766 STEP_C_LOG("step_c register data path vender_div: %d\n", cxt->step_c_data.vender_div);
767 if(NULL == cxt->step_c_data.get_data
768 || NULL == cxt->step_c_data.get_data_significant
769 || NULL == cxt->step_c_data.get_data_step_d)
770 {
771 STEP_C_LOG("step_c register data path fail \n");
772 return -1;
773 }
774 return 0;
775 }
776
777 int step_c_register_control_path(struct step_c_control_path *ctl)
778 {
779 struct step_c_context *cxt = NULL;
780 int err =0;
781 cxt = step_c_context_obj;
782 cxt->step_c_ctl.set_delay = ctl->set_delay;
783 cxt->step_c_ctl.open_report_data= ctl->open_report_data;
784 cxt->step_c_ctl.enable_nodata = ctl->enable_nodata;
785 cxt->step_c_ctl.is_support_batch = ctl->is_support_batch;
786 cxt->step_c_ctl.is_report_input_direct= ctl->is_report_input_direct;
787 cxt->step_c_ctl.is_support_batch = ctl->is_support_batch;
788 cxt->step_c_ctl.enable_significant = ctl->enable_significant;
789 cxt->step_c_ctl.enable_step_detect = ctl->enable_step_detect;
790
791 if(NULL==cxt->step_c_ctl.set_delay || NULL==cxt->step_c_ctl.open_report_data
792 || NULL==cxt->step_c_ctl.enable_nodata
793 || NULL==cxt->step_c_ctl.enable_significant
794 || NULL==cxt->step_c_ctl.enable_step_detect)
795 {
796 STEP_C_LOG("step_c register control path fail \n");
797 return -1;
798 }
799
800 //add misc dev for sensor hal control cmd
801 err = step_c_misc_init(step_c_context_obj);
802 if(err)
803 {
804 STEP_C_ERR("unable to register step_c misc device!!\n");
805 return -2;
806 }
807 err = sysfs_create_group(&step_c_context_obj->mdev.this_device->kobj,
808 &step_c_attribute_group);
809 if (err < 0)
810 {
811 STEP_C_ERR("unable to create step_c attribute file\n");
812 return -3;
813 }
814
815 kobject_uevent(&step_c_context_obj->mdev.this_device->kobj, KOBJ_ADD);
816
817 return 0;
818 }
819
820 int step_c_data_report(struct input_dev *dev, int value, int status)
821 {
822 //STEP_C_LOG("+step_c_data_report! %d, %d, %d, %d\n",x,y,z,status);
823 input_report_abs(dev, EVENT_TYPE_STEP_C_VALUE, value);
824 input_report_abs(dev, EVENT_TYPE_STEP_C_STATUS, status);
825 input_sync(dev);
826 }
827
828 static int step_c_probe(struct platform_device *pdev)
829 {
830
831 int err;
832 STEP_C_LOG("+++++++++++++step_c_probe!!\n");
833
834 step_c_context_obj = step_c_context_alloc_object();
835 if (!step_c_context_obj)
836 {
837 err = -ENOMEM;
838 STEP_C_ERR("unable to allocate devobj!\n");
839 goto exit_alloc_data_failed;
840 }
841
842 //init real step_c driver
843 err = step_c_real_driver_init();
844 if(err)
845 {
846 STEP_C_ERR("step_c real driver init fail\n");
847 goto real_driver_init_fail;
848 }
849
850 //init input dev
851 err = step_c_input_init(step_c_context_obj);
852 if(err)
853 {
854 STEP_C_ERR("unable to register step_c input device!\n");
855 goto exit_alloc_input_dev_failed;
856 }
857
858 atomic_set(&(step_c_context_obj->early_suspend), 0);
859 step_c_context_obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1,
860 step_c_context_obj->early_drv.suspend = step_c_early_suspend,
861 step_c_context_obj->early_drv.resume = step_c_late_resume,
862 register_early_suspend(&step_c_context_obj->early_drv);
863
864
865 STEP_C_LOG("----step_c_probe OK !!\n");
866 return 0;
867
868 exit_hwmsen_create_attr_failed:
869 exit_misc_register_failed:
870
871 exit_err_sysfs:
872
873 if (err)
874 {
875 STEP_C_ERR("sysfs node creation error \n");
876 step_c_input_destroy(step_c_context_obj);
877 }
878
879 real_driver_init_fail:
880 exit_alloc_input_dev_failed:
881 kfree(step_c_context_obj);
882
883 exit_alloc_data_failed:
884
885
886 STEP_C_LOG("----step_c_probe fail !!!\n");
887 return err;
888 }
889
890
891
892 static int step_c_remove(struct platform_device *pdev)
893 {
894 STEP_C_FUN(f);
895 int err=0;
896 input_unregister_device(step_c_context_obj->idev);
897 sysfs_remove_group(&step_c_context_obj->idev->dev.kobj,
898 &step_c_attribute_group);
899
900 if((err = misc_deregister(&step_c_context_obj->mdev)))
901 {
902 STEP_C_ERR("misc_deregister fail: %d\n", err);
903 }
904 kfree(step_c_context_obj);
905
906 return 0;
907 }
908
909 static void step_c_early_suspend(struct early_suspend *h)
910 {
911 atomic_set(&(step_c_context_obj->early_suspend), 1);
912 STEP_C_LOG(" step_c_early_suspend ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(step_c_context_obj->early_suspend)));
913 return ;
914 }
915 /*----------------------------------------------------------------------------*/
916 static void step_c_late_resume(struct early_suspend *h)
917 {
918 atomic_set(&(step_c_context_obj->early_suspend), 0);
919 STEP_C_LOG(" step_c_late_resume ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(step_c_context_obj->early_suspend)));
920 return ;
921 }
922
923 static int step_c_suspend(struct platform_device *dev, pm_message_t state)
924 {
925 return 0;
926 }
927 /*----------------------------------------------------------------------------*/
928 static int step_c_resume(struct platform_device *dev)
929 {
930 return 0;
931 }
932
933 #ifdef CONFIG_OF
934 static const struct of_device_id m_step_c_pl_of_match[] = {
935 { .compatible = "mediatek,m_step_c_pl", },
936 {},
937 };
938 #endif
939
940 static struct platform_driver step_c_driver =
941 {
942 .probe = step_c_probe,
943 .remove = step_c_remove,
944 .suspend = step_c_suspend,
945 .resume = step_c_resume,
946 .driver =
947 {
948 .name = STEP_C_PL_DEV_NAME,
949 #ifdef CONFIG_OF
950 .of_match_table = m_step_c_pl_of_match,
951 #endif
952 }
953 };
954
955 static int __init step_c_init(void)
956 {
957 STEP_C_FUN();
958
959 if(platform_driver_register(&step_c_driver))
960 {
961 STEP_C_ERR("failed to register step_c driver\n");
962 return -ENODEV;
963 }
964
965 return 0;
966 }
967
968 static void __exit step_c_exit(void)
969 {
970 platform_driver_unregister(&step_c_driver);
971 platform_driver_unregister(&step_counter_driver);
972 }
973
974 late_initcall(step_c_init);
975 //module_init(step_c_init);
976 //module_exit(step_c_exit);
977 MODULE_LICENSE("GPL");
978 MODULE_DESCRIPTION("STEP_CMETER device driver");
979 MODULE_AUTHOR("Mediatek");
980