import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / hwmon / hwmsen / hwmsen_dev.c
1 /* alps/ALPS_SW/TRUNK/MAIN/alps/kernel/drivers/hwmon/mt6516/hwmsen_dev.c
2 *
3 * (C) Copyright 2009
4 * MediaTek <www.MediaTek.com>
5 *
6 * Sensor devices
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22 #include <linux/interrupt.h>
23 #include <linux/miscdevice.h>
24 #include <linux/platform_device.h>
25 #include <asm/uaccess.h>
26 #include <linux/delay.h>
27 #include <linux/input.h>
28 #include <linux/workqueue.h>
29 #include <linux/wait.h>
30 #include <linux/slab.h>
31
32
33 #include <linux/hwmsensor.h>
34 #include <linux/hwmsen_helper.h>
35 #include <linux/hwmsen_dev.h>
36 //add for fix resume issue
37 #include <linux/earlysuspend.h>
38 #include <linux/wakelock.h>
39 //add for fix resume issue end
40
41 #include <cust_alsps.h>
42 #include <aal_control.h>
43
44 #define SENSOR_INVALID_VALUE -1
45 #define MAX_CHOOSE_G_NUM 5
46 #define MAX_CHOOSE_M_NUM 5
47 #if defined(CONFIG_HAS_EARLYSUSPEND)
48 static void hwmsen_early_suspend(struct early_suspend *h);
49 static void hwmsen_late_resume(struct early_suspend *h);
50 #endif
51 static void update_workqueue_polling_rate(int newDelay);
52
53 struct workqueue_struct * sensor_workqueue = NULL;
54
55 /******************************************************************************
56 * structure / enumeration / macro / definition
57 *****************************************************************************/
58
59 struct sensor_delay
60 {
61 int handle;
62 uint32_t delay;
63 };
64
65 struct hwmsen_context { /*sensor context*/
66 atomic_t enable;
67 atomic_t delay;
68 uint32_t delayCountSet;
69 uint32_t delayCount;
70
71 struct hwmsen_object obj;
72 };
73
74 #if defined(CONFIG_MTK_AUTO_DETECT_ACCELEROMETER)
75 static char gsensor_name[25];
76 static struct sensor_init_info* gsensor_init_list[MAX_CHOOSE_G_NUM]= {0}; //modified
77 #endif
78 #if defined(CONFIG_MTK_AUTO_DETECT_MAGNETOMETER)
79 static char msensor_name[25];
80 static struct sensor_init_info* msensor_init_list[MAX_CHOOSE_G_NUM]= {0}; //modified
81 #endif
82 #if defined(CONFIG_MTK_AUTO_DETECT_ALSPS)
83 static char alsps_name[25];
84 static struct sensor_init_info* alsps_init_list[MAX_CHOOSE_G_NUM]= {0}; //modified
85 #endif
86
87 /*----------------------------------------------------------------------------*/
88 struct dev_context {
89 int polling_running;
90 struct mutex lock;
91 struct hwmsen_context* cxt[MAX_ANDROID_SENSOR_NUM+1];
92 };
93 /*-------------Sensor daa-----------------------------------------------------*/
94 struct hwmsen_data{
95 hwm_sensor_data sensors_data[MAX_ANDROID_SENSOR_NUM+1];
96 int data_updata[MAX_ANDROID_SENSOR_NUM+1];
97 struct mutex lock;
98 };
99 /*----------------------------------------------------------------------------*/
100 typedef enum {
101 HWM_TRC_REPORT_NUM = 0x0001,
102 HWM_TRC_REPORT_EVT = 0x0002,
103 HWM_TRC_REPORT_INF = 0X0004,
104 } HWM_TRC;
105 /*----------------------------------------------------------------------------*/
106 #define C_MAX_OBJECT_NUM 1
107 struct hwmdev_object {
108 struct input_dev *idev;
109 struct miscdevice mdev;
110 struct dev_context *dc;
111 struct work_struct report;
112 atomic_t delay; /*polling period for reporting input event*/
113 atomic_t wake; /*user-space request to wake-up, used with stop*/
114 struct timer_list timer; /* polling timer */
115 atomic_t trace;
116 uint32_t active_sensor; // Active, but hwmsen don't need data sensor. Maybe other need it's data.
117 uint32_t active_data_sensor; // Active and hwmsen need data sensor.
118 #if defined(CONFIG_HAS_EARLYSUSPEND)
119 //add for fix resume issue
120 struct early_suspend early_drv;
121 struct wake_lock read_data_wake_lock;
122 atomic_t early_suspend;
123 //add for fix resume end
124 #endif //#if defined(CONFIG_HAS_EARLYSUSPEND)
125 };
126
127 static bool enable_again = false;
128 static struct hwmdev_object *hwm_obj = NULL;
129 /******************************************************************************
130 * static variables
131 *****************************************************************************/
132
133 static struct hwmsen_data obj_data ={
134 .lock =__MUTEX_INITIALIZER(obj_data.lock),
135 };
136 static struct dev_context dev_cxt = {
137 .lock = __MUTEX_INITIALIZER(dev_cxt.lock),
138 };
139 /*----------------------------------------------------------------------------*/
140
141
142 //AAL functions**********************************************************************
143 int hwmsen_aal_enable(int en)
144 {
145 struct hwmsen_context *cxt = NULL;
146 int err = 0;
147 int enable = 0;
148
149 if(!hwm_obj)
150 {
151 HWM_ERR("AAL hwmdev obj pointer is NULL!\n");
152 return -EINVAL;
153 }
154 else if((hwm_obj->dc->cxt[ID_LIGHT]) == NULL)
155 {
156 HWM_ERR("the sensor (%d) is not attached!!\n", ID_LIGHT);
157 return -ENODEV;
158 }
159
160 mutex_lock(&hwm_obj->dc->lock);
161 cxt = hwm_obj->dc->cxt[ID_LIGHT];
162
163 if(en == 1){
164 if((hwm_obj->active_data_sensor & (1 << ID_LIGHT))==0){
165 HWM_LOG("enable sensor(%d) by AAL operation\n", ID_LIGHT);
166 if (cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &en, sizeof(int), NULL, 0, NULL) != 0)
167 {
168 HWM_ERR("enable sensor(%d) err = %d\n", ID_LIGHT, err);
169 err = -EINVAL;
170 }
171 }
172 }else{
173 if((hwm_obj->active_data_sensor & (1 << ID_LIGHT))==0){
174 HWM_LOG("disable sensor(%d) by AAL operation\n", ID_LIGHT);
175 if (cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &en, sizeof(int), NULL, 0, NULL) != 0)
176 {
177 HWM_ERR("disable sensor(%d) err = %d\n", ID_LIGHT, err);
178 err = -EINVAL;
179 }
180 }
181 }
182 mutex_unlock(&hwm_obj->dc->lock);
183
184 return err;
185 }
186
187 int hwmsen_aal_get_data()
188 {
189 struct hwmsen_context *cxt = NULL;
190 int err = 0;
191 int enable = 0;
192 int out_size;
193 hwm_sensor_data sensor_data;
194 int als_data = 0;
195
196 //HWM_LOG("hwmsen_aal_get_data1\n");
197 if(!hwm_obj)
198 {
199 HWM_ERR("AAL hwmdev obj pointer is NULL!\n");
200 return -EINVAL;
201 }
202 else if((hwm_obj->dc->cxt[ID_LIGHT]) == NULL)
203 {
204 HWM_ERR("the sensor (%d) is not attached!!\n", ID_LIGHT);
205 return -ENODEV;
206 }
207
208 mutex_lock(&hwm_obj->dc->lock);
209 cxt = hwm_obj->dc->cxt[ID_LIGHT];
210 //HWM_LOG("hwmsen_aal_get_data2\n");
211 err = cxt->obj.sensor_operate(cxt->obj.self,SENSOR_GET_DATA, NULL, 0,
212 &sensor_data, sizeof(hwm_sensor_data), &out_size);
213 if(err)
214 {
215 mutex_unlock(&hwm_obj->dc->lock);
216 HWM_ERR("get data from sensor (%d) fails!!\n", ID_LIGHT);
217 return -ENODEV;
218 }
219 else
220 {
221 als_data = sensor_data.values[0];
222 }
223 mutex_unlock(&hwm_obj->dc->lock);
224 //HWM_LOG("hwmsen_aal_get_data3\n");
225 return als_data;
226 }
227
228 int hwmsen_aal_get_status()
229 {
230 return 0;
231 }
232 //************************************************************************************
233
234 /******************************************************************************
235 * Local functions
236 *****************************************************************************/
237 static void hwmsen_work_func(struct work_struct *work)
238 {
239
240 //HWM_LOG("+++++++++++++++++++++++++hwmsen_work_func workqueue performed!+++++++++++++++++++++++++++++\n");
241 //struct hwmdev_object *obj = container_of(work, struct hwmdev_object, report);
242 struct hwmdev_object *obj = hwm_obj;
243 struct hwmsen_context *cxt = NULL;
244 int out_size;
245 hwm_sensor_data sensor_data;
246 uint32_t event_type = 0;
247 int64_t nt;
248 struct timespec time;
249 int err, idx;
250 //int trc = atomic_read(&obj->trace);
251
252 if (obj == NULL)
253 {
254 HWM_ERR("obj point is NULL!\n");
255 return;
256 }
257
258
259 if(atomic_read(&obj->wake))
260 {
261 input_event(obj->idev, EV_SYN, SYN_CONFIG, 0);
262 atomic_set(&obj->wake, 0);
263 return;
264 }
265
266 memset(&sensor_data, 0, sizeof(sensor_data));
267 time.tv_sec = time.tv_nsec = 0;
268 get_monotonic_boottime(&time);
269 nt = time.tv_sec*1000000000LL+time.tv_nsec;
270 //mutex_lock(&obj_data.lock);
271 for(idx = 0; idx < MAX_ANDROID_SENSOR_NUM; idx++)
272 {
273 cxt = obj->dc->cxt[idx];
274 if((cxt == NULL) || (cxt->obj.sensor_operate == NULL)
275 || !(obj->active_data_sensor&(0x01<<idx)))
276 {
277 continue;
278 }
279
280 // Interrupt sensor
281 if(cxt->obj.polling == 0)
282 {
283 if(obj_data.data_updata[idx] == 1)
284 {
285 mutex_lock(&obj_data.lock);
286 event_type |= (1 << idx);
287 obj_data.data_updata[idx] = 0;
288 mutex_unlock(&obj_data.lock);
289 }
290 continue;
291 }
292
293
294 //added to surpport set delay to specified sensor
295 if(cxt->delayCount > 0)
296 {
297 //HWM_LOG("sensor(%d) delayCount = %d\n",idx,cxt->delayCount);
298 cxt->delayCount--;
299 if(0 == cxt->delayCount)
300 {
301 cxt->delayCount = cxt->delayCountSet;
302 //HWM_LOG("sensor(%d) go to get data\n",idx);
303 }
304 else
305 {
306 //HWM_LOG("sensor(%d) wait for next work\n",idx);
307 continue;
308 }
309 }
310
311 err = cxt->obj.sensor_operate(cxt->obj.self,SENSOR_GET_DATA, NULL, 0,
312 &sensor_data, sizeof(hwm_sensor_data), &out_size);
313
314 if(err)
315 {
316 HWM_ERR("get data from sensor (%d) fails!!\n", idx);
317 continue;
318 }
319 else
320 {
321 if((idx == ID_LIGHT) ||(idx == ID_PRESSURE)
322 ||(idx == ID_PROXIMITY) || (idx == ID_TEMPRERATURE))
323 {
324 // data changed, update the data
325 if(sensor_data.values[0] != obj_data.sensors_data[idx].values[0])
326 {
327 mutex_lock(&obj_data.lock);
328 obj_data.sensors_data[idx].values[0] = sensor_data.values[0];
329 obj_data.sensors_data[idx].value_divide = sensor_data.value_divide;
330 obj_data.sensors_data[idx].status = sensor_data.status;
331 obj_data.sensors_data[idx].time = nt;
332 event_type |= (1 << idx);
333 mutex_unlock(&obj_data.lock);
334 //HWM_LOG("get %d sensor, values: %d!\n", idx, sensor_data.values[0]);
335 }
336 }
337 else
338 {
339 // data changed, update the data
340 if((sensor_data.values[0] != obj_data.sensors_data[idx].values[0])
341 || (sensor_data.values[1] != obj_data.sensors_data[idx].values[1])
342 || (sensor_data.values[2] != obj_data.sensors_data[idx].values[2])
343 || (idx == ID_MAGNETIC) || (idx == ID_ACCELEROMETER))
344 {
345 if( 0 == sensor_data.values[0] && 0==sensor_data.values[1]
346 && 0 == sensor_data.values[2])
347 {
348
349 continue;
350 }
351 mutex_lock(&obj_data.lock);
352 obj_data.sensors_data[idx].values[0] = sensor_data.values[0];
353 obj_data.sensors_data[idx].values[1] = sensor_data.values[1];
354 obj_data.sensors_data[idx].values[2] = sensor_data.values[2];
355 obj_data.sensors_data[idx].value_divide = sensor_data.value_divide;
356 obj_data.sensors_data[idx].status = sensor_data.status;
357 obj_data.sensors_data[idx].time = nt;
358 event_type |= (1 << idx);
359 mutex_unlock(&obj_data.lock);
360 //HWM_LOG("get %d sensor, values: %d, %d, %d!\n", idx,
361 //sensor_data.values[0], sensor_data.values[1], sensor_data.values[2]);
362 }
363 }
364 }
365 }
366
367 //
368 //mutex_unlock(&obj_data.lock);
369
370 if(enable_again == true)
371 {
372 event_type = obj->active_data_sensor;
373 enable_again = false;
374 //filter -1 value
375 for(idx = 0; idx <= MAX_ANDROID_SENSOR_NUM; idx++)
376 {
377 if(ID_ACCELEROMETER==idx || ID_MAGNETIC==idx || ID_ORIENTATION==idx
378 ||ID_GYROSCOPE==idx || ID_TEMPRERATURE==idx
379 ||ID_LINEAR_ACCELERATION==idx || ID_ROTATION_VECTOR==idx
380 ||ID_GRAVITY==idx)
381 {
382 if(SENSOR_INVALID_VALUE == obj_data.sensors_data[idx].values[0] ||
383 SENSOR_INVALID_VALUE == obj_data.sensors_data[idx].values[1] ||
384 SENSOR_INVALID_VALUE == obj_data.sensors_data[idx].values[2])
385 {
386 event_type &= ~(1 << idx);
387 //HWM_LOG("idx=%d,obj->active_sensor after clear: %d\n",idx);
388 }
389 }
390
391 if(ID_PROXIMITY==idx || ID_LIGHT==idx || ID_PRESSURE==idx)
392 {
393 if(SENSOR_INVALID_VALUE == obj_data.sensors_data[idx].values[0])
394 {
395 event_type &= ~(1 << idx);
396 //HWM_LOG("idx=%d,obj->active_sensor after clear: %d\n",idx);
397 }
398 }
399 }
400 //HWM_LOG("event type after enable: %d\n", event_type);
401 }
402
403 if((event_type&(1 << ID_PROXIMITY))&& SENSOR_INVALID_VALUE == obj_data.sensors_data[ID_PROXIMITY].values[0])
404 {
405 event_type &= ~(1 << ID_PROXIMITY);
406 //HWM_LOG("remove ps event!!!!!!!!!!!\n");
407 }
408
409 if(event_type != 0)
410 {
411 input_report_rel(obj->idev, EVENT_TYPE_SENSOR, event_type);
412 input_sync(obj->idev);//modified
413 //HWM_LOG("event type: %d\n", event_type);
414 }
415 else
416 {
417 //HWM_LOG("no available sensor!!\n");
418 }
419
420 if(obj->dc->polling_running == 1)
421 {
422 mod_timer(&obj->timer, jiffies + atomic_read(&obj->delay)/(1000/HZ));
423 }
424 }
425
426 /******************************************************************************
427 * export functions
428 *****************************************************************************/
429 int hwmsen_get_interrupt_data(int sensor, hwm_sensor_data *data)
430 {
431 //HWM_LOG("++++++++++++++++++++++++++++hwmsen_get_interrupt_data function sensor = %d\n",sensor);
432 struct dev_context *mcxt = &dev_cxt;
433 struct hwmdev_object *obj = hwm_obj;
434 int64_t nt;
435 struct timespec time;
436
437 if((sensor > MAX_ANDROID_SENSOR_NUM) || (mcxt->cxt[sensor] == NULL)
438 || (mcxt->cxt[sensor]->obj.polling != 0))
439 {
440 HWM_ERR("sensor %d!\n", sensor);
441 return -EINVAL;
442 }
443 else
444 {
445 time.tv_sec = time.tv_nsec = 0;
446 get_monotonic_boottime(&time);
447 nt = time.tv_sec*1000000000LL+time.tv_nsec;
448 if((sensor == ID_LIGHT) ||(sensor == ID_PRESSURE)
449 ||(sensor == ID_PROXIMITY) || (sensor == ID_TEMPRERATURE))
450 {
451 // data changed, update the data
452 if(data->values[0] != obj_data.sensors_data[sensor].values[0])
453 {
454 mutex_lock(&obj_data.lock);
455 obj_data.data_updata[sensor] = 1;
456 obj_data.sensors_data[sensor].values[0] = data->values[0];
457 obj_data.sensors_data[sensor].time = nt;
458 obj_data.sensors_data[sensor].value_divide = data->value_divide;
459 mutex_unlock(&obj_data.lock);
460 }
461 }
462 else
463 {
464 // data changed, update the data
465 if((data->values[0] != obj_data.sensors_data[sensor].values[0])
466 || (data->values[1] != obj_data.sensors_data[sensor].values[1])
467 || (data->values[2] != obj_data.sensors_data[sensor].values[2]))
468 {
469 mutex_lock(&obj_data.lock);
470 obj_data.sensors_data[sensor].values[0] = data->values[0];
471 obj_data.sensors_data[sensor].values[1] = data->values[1];
472 obj_data.sensors_data[sensor].values[2] = data->values[2];
473 obj_data.sensors_data[sensor].value_divide = data->value_divide;
474 obj_data.data_updata[sensor] = 1;
475 obj_data.sensors_data[sensor].time = nt;
476 mutex_unlock(&obj_data.lock);
477 }
478 }
479
480 if(obj->dc->polling_running == 1)
481 {
482 hwmsen_work_func(NULL);
483 }
484
485 return 0;
486 }
487 }
488 /*----------------------------------------------------------------------------*/
489 EXPORT_SYMBOL_GPL(hwmsen_get_interrupt_data);
490
491 /*----------------------------------------------------------------------------*/
492 static void hwmsen_poll(unsigned long data)
493 {
494 struct hwmdev_object *obj = (struct hwmdev_object *)data;
495 if(obj != NULL)
496 {
497 queue_work(sensor_workqueue, &obj->report);
498 }
499 }
500 /*----------------------------------------------------------------------------*/
501 static struct hwmdev_object *hwmsen_alloc_object(void)
502 {
503
504 struct hwmdev_object *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
505 HWM_FUN(f);
506
507 if(!obj)
508 {
509 HWM_ERR("Alloc hwmsen object error!\n");
510 return NULL;
511 }
512
513 obj->dc = &dev_cxt;
514 obj->active_data_sensor = 0;
515 obj->active_sensor = 0;
516 atomic_set(&obj->delay, 200); /*5Hz*/// set work queue delay time 200ms
517 atomic_set(&obj->wake, 0);
518 sensor_workqueue = create_singlethread_workqueue("sensor_polling");
519 if (!sensor_workqueue)
520 {
521 kfree(obj);
522 return NULL;
523 }
524 INIT_WORK(&obj->report, hwmsen_work_func);
525 init_timer(&obj->timer);
526 obj->timer.expires = jiffies + atomic_read(&obj->delay)/(1000/HZ);
527 obj->timer.function = hwmsen_poll;
528 obj->timer.data = (unsigned long)obj;
529 return obj;
530 }
531
532 /*Sensor device driver attach to hwmsen device------------------------------------------------*/
533 int hwmsen_attach(int sensor, struct hwmsen_object *obj)
534 {
535
536 struct dev_context *mcxt = &dev_cxt;
537 int err = 0;
538 HWM_FUN(f);
539 if((mcxt == NULL) || (sensor > MAX_ANDROID_SENSOR_NUM))
540 {
541 err = -EINVAL;
542 goto err_exit;
543 }
544
545 mutex_lock(&mcxt->lock);
546 if(mcxt->cxt[sensor] != NULL)
547 {
548 err = -EEXIST;
549 goto err_exit;
550 }
551 else
552 {
553 mcxt->cxt[sensor] = kzalloc(sizeof(struct hwmsen_context), GFP_KERNEL);
554 if(mcxt->cxt[sensor] == NULL)
555 {
556 err = -EPERM;
557 goto err_exit;
558 }
559 atomic_set(&mcxt->cxt[sensor]->enable, 0);
560 memcpy(&mcxt->cxt[sensor]->obj, obj, sizeof(*obj));
561
562 // add for android2.3 set sensors default polling delay time is 200ms
563 atomic_set(&mcxt->cxt[sensor]->delay, 200);
564
565
566 }
567
568 err_exit:
569 mutex_unlock(&mcxt->lock);
570 return err;
571 }
572 /*----------------------------------------------------------------------------*/
573 EXPORT_SYMBOL_GPL(hwmsen_attach);
574 /*----------------------------------------------------------------------------*/
575 int hwmsen_detach(int sensor)
576 {
577
578 int err = 0;
579 struct dev_context *mcxt = &dev_cxt;
580 HWM_FUN(f);
581 if ((sensor > MAX_ANDROID_SENSOR_NUM) || (mcxt->cxt[sensor] == NULL))
582 {
583 err = -EINVAL;
584 goto err_exit;
585 }
586
587 mutex_lock(&mcxt->lock);
588 kfree(mcxt->cxt[sensor]);
589 mcxt->cxt[sensor] = NULL;
590
591 err_exit:
592 mutex_unlock(&mcxt->lock);
593 return 0;
594 }
595 /*----------------------------------------------------------------------------*/
596 EXPORT_SYMBOL_GPL(hwmsen_detach);
597 /*----------------------------------------------------------------------------*/
598 static int hwmsen_enable(struct hwmdev_object *obj, int sensor, int enable)
599 {
600 struct hwmsen_context *cxt = NULL;
601 int err = 0;
602 uint32_t sensor_type;
603
604 sensor_type = 1 << sensor;
605
606 if (sensor > MAX_ANDROID_SENSOR_NUM || sensor < 0) {
607 HWM_ERR("handle %d!\n", sensor);
608 return -EINVAL;
609 }
610
611 if(!obj)
612 {
613 HWM_ERR("hwmdev obj pointer is NULL!\n");
614 return -EINVAL;
615 }
616 else if(obj->dc->cxt[sensor] == NULL)
617 {
618 HWM_ERR("the sensor (%d) is not attached!!\n", sensor);
619 return -ENODEV;
620 }
621
622 mutex_lock(&obj->dc->lock);
623 cxt = obj->dc->cxt[sensor];
624
625
626 if(enable == 1)
627 {
628 //{@for mt6582 blocking issue work around
629 if(sensor == 7){
630 HWM_LOG("P-sensor disable LDO low power\n");
631 pmic_ldo_suspend_enable(0);
632 }
633 //@}
634 enable_again = true;
635 obj->active_data_sensor |= sensor_type;
636 if((obj->active_sensor & sensor_type) == 0) // no no-data active
637 {
638 if (cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable,sizeof(int), NULL, 0, NULL) != 0)
639 {
640 if (cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable,sizeof(int), NULL, 0, NULL) != 0)
641 {
642 if (cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable,sizeof(int), NULL, 0, NULL) != 0)
643 {
644 HWM_ERR("activate sensor(%d) 3 times err = %d\n", sensor, err);
645 err = -EINVAL;
646 goto exit;
647 }
648 }
649
650 }
651 update_workqueue_polling_rate(200);
652 atomic_set(&cxt->enable, 1);
653 }
654
655 // Need to complete the interrupt sensor work
656 if((0 == obj->dc->polling_running) && (obj->active_data_sensor != 0))
657 {
658 obj->dc->polling_running = 1;
659 //obj->timer.expires = jiffies + atomic_read(&obj->delay)/(1000/HZ);
660 //add_timer(&obj->timer);
661 mod_timer(&obj->timer, jiffies + atomic_read(&obj->delay)/(1000/HZ));
662
663 }
664
665 }
666 else if ((enable == 0))
667 {
668 //{@for mt6582 blocking issue work around
669 if(sensor == 7){
670 HWM_LOG("P-sensor enable LDO low power\n");
671 pmic_ldo_suspend_enable(1);
672
673 }
674 //@}
675
676 obj->active_data_sensor &= ~sensor_type;
677 if((obj->active_sensor & sensor_type) == 0) // no no-data active
678 {
679 #ifdef CONFIG_CUSTOM_KERNEL_ALSPS
680 if(sensor == 4 && aal_use == 1){
681 HWM_ERR("AAL is used ingnore common light disable\n");
682 err = 0;
683 }
684 else
685 #endif
686 {
687
688 if(cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable,sizeof(int), NULL, 0, NULL) != 0)
689 {
690 HWM_ERR("deactiva sensor(%d) err = %d\n", sensor, err);
691 err = -EINVAL;
692 goto exit;
693 }
694 }
695
696 atomic_set(&cxt->enable, 0);
697 update_workqueue_polling_rate(200);// re-update workqueue polling rate
698 }
699
700 if((1 == obj->dc->polling_running) && (obj->active_data_sensor == 0))
701 {
702 obj->dc->polling_running = 0;
703 del_timer_sync(&obj->timer);
704 cancel_work_sync(&obj->report);
705
706 }
707
708 obj_data.sensors_data[sensor].values[0] = SENSOR_INVALID_VALUE;
709 obj_data.sensors_data[sensor].values[1] = SENSOR_INVALID_VALUE;
710 obj_data.sensors_data[sensor].values[2] = SENSOR_INVALID_VALUE;
711
712 }
713
714 HWM_LOG("sensor(%d), flag(%d)\n", sensor, enable);
715
716 exit:
717
718 mutex_unlock(&obj->dc->lock);
719 return err;
720 }
721
722 /*-------------no data sensor enable/disable--------------------------------------*/
723 static int hwmsen_enable_nodata(struct hwmdev_object *obj, int sensor, int enable)
724 {
725 struct hwmsen_context *cxt = NULL;
726 int err = 0;
727 uint32_t sensor_type;
728 HWM_FUN(f);
729 sensor_type = 1 << sensor;
730
731 if (sensor > MAX_ANDROID_SENSOR_NUM || sensor < 0) {
732 HWM_ERR("handle %d!\n", sensor);
733 return -EINVAL;
734 }
735
736 if(NULL == obj)
737 {
738 HWM_ERR("hwmdev obj pointer is NULL!\n");
739 return -EINVAL;
740 }
741 else if(obj->dc->cxt[sensor] == NULL)
742 {
743 HWM_ERR("the sensor (%d) is not attached!!\n", sensor);
744 return -ENODEV;
745 }
746
747 mutex_lock(&obj->dc->lock);
748 cxt = obj->dc->cxt[sensor];
749
750 if(enable == 1)
751 {
752 obj->active_sensor |= sensor_type;
753
754 if((obj->active_data_sensor & sensor_type) == 0) // no data active
755 {
756 if(cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable, sizeof(int), NULL, 0, NULL) != 0)
757 {
758 HWM_ERR("activate sensor(%d) err = %d\n", sensor, err);
759 err = -EINVAL;
760 goto exit;
761 }
762
763 atomic_set(&cxt->enable, 1);
764 }
765 }
766 else
767 {
768 obj->active_sensor &= ~sensor_type;
769
770 if((obj->active_data_sensor & sensor_type) == 0) // no data active
771 {
772 if(cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable,sizeof(int), NULL, 0, NULL) != 0)
773 {
774 HWM_ERR("Deactivate sensor(%d) err = %d\n", sensor, err);
775 err = -EINVAL;
776 goto exit;
777 }
778
779 atomic_set(&cxt->enable, 0);
780 }
781
782 }
783
784 exit:
785
786 mutex_unlock(&obj->dc->lock);
787 return err;
788 }
789 /*------------set delay--------------------------------------------------------*/
790 static int hwmsen_set_delay(int delay, int handle )
791 {
792 int err = 0;
793 struct hwmsen_context *cxt = NULL;
794
795 if (handle > MAX_ANDROID_SENSOR_NUM || handle < 0) {
796 HWM_ERR("handle %d!\n", handle);
797 return -EINVAL;
798 }
799 cxt = hwm_obj->dc->cxt[handle];
800 if(NULL == cxt ||(cxt->obj.sensor_operate == NULL))
801 {
802 HWM_ERR("have no this sensor %d or operator point is null!\r\n", handle);
803 }
804 else //if(atomic_read(&cxt->enable) != 0) //always update delay even sensor is not enabled.
805 {
806 if(cxt->obj.sensor_operate(cxt->obj.self, SENSOR_DELAY, &delay,sizeof(int), NULL, 0, NULL) != 0)
807 {
808 HWM_ERR("%d sensor's sensor_operate function error %d!\r\n",handle,err);
809 return err;
810 }
811 //record sensor delay
812 atomic_set(&cxt->delay, delay);
813 }
814 return err;
815 }
816 /*----------------------------------------------------------------------------*/
817 static int hwmsen_wakeup(struct hwmdev_object *obj)
818 {
819 HWM_FUN(f);
820 if(obj == NULL)
821 {
822 HWM_ERR("null pointer!!\n");
823 return -EINVAL;
824 }
825
826 input_event(obj->idev, EV_SYN, SYN_CONFIG, 0);
827
828 return 0;
829 }
830 /*----------------------------------------------------------------------------*/
831 static ssize_t hwmsen_show_hwmdev(struct device* dev,
832 struct device_attribute *attr, char *buf)
833 {
834
835 //struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
836 int len = 0;
837 printk("sensor test: hwmsen_show_hwmdev function!\n");
838 /*
839 if (!devobj || !devobj->dc) {
840 HWM_ERR("null pointer: %p, %p", devobj, (!devobj) ? (NULL) : (devobj->dc));
841 return 0;
842 }
843 for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
844 len += snprintf(buf+len, PAGE_SIZE-len, " %d", idx);
845 len += snprintf(buf+len, PAGE_SIZE-len, "\n");
846 for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
847 len += snprintf(buf+len, PAGE_SIZE-len, " %d", atomic_read(&devobj->dc->cxt[idx].enable));
848 len += snprintf(buf+len, PAGE_SIZE-len, "\n");
849 */
850 return len;
851 }
852 /*----------------------------------------------------------------------------*/
853 static ssize_t hwmsen_store_active(struct device* dev, struct device_attribute *attr,
854 const char *buf, size_t count)
855 {
856 /*
857 printk("sensor test: hwmsen_store_active function!\n");
858 struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
859 int sensor, enable, err, idx;
860
861 if (!devobj || !devobj->dc) {
862 HWM_ERR("null pointer!!\n");
863 return count;
864 }
865
866 if (!strncmp(buf, "all-start", 9)) {
867 for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
868 hwmsen_enable(devobj, idx, 1);
869 } else if (!strncmp(buf, "all-stop", 8)) {
870 for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
871 hwmsen_enable(devobj, idx, 0);
872 } else if (2 == sscanf(buf, "%d %d", &sensor, &enable)) {
873 if ((err = hwmsen_enable(devobj, sensor, enable)))
874 HWM_ERR("sensor enable failed: %d\n", err);
875 }
876 */
877 return count;
878 }
879 /*----------------------------------------------------------------------------*/
880 static ssize_t hwmsen_show_delay(struct device* dev,
881 struct device_attribute *attr, char *buf)
882 {
883 /*
884 struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
885 printk("sensor test: hwmsen_show_delay function!\n");
886 if (!devobj || !devobj->dc) {
887 HWM_ERR("null pointer!!\n");
888 return 0;
889 }
890
891 return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&devobj->delay));
892 */
893
894 return 0;
895
896 }
897 /*----------------------------------------------------------------------------*/
898 static ssize_t hwmsen_store_delay(struct device* dev, struct device_attribute *attr,
899 const char *buf, size_t count)
900 {
901 /*
902 struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
903 int delay;
904 printk("sensor test: hwmsen_show_delay function!\n");
905 if (!devobj || !devobj->dc) {
906 HWM_ERR("null pointer!!\n");
907 return count;
908 }
909
910 if (1 != sscanf(buf, "%d", &delay)) {
911 HWM_ERR("invalid format!!\n");
912 return count;
913 }
914
915 atomic_set(&devobj->delay, delay);
916 */
917 return count;
918 }
919 /*----------------------------------------------------------------------------*/
920 static ssize_t hwmsen_show_wake(struct device* dev,
921 struct device_attribute *attr, char *buf)
922 {
923 /*
924 printk("sensor test: hwmsen_show_wake function!\n");
925 struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
926
927 if (!devobj || !devobj->dc) {
928 HWM_ERR("null pointer!!\n");
929 return 0;
930 }
931 return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&devobj->wake));
932 */
933 return 0;
934 }
935 /*----------------------------------------------------------------------------*/
936 static ssize_t hwmsen_store_wake(struct device* dev, struct device_attribute *attr,
937 const char *buf, size_t count)
938 {
939 /*
940 struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
941 int wake, err;
942 printk("sensor test: hwmsen_store_wake function!\n");
943 if (!devobj || !devobj->dc) {
944 HWM_ERR("null pointer!!\n");
945 return count;
946 }
947
948 if (1 != sscanf(buf, "%d", &wake)) {
949 HWM_ERR("invalid format!!\n");
950 return count;
951 }
952
953 if ((err = hwmsen_wakeup(devobj))) {
954 HWM_ERR("wakeup sensor fail, %d\n", err);
955 return count;
956 }
957 */
958 return count;
959 }
960
961 /*----------------------------------------------------------------------------*/
962 static ssize_t hwmsen_show_trace(struct device *dev,
963 struct device_attribute *attr, char *buf)
964 {
965
966 struct i2c_client *client = to_i2c_client(dev);
967 struct hwmdev_object *obj = i2c_get_clientdata(client);
968 HWM_FUN(f);
969
970 return snprintf(buf, PAGE_SIZE, "0x%08X\n", atomic_read(&obj->trace));
971 }
972 /*----------------------------------------------------------------------------*/
973 static ssize_t hwmsen_store_trace(struct device* dev,
974 struct device_attribute *attr, const char *buf, size_t count)
975 {
976 struct i2c_client *client = to_i2c_client(dev);
977 struct hwmdev_object *obj = i2c_get_clientdata(client);
978 int trc;
979 HWM_FUN(f);
980
981 if (1 == sscanf(buf, "0x%x\n", &trc))
982 {
983 atomic_set(&obj->trace, trc);
984 }
985 else
986 {
987 HWM_ERR("set trace level fail!!\n");
988 }
989 return count;
990 }
991 /*----------------------------------------------------------------------------*/
992 static ssize_t hwmsen_show_sensordevnum(struct device *dev,
993 struct device_attribute *attr, char *buf)
994 {
995 const char *devname = NULL;
996 devname = dev_name(&hwm_obj->idev->dev);
997
998 return snprintf(buf, PAGE_SIZE, "%s\n", devname+5);
999 }
1000 DEVICE_ATTR(hwmdev, S_IRUGO, hwmsen_show_hwmdev, NULL);
1001 DEVICE_ATTR(active, S_IWUSR | S_IRUGO, hwmsen_show_hwmdev, hwmsen_store_active);
1002 DEVICE_ATTR(delay, S_IWUSR | S_IRUGO, hwmsen_show_delay, hwmsen_store_delay);
1003 DEVICE_ATTR(wake, S_IWUSR | S_IRUGO, hwmsen_show_wake, hwmsen_store_wake);
1004 DEVICE_ATTR(trace, S_IWUSR | S_IRUGO, hwmsen_show_trace, hwmsen_store_trace);
1005 DEVICE_ATTR(hwmsensordevnum, S_IRUGO, hwmsen_show_sensordevnum, NULL);
1006 /*----------------------------------------------------------------------------*/
1007 static struct device_attribute *hwmsen_attr_list[] =
1008 {
1009 &dev_attr_hwmdev,
1010 &dev_attr_active,
1011 &dev_attr_delay,
1012 &dev_attr_wake,
1013 &dev_attr_trace,
1014 &dev_attr_hwmsensordevnum,
1015 };
1016
1017
1018 /*----------------------------------------------------------------------------*/
1019 static int hwmsen_create_attr(struct device *dev)
1020 {
1021 int idx, err = 0;
1022 int num = (int)(sizeof(hwmsen_attr_list)/sizeof(hwmsen_attr_list[0]));
1023 HWM_FUN();
1024 if(!dev)
1025 {
1026 return -EINVAL;
1027 }
1028
1029 for(idx = 0; idx < num; idx++)
1030 {
1031 if((err = device_create_file(dev, hwmsen_attr_list[idx])))
1032 {
1033 HWM_ERR("device_create_file (%s) = %d\n", hwmsen_attr_list[idx]->attr.name, err);
1034 break;
1035 }
1036 }
1037
1038 return err;
1039 }
1040 /*----------------------------------------------------------------------------*/
1041 static int hwmsen_delete_attr(struct device *dev)
1042 {
1043
1044 int idx ,err = 0;
1045 int num = (int)(sizeof(hwmsen_attr_list)/sizeof(hwmsen_attr_list[0]));
1046 HWM_FUN(f);
1047 if (!dev)
1048 {
1049 return -EINVAL;
1050 }
1051
1052
1053 for (idx = 0; idx < num; idx++)
1054 {
1055 device_remove_file(dev, hwmsen_attr_list[idx]);
1056 }
1057
1058 return err;
1059 }
1060
1061 /*----------------------------------------------------------------*/
1062 static int init_static_data(void)
1063 {
1064 int i = 0;
1065 // memset(&obj_data, 0, sizeof(struct hwmsen_data));
1066 // obj_data.lock = __MUTEX_INITIALIZER(obj_data.lock);
1067 for(i=0; i < MAX_ANDROID_SENSOR_NUM; i++)
1068 {
1069 dev_cxt.cxt[i] = NULL;
1070 memset(&obj_data.sensors_data[i], SENSOR_INVALID_VALUE, sizeof(hwm_sensor_data));
1071 obj_data.sensors_data[i].sensor = i;
1072
1073 }
1074 return 0;
1075 }
1076 /*----------------------------------------------------------------*/
1077 static int hwmsen_open(struct inode *node , struct file *fp)
1078 {
1079 HWM_FUN(f);
1080 //struct file_private* data = kzalloc(sizeof(struct file_private), GFP_KERNEL);
1081 // fp->private_data = data;
1082 fp->private_data = NULL;
1083 return nonseekable_open(node,fp);
1084 }
1085 /*----------------------------------------------------------------------------*/
1086 static int hwmsen_release(struct inode *node, struct file *fp)
1087 {
1088 HWM_FUN(f);
1089 kfree(fp->private_data);
1090 fp->private_data = NULL;
1091 return 0;
1092 }
1093 /*----------------------------------------------------------------------------*/
1094 static void update_workqueue_polling_rate(int newDelay)
1095 {
1096 atomic_t delaytemp;
1097 int i=0;
1098 int idx=0;
1099 struct hwmsen_context *cxt = NULL;
1100 struct hwmdev_object *obj = hwm_obj;
1101 HWM_FUN(f);
1102 atomic_set(&delaytemp, 200);//used to finding fastest sensor polling rate
1103
1104 for(i = 0; i < MAX_ANDROID_SENSOR_NUM; i++)
1105 {
1106 if(hwm_obj->active_data_sensor & 1<<i)
1107 {
1108 if(atomic_read(&delaytemp) > atomic_read(&(hwm_obj->dc->cxt[i]->delay)))
1109 {
1110 atomic_set(&delaytemp, atomic_read(&(hwm_obj->dc->cxt[i]->delay)));// work queue polling delay base time
1111 }
1112 }
1113 }
1114 //use the fastest sensor polling delay as work queue polling delay base time
1115 if(atomic_read(&delaytemp) > newDelay)
1116 {
1117 atomic_set(&hwm_obj->delay, newDelay);// work queue polling delay base time
1118 HWM_LOG("set new workqueue base time=%d\n",atomic_read(&hwm_obj->delay));
1119 }
1120 else
1121 {
1122 atomic_set(&hwm_obj->delay, atomic_read(&delaytemp));
1123 HWM_LOG("set old fastest sensor delay as workqueue base time=%d\n",atomic_read(&hwm_obj->delay));
1124 }
1125
1126 //upadate all sensors delayCountSet
1127 for(idx = 0; idx < MAX_ANDROID_SENSOR_NUM; idx++)
1128 {
1129 cxt = obj->dc->cxt[idx];
1130 if((cxt == NULL) || (cxt->obj.sensor_operate == NULL)
1131 || !(obj->active_data_sensor&(0x01<<idx)))
1132 {
1133 continue;
1134 }
1135
1136 if(0 == atomic_read(&cxt->delay))
1137 {
1138 cxt->delayCount = cxt->delayCountSet = 0;
1139 HWM_LOG("%s,set delayCountSet=0 delay =%d handle=%d\r\n",__func__, atomic_read(&cxt->delay), idx);
1140 }
1141 if(atomic_read(&cxt->delay) <= atomic_read(&hwm_obj->delay))
1142 {
1143 cxt->delayCount = cxt->delayCountSet = 0;
1144 HWM_LOG("%s,set delayCountSet=0 delay =%d handle=%d\r\n",__func__, atomic_read(&cxt->delay), idx);
1145 }
1146 else
1147 {
1148 i= atomic_read(&cxt->delay)/atomic_read(&hwm_obj->delay);
1149 cxt->delayCount = cxt->delayCountSet = i;
1150 HWM_LOG("%s:set delayCountSet=%d delay =%d handle=%d\r\n",__func__, i, atomic_read(&cxt->delay), idx);
1151 #if 0
1152 switch(i)
1153 {
1154 case 3:
1155 // 200/60 ;60/20
1156 cxt->delayCount = cxt->delayCountSet = 3;
1157 HWM_LOG("%s:set delayCountSet=3 delay =%d handle=%d\r\n",__func__,atomic_read(&cxt->delay), idx);
1158 break;
1159 case 10:
1160 // 200/20
1161 cxt->delayCount = cxt->delayCountSet = 10;
1162 HWM_LOG("%s:set delayCountSet=10 delay =%d handle=%d\r\n",__func__, atomic_read(&cxt->delay), idx);
1163 break;
1164 }
1165 #endif
1166 }
1167 }
1168 }
1169
1170 //static int hwmsen_ioctl(struct inode *node, struct file *fp,
1171 // unsigned int cmd, unsigned long arg)
1172 static long hwmsen_unlocked_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
1173 {
1174 //HWM_LOG("IO parament %d!\r\n", cmd);
1175 void __user *argp = (void __user*)arg;
1176 uint32_t flag;
1177 struct sensor_delay delayPara;
1178 hwm_trans_data hwm_sensors_data;
1179 int i = 0;
1180 atomic_t delaytemp;
1181 atomic_set(&delaytemp, 200);//used to finding fastest sensor polling rate
1182 //int delaytemp=200;//used to finding fastest sensor polling rate
1183
1184 if(!hwm_obj)
1185 {
1186 HWM_ERR("null pointer!!\n");
1187 return -EINVAL;
1188 }
1189
1190 switch(cmd)
1191 {
1192 case HWM_IO_SET_DELAY:
1193 // android2.3 sensor system has 4 sample delay 0ms 20ms 60ms 200ms
1194 if(copy_from_user(&delayPara, argp, sizeof(delayPara)))
1195 {
1196 HWM_ERR("copy_from_user fail!!\n");
1197 return -EFAULT;
1198 }
1199 HWM_LOG("ioctl delay handle=%d,delay =%d\n",delayPara.handle,delayPara.delay);
1200 hwmsen_set_delay(delayPara.delay,delayPara.handle);//modified for android2.3
1201 update_workqueue_polling_rate(delayPara.delay);
1202
1203 break;
1204
1205 case HWM_IO_SET_WAKE:
1206 hwmsen_wakeup(hwm_obj);
1207 break;
1208
1209 case HWM_IO_ENABLE_SENSOR:
1210 if(copy_from_user(&flag, argp, sizeof(flag)))
1211 {
1212 HWM_ERR("copy_from_user fail!!\n");
1213 return -EFAULT;
1214 }
1215 hwmsen_enable(hwm_obj, flag, 1);
1216 break;
1217
1218 case HWM_IO_DISABLE_SENSOR:
1219 if(copy_from_user(&flag, argp, sizeof(flag)))
1220 {
1221 HWM_ERR("copy_from_user fail!!\n");
1222 return -EFAULT;
1223 }
1224 hwmsen_enable(hwm_obj, flag, 0);
1225 break;
1226
1227 case HWM_IO_GET_SENSORS_DATA:
1228 if(copy_from_user(&hwm_sensors_data, argp, sizeof(hwm_sensors_data)))
1229 {
1230 HWM_ERR("copy_from_user fail!!\n");
1231 return -EFAULT;
1232 }
1233 mutex_lock(&obj_data.lock);
1234 memcpy(hwm_sensors_data.data, &(obj_data.sensors_data),sizeof(hwm_sensor_data) * MAX_ANDROID_SENSOR_NUM);
1235 for(i = 0; i < MAX_ANDROID_SENSOR_NUM; i++)
1236 {
1237 if(hwm_sensors_data.date_type & 1<<i)
1238 {
1239 hwm_sensors_data.data[i].update = 1;
1240 }
1241 else
1242 {
1243 hwm_sensors_data.data[i].update = 0;
1244 }
1245 }
1246 mutex_unlock(&obj_data.lock);
1247 if(copy_to_user(argp, &hwm_sensors_data, sizeof(hwm_sensors_data)))
1248 {
1249 HWM_ERR("copy_to_user fail!!\n");
1250 return -EFAULT;
1251 }
1252 break;
1253
1254 case HWM_IO_ENABLE_SENSOR_NODATA:
1255 if(copy_from_user(&flag, argp, sizeof(flag)))
1256 {
1257 HWM_ERR("copy_from_user fail!!\n");
1258 return -EFAULT;
1259 }
1260 hwmsen_enable_nodata(hwm_obj, flag, 1);
1261 break;
1262
1263 case HWM_IO_DISABLE_SENSOR_NODATA:
1264 if(copy_from_user(&flag, argp, sizeof(flag)))
1265 {
1266 HWM_ERR("copy_from_user fail!!\n");
1267 return -EFAULT;
1268 }
1269 hwmsen_enable_nodata(hwm_obj, flag, 0);
1270 break;
1271
1272 default:
1273 HWM_ERR("have no this paramenter %d!!\n", cmd);
1274 return -ENOIOCTLCMD;
1275 }
1276
1277 return 0;
1278 }
1279 /*----------------------------------------------------------------------------*/
1280 static struct file_operations hwmsen_fops = {
1281 // .owner = THIS_MODULE,
1282 .open = hwmsen_open,
1283 .release = hwmsen_release,
1284 // .ioctl = hwmsen_ioctl,
1285 .unlocked_ioctl = hwmsen_unlocked_ioctl,
1286 };
1287 /*----------------------------------------------------------------------------*/
1288 static int hwmsen_probe(struct platform_device *pdev)
1289 {
1290
1291 int err;
1292 //HWM_LOG("+++++++++++++++++hwmsen_probe!!\n");
1293
1294 HWM_FUN(f);
1295 init_static_data();
1296 hwm_obj = hwmsen_alloc_object();
1297 if (!hwm_obj)
1298 {
1299 err = -ENOMEM;
1300 HWM_ERR("unable to allocate devobj!\n");
1301 goto exit_alloc_data_failed;
1302 }
1303
1304 hwm_obj->idev = input_allocate_device();
1305 if (!hwm_obj->idev)
1306 {
1307 err = -ENOMEM;
1308 HWM_ERR("unable to allocate input device!\n");
1309 goto exit_alloc_input_dev_failed;
1310 }
1311
1312 set_bit(EV_REL, hwm_obj->idev->evbit);
1313 set_bit(EV_SYN, hwm_obj->idev->evbit);
1314
1315 input_set_capability(hwm_obj->idev, EV_REL, EVENT_TYPE_SENSOR);
1316 hwm_obj->idev->name = HWM_INPUTDEV_NAME;
1317 if((err = input_register_device(hwm_obj->idev)))
1318 {
1319 HWM_ERR("unable to register input device!\n");
1320 goto exit_input_register_device_failed;
1321 }
1322 input_set_drvdata(hwm_obj->idev, hwm_obj);
1323
1324 hwm_obj->mdev.minor = MISC_DYNAMIC_MINOR;
1325 hwm_obj->mdev.name = HWM_SENSOR_DEV_NAME;
1326 hwm_obj->mdev.fops = &hwmsen_fops;
1327 if((err = misc_register(&hwm_obj->mdev)))
1328 {
1329 HWM_ERR("unable to register sensor device!!\n");
1330 goto exit_misc_register_failed;
1331 }
1332 dev_set_drvdata(hwm_obj->mdev.this_device, hwm_obj);
1333
1334 if(hwmsen_create_attr(hwm_obj->mdev.this_device) != 0)
1335 {
1336 HWM_ERR("unable to create attributes!!\n");
1337 goto exit_hwmsen_create_attr_failed;
1338 }
1339 #if defined(CONFIG_HAS_EARLYSUSPEND)
1340 // add for fix resume bug
1341 atomic_set(&(hwm_obj->early_suspend), 0);
1342 hwm_obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1,
1343 hwm_obj->early_drv.suspend = hwmsen_early_suspend,
1344 hwm_obj->early_drv.resume = hwmsen_late_resume,
1345 register_early_suspend(&hwm_obj->early_drv);
1346 wake_lock_init(&(hwm_obj->read_data_wake_lock),WAKE_LOCK_SUSPEND,"read_data_wake_lock");
1347 // add for fix resume bug end
1348 #endif //#if defined(CONFIG_HAS_EARLYSUSPEND)
1349 return 0;
1350
1351 exit_hwmsen_create_attr_failed:
1352 exit_misc_register_failed:
1353 // exit_get_hwmsen_info_failed:
1354 exit_input_register_device_failed:
1355 input_free_device(hwm_obj->idev);
1356
1357 exit_alloc_input_dev_failed:
1358 kfree(hwm_obj);
1359
1360 exit_alloc_data_failed:
1361 return err;
1362 }
1363 /*----------------------------------------------------------------------------*/
1364 static int hwmsen_remove(struct platform_device *pdev)
1365 {
1366 HWM_FUN(f);
1367
1368 input_unregister_device(hwm_obj->idev);
1369 hwmsen_delete_attr(hwm_obj->mdev.this_device);
1370 misc_deregister(&hwm_obj->mdev);
1371 kfree(hwm_obj);
1372
1373 return 0;
1374 }
1375 #if defined(CONFIG_HAS_EARLYSUSPEND)
1376 static void hwmsen_early_suspend(struct early_suspend *h)
1377 {
1378 //HWM_FUN(f);
1379 atomic_set(&(hwm_obj->early_suspend), 1);
1380 HWM_LOG(" hwmsen_early_suspend ok------->hwm_obj->early_suspend=%d \n",atomic_read(&hwm_obj->early_suspend));
1381 return ;
1382 }
1383 /*----------------------------------------------------------------------------*/
1384 static void hwmsen_late_resume(struct early_suspend *h)
1385 {
1386 //HWM_FUN(f);
1387 atomic_set(&(hwm_obj->early_suspend), 0);
1388 HWM_LOG(" hwmsen_late_resume ok------->hwm_obj->early_suspend=%d \n",atomic_read(&hwm_obj->early_suspend));
1389 return ;
1390 }
1391 #endif //#if defined(CONFIG_HAS_EARLYSUSPEND)
1392 /*----------------------------------------------------------------------------*/
1393 static int hwmsen_suspend(struct platform_device *dev, pm_message_t state)
1394 {
1395 //HWM_FUN(f);
1396 return 0;
1397 }
1398 /*----------------------------------------------------------------------------*/
1399 static int hwmsen_resume(struct platform_device *dev)
1400 {
1401 //HWM_FUN(f);
1402 return 0;
1403 }
1404 /*----------------------------------------------------------------------------*/
1405
1406 #ifdef CONFIG_OF
1407 static const struct of_device_id hwmsensor_of_match[] = {
1408 { .compatible = "mediatek,hwmsensor", },
1409 {},
1410 };
1411 #endif
1412
1413 static struct platform_driver hwmsen_driver =
1414 {
1415 .probe = hwmsen_probe,
1416 .remove = hwmsen_remove,
1417 .suspend = hwmsen_suspend,
1418 .resume = hwmsen_resume,
1419 .driver =
1420 {
1421 .name = HWM_SENSOR_DEV_NAME,
1422 #ifdef CONFIG_OF
1423 .of_match_table = hwmsensor_of_match,
1424 #endif
1425 // .owner = THIS_MODULE,
1426 }
1427 };
1428
1429 /*----------------------------------------------------------------------------*/
1430
1431 #if defined(CONFIG_MTK_AUTO_DETECT_MAGNETOMETER)
1432
1433 int hwmsen_msensor_remove(struct platform_device *pdev)
1434 {
1435 int err =0;
1436 int i=0;
1437 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
1438 {
1439 if(0 == strcmp(msensor_name,msensor_init_list[i]->name))
1440 {
1441 if(NULL == msensor_init_list[i]->uninit)
1442 {
1443 HWM_LOG(" hwmsen_msensor_remove null pointer \n");
1444 return -1;
1445 }
1446 msensor_init_list[i]->uninit();
1447 }
1448 }
1449 return 0;
1450 }
1451
1452 static int msensor_probe(struct platform_device *pdev)
1453 {
1454 int i =0;
1455 int err=0;
1456 HWM_LOG(" msensor_probe +\n");
1457 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
1458 {
1459 if(NULL != msensor_init_list[i])
1460 {
1461 err = msensor_init_list[i]->init();
1462 if(0 == err)
1463 {
1464 strcpy(msensor_name,msensor_init_list[i]->name);
1465 HWM_LOG(" msensor %s probe ok\n", msensor_name);
1466 break;
1467 }
1468 }
1469 }
1470 return 0;
1471 }
1472
1473
1474 static struct platform_driver msensor_driver = {
1475 .probe = msensor_probe,
1476 .remove = hwmsen_msensor_remove,
1477 .driver =
1478 {
1479 .name = "msensor",
1480 // .owner = THIS_MODULE,
1481 }
1482 };
1483
1484 int hwmsen_msensor_add(struct sensor_init_info* obj)
1485 {
1486 int err=0;
1487 int i =0;
1488
1489 HWM_FUN(f);
1490
1491 for(i =0; i < MAX_CHOOSE_G_NUM; i++ )
1492 {
1493 if(NULL == msensor_init_list[i])
1494 {
1495 msensor_init_list[i] = kzalloc(sizeof(struct sensor_init_info), GFP_KERNEL);
1496 if(NULL == msensor_init_list[i])
1497 {
1498 HWM_ERR("kzalloc error");
1499 return -1;
1500 }
1501 obj->platform_diver_addr = &msensor_driver;
1502 msensor_init_list[i] = obj;
1503
1504 break;
1505 }
1506 }
1507
1508 return err;
1509 }
1510 EXPORT_SYMBOL_GPL(hwmsen_msensor_add);
1511
1512 #endif
1513
1514
1515
1516 #if defined(CONFIG_MTK_AUTO_DETECT_ACCELEROMETER)//
1517
1518 int hwmsen_gsensor_remove(struct platform_device *pdev)
1519 {
1520 int i=0;
1521 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
1522 {
1523 if(0 == strcmp(gsensor_name,gsensor_init_list[i]->name))
1524 {
1525 if(NULL == gsensor_init_list[i]->uninit)
1526 {
1527 HWM_LOG(" hwmsen_gsensor_remove null pointer +\n");
1528 return -1;
1529 }
1530 gsensor_init_list[i]->uninit();
1531 }
1532 }
1533 return 0;
1534 }
1535
1536 static int gsensor_probe(struct platform_device *pdev)
1537 {
1538 int i =0;
1539 int err=0;
1540 HWM_LOG(" gsensor_probe +\n");
1541
1542 //
1543 /*
1544 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
1545 {
1546 HWM_LOG(" gsensor_init_list[i]=%d\n",gsensor_init_list[i]);
1547 }
1548 */
1549 //
1550 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
1551 {
1552 HWM_LOG(" i=%d\n",i);
1553 if(0 != gsensor_init_list[i])
1554 {
1555 HWM_LOG(" !!!!!!!!\n");
1556 err = gsensor_init_list[i]->init();
1557 if(0 == err)
1558 {
1559 strcpy(gsensor_name,gsensor_init_list[i]->name);
1560 HWM_LOG(" gsensor %s probe ok\n", gsensor_name);
1561 break;
1562 }
1563 }
1564 }
1565
1566 if(i == MAX_CHOOSE_G_NUM)
1567 {
1568 HWM_LOG(" gsensor probe fail\n");
1569 }
1570 return 0;
1571 }
1572
1573
1574 static struct platform_driver gsensor_driver = {
1575 .probe = gsensor_probe,
1576 .remove = hwmsen_gsensor_remove,
1577 .driver =
1578 {
1579 .name = "gsensor",
1580 // .owner = THIS_MODULE,
1581 }
1582 };
1583
1584 int hwmsen_gsensor_add(struct sensor_init_info* obj)
1585 {
1586 int err=0;
1587 int i =0;
1588
1589 HWM_FUN(f);
1590
1591 for(i =0; i < MAX_CHOOSE_G_NUM; i++ )
1592 {
1593 if(NULL == gsensor_init_list[i])
1594 {
1595 gsensor_init_list[i] = kzalloc(sizeof(struct sensor_init_info), GFP_KERNEL);
1596 if(NULL == gsensor_init_list[i])
1597 {
1598 HWM_ERR("kzalloc error");
1599 return -1;
1600 }
1601 obj->platform_diver_addr = &gsensor_driver;
1602 gsensor_init_list[i] = obj;
1603
1604 break;
1605 }
1606 }
1607
1608 return err;
1609 }
1610 EXPORT_SYMBOL_GPL(hwmsen_gsensor_add);
1611
1612 #endif
1613
1614 #if defined(CONFIG_MTK_AUTO_DETECT_ALSPS)
1615
1616 int hwmsen_alsps_sensor_remove(struct platform_device *pdev)
1617 {
1618 int err =0;
1619 int i=0;
1620 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
1621 {
1622 if(0 == strcmp(alsps_name,alsps_init_list[i]->name))
1623 {
1624 if(NULL == alsps_init_list[i]->uninit)
1625 {
1626 HWM_LOG(" hwmsen_alsps_sensor_remove null pointer \n");
1627 return -1;
1628 }
1629 alsps_init_list[i]->uninit();
1630 }
1631 }
1632 return 0;
1633 }
1634
1635 static int alsps_sensor_probe(struct platform_device *pdev)
1636 {
1637 int i =0;
1638 int err=0;
1639 HWM_LOG(" als_ps sensor_probe +\n");
1640 for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
1641 {
1642 if(NULL != alsps_init_list[i])
1643 {
1644 err = alsps_init_list[i]->init();
1645 if(0 == err)
1646 {
1647 strcpy(alsps_name,alsps_init_list[i]->name);
1648 HWM_LOG(" alsps sensor %s probe ok\n", alsps_name);
1649 break;
1650 }
1651 }
1652 }
1653 return 0;
1654 }
1655
1656
1657 static struct platform_driver alsps_sensor_driver = {
1658 .probe = alsps_sensor_probe,
1659 .remove = hwmsen_alsps_sensor_remove,
1660 .driver =
1661 {
1662 .name = "als_ps",
1663 }
1664 };
1665
1666 int hwmsen_alsps_sensor_add(struct sensor_init_info* obj)
1667 {
1668 int err=0;
1669 int i =0;
1670
1671 HWM_FUN(f);
1672
1673 for(i =0; i < MAX_CHOOSE_G_NUM; i++ )
1674 {
1675 if(NULL == alsps_init_list[i])
1676 {
1677 alsps_init_list[i] = kzalloc(sizeof(struct sensor_init_info), GFP_KERNEL);
1678 if(NULL == alsps_init_list[i])
1679 {
1680 HWM_ERR("kzalloc error");
1681 return -1;
1682 }
1683 obj->platform_diver_addr = &alsps_sensor_driver;
1684 alsps_init_list[i] = obj;
1685
1686 break;
1687 }
1688 }
1689
1690 return err;
1691 }
1692 EXPORT_SYMBOL_GPL(hwmsen_alsps_sensor_add);
1693
1694 #endif
1695
1696 /*----------------------------------------------------------------------------*/
1697 static int __init hwmsen_init(void)
1698 {
1699 HWM_FUN(f);
1700 if(platform_driver_register(&hwmsen_driver))
1701 {
1702 HWM_ERR("failed to register sensor driver");
1703 return -ENODEV;
1704 }
1705
1706
1707 #if defined(CONFIG_MTK_AUTO_DETECT_ACCELEROMETER)
1708 if(platform_driver_register(&gsensor_driver))
1709 {
1710 HWM_ERR("failed to register gensor driver");
1711 return -ENODEV;
1712 }
1713 #endif
1714
1715 #if defined(CONFIG_MTK_AUTO_DETECT_MAGNETOMETER)
1716 if(platform_driver_register(&msensor_driver))
1717 {
1718 HWM_ERR("failed to register mensor driver");
1719 return -ENODEV;
1720 }
1721 #endif
1722
1723 #if defined(CONFIG_MTK_AUTO_DETECT_ALSPS)
1724 if(platform_driver_register(&alsps_sensor_driver))
1725 {
1726 HWM_ERR("failed to register alsps_sensor_driver driver");
1727 return -ENODEV;
1728 }
1729 #endif
1730
1731
1732 return 0;
1733 }
1734 /*----------------------------------------------------------------------------*/
1735 static void __exit hwmsen_exit(void)
1736 {
1737 platform_driver_unregister(&hwmsen_driver);
1738 }
1739 /*----------------------------------------------------------------------------*/
1740 module_init(hwmsen_init);
1741 module_exit(hwmsen_exit);
1742 MODULE_LICENSE("GPL");
1743 MODULE_DESCRIPTION("sensor device driver");
1744 MODULE_AUTHOR("Chunlei Wang<chunlei.wang@mediatek.com");