Merge tag 'v3.10.55' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-mt8127 / pixi3_10 / magnetometer / mag.c
1
2 #include "mag.h"
3 #include "accel.h"
4
5 static struct mag_context *mag_context_obj = NULL;
6
7 static struct mag_init_info* msensor_init_list[MAX_CHOOSE_G_NUM]= {0}; //modified
8
9 static void mag_early_suspend(struct early_suspend *h);
10 static void mag_late_resume(struct early_suspend *h);
11
12 static void mag_work_func(struct work_struct *work)
13 {
14
15 struct mag_context *cxt = NULL;
16 int out_size;
17 hwm_sensor_data sensor_data;
18 int64_t nt;
19 struct timespec time;
20 int err, idx;
21 int i;
22
23 cxt = mag_context_obj;
24 memset(&sensor_data, 0, sizeof(sensor_data));
25 time.tv_sec = time.tv_nsec = 0;
26 time = get_monotonic_coarse();
27 nt = time.tv_sec*1000000000LL+time.tv_nsec;
28
29 for(i = 0; i < MAX_M_V_SENSOR; i++)
30 {
31 if (NULL == cxt->drv_obj[i])
32 {
33 //MAG_LOG("%d driver not atteched\n",i);
34 continue;
35 }
36
37 if((0 == cxt->drv_obj[i]->polling) || !(cxt->active_data_sensor&(0x01<<i)))
38 {
39 MAG_LOG("mag_type(%d) polling(%d) enabled(%d)\n",i, cxt->drv_obj[i]->polling,cxt->active_data_sensor);
40 continue;
41 }
42
43 err = cxt->drv_obj[i]->mag_operate(cxt->drv_obj[i]->self,OP_MAG_GET_DATA, NULL, 0,
44 &sensor_data, sizeof(hwm_sensor_data), &out_size);
45
46 if(err)
47 {
48 MAG_ERR("get %d data fails!!\n" ,i);
49 return;
50 }
51 else
52 {
53 {
54 if( 0 == sensor_data.values[0] && 0==sensor_data.values[1]
55 && 0 == sensor_data.values[2])
56 {
57 MAG_ERR("data is zero.\n" );
58 continue;
59 }
60
61 cxt->drv_data[i].mag_data.values[0] = sensor_data.values[0];
62 cxt->drv_data[i].mag_data.values[1] = sensor_data.values[1];
63 cxt->drv_data[i].mag_data.values[2] = sensor_data.values[2];
64 cxt->drv_data[i].mag_data.status = sensor_data.status;
65 cxt->drv_data[i].mag_data.time = nt;
66 }
67 }
68
69 if(true == cxt->is_first_data_after_enable)
70 {
71 cxt->is_first_data_after_enable = false;
72 //filter -1 value
73 if(MAG_INVALID_VALUE == cxt->drv_data[i].mag_data.values[0] ||
74 MAG_INVALID_VALUE == cxt->drv_data[i].mag_data.values[1] ||
75 MAG_INVALID_VALUE == cxt->drv_data[i].mag_data.values[2])
76 {
77 MAG_LOG(" read invalid data \n");
78 continue;
79
80 }
81 }
82
83 if(ID_M_V_MAGNETIC ==i)
84 {
85 mag_data_report(MAGNETIC,cxt->drv_data[i].mag_data.values[0],
86 cxt->drv_data[i].mag_data.values[1],
87 cxt->drv_data[i].mag_data.values[2],
88 cxt->drv_data[i].mag_data.status);
89
90 MAG_LOG("mag_type(%d) data[%d,%d,%d] \n" ,i,cxt->drv_data[i].mag_data.values[0],
91 cxt->drv_data[i].mag_data.values[1],cxt->drv_data[i].mag_data.values[2]);
92 }
93
94 if(ID_M_V_ORIENTATION ==i)
95 {
96 mag_data_report(ORIENTATION,cxt->drv_data[i].mag_data.values[0],
97 cxt->drv_data[i].mag_data.values[1],
98 cxt->drv_data[i].mag_data.values[2],
99 cxt->drv_data[i].mag_data.status);
100
101 MAG_LOG("mag_type(%d) data[%d,%d,%d] \n" ,i,cxt->drv_data[i].mag_data.values[0],
102 cxt->drv_data[i].mag_data.values[1],cxt->drv_data[i].mag_data.values[2]);
103 }
104
105
106 }
107
108 //report data to input device
109 //printk("new mag work run....\n");
110
111 if(true == cxt->is_polling_run)
112 {
113 mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
114 }
115 }
116
117 static void mag_poll(unsigned long data)
118 {
119 struct mag_context *obj = (struct mag_context *)data;
120 if(obj != NULL)
121 {
122 schedule_work(&obj->report);
123 }
124 }
125
126 static struct mag_context *mag_context_alloc_object(void)
127 {
128
129 struct mag_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
130 MAG_LOG("mag_context_alloc_object++++\n");
131 if(!obj)
132 {
133 MAG_ERR("Alloc magel object error!\n");
134 return NULL;
135 }
136 atomic_set(&obj->delay, 200); /*5Hz*/// set work queue delay time 200ms
137 atomic_set(&obj->wake, 0);
138 INIT_WORK(&obj->report, mag_work_func);
139 init_timer(&obj->timer);
140 obj->timer.expires = jiffies + atomic_read(&obj->delay)/(1000/HZ);
141 obj->timer.function = mag_poll;
142 obj->timer.data = (unsigned long)obj;
143 obj->is_first_data_after_enable = false;
144 obj->is_polling_run = false;
145 obj->active_data_sensor = 0;
146 obj->active_nodata_sensor = 0;
147 obj->is_batch_enable = false;
148 mutex_init(&obj->mag_op_mutex);
149 MAG_LOG("mag_context_alloc_object----\n");
150 return obj;
151 }
152 static int mag_enable_data(int handle,int enable)
153 {
154 struct mag_context *cxt = NULL;
155 int err =0;
156 cxt = mag_context_obj;
157 if(NULL == cxt->drv_obj[handle])
158 {
159 MAG_ERR("no real mag driver\n");
160 return -1;
161 }
162
163 if(1 == enable)
164 {
165 MAG_LOG("MAG(%d) enable \n",handle);
166 cxt->is_first_data_after_enable = true;
167 cxt->active_data_sensor |= 1<<handle;
168
169 if(ID_M_V_ORIENTATION == handle)
170 {
171 cxt->mag_ctl.o_enable(1);
172 cxt->mag_ctl.o_open_report_data(1);
173 }
174 if(ID_M_V_MAGNETIC == handle)
175 {
176 cxt->mag_ctl.m_enable(1);
177 cxt->mag_ctl.m_open_report_data(1);
178 }
179
180 if((0!=cxt->active_data_sensor) && (false == cxt->is_polling_run)&&(false == cxt->is_batch_enable))
181 {
182 if(false == cxt->mag_ctl.is_report_input_direct)
183 {
184 MAG_LOG("MAG(%d) mod timer \n",handle);
185 mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
186 cxt->is_polling_run = true;
187 }
188 }
189
190
191 }
192 if(0 == enable)
193 {
194 MAG_LOG("MAG(%d) disable \n",handle);
195 cxt->active_data_sensor &= ~(1<<handle);
196 if(ID_M_V_ORIENTATION == handle)
197 {
198 cxt->mag_ctl.o_enable(0);
199 cxt->mag_ctl.o_open_report_data(0);
200 }
201 if(ID_M_V_MAGNETIC == handle)
202 {
203 cxt->mag_ctl.m_enable(0);
204 cxt->mag_ctl.m_open_report_data(0);
205 }
206
207 if(0 == cxt->active_data_sensor && true == cxt->is_polling_run)
208 {
209 if(false == cxt->mag_ctl.is_report_input_direct)
210 {
211 MAG_LOG("MAG(%d) del timer \n",handle);
212 cxt->is_polling_run = false;
213 del_timer_sync(&cxt->timer);
214 cancel_work_sync(&cxt->report);
215 cxt->drv_data[handle].mag_data.values[0] = MAG_INVALID_VALUE;
216 cxt->drv_data[handle].mag_data.values[1] = MAG_INVALID_VALUE;
217 cxt->drv_data[handle].mag_data.values[2] = MAG_INVALID_VALUE;
218 }
219
220 }
221
222 }
223 //mag_real_enable(handle,enable);
224 return 0;
225 }
226
227 static int m_enable_data(int en)
228 {
229 int err;
230 err=mag_enable_data(ID_M_V_MAGNETIC,en);
231 return err;
232 }
233 static int o_enable_data(int en)
234 {
235 int err;
236 err=mag_enable_data(ID_M_V_ORIENTATION,en);
237 return err;
238 }
239
240 /*
241 static int m_set_delay(u64 delay)//ns
242 {
243 int m_delay =0;
244 m_delay = (int)delay/1000/1000;
245
246 if(NULL == mag_context_obj->drv_obj[ID_M_V_MAGNETIC])
247 {
248 MAG_ERR("no real mag driver\n");
249 return -1;
250 }
251 if(mag_context_obj->drv_obj[ID_M_V_MAGNETIC]->mag_operate(mag_context_obj->drv_obj[ID_M_V_MAGNETIC]->self, OP_MAG_DELAY, &m_delay,sizeof(int), NULL, 0, NULL) != 0)
252 {
253 MAG_ERR("mag sensor_operate set delay function error \r\n");
254 }
255
256 atomic_set(&mag_context_obj->delay, m_delay);
257 MAG_LOG(" mag_delay %d ms\n",m_delay);
258 return 0;
259 }
260
261 static int o_set_delay(u64 delay)//ns
262 {
263 int m_delay =0;
264 m_delay = (int)delay/1000/1000;
265
266 if(NULL == mag_context_obj->drv_obj[ID_M_V_ORIENTATION])
267 {
268 MAG_ERR("no real mag odriver\n");
269 return -1;
270 }
271
272 if(mag_context_obj->drv_obj[ID_M_V_ORIENTATION]->mag_operate(mag_context_obj->drv_obj[ID_M_V_ORIENTATION]->self, OP_MAG_DELAY, &m_delay,sizeof(int), NULL, 0, NULL) != 0)
273 {
274 MAG_ERR("mag osensor_operate set delay function error \r\n");
275 }
276 atomic_set(&mag_context_obj->delay, m_delay);
277 MAG_LOG(" mag_odelay %d ms\n",m_delay);
278 return 0;
279
280 }
281 */
282
283 /*----------------------------------------------------------------------------*/
284 static ssize_t mag_show_magdev(struct device* dev,
285 struct device_attribute *attr, char *buf)
286 {
287 int len = 0;
288 printk("sensor test: mag function!\n");
289 return len;
290 }
291 /*----------------------------------------------------------------------------*/
292
293 static ssize_t mag_store_oactive(struct device* dev, struct device_attribute *attr,
294 const char *buf, size_t count)
295 {
296 MAG_LOG("mag_store_oactive buf=%s\n",buf);
297 mutex_lock(&mag_context_obj->mag_op_mutex);
298 struct mag_context *cxt = NULL;
299 int err =0;
300 cxt = mag_context_obj;
301 if(NULL == cxt->mag_ctl.o_enable)
302 {
303 mutex_unlock(&mag_context_obj->mag_op_mutex);
304 MAG_LOG("mag_ctl o-enable NULL\n");
305 return count;
306 }
307
308 if (!strncmp(buf, "1", 1))
309 {
310 mag_enable_data(ID_M_V_ORIENTATION,1);
311 //cxt->mag_ctl.o_enable(1);
312 }
313 else if (!strncmp(buf, "0", 1))
314 {
315 mag_enable_data(ID_M_V_ORIENTATION,0);
316 //cxt->mag_ctl.o_enable(0);
317 }
318 else
319 {
320 MAG_ERR(" mag_store_oactive error !!\n");
321 }
322 mutex_unlock(&mag_context_obj->mag_op_mutex);
323 MAG_LOG(" mag_store_oactive done\n");
324 return count;
325 }
326 /*----------------------------------------------------------------------------*/
327 static ssize_t mag_show_oactive(struct device* dev,
328 struct device_attribute *attr, char *buf)
329 {
330 struct mag_context *cxt = NULL;
331 cxt = mag_context_obj;
332
333 int div = cxt->mag_dev_data.div_o;
334 ACC_LOG("acc mag_dev_data o_div value: %d\n", div);
335 return snprintf(buf, PAGE_SIZE, "%d\n", div);
336
337 }
338
339 static ssize_t mag_store_active(struct device* dev, struct device_attribute *attr,
340 const char *buf, size_t count)
341 {
342 MAG_LOG("mag_store_active buf=%s\n",buf);
343 mutex_lock(&mag_context_obj->mag_op_mutex);
344 struct mag_context *cxt = NULL;
345 int err =0;
346 cxt = mag_context_obj;
347 if(NULL == cxt->mag_ctl.m_enable)
348 {
349 mutex_unlock(&mag_context_obj->mag_op_mutex);
350 MAG_LOG("mag_ctl path is NULL\n");
351 return count;
352 }
353
354 if (!strncmp(buf, "1", 1))
355 {
356 mag_enable_data(ID_M_V_MAGNETIC,1);
357 //cxt->mag_ctl.m_enable(1);
358 }
359 else if (!strncmp(buf, "0", 1))
360 {
361 mag_enable_data(ID_M_V_MAGNETIC,0);
362 //cxt->mag_ctl.m_enable(0);
363 }
364 else
365 {
366 MAG_ERR(" mag_store_active error !!\n");
367 }
368 mutex_unlock(&mag_context_obj->mag_op_mutex);
369 MAG_LOG(" mag_store_active done\n");
370 return count;
371 }
372 /*----------------------------------------------------------------------------*/
373 static ssize_t mag_show_active(struct device* dev,
374 struct device_attribute *attr, char *buf)
375 {
376 struct mag_context *cxt = NULL;
377 cxt = mag_context_obj;
378
379 int div = cxt->mag_dev_data.div_m;
380 ACC_LOG("acc mag_dev_data m_div value: %d\n", div);
381 return snprintf(buf, PAGE_SIZE, "%d\n", div);
382 }
383
384 static ssize_t mag_store_odelay(struct device* dev, struct device_attribute *attr,
385 const char *buf, size_t count)
386 {
387 mutex_lock(&mag_context_obj->mag_op_mutex);
388 struct mag_context *devobj = (struct mag_context*)dev_get_drvdata(dev);
389 int delay=0;
390 int mdelay=0;
391 struct mag_context *cxt = NULL;
392 int err =0;
393 cxt = mag_context_obj;
394 if(NULL == cxt->mag_ctl.o_set_delay)
395 {
396 mutex_unlock(&mag_context_obj->mag_op_mutex);
397 MAG_LOG("mag_ctl o_delay NULL\n");
398 return count;
399 }
400
401 MAG_LOG(" mag_odelay ++ \n");
402
403
404 if (1 != sscanf(buf, "%d", &delay)) {
405 mutex_unlock(&mag_context_obj->mag_op_mutex);
406 MAG_ERR("invalid format!!\n");
407 return count;
408 }
409 if(false == cxt->mag_ctl.is_report_input_direct)
410 {
411 mdelay = (int)delay/1000/1000;
412 atomic_set(&mag_context_obj->delay, mdelay);
413 }
414 cxt->mag_ctl.o_set_delay(delay);
415 mutex_unlock(&mag_context_obj->mag_op_mutex);
416 MAG_LOG(" mag_odelay %d ns done\n",delay);
417 return count;
418 }
419
420 static ssize_t mag_show_odelay(struct device* dev,
421 struct device_attribute *attr, char *buf)
422 {
423 int len = 0;
424 MAG_LOG(" not support now\n");
425 return len;
426 }
427
428 static ssize_t mag_store_delay(struct device* dev, struct device_attribute *attr,
429 const char *buf, size_t count)
430 {
431 mutex_lock(&mag_context_obj->mag_op_mutex);
432 struct mag_context *devobj = (struct mag_context*)dev_get_drvdata(dev);
433 int delay=0;
434 int mdelay=0;
435 struct mag_context *cxt = NULL;
436 int err =0;
437 cxt = mag_context_obj;
438 if(NULL == cxt->mag_ctl.m_set_delay)
439 {
440 mutex_unlock(&mag_context_obj->mag_op_mutex);
441 MAG_LOG("mag_ctl m_delay NULL\n");
442 return count;
443 }
444
445 MAG_LOG(" mag_delay ++ \n");
446
447 if (1 != sscanf(buf, "%d", &delay)) {
448 mutex_unlock(&mag_context_obj->mag_op_mutex);
449 MAG_ERR("invalid format!!\n");
450 return count;
451 }
452 if(false == cxt->mag_ctl.is_report_input_direct)
453 {
454 mdelay = (int)delay/1000/1000;
455 atomic_set(&mag_context_obj->delay, mdelay);
456 }
457 cxt->mag_ctl.m_set_delay(delay);
458 mutex_unlock(&mag_context_obj->mag_op_mutex);
459 MAG_LOG(" mag_delay %d ns done\n",delay);
460 return count;
461 }
462
463 static ssize_t mag_show_delay(struct device* dev,
464 struct device_attribute *attr, char *buf)
465 {
466 int len = 0;
467 MAG_LOG(" not support now\n");
468 return len;
469 }
470
471 static ssize_t mag_store_batch(struct device* dev, struct device_attribute *attr,
472 const char *buf, size_t count)
473 {
474 MAG_LOG("mag_store_batch buf=%s\n",buf);
475 mutex_lock(&mag_context_obj->mag_op_mutex);
476 struct mag_context *cxt = NULL;
477 int err =0;
478 cxt = mag_context_obj;
479 if(cxt->mag_ctl.is_support_batch){
480 if (!strncmp(buf, "1", 1))
481 {
482 cxt->is_batch_enable = true;
483 }
484 else if (!strncmp(buf, "0", 1))
485 {
486 cxt->is_batch_enable = false;
487 }
488 else
489 {
490 MAG_ERR(" mag_store_batch error !!\n");
491 }
492 }else{
493 MAG_LOG(" mag_store_batch not supported\n");
494 }
495 mutex_unlock(&mag_context_obj->mag_op_mutex);
496 MAG_LOG(" mag_store_batch done: %d\n", cxt->is_batch_enable);
497 return count;
498 }
499
500
501 static ssize_t mag_show_batch(struct device* dev,
502 struct device_attribute *attr, char *buf)
503 {
504 int len = 0;
505 MAG_LOG(" not support now\n");
506 return len;
507 }
508
509 static ssize_t mag_store_flush(struct device* dev, struct device_attribute *attr,
510 const char *buf, size_t count)
511 {
512 return count;
513 }
514 static ssize_t mag_show_sensordevnum(struct device* dev,
515 struct device_attribute *attr, char *buf)
516 {
517 struct mag_context *cxt = NULL;
518 char *devname = NULL;
519 cxt = mag_context_obj;
520 devname = dev_name(&cxt->idev->dev);
521
522 return snprintf(buf, PAGE_SIZE, "%s\n", devname+5);
523 }
524
525
526 static ssize_t mag_show_flush(struct device* dev,
527 struct device_attribute *attr, char *buf)
528 {
529 int len = 0;
530 MAG_LOG(" not support now\n");
531 return len;
532 }
533
534 static ssize_t mag_store_obatch(struct device* dev, struct device_attribute *attr,
535 const char *buf, size_t count)
536 {
537 MAG_LOG("mag_store_obatch buf=%s\n",buf);
538 mutex_lock(&mag_context_obj->mag_op_mutex);
539 struct mag_context *cxt = NULL;
540 int err =0;
541 cxt = mag_context_obj;
542 if(cxt->mag_ctl.is_support_batch){
543 if (!strncmp(buf, "1", 1))
544 {
545 cxt->is_batch_enable = true;
546 }
547 else if (!strncmp(buf, "0", 1))
548 {
549 cxt->is_batch_enable = false;
550 }
551 else
552 {
553 MAG_ERR(" mag_store_obatch error !!\n");
554 }
555 }else{
556 MAG_LOG(" mag_store_obatch not supported\n");
557 }
558 mutex_unlock(&mag_context_obj->mag_op_mutex);
559 MAG_LOG(" mag_store_obatch done: %d\n", cxt->is_batch_enable);
560 return count;
561
562 }
563
564
565 static ssize_t mag_show_obatch(struct device* dev,
566 struct device_attribute *attr, char *buf)
567 {
568 int len = 0;
569 MAG_LOG(" not support now\n");
570 return len;
571 }
572
573 static ssize_t mag_store_oflush(struct device* dev, struct device_attribute *attr,
574 const char *buf, size_t count)
575 {
576 return count;
577 }
578
579
580 static ssize_t mag_show_oflush(struct device* dev,
581 struct device_attribute *attr, char *buf)
582 {
583 int len = 0;
584 MAG_LOG(" not support now\n");
585 return len;
586 }
587
588
589 int mag_attach(int sensor,struct mag_drv_obj *obj)
590 {
591 int err = 0;
592 MAG_FUN();
593 //mag_context_obj->drv_obj[sensor] = obj;
594 mag_context_obj->drv_obj[sensor] = kzalloc(sizeof(struct mag_drv_obj), GFP_KERNEL);
595 if(mag_context_obj->drv_obj[sensor] == NULL)
596 {
597 err = -EPERM;
598 MAG_ERR(" mag attatch alloc fail \n");
599 return err;
600 }
601
602 memcpy(mag_context_obj->drv_obj[sensor], obj, sizeof(*obj));
603 if(NULL == mag_context_obj->drv_obj[sensor])
604 {
605 err =-1;
606 MAG_ERR(" mag attatch fail \n");
607 }
608 return err;
609 }
610 /*----------------------------------------------------------------------------*/
611 EXPORT_SYMBOL_GPL(mag_attach);
612
613
614 static int msensor_remove(struct platform_device *pdev)
615 {
616 MAG_LOG("msensor_remove\n");
617 return 0;
618 }
619
620 static int msensor_probe(struct platform_device *pdev)
621 {
622 MAG_LOG("msensor_probe\n");
623 return 0;
624 }
625
626 static struct platform_driver msensor_driver = {
627 .probe = msensor_probe,
628 .remove = msensor_remove,
629 .driver =
630 {
631 .name = "msensor",
632 }
633 };
634
635 static int mag_real_driver_init(void)
636 {
637 int i =0;
638 int err=0;
639 MAG_LOG(" mag_real_driver_init +\n");
640 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
641 {
642 MAG_LOG(" i=%d\n",i);
643 if(0 != msensor_init_list[i])
644 {
645 MAG_LOG(" mag try to init driver %s\n", msensor_init_list[i]->name);
646 err = msensor_init_list[i]->init();
647 if(0 == err)
648 {
649 MAG_LOG(" mag real driver %s probe ok\n", msensor_init_list[i]->name);
650 break;
651 }
652 }
653 }
654
655 if(i == MAX_CHOOSE_G_NUM)
656 {
657 MAG_LOG(" mag_real_driver_init fail\n");
658 err =-1;
659 }
660 return err;
661 }
662
663 int mag_driver_add(struct mag_init_info* obj)
664 {
665 int err=0;
666 int i =0;
667
668 MAG_FUN();
669
670 for(i =0; i < MAX_CHOOSE_G_NUM; i++ )
671 {
672 if(i == 0){
673 MAG_LOG("register mensor driver for the first time\n");
674 if(platform_driver_register(&msensor_driver))
675 {
676 MAG_ERR("failed to register msensor driver already exist\n");
677 }
678 }
679 if(NULL == msensor_init_list[i])
680 {
681 obj->platform_diver_addr = &msensor_driver;
682 msensor_init_list[i] = obj;
683 break;
684 }
685 }
686 if(NULL==msensor_init_list[i])
687 {
688 MAG_ERR("MAG driver add err \n");
689 err =-1;
690 }
691
692 return err;
693 }
694 EXPORT_SYMBOL_GPL(mag_driver_add);
695
696 static int mag_misc_init(struct mag_context *cxt)
697 {
698
699 int err=0;
700 cxt->mdev.minor = MISC_DYNAMIC_MINOR;
701 cxt->mdev.name = MAG_MISC_DEV_NAME;
702
703 if((err = misc_register(&cxt->mdev)))
704 {
705 MAG_ERR("unable to register mag misc device!!\n");
706 }
707 return err;
708 }
709
710 static void mag_input_destroy(struct mag_context *cxt)
711 {
712 struct input_dev *dev = cxt->idev;
713
714 input_unregister_device(dev);
715 input_free_device(dev);
716 }
717
718 static int mag_input_init(struct mag_context *cxt)
719 {
720 struct input_dev *dev;
721 int err = 0;
722
723 dev = input_allocate_device();
724 if (NULL == dev)
725 return -ENOMEM;
726
727 dev->name = MAG_INPUTDEV_NAME;
728
729 input_set_capability(dev, EV_ABS, EVENT_TYPE_MAGEL_X);
730 input_set_capability(dev, EV_ABS, EVENT_TYPE_MAGEL_Y);
731 input_set_capability(dev, EV_ABS, EVENT_TYPE_MAGEL_Z);
732 input_set_capability(dev, EV_ABS, EVENT_TYPE_MAGEL_STATUS);
733
734 input_set_capability(dev, EV_ABS, EVENT_TYPE_O_X);
735 input_set_capability(dev, EV_ABS, EVENT_TYPE_O_Y);
736 input_set_capability(dev, EV_ABS, EVENT_TYPE_O_Z);
737 input_set_capability(dev, EV_ABS, EVENT_TYPE_O_STATUS);
738
739 input_set_abs_params(dev, EVENT_TYPE_MAGEL_X, MAG_VALUE_MIN, MAG_VALUE_MAX, 0, 0);
740 input_set_abs_params(dev, EVENT_TYPE_MAGEL_Y, MAG_VALUE_MIN, MAG_VALUE_MAX, 0, 0);
741 input_set_abs_params(dev, EVENT_TYPE_MAGEL_Z, MAG_VALUE_MIN, MAG_VALUE_MAX, 0, 0);
742 input_set_abs_params(dev, EVENT_TYPE_MAGEL_STATUS, MAG_STATUS_MIN, MAG_STATUS_MAX, 0, 0);
743
744 input_set_abs_params(dev, EVENT_TYPE_O_X, MAG_VALUE_MIN, MAG_VALUE_MAX, 0, 0);
745 input_set_abs_params(dev, EVENT_TYPE_O_Y, MAG_VALUE_MIN, MAG_VALUE_MAX, 0, 0);
746 input_set_abs_params(dev, EVENT_TYPE_O_Z, MAG_VALUE_MIN, MAG_VALUE_MAX, 0, 0);
747 input_set_abs_params(dev, EVENT_TYPE_O_STATUS, MAG_STATUS_MIN, MAG_STATUS_MAX, 0, 0);
748
749 input_set_drvdata(dev, cxt);
750
751 err = input_register_device(dev);
752 if (err < 0) {
753 input_free_device(dev);
754 return err;
755 }
756 cxt->idev= dev;
757
758 return 0;
759 }
760
761 DEVICE_ATTR(magdev, S_IWUSR | S_IRUGO, mag_show_magdev, NULL);
762 DEVICE_ATTR(magactive, S_IWUSR | S_IRUGO, mag_show_active, mag_store_active);
763 DEVICE_ATTR(magdelay, S_IWUSR | S_IRUGO, mag_show_delay, mag_store_delay);
764 DEVICE_ATTR(magoactive, S_IWUSR | S_IRUGO, mag_show_oactive, mag_store_oactive);
765 DEVICE_ATTR(magodelay, S_IWUSR | S_IRUGO, mag_show_odelay, mag_store_odelay);
766 DEVICE_ATTR(magbatch, S_IWUSR | S_IRUGO, mag_show_batch, mag_store_batch);
767 DEVICE_ATTR(magflush, S_IWUSR | S_IRUGO, mag_show_flush, mag_store_flush);
768 DEVICE_ATTR(magobatch, S_IWUSR | S_IRUGO, mag_show_obatch, mag_store_obatch);
769 DEVICE_ATTR(magoflush, S_IWUSR | S_IRUGO, mag_show_oflush, mag_store_oflush);
770 DEVICE_ATTR(magdevnum, S_IWUSR | S_IRUGO, mag_show_sensordevnum, NULL);
771
772 static struct attribute *mag_attributes[] = {
773 &dev_attr_magdev.attr,
774 &dev_attr_magactive.attr,
775 &dev_attr_magdelay.attr,
776 &dev_attr_magbatch.attr,
777 &dev_attr_magflush.attr,
778 &dev_attr_magoactive.attr,
779 &dev_attr_magodelay.attr,
780 &dev_attr_magobatch.attr,
781 &dev_attr_magoflush.attr,
782 &dev_attr_magdevnum.attr,
783 NULL
784 };
785
786 static struct attribute_group mag_attribute_group = {
787 .attrs = mag_attributes
788 };
789
790
791 int mag_register_data_path(struct mag_data_path *data)
792 {
793 struct mag_context *cxt = NULL;
794 int err =0;
795 cxt = mag_context_obj;
796 cxt->mag_dev_data.div_m = data->div_m;
797 cxt->mag_dev_data.div_o = data->div_o;
798 MAG_LOG("mag register data path div_o: %d\n", cxt->mag_dev_data.div_o);
799 MAG_LOG("mag register data path div_m: %d\n", cxt->mag_dev_data.div_m);
800
801 return 0;
802 }
803
804 int mag_register_control_path(struct mag_control_path *ctl)
805 {
806 struct mag_context *cxt = NULL;
807 int err =0;
808 cxt = mag_context_obj;
809
810 cxt->mag_ctl.m_set_delay = ctl->m_set_delay;
811 cxt->mag_ctl.m_enable= ctl->m_enable;
812 cxt->mag_ctl.m_open_report_data= ctl->m_open_report_data;
813 cxt->mag_ctl.o_set_delay = ctl->o_set_delay;
814 cxt->mag_ctl.o_open_report_data= ctl->o_open_report_data;
815 cxt->mag_ctl.o_enable= ctl->o_enable;
816 cxt->mag_ctl.is_report_input_direct = ctl->is_report_input_direct;
817 cxt->mag_ctl.is_support_batch = ctl->is_support_batch;
818
819 if(NULL==cxt->mag_ctl.m_set_delay || NULL==cxt->mag_ctl.m_enable
820 || NULL==cxt->mag_ctl.m_open_report_data
821 || NULL==cxt->mag_ctl.o_set_delay || NULL==cxt->mag_ctl.o_open_report_data
822 || NULL==cxt->mag_ctl.o_enable)
823 {
824 MAG_LOG("mag register control path fail \n");
825 return -1;
826 }
827
828 //add misc dev for sensor hal control cmd
829 err = mag_misc_init(mag_context_obj);
830 if(err)
831 {
832 MAG_ERR("unable to register acc misc device!!\n");
833 return -2;
834 }
835 err = sysfs_create_group(&mag_context_obj->mdev.this_device->kobj,
836 &mag_attribute_group);
837 if (err < 0)
838 {
839 MAG_ERR("unable to create acc attribute file\n");
840 return -3;
841 }
842
843 kobject_uevent(&mag_context_obj->mdev.this_device->kobj, KOBJ_ADD);
844
845 return 0;
846 }
847
848 int mag_data_report(MAG_TYPE type,int x, int y, int z, int status)
849 {
850 //MAG_LOG("update!valus: %d, %d, %d, %d\n" , x, y, z, status);
851 struct acc_context *cxt = NULL;
852 int err =0;
853 cxt = mag_context_obj;
854 if(MAGNETIC==type)
855 {
856 input_report_abs(cxt->idev, EVENT_TYPE_MAGEL_STATUS, status);
857 input_report_abs(cxt->idev, EVENT_TYPE_MAGEL_X, x);
858 input_report_abs(cxt->idev, EVENT_TYPE_MAGEL_Y, y);
859 input_report_abs(cxt->idev, EVENT_TYPE_MAGEL_Z, z);
860 input_sync(cxt->idev);
861 }
862 if(ORIENTATION==type)
863 {
864 input_report_abs(cxt->idev, EVENT_TYPE_O_STATUS, status);
865 input_report_abs(cxt->idev, EVENT_TYPE_O_X, x);
866 input_report_abs(cxt->idev, EVENT_TYPE_O_Y, y);
867 input_report_abs(cxt->idev, EVENT_TYPE_O_Z, z);
868 input_sync(cxt->idev);
869 }
870
871 return 0;
872 }
873
874 static int mag_probe(struct platform_device *pdev)
875 {
876
877 int err;
878 MAG_LOG("+++++++++++++mag_probe!!\n");
879 mag_context_obj = mag_context_alloc_object();
880 if (!mag_context_obj)
881 {
882 err = -ENOMEM;
883 MAG_ERR("unable to allocate devobj!\n");
884 goto exit_alloc_data_failed;
885 }
886
887 //init real mageleration driver
888 err = mag_real_driver_init();
889 if(err)
890 {
891 goto mag_real_driver_init_fail;
892 MAG_ERR("mag_real_driver_init fail\n");
893 }
894 //init input dev
895 err = mag_input_init(mag_context_obj);
896 if(err)
897 {
898 MAG_ERR("unable to register mag input device!\n");
899 goto exit_alloc_input_dev_failed;
900 }
901
902 atomic_set(&(mag_context_obj->early_suspend), 0);
903 mag_context_obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1,
904 mag_context_obj->early_drv.suspend = mag_early_suspend,
905 mag_context_obj->early_drv.resume = mag_late_resume,
906 register_early_suspend(&mag_context_obj->early_drv);
907
908 MAG_LOG("----magel_probe OK !!\n");
909 return 0;
910
911 exit_hwmsen_create_attr_failed:
912 exit_misc_register_failed:
913
914 exit_err_sysfs:
915
916 if (err)
917 {
918 MAG_ERR("sysfs node creation error \n");
919 mag_input_destroy(mag_context_obj);
920 }
921
922 mag_real_driver_init_fail:
923 exit_alloc_input_dev_failed:
924 kfree(mag_context_obj);
925
926 exit_alloc_data_failed:
927
928 MAG_LOG("----magel_probe fail !!!\n");
929 return err;
930 }
931
932
933
934 static int mag_remove(struct platform_device *pdev)
935 {
936 MAG_FUN(f);
937 int err=0;
938 input_unregister_device(mag_context_obj->idev);
939 sysfs_remove_group(&mag_context_obj->idev->dev.kobj,
940 &mag_attribute_group);
941
942 if((err = misc_deregister(&mag_context_obj->mdev)))
943 {
944 MAG_ERR("misc_deregister fail: %d\n", err);
945 }
946 kfree(mag_context_obj);
947
948 return 0;
949 }
950
951 static void mag_early_suspend(struct early_suspend *h)
952 {
953 atomic_set(&(mag_context_obj->early_suspend), 1);
954 MAG_LOG(" mag_context_obj ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(mag_context_obj->early_suspend)));
955 return ;
956 }
957 /*----------------------------------------------------------------------------*/
958 static void mag_late_resume(struct early_suspend *h)
959 {
960 atomic_set(&(mag_context_obj->early_suspend), 0);
961 MAG_LOG(" mag_context_obj ok------->hwm_obj->early_suspend=%d \n",atomic_read(&(mag_context_obj->early_suspend)));
962 return ;
963 }
964
965 static int mag_suspend(struct platform_device *dev, pm_message_t state)
966 {
967 return 0;
968 }
969 /*----------------------------------------------------------------------------*/
970 static int mag_resume(struct platform_device *dev)
971 {
972 return 0;
973 }
974
975 static struct platform_driver mag_driver =
976 {
977 .probe = mag_probe,
978 .remove = mag_remove,
979 .suspend = mag_suspend,
980 .resume = mag_resume,
981 .driver =
982 {
983 .name = MAG_PL_DEV_NAME,
984 }
985 };
986
987 static int __init mag_init(void)
988 {
989 MAG_FUN();
990
991 if(platform_driver_register(&mag_driver))
992 {
993 MAG_ERR("failed to register mag driver\n");
994 return -ENODEV;
995 }
996
997 return 0;
998 }
999
1000 static void __exit mag_exit(void)
1001 {
1002 platform_driver_unregister(&mag_driver);
1003 platform_driver_unregister(&msensor_driver);
1004 }
1005
1006 module_init(mag_init);
1007 module_exit(mag_exit);
1008 MODULE_LICENSE("GPL");
1009 MODULE_DESCRIPTION("MAGELEROMETER device driver");
1010 MODULE_AUTHOR("Mediatek");
1011