Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / kr076 / gyroscope / gyroscope.c
1
2 #include "gyroscope.h"
3
4 static struct gyro_context *gyro_context_obj = NULL;
5
6
7 static struct gyro_init_info* gyroscope_init_list[MAX_CHOOSE_GYRO_NUM]= {0}; //modified
8 static void gyro_early_suspend(struct early_suspend *h);
9 static void gyro_late_resume(struct early_suspend *h);
10
11 static void gyro_work_func(struct work_struct *work)
12 {
13
14 struct gyro_context *cxt = NULL;
15 int out_size;
16 //hwm_sensor_data sensor_data;
17 int x,y,z,status,div;
18 int64_t nt;
19 struct timespec time;
20 int err, idx;
21
22 cxt = gyro_context_obj;
23
24 if(NULL == cxt->gyro_data.get_data)
25 {
26 GYRO_ERR("gyro 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 cxt->gyro_data.get_data(&x,&y,&z,&status);
36
37 if(err)
38 {
39 GYRO_ERR("get gyro data fails!!\n" );
40 goto gyro_loop;
41 }
42 else
43 {
44 if((x != cxt->drv_data.gyro_data.values[0])
45 || (y != cxt->drv_data.gyro_data.values[1])
46 || (z != cxt->drv_data.gyro_data.values[2]))
47 {
48 if( 0 == x && 0==y
49 && 0 == z)
50 {
51 goto gyro_loop;
52 }
53
54 cxt->drv_data.gyro_data.values[0] = x;
55 cxt->drv_data.gyro_data.values[1] = y;
56 cxt->drv_data.gyro_data.values[2] = z;
57 cxt->drv_data.gyro_data.status = status;
58 cxt->drv_data.gyro_data.time = nt;
59
60 }
61 }
62
63 if(true == cxt->is_first_data_after_enable)
64 {
65 cxt->is_first_data_after_enable = false;
66 //filter -1 value
67 if(GYRO_INVALID_VALUE == cxt->drv_data.gyro_data.values[0] ||
68 GYRO_INVALID_VALUE == cxt->drv_data.gyro_data.values[1] ||
69 GYRO_INVALID_VALUE == cxt->drv_data.gyro_data.values[2])
70 {
71 GYRO_LOG(" read invalid data \n");
72 goto gyro_loop;
73
74 }
75 }
76 //report data to input device
77 //printk("new gyro work run....\n");
78 //GYRO_LOG("gyro data[%d,%d,%d] \n" ,cxt->drv_data.gyro_data.values[0],
79 //cxt->drv_data.gyro_data.values[1],cxt->drv_data.gyro_data.values[2]);
80
81 gyro_data_report(cxt->drv_data.gyro_data.values[0],
82 cxt->drv_data.gyro_data.values[1],cxt->drv_data.gyro_data.values[2],
83 cxt->drv_data.gyro_data.status);
84
85 gyro_loop:
86 if(true == cxt->is_polling_run)
87 {
88 {
89 mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
90 }
91
92 }
93 }
94
95 static void gyro_poll(unsigned long data)
96 {
97 struct gyro_context *obj = (struct gyro_context *)data;
98 if(obj != NULL)
99 {
100 schedule_work(&obj->report);
101 }
102 }
103
104 static struct gyro_context *gyro_context_alloc_object(void)
105 {
106
107 struct gyro_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
108 GYRO_LOG("gyro_context_alloc_object++++\n");
109 if(!obj)
110 {
111 GYRO_ERR("Alloc gyro object error!\n");
112 return NULL;
113 }
114 atomic_set(&obj->delay, 200); /*5Hz*/// set work queue delay time 200ms
115 atomic_set(&obj->wake, 0);
116 INIT_WORK(&obj->report, gyro_work_func);
117 init_timer(&obj->timer);
118 obj->timer.expires = jiffies + atomic_read(&obj->delay)/(1000/HZ);
119 obj->timer.function = gyro_poll;
120 obj->timer.data = (unsigned long)obj;
121 obj->is_first_data_after_enable = false;
122 obj->is_polling_run = false;
123 obj->is_batch_enable = false;
124 mutex_init(&obj->gyro_op_mutex);
125 GYRO_LOG("gyro_context_alloc_object----\n");
126 return obj;
127 }
128
129 static int gyro_real_enable(int enable)
130 {
131 int err =0;
132 struct gyro_context *cxt = NULL;
133 cxt = gyro_context_obj;
134 if(1==enable)
135 {
136
137 if(true==cxt->is_active_data || true ==cxt->is_active_nodata)
138 {
139 err = cxt->gyro_ctl.enable_nodata(1);
140 if(err)
141 {
142 err = cxt->gyro_ctl.enable_nodata(1);
143 if(err)
144 {
145 err = cxt->gyro_ctl.enable_nodata(1);
146 if(err)
147 GYRO_ERR("gyro enable(%d) err 3 timers = %d\n", enable, err);
148 }
149 }
150 GYRO_LOG("gyro real enable \n" );
151 }
152
153 }
154 if(0==enable)
155 {
156 if(false==cxt->is_active_data && false ==cxt->is_active_nodata)
157 {
158 err = cxt->gyro_ctl.enable_nodata(0);
159 if(err)
160 {
161 GYRO_ERR("gyro enable(%d) err = %d\n", enable, err);
162 }
163 GYRO_LOG("gyro real disable \n" );
164 }
165
166 }
167
168 return err;
169 }
170 static int gyro_enable_data(int enable)
171 {
172 struct gyro_context *cxt = NULL;
173 int err =0;
174 cxt = gyro_context_obj;
175 if(NULL == cxt->gyro_ctl.open_report_data)
176 {
177 GYRO_ERR("no gyro control path\n");
178 return -1;
179 }
180
181 if(1 == enable)
182 {
183 GYRO_LOG("gyro enable data\n");
184 cxt->is_active_data =true;
185 cxt->is_first_data_after_enable = true;
186 cxt->gyro_ctl.open_report_data(1);
187 if(false == cxt->is_polling_run && cxt->is_batch_enable == false)
188 {
189 if(false == cxt->gyro_ctl.is_report_input_direct)
190 {
191 mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
192 cxt->is_polling_run = true;
193 }
194 }
195 }
196 if(0 == enable)
197 {
198 GYRO_LOG("gyro disable \n");
199
200 cxt->is_active_data =false;
201 cxt->gyro_ctl.open_report_data(0);
202 if(true == cxt->is_polling_run)
203 {
204 if(false == cxt->gyro_ctl.is_report_input_direct)
205 {
206 cxt->is_polling_run = false;
207 del_timer_sync(&cxt->timer);
208 cancel_work_sync(&cxt->report);
209 cxt->drv_data.gyro_data.values[0] = GYRO_INVALID_VALUE;
210 cxt->drv_data.gyro_data.values[1] = GYRO_INVALID_VALUE;
211 cxt->drv_data.gyro_data.values[2] = GYRO_INVALID_VALUE;
212 }
213 }
214
215 }
216 gyro_real_enable(enable);
217 return 0;
218 }
219
220
221
222 int gyro_enable_nodata(int enable)
223 {
224 struct gyro_context *cxt = NULL;
225 int err =0;
226 cxt = gyro_context_obj;
227 if(NULL == cxt->gyro_ctl.enable_nodata)
228 {
229 GYRO_ERR("gyro_enable_nodata:gyro ctl path is NULL\n");
230 return -1;
231 }
232
233 if(1 == enable)
234 {
235 cxt->is_active_nodata = true;
236 }
237
238 if(0 == enable)
239 {
240 cxt->is_active_nodata = false;
241 }
242 gyro_real_enable(enable);
243 return 0;
244 }
245
246
247 static ssize_t gyro_show_enable_nodata(struct device* dev,
248 struct device_attribute *attr, char *buf)
249 {
250 int len = 0;
251 GYRO_LOG(" not support now\n");
252 return len;
253 }
254
255 static ssize_t gyro_store_enable_nodata(struct device* dev, struct device_attribute *attr,
256 const char *buf, size_t count)
257 {
258 GYRO_LOG("gyro_store_enable nodata buf=%s\n",buf);
259 mutex_lock(&gyro_context_obj->gyro_op_mutex);
260 struct gyro_context *cxt = NULL;
261 int err =0;
262 cxt = gyro_context_obj;
263 if(NULL == cxt->gyro_ctl.enable_nodata)
264 {
265 GYRO_LOG("gyro_ctl enable nodata NULL\n");
266 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
267 return count;
268 }
269 if (!strncmp(buf, "1", 1))
270 {
271 gyro_enable_nodata(1);
272 }
273 else if (!strncmp(buf, "0", 1))
274 {
275 gyro_enable_nodata(0);
276 }
277 else
278 {
279 GYRO_ERR(" gyro_store enable nodata cmd error !!\n");
280 }
281 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
282 }
283
284 static ssize_t gyro_store_active(struct device* dev, struct device_attribute *attr,
285 const char *buf, size_t count)
286 {
287 GYRO_LOG("gyro_store_active buf=%s\n",buf);
288 mutex_lock(&gyro_context_obj->gyro_op_mutex);
289 struct gyro_context *cxt = NULL;
290 int err =0;
291 cxt = gyro_context_obj;
292 if(NULL == cxt->gyro_ctl.open_report_data)
293 {
294 GYRO_LOG("gyro_ctl enable NULL\n");
295 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
296 return count;
297 }
298 if (!strncmp(buf, "1", 1))
299 {
300 // cxt->gyro_ctl.enable(1);
301 gyro_enable_data(1);
302
303 }
304 else if (!strncmp(buf, "0", 1))
305 {
306
307 //cxt->gyro_ctl.enable(0);
308 gyro_enable_data(0);
309 }
310 else
311 {
312 GYRO_ERR(" gyro_store_active error !!\n");
313 }
314 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
315 GYRO_LOG(" gyro_store_active done\n");
316 return count;
317 }
318 /*----------------------------------------------------------------------------*/
319 static ssize_t gyro_show_active(struct device* dev,
320 struct device_attribute *attr, char *buf)
321 {
322 struct gyro_context *cxt = NULL;
323 cxt = gyro_context_obj;
324
325 int len = 0;
326 GYRO_LOG("gyro show active not support now\n");
327 int div=cxt->gyro_data.vender_div;
328 GYRO_LOG("gyro vender_div value: %d\n", div);
329 return snprintf(buf, PAGE_SIZE, "%d\n", div);
330
331 //return len;
332 }
333
334 static ssize_t gyro_store_delay(struct device* dev, struct device_attribute *attr,
335 const char *buf, size_t count)
336 {
337 mutex_lock(&gyro_context_obj->gyro_op_mutex);
338 struct gyro_context *devobj = (struct gyro_context*)dev_get_drvdata(dev);
339 int delay;
340 int mdelay=0;
341 struct gyro_context *cxt = NULL;
342 int err =0;
343 cxt = gyro_context_obj;
344 if(NULL == cxt->gyro_ctl.set_delay)
345 {
346 GYRO_LOG("gyro_ctl set_delay NULL\n");
347 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
348 return count;
349 }
350
351 if (1 != sscanf(buf, "%d", &delay)) {
352 GYRO_ERR("invalid format!!\n");
353 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
354 return count;
355 }
356
357 if(false == cxt->gyro_ctl.is_report_input_direct)
358 {
359 mdelay = (int)delay/1000/1000;
360 atomic_set(&gyro_context_obj->delay, mdelay);
361 }
362 cxt->gyro_ctl.set_delay(delay);
363 GYRO_LOG(" gyro_delay %d ns\n",delay);
364 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
365 return count;
366 }
367
368 static ssize_t gyro_show_delay(struct device* dev,
369 struct device_attribute *attr, char *buf)
370 {
371 int len = 0;
372 GYRO_LOG(" not support now\n");
373 return len;
374 }
375
376 static ssize_t gyro_store_batch(struct device* dev, struct device_attribute *attr,
377 const char *buf, size_t count)
378 {
379 GYRO_LOG("gyro_store_batch buf=%s\n",buf);
380 mutex_lock(&gyro_context_obj->gyro_op_mutex);
381 struct gyro_context *cxt = NULL;
382 int err =0;
383 cxt = gyro_context_obj;
384 if(cxt->gyro_ctl.is_support_batch){
385
386 if (!strncmp(buf, "1", 1))
387 {
388 cxt->is_batch_enable = true;
389 }
390 else if (!strncmp(buf, "0", 1))
391 {
392 cxt->is_batch_enable = false;
393 }
394 else
395 {
396 GYRO_ERR(" gyro_store_batch error !!\n");
397 }
398 }else{
399 GYRO_LOG(" gyro_store_batch not support\n");
400 }
401 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
402 GYRO_LOG(" gyro_store_batch done: %d\n", cxt->is_batch_enable);
403 return count;
404
405 }
406
407 static ssize_t gyro_show_batch(struct device* dev,
408 struct device_attribute *attr, char *buf)
409 {
410 return snprintf(buf, PAGE_SIZE, "%d\n", 0);
411 }
412
413 static ssize_t gyro_store_flush(struct device* dev, struct device_attribute *attr,
414 const char *buf, size_t count)
415 {
416 mutex_lock(&gyro_context_obj->gyro_op_mutex);
417 struct gyro_context *devobj = (struct gyro_context*)dev_get_drvdata(dev);
418 //do read FIFO data function and report data immediately
419 mutex_unlock(&gyro_context_obj->gyro_op_mutex);
420 return count;
421 }
422
423 static ssize_t gyro_show_flush(struct device* dev,
424 struct device_attribute *attr, char *buf)
425 {
426 return snprintf(buf, PAGE_SIZE, "%d\n", 0);
427 }
428
429 static ssize_t gyro_show_devnum(struct device* dev,
430 struct device_attribute *attr, char *buf)
431 {
432 char *devname = NULL;
433 devname = dev_name(&gyro_context_obj->idev->dev);
434 return snprintf(buf, PAGE_SIZE, "%s\n", devname+5);
435 }
436 static int gyroscope_remove(struct platform_device *pdev)
437 {
438 GYRO_LOG("gyroscope_remove\n");
439 return 0;
440 }
441
442 static int gyroscope_probe(struct platform_device *pdev)
443 {
444 GYRO_LOG("gyroscope_probe\n");
445 return 0;
446 }
447
448 static struct platform_driver gyroscope_driver = {
449 .probe = gyroscope_probe,
450 .remove = gyroscope_remove,
451 .driver =
452 {
453 .name = "gyroscope",
454 }
455 };
456
457 static int gyro_real_driver_init(void)
458 {
459 int i =0;
460 int err=0;
461 GYRO_LOG(" gyro_real_driver_init +\n");
462 for(i = 0; i < MAX_CHOOSE_GYRO_NUM; i++)
463 {
464 GYRO_LOG(" i=%d\n",i);
465 if(0 != gyroscope_init_list[i])
466 {
467 GYRO_LOG(" gyro try to init driver %s\n", gyroscope_init_list[i]->name);
468 err = gyroscope_init_list[i]->init();
469 if(0 == err)
470 {
471 GYRO_LOG(" gyro real driver %s probe ok\n", gyroscope_init_list[i]->name);
472 break;
473 }
474 }
475 }
476
477 if(i == MAX_CHOOSE_GYRO_NUM)
478 {
479 GYRO_LOG(" gyro_real_driver_init fail\n");
480 err=-1;
481 }
482 return err;
483 }
484
485 int gyro_driver_add(struct gyro_init_info* obj)
486 {
487 int err=0;
488 int i =0;
489
490 GYRO_FUN(f);
491
492 for(i =0; i < MAX_CHOOSE_GYRO_NUM; i++ )
493 {
494 if(i == 0){
495 GYRO_LOG("register gyro driver for the first time\n");
496 if(platform_driver_register(&gyroscope_driver))
497 {
498 GYRO_ERR("failed to register gyro driver already exist\n");
499 }
500 }
501
502 if(NULL == gyroscope_init_list[i])
503 {
504 obj->platform_diver_addr = &gyroscope_driver;
505 gyroscope_init_list[i] = obj;
506 break;
507 }
508 }
509 if(NULL==gyroscope_init_list[i])
510 {
511 GYRO_ERR("gyro driver add err \n");
512 err=-1;
513 }
514
515 return err;
516 }
517 EXPORT_SYMBOL_GPL(gyro_driver_add);
518
519 static int gyro_misc_init(struct gyro_context *cxt)
520 {
521
522 int err=0;
523 cxt->mdev.minor = MISC_DYNAMIC_MINOR;
524 cxt->mdev.name = GYRO_MISC_DEV_NAME;
525 if((err = misc_register(&cxt->mdev)))
526 {
527 GYRO_ERR("unable to register gyro misc device!!\n");
528 }
529 return err;
530 }
531
532 static void gyro_input_destroy(struct gyro_context *cxt)
533 {
534 struct input_dev *dev = cxt->idev;
535
536 input_unregister_device(dev);
537 input_free_device(dev);
538 }
539
540 static int gyro_input_init(struct gyro_context *cxt)
541 {
542 struct input_dev *dev;
543 int err = 0;
544
545 dev = input_allocate_device();
546 if (NULL == dev)
547 return -ENOMEM;
548
549 dev->name = GYRO_INPUTDEV_NAME;
550
551 input_set_capability(dev, EV_ABS, EVENT_TYPE_GYRO_X);
552 input_set_capability(dev, EV_ABS, EVENT_TYPE_GYRO_Y);
553 input_set_capability(dev, EV_ABS, EVENT_TYPE_GYRO_Z);
554 input_set_capability(dev, EV_ABS, EVENT_TYPE_GYRO_STATUS);
555
556 input_set_abs_params(dev, EVENT_TYPE_GYRO_X, GYRO_VALUE_MIN, GYRO_VALUE_MAX, 0, 0);
557 input_set_abs_params(dev, EVENT_TYPE_GYRO_Y, GYRO_VALUE_MIN, GYRO_VALUE_MAX, 0, 0);
558 input_set_abs_params(dev, EVENT_TYPE_GYRO_Z, GYRO_VALUE_MIN, GYRO_VALUE_MAX, 0, 0);
559 input_set_abs_params(dev, EVENT_TYPE_GYRO_STATUS, GYRO_STATUS_MIN, GYRO_STATUS_MAX, 0, 0);
560 input_set_drvdata(dev, cxt);
561
562 err = input_register_device(dev);
563 if (err < 0) {
564 input_free_device(dev);
565 return err;
566 }
567 cxt->idev= dev;
568
569 return 0;
570 }
571
572 DEVICE_ATTR(gyroenablenodata, S_IWUSR | S_IRUGO, gyro_show_enable_nodata, gyro_store_enable_nodata);
573 DEVICE_ATTR(gyroactive, S_IWUSR | S_IRUGO, gyro_show_active, gyro_store_active);
574 DEVICE_ATTR(gyrodelay, S_IWUSR | S_IRUGO, gyro_show_delay, gyro_store_delay);
575 DEVICE_ATTR(gyrobatch, S_IWUSR | S_IRUGO, gyro_show_batch, gyro_store_batch);
576 DEVICE_ATTR(gyroflush, S_IWUSR | S_IRUGO, gyro_show_flush, gyro_store_flush);
577 DEVICE_ATTR(gyrodevnum, S_IWUSR | S_IRUGO, gyro_show_devnum, NULL);
578
579 static struct attribute *gyro_attributes[] = {
580 &dev_attr_gyroenablenodata.attr,
581 &dev_attr_gyroactive.attr,
582 &dev_attr_gyrodelay.attr,
583 &dev_attr_gyrobatch.attr,
584 &dev_attr_gyroflush.attr,
585 &dev_attr_gyrodevnum.attr,
586 NULL
587 };
588
589 static struct attribute_group gyro_attribute_group = {
590 .attrs = gyro_attributes
591 };
592
593 int gyro_register_data_path(struct gyro_data_path *data)
594 {
595 struct gyro_context *cxt = NULL;
596 int err =0;
597 cxt = gyro_context_obj;
598 cxt->gyro_data.get_data = data->get_data;
599 cxt->gyro_data.vender_div = data->vender_div;
600 GYRO_LOG("gyro register data path vender_div: %d\n", cxt->gyro_data.vender_div);
601 if(NULL == cxt->gyro_data.get_data)
602 {
603 GYRO_LOG("gyro register data path fail \n");
604 return -1;
605 }
606 return 0;
607 }
608
609 int gyro_register_control_path(struct gyro_control_path *ctl)
610 {
611 struct gyro_context *cxt = NULL;
612 int err =0;
613 cxt = gyro_context_obj;
614 cxt->gyro_ctl.set_delay = ctl->set_delay;
615 cxt->gyro_ctl.open_report_data= ctl->open_report_data;
616 cxt->gyro_ctl.enable_nodata = ctl->enable_nodata;
617 cxt->gyro_ctl.is_support_batch = ctl->is_support_batch;
618
619 if(NULL==cxt->gyro_ctl.set_delay || NULL==cxt->gyro_ctl.open_report_data
620 || NULL==cxt->gyro_ctl.enable_nodata)
621 {
622 GYRO_LOG("gyro register control path fail \n");
623 return -1;
624 }
625
626 //add misc dev for sensor hal control cmd
627 err = gyro_misc_init(gyro_context_obj);
628 if(err)
629 {
630 GYRO_ERR("unable to register gyro misc device!!\n");
631 return -2;
632 }
633 err = sysfs_create_group(&gyro_context_obj->mdev.this_device->kobj,
634 &gyro_attribute_group);
635 if (err < 0)
636 {
637 GYRO_ERR("unable to create gyro attribute file\n");
638 return -3;
639 }
640
641 kobject_uevent(&gyro_context_obj->mdev.this_device->kobj, KOBJ_ADD);
642
643 return 0;
644 }
645
646 int gyro_data_report(int x, int y, int z,int status)
647 {
648 //GYRO_LOG("+gyro_data_report! %d, %d, %d, %d\n",x,y,z,status);
649 struct gyro_context *cxt = NULL;
650 int err =0;
651 cxt = gyro_context_obj;
652 input_report_abs(cxt->idev, EVENT_TYPE_GYRO_X, x);
653 input_report_abs(cxt->idev, EVENT_TYPE_GYRO_Y, y);
654 input_report_abs(cxt->idev, EVENT_TYPE_GYRO_Z, z);
655 input_report_abs(cxt->idev, EVENT_TYPE_GYRO_STATUS, status);
656 input_sync(cxt->idev);
657 }
658
659 static int gyro_probe(struct platform_device *pdev)
660 {
661
662 int err;
663 GYRO_LOG("+++++++++++++gyro_probe!!\n");
664
665 gyro_context_obj = gyro_context_alloc_object();
666 if (!gyro_context_obj)
667 {
668 err = -ENOMEM;
669 GYRO_ERR("unable to allocate devobj!\n");
670 goto exit_alloc_data_failed;
671 }
672
673 //init real gyroeleration driver
674 err = gyro_real_driver_init();
675 if(err)
676 {
677 GYRO_ERR("gyro real driver init fail\n");
678 goto real_driver_init_fail;
679 }
680
681 //init input dev
682 err = gyro_input_init(gyro_context_obj);
683 if(err)
684 {
685 GYRO_ERR("unable to register gyro input device!\n");
686 goto exit_alloc_input_dev_failed;
687 }
688
689 atomic_set(&(gyro_context_obj->early_suspend), 0);
690 gyro_context_obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1,
691 gyro_context_obj->early_drv.suspend = gyro_early_suspend,
692 gyro_context_obj->early_drv.resume = gyro_late_resume,
693 register_early_suspend(&gyro_context_obj->early_drv);
694
695 GYRO_LOG("----gyro_probe OK !!\n");
696 return 0;
697
698 exit_hwmsen_create_attr_failed:
699 exit_misc_register_failed:
700
701 exit_err_sysfs:
702
703 if (err)
704 {
705 GYRO_ERR("sysfs node creation error \n");
706 gyro_input_destroy(gyro_context_obj);
707 }
708
709 real_driver_init_fail:
710 exit_alloc_input_dev_failed:
711 kfree(gyro_context_obj);
712
713 exit_alloc_data_failed:
714
715
716 GYRO_LOG("----gyro_probe fail !!!\n");
717 return err;
718 }
719
720
721
722 static int gyro_remove(struct platform_device *pdev)
723 {
724 GYRO_FUN(f);
725 int err=0;
726 input_unregister_device(gyro_context_obj->idev);
727 sysfs_remove_group(&gyro_context_obj->idev->dev.kobj,
728 &gyro_attribute_group);
729
730 if((err = misc_deregister(&gyro_context_obj->mdev)))
731 {
732 GYRO_ERR("misc_deregister fail: %d\n", err);
733 }
734 kfree(gyro_context_obj);
735
736 return 0;
737 }
738
739 static void gyro_early_suspend(struct early_suspend *h)
740 {
741 atomic_set(&(gyro_context_obj->early_suspend), 1);
742 GYRO_LOG(" gyro_early_suspend ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(gyro_context_obj->early_suspend)));
743 return ;
744 }
745 /*----------------------------------------------------------------------------*/
746 static void gyro_late_resume(struct early_suspend *h)
747 {
748 atomic_set(&(gyro_context_obj->early_suspend), 0);
749 GYRO_LOG(" gyro_late_resume ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(gyro_context_obj->early_suspend)));
750 return ;
751 }
752
753 static int gyro_suspend(struct platform_device *dev, pm_message_t state)
754 {
755 return 0;
756 }
757 /*----------------------------------------------------------------------------*/
758 static int gyro_resume(struct platform_device *dev)
759 {
760 return 0;
761 }
762
763 static struct platform_driver gyro_driver =
764 {
765 .probe = gyro_probe,
766 .remove = gyro_remove,
767 .suspend = gyro_suspend,
768 .resume = gyro_resume,
769 .driver =
770 {
771 .name = GYRO_PL_DEV_NAME,//mt_gyro_pl
772 }
773 };
774
775 static int __init gyro_init(void)
776 {
777 GYRO_FUN(f);
778
779 if(platform_driver_register(&gyro_driver))
780 {
781 GYRO_ERR("failed to register gyro driver\n");
782 return -ENODEV;
783 }
784
785 return 0;
786 }
787
788 static void __exit gyro_exit(void)
789 {
790 platform_driver_unregister(&gyro_driver);
791 platform_driver_unregister(&gyroscope_driver);
792 }
793
794 module_init(gyro_init);
795 module_exit(gyro_exit);
796 MODULE_LICENSE("GPL");
797 MODULE_DESCRIPTION("GYROSCOPE device driver");
798 MODULE_AUTHOR("Mediatek");
799