add sensor version info
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / sensor-dev.c
1 /* drivers/input/sensors/sensor-dev.c - handle all gsensor in this file\r
2  *\r
3  * Copyright (C) 2012-2015 ROCKCHIP.\r
4  * Author: luowei <lw@rock-chips.com>\r
5  *\r
6  * This software is licensed under the terms of the GNU General Public\r
7  * License version 2, as published by the Free Software Foundation, and\r
8  * may be copied, distributed, and modified under those terms.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  */\r
16 \r
17 #include <linux/interrupt.h>\r
18 #include <linux/i2c.h>\r
19 #include <linux/slab.h>\r
20 #include <linux/irq.h>\r
21 #include <linux/miscdevice.h>\r
22 #include <linux/gpio.h>\r
23 #include <asm/uaccess.h>\r
24 #include <asm/atomic.h>\r
25 #include <linux/delay.h>\r
26 #include <linux/input.h>\r
27 #include <linux/workqueue.h>\r
28 #include <linux/freezer.h>\r
29 #include <mach/gpio.h>\r
30 #include <mach/board.h> \r
31 #ifdef CONFIG_HAS_EARLYSUSPEND\r
32 #include <linux/earlysuspend.h>\r
33 #endif\r
34 #include <linux/akm8975.h>\r
35 #include <linux/l3g4200d.h>\r
36 #include <linux/sensor-dev.h>\r
37 \r
38 \r
39 #if 0\r
40 #define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL\r
41 #define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
42 #else\r
43 #define DBG(x...)\r
44 #endif\r
45 \r
46 #define SENSOR_VERSION_AND_TIME  "sensor-dev.c v1.0 2013-2-18"\r
47 \r
48 \r
49 struct sensor_private_data *g_sensor[SENSOR_NUM_TYPES];\r
50 static struct sensor_operate *sensor_ops[SENSOR_NUM_ID]; \r
51 static struct class *g_sensor_class[SENSOR_NUM_TYPES];\r
52 \r
53 \r
54 static int sensor_get_id(struct i2c_client *client, int *value)\r
55 {\r
56         struct sensor_private_data *sensor =\r
57             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
58         int result = 0;\r
59         char temp = sensor->ops->id_reg;\r
60         int i = 0;\r
61 \r
62         if(sensor->ops->id_reg >= 0)\r
63         {\r
64                 for(i=0; i<3; i++)\r
65                 {\r
66                         result = sensor_rx_data(client, &temp, 1);\r
67                         *value = temp;\r
68                         if(!result)\r
69                         break;\r
70                 }\r
71 \r
72                 if(result)\r
73                         return result;\r
74 \r
75                 if(*value != sensor->ops->id_data)\r
76                 {\r
77                         printk("%s:id=0x%x is not 0x%x\n",__func__,*value, sensor->ops->id_data);\r
78                         result = -1;\r
79                 }\r
80                         \r
81                 DBG("%s:devid=0x%x\n",__func__,*value);\r
82         }\r
83         \r
84         return result;\r
85 }\r
86 \r
87 static int sensor_initial(struct i2c_client *client)\r
88 {\r
89         struct sensor_private_data *sensor =\r
90             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
91         int result = 0;\r
92 \r
93         //register setting according to chip datasheet  \r
94         result = sensor->ops->init(client);\r
95         if(result < 0)\r
96         {\r
97                 printk("%s:fail to init sensor\n",__func__);\r
98                 return result;\r
99         }\r
100 \r
101 \r
102         DBG("%s:ctrl_data=0x%x\n",__func__,sensor->ops->ctrl_data);\r
103         \r
104         return result;\r
105 \r
106 }\r
107 \r
108 static int sensor_chip_init(struct i2c_client *client)\r
109 {\r
110         struct sensor_private_data *sensor =\r
111             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
112         struct sensor_operate *ops = sensor_ops[(int)sensor->i2c_id->driver_data];\r
113         int result = 0;\r
114         \r
115         if(ops)\r
116         {\r
117                 sensor->ops = ops;\r
118         }\r
119         else\r
120         {\r
121                 printk("%s:ops is null,sensor name is %s\n",__func__,sensor->i2c_id->name);\r
122                 result = -1;\r
123                 goto error;\r
124         }\r
125 \r
126         if((sensor->type != ops->type) || ((int)sensor->i2c_id->driver_data != ops->id_i2c))\r
127         {\r
128                 printk("%s:type or id is different:type=%d,%d,id=%d,%d\n",__func__,sensor->type, ops->type, (int)sensor->i2c_id->driver_data, ops->id_i2c);\r
129                 result = -1;\r
130                 goto error;\r
131         }\r
132         \r
133         if(!ops->init || !ops->active || !ops->report)\r
134         {\r
135                 printk("%s:error:some function is needed\n",__func__);          \r
136                 result = -1;\r
137                 goto error;\r
138         }\r
139 \r
140         result = sensor_get_id(sensor->client, &sensor->devid);//get id\r
141         if(result < 0)\r
142         {       \r
143                 printk("%s:fail to read %s devid:0x%x\n",__func__, sensor->i2c_id->name, sensor->devid);        \r
144                 goto error;\r
145         }\r
146         \r
147         printk("%s:%s:devid=0x%x,ops=0x%p\n",__func__, sensor->i2c_id->name, sensor->devid,sensor->ops);\r
148 \r
149         result = sensor_initial(sensor->client);        //init sensor\r
150         if(result < 0)\r
151         {       \r
152                 printk("%s:fail to init sensor\n",__func__);            \r
153                 goto error;\r
154         }\r
155 \r
156         return 0;\r
157 \r
158 error:\r
159         \r
160         return result;\r
161 }\r
162 \r
163 static int sensor_reset_rate(struct i2c_client *client, int rate)\r
164 {\r
165         struct sensor_private_data *sensor =\r
166             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
167         int result = 0; \r
168         \r
169         result = sensor->ops->active(client,SENSOR_OFF,rate);\r
170         sensor->ops->init(client);\r
171         result = sensor->ops->active(client,SENSOR_ON,rate);\r
172 \r
173         return result;\r
174 }\r
175 \r
176 static int sensor_get_data(struct i2c_client *client)\r
177 {\r
178         struct sensor_private_data *sensor =\r
179             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
180         int result = 0;\r
181         \r
182         result = sensor->ops->report(client);\r
183         if(result)\r
184                 goto error;\r
185 \r
186         /* set data_ready */\r
187         atomic_set(&sensor->data_ready, 1);\r
188         /*wake up data_ready  work queue*/\r
189         wake_up(&sensor->data_ready_wq);\r
190         \r
191 error:          \r
192         return result;\r
193 }\r
194 \r
195 #if 0\r
196 int sensor_get_cached_data(struct i2c_client* client, char *buffer, int length, struct sensor_axis *axis)\r
197 {\r
198     struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(client);      \r
199     wait_event_interruptible_timeout(sensor->data_ready_wq, \r
200                                      atomic_read(&(sensor->data_ready) ),\r
201                                      msecs_to_jiffies(1000) );\r
202     if ( 0 == atomic_read(&(sensor->data_ready) ) ) {\r
203         printk("waiting 'data_ready_wq' timed out.");\r
204         goto error;\r
205     }\r
206 \r
207         \r
208         mutex_lock(&sensor->data_mutex);\r
209 \r
210         switch(sensor->type)\r
211         {\r
212                 case SENSOR_TYPE_ACCEL:\r
213                 *axis = sensor->axis;\r
214                 break;\r
215 \r
216                 case SENSOR_TYPE_COMPASS:\r
217                 memcpy(buffer, sensor->sensor_data, length);\r
218                 break;\r
219         }\r
220         \r
221         mutex_unlock(&sensor->data_mutex);\r
222         \r
223     return 0;\r
224         \r
225 error:\r
226         return -1;\r
227 }\r
228 #endif\r
229 \r
230 static void  sensor_delaywork_func(struct work_struct *work)\r
231 {\r
232         struct delayed_work *delaywork = container_of(work, struct delayed_work, work);\r
233         struct sensor_private_data *sensor = container_of(delaywork, struct sensor_private_data, delaywork);\r
234         struct i2c_client *client = sensor->client;\r
235 \r
236         mutex_lock(&sensor->sensor_mutex);      \r
237         if (sensor_get_data(client) < 0) \r
238                 DBG(KERN_ERR "%s: Get data failed\n",__func__);\r
239         \r
240         if(!sensor->pdata->irq_enable)//restart work while polling\r
241         schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
242         //else\r
243         //{\r
244                 //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH))\r
245                 //enable_irq(sensor->client->irq);\r
246         //}\r
247         mutex_unlock(&sensor->sensor_mutex);\r
248         \r
249         DBG("%s:%s\n",__func__,sensor->i2c_id->name);\r
250 }\r
251 \r
252 /*\r
253  * This is a threaded IRQ handler so can access I2C/SPI.  Since all\r
254  * interrupts are clear on read the IRQ line will be reasserted and\r
255  * the physical IRQ will be handled again if another interrupt is\r
256  * asserted while we run - in the normal course of events this is a\r
257  * rare occurrence so we save I2C/SPI reads.  We're also assuming that\r
258  * it's rare to get lots of interrupts firing simultaneously so try to\r
259  * minimise I/O.\r
260  */\r
261 static irqreturn_t sensor_interrupt(int irq, void *dev_id)\r
262 {\r
263         struct sensor_private_data *sensor = (struct sensor_private_data *)dev_id;\r
264 \r
265         //use threaded IRQ\r
266         if (sensor_get_data(sensor->client) < 0) \r
267                 DBG(KERN_ERR "%s: Get data failed\n",__func__);\r
268         msleep(sensor->pdata->poll_delay_ms);\r
269 \r
270         \r
271         //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH))\r
272         //disable_irq_nosync(irq);\r
273         //schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
274         DBG("%s:irq=%d\n",__func__,irq);\r
275         return IRQ_HANDLED;\r
276 }\r
277 \r
278 \r
279 static int sensor_irq_init(struct i2c_client *client)\r
280 {\r
281         struct sensor_private_data *sensor =\r
282             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
283         int result = 0;\r
284         int irq;\r
285         if((sensor->pdata->irq_enable)&&(sensor->ops->trig != SENSOR_UNKNOW_DATA))\r
286         {\r
287                 //INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
288                 if(sensor->pdata->poll_delay_ms < 0)\r
289                         sensor->pdata->poll_delay_ms = 30;\r
290                 \r
291                 result = gpio_request(client->irq, sensor->i2c_id->name);\r
292                 if (result)\r
293                 {\r
294                         printk("%s:fail to request gpio :%d\n",__func__,client->irq);\r
295                 }\r
296         \r
297                 gpio_pull_updown(client->irq, PullEnable);\r
298                 irq = gpio_to_irq(client->irq);\r
299                 //result = request_irq(irq, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor);\r
300                 result = request_threaded_irq(irq, NULL, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor);\r
301                 if (result) {\r
302                         printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, irq, result);            \r
303                         goto error;            \r
304                 }\r
305                 client->irq = irq;\r
306                 if((sensor->pdata->type == SENSOR_TYPE_GYROSCOPE) || (sensor->pdata->type == SENSOR_TYPE_ACCEL))\r
307                 disable_irq_nosync(client->irq);//disable irq\r
308                 if(((sensor->pdata->type == SENSOR_TYPE_LIGHT) || (sensor->pdata->type == SENSOR_TYPE_PROXIMITY))&& (!(sensor->ops->trig & IRQF_SHARED)))       \r
309                 disable_irq_nosync(client->irq);//disable irq\r
310                 printk("%s:use irq=%d\n",__func__,irq);\r
311         }\r
312         else if(!sensor->pdata->irq_enable)\r
313         {               \r
314                 INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
315                 if(sensor->pdata->poll_delay_ms < 0)\r
316                         sensor->pdata->poll_delay_ms = 30;\r
317                 \r
318                 printk("%s:use polling,delay=%d ms\n",__func__,sensor->pdata->poll_delay_ms);\r
319         }\r
320 \r
321 error:  \r
322         return result;\r
323 }\r
324 \r
325 #ifdef CONFIG_HAS_EARLYSUSPEND\r
326 static void sensor_suspend(struct early_suspend *h)\r
327 {\r
328         struct sensor_private_data *sensor = \r
329                         container_of(h, struct sensor_private_data, early_suspend);\r
330         \r
331         if(sensor->ops->suspend)\r
332                 sensor->ops->suspend(sensor->client);\r
333 \r
334 }\r
335 \r
336 static void sensor_resume(struct early_suspend *h)\r
337 {\r
338         struct sensor_private_data *sensor = \r
339                         container_of(h, struct sensor_private_data, early_suspend);\r
340 \r
341         if(sensor->ops->resume)\r
342                 sensor->ops->resume(sensor->client);\r
343 }\r
344 #endif\r
345 \r
346 static int gsensor_dev_open(struct inode *inode, struct file *file)\r
347 {\r
348         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];     \r
349         //struct i2c_client *client = sensor->client;\r
350 \r
351         int result = 0;\r
352 \r
353 \r
354         return result;\r
355 }\r
356 \r
357 \r
358 static int gsensor_dev_release(struct inode *inode, struct file *file)\r
359 {\r
360         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];     \r
361         //struct i2c_client *client = sensor->client;\r
362 \r
363         int result = 0;\r
364 \r
365 \r
366         return result;\r
367 }\r
368 \r
369 /* ioctl - I/O control */\r
370 static long gsensor_dev_ioctl(struct file *file,\r
371                           unsigned int cmd, unsigned long arg)\r
372 {\r
373         struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];\r
374         struct i2c_client *client = sensor->client;\r
375         void __user *argp = (void __user *)arg;\r
376         struct sensor_axis axis = {0};\r
377         char rate;\r
378         int result = 0;\r
379 \r
380         switch (cmd) {\r
381         case GSENSOR_IOCTL_APP_SET_RATE:\r
382                 if (copy_from_user(&rate, argp, sizeof(rate)))\r
383                 {\r
384                         result = -EFAULT;\r
385                         goto error;\r
386                 }\r
387                 break;\r
388         default:\r
389                 break;\r
390         }\r
391 \r
392         switch (cmd) {\r
393         case GSENSOR_IOCTL_START:       \r
394                 DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur);\r
395                 mutex_lock(&sensor->operation_mutex);   \r
396                 if(++sensor->start_count == 1)\r
397                 {\r
398                         if(sensor->status_cur == SENSOR_OFF)\r
399                         {\r
400                                 atomic_set(&(sensor->data_ready), 0);\r
401                                 if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) {\r
402                                         mutex_unlock(&sensor->operation_mutex);\r
403                                         printk("%s:fail to active sensor,ret=%d\n",__func__,result);         \r
404                                         goto error;           \r
405                                 }                       \r
406                                 if(sensor->pdata->irq_enable)\r
407                                 {\r
408                                         DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
409                                         enable_irq(client->irq);        //enable irq\r
410                                 }       \r
411                                 else\r
412                                 {\r
413                                         PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
414                                         schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
415                                 }\r
416                                 sensor->status_cur = SENSOR_ON;\r
417                         }       \r
418                 }\r
419                 mutex_unlock(&sensor->operation_mutex);\r
420                 DBG("%s:GSENSOR_IOCTL_START OK\n", __func__);\r
421                 break;\r
422 \r
423         case GSENSOR_IOCTL_CLOSE:                               \r
424                 DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur);\r
425                 mutex_lock(&sensor->operation_mutex);           \r
426                 if(--sensor->start_count == 0)\r
427                 {\r
428                         if(sensor->status_cur == SENSOR_ON)\r
429                         {\r
430                                 atomic_set(&(sensor->data_ready), 0);\r
431                                 if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {\r
432                                         mutex_unlock(&sensor->operation_mutex);              \r
433                                         goto error;\r
434                                 }\r
435                                 \r
436                                 if(sensor->pdata->irq_enable)\r
437                                 {                               \r
438                                         DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
439                                         disable_irq_nosync(client->irq);//disable irq\r
440                                 }\r
441                                 else\r
442                                 cancel_delayed_work_sync(&sensor->delaywork);           \r
443                                 sensor->status_cur = SENSOR_OFF;\r
444                         }\r
445                         \r
446                         DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__);\r
447                 }\r
448                 \r
449                 mutex_unlock(&sensor->operation_mutex); \r
450                 break;\r
451 \r
452         case GSENSOR_IOCTL_APP_SET_RATE:                \r
453                 DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__);         \r
454                 mutex_lock(&sensor->operation_mutex);   \r
455                 result = sensor_reset_rate(client, rate);\r
456                 if (result < 0){\r
457                         mutex_unlock(&sensor->operation_mutex);\r
458                         goto error;\r
459                 }\r
460 \r
461                 sensor->status_cur = SENSOR_ON;\r
462                 mutex_unlock(&sensor->operation_mutex); \r
463                 DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__);\r
464                 break;\r
465                 \r
466         case GSENSOR_IOCTL_GETDATA:\r
467                 mutex_lock(&sensor->data_mutex);\r
468                 memcpy(&axis, &sensor->axis, sizeof(sensor->axis));     //get data from buffer\r
469                 mutex_unlock(&sensor->data_mutex);              \r
470                 break;\r
471         default:\r
472                 result = -ENOTTY;\r
473         goto error;\r
474         }\r
475 \r
476         switch (cmd) {\r
477         case GSENSOR_IOCTL_GETDATA:\r
478                 if ( copy_to_user(argp, &axis, sizeof(axis) ) ) {\r
479                     printk("failed to copy sense data to user space.");\r
480                                 result = -EFAULT;                       \r
481                                 goto error;\r
482                 }               \r
483                 DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__);\r
484                 break;\r
485         default:\r
486                 break;\r
487         }\r
488         \r
489 error:\r
490         return result;\r
491 }\r
492 \r
493 static ssize_t gsensor_set_orientation_online(struct class *class,\r
494                 struct class_attribute *attr, const char *buf, size_t count)\r
495 {\r
496         int i=0;\r
497         char orientation[20];\r
498         char *tmp;\r
499         \r
500         struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];\r
501         struct sensor_platform_data *pdata = sensor->pdata;\r
502 \r
503         \r
504         char *p = strstr(buf,"gsensor_class");\r
505         int start = strcspn(p,"{");\r
506         int end = strcspn(p,"}");\r
507         \r
508         strncpy(orientation,p+start,end-start+1);\r
509         tmp = orientation;\r
510         \r
511 \r
512         while(strncmp(tmp,"}",1)!=0)\r
513          {\r
514                 if((strncmp(tmp,",",1)==0)||(strncmp(tmp,"{",1)==0))\r
515                 {\r
516                         \r
517                          tmp++;         \r
518                          continue;\r
519                 }       \r
520                 else if(strncmp(tmp,"-",1)==0)\r
521                 {\r
522                         pdata->orientation[i++]=-1;\r
523                         DBG("i=%d,data=%d\n",i,pdata->orientation[i]);\r
524                          tmp++;\r
525                 }               \r
526                 else\r
527                 {\r
528                         pdata->orientation[i++]=tmp[0]-48;              \r
529                         DBG("----i=%d,data=%d\n",i,pdata->orientation[i]);      \r
530                 }       \r
531                 tmp++;\r
532         \r
533                                                 \r
534          }\r
535 \r
536         for(i=0;i<9;i++)\r
537                 DBG("i=%d gsensor_info=%d\n",i,pdata->orientation[i]);\r
538         return 0;\r
539 \r
540 }\r
541 \r
542 static CLASS_ATTR(orientation, 0660, NULL, gsensor_set_orientation_online);\r
543 \r
544 static int  gsensor_class_init(void)\r
545 {\r
546         int ret ;\r
547         struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];       \r
548         g_sensor_class[SENSOR_TYPE_ACCEL] = class_create(THIS_MODULE, "gsensor_class");\r
549         ret =  class_create_file(g_sensor_class[SENSOR_TYPE_ACCEL], &class_attr_orientation);\r
550         if (ret)\r
551         {\r
552                 printk("%s:Fail to creat class\n",__func__);\r
553                 return ret;\r
554         }\r
555         printk("%s:%s\n",__func__,sensor->i2c_id->name);\r
556         return 0;\r
557 }\r
558 \r
559 \r
560 \r
561 static int compass_dev_open(struct inode *inode, struct file *file)\r
562 {\r
563         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
564         //struct i2c_client *client = sensor->client;\r
565         int result = 0;\r
566         \r
567         //to do\r
568         return result;\r
569 }\r
570 \r
571 \r
572 static int compass_dev_release(struct inode *inode, struct file *file)\r
573 {\r
574         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
575         //struct i2c_client *client = sensor->client;   \r
576         int result = 0;\r
577 \r
578         //to do\r
579         return result;\r
580 }\r
581 \r
582 \r
583 /* ioctl - I/O control */\r
584 static long compass_dev_ioctl(struct file *file,\r
585                           unsigned int cmd, unsigned long arg)\r
586 {\r
587         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
588         //struct i2c_client *client = sensor->client;\r
589         //void __user *argp = (void __user *)arg;\r
590         int result = 0;\r
591         \r
592         //to do\r
593         return result;\r
594 }\r
595 \r
596 static int gyro_dev_open(struct inode *inode, struct file *file)\r
597 {\r
598         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];\r
599         //struct i2c_client *client = sensor->client;\r
600 \r
601         int result = 0;\r
602 \r
603 \r
604         return result;\r
605 }\r
606 \r
607 \r
608 static int gyro_dev_release(struct inode *inode, struct file *file)\r
609 {\r
610         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];\r
611         //struct i2c_client *client = sensor->client;\r
612 \r
613         int result = 0;\r
614 \r
615 \r
616         return result;\r
617 }\r
618 \r
619 \r
620 /* ioctl - I/O control */\r
621 static long gyro_dev_ioctl(struct file *file,\r
622                           unsigned int cmd, unsigned long arg)\r
623 {\r
624         struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];   \r
625         struct i2c_client *client = sensor->client;     \r
626         void __user *argp = (void __user *)arg;\r
627         int result = 0;\r
628         char rate;\r
629         switch (cmd) {\r
630         case L3G4200D_IOCTL_GET_ENABLE: \r
631                 result = !sensor->status_cur;\r
632                 if (copy_to_user(argp, &result, sizeof(result)))\r
633                 {\r
634                         printk("%s:failed to copy status to user space.\n",__FUNCTION__);\r
635                         return -EFAULT;\r
636                 }\r
637                 \r
638                 DBG("%s :L3G4200D_IOCTL_GET_ENABLE,status=%d\n",__FUNCTION__,result);   \r
639                 break;\r
640         case L3G4200D_IOCTL_SET_ENABLE:                 \r
641                 DBG("%s :L3G4200D_IOCTL_SET_ENABLE,flag=%d\n",__FUNCTION__,*(unsigned int *)argp);\r
642                 mutex_lock(&sensor->operation_mutex);   \r
643                 if(*(unsigned int *)argp)\r
644                 {\r
645                         if(sensor->status_cur == SENSOR_OFF)\r
646                         {\r
647                                 if ( (result = sensor->ops->active(client, 1, ODR100_BW12_5) ) < 0 ) {\r
648                                 mutex_unlock(&sensor->operation_mutex);\r
649                                 printk("%s:fail to active sensor,ret=%d\n",__func__,result);         \r
650                                 goto error;           \r
651                                 }                       \r
652                                 if(sensor->pdata->irq_enable)\r
653                                 {\r
654                                         DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
655                                         enable_irq(client->irq);        //enable irq\r
656                                 }       \r
657                                 else\r
658                                 {\r
659                                         PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
660                                         schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
661                                 }\r
662                                 sensor->status_cur = SENSOR_ON;\r
663                         }       \r
664                 }\r
665                 else\r
666                 {\r
667                         if(sensor->status_cur == SENSOR_ON)\r
668                         {\r
669                                 if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {\r
670                                 mutex_unlock(&sensor->operation_mutex);              \r
671                                 goto error;\r
672                                 }\r
673                                 \r
674                                 if(sensor->pdata->irq_enable)\r
675                                 {                               \r
676                                         DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
677                                         disable_irq_nosync(client->irq);//disable irq\r
678                                 }\r
679                                 else\r
680                                 cancel_delayed_work_sync(&sensor->delaywork);           \r
681                                 sensor->status_cur = SENSOR_OFF;\r
682                         }\r
683                 }\r
684         \r
685                 result = sensor->status_cur;\r
686                 if (copy_to_user(argp, &result, sizeof(result)))\r
687                 {\r
688                         printk("%s:failed to copy sense data to user space.\n",__FUNCTION__);\r
689                         return -EFAULT;\r
690                 }\r
691 \r
692                 mutex_unlock(&sensor->operation_mutex);\r
693                 DBG("%s:L3G4200D_IOCTL_SET_ENABLE OK\n", __func__);\r
694                 break;\r
695         case L3G4200D_IOCTL_SET_DELAY:                                  \r
696                 mutex_lock(&sensor->operation_mutex);\r
697                 if (copy_from_user(&rate, argp, sizeof(rate)))\r
698                 return -EFAULT;\r
699                 if(sensor->status_cur == SENSOR_OFF)\r
700                 {\r
701                         if ( (result = sensor->ops->active(client, 1, rate) ) < 0 ) {\r
702                         mutex_unlock(&sensor->operation_mutex);\r
703                         printk("%s:fail to active sensor,ret=%d\n",__func__,result);         \r
704                         goto error;           \r
705                         }\r
706                         \r
707                         if(sensor->pdata->irq_enable)\r
708                         {\r
709                                 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
710                                 enable_irq(client->irq);        //enable irq\r
711                         }       \r
712                         else\r
713                         {\r
714                                 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
715                                 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
716                         }\r
717                         sensor->status_cur = SENSOR_ON;\r
718                 }       \r
719                 \r
720                 mutex_unlock(&sensor->operation_mutex);\r
721                 DBG("%s :L3G4200D_IOCTL_SET_DELAY,rate=%d\n",__FUNCTION__,rate);\r
722                 break;\r
723 \r
724         default:\r
725                 printk("%s:error,cmd=0x%x\n",__func__,cmd);\r
726                 return -ENOTTY;\r
727         }\r
728         \r
729         DBG("%s:line=%d,cmd=0x%x\n",__func__,__LINE__,cmd);\r
730 \r
731 error:\r
732         return result;\r
733 }\r
734 \r
735 static int light_dev_open(struct inode *inode, struct file *file)\r
736 {\r
737         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];\r
738         //struct i2c_client *client = sensor->client;   \r
739         int result = 0; \r
740 \r
741 \r
742         return result;\r
743 }\r
744 \r
745 \r
746 \r
747 \r
748 static int light_dev_release(struct inode *inode, struct file *file)\r
749 {\r
750         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];\r
751         //struct i2c_client *client = sensor->client;   \r
752         int result = 0;\r
753 \r
754 \r
755         return result;\r
756 }\r
757 \r
758 \r
759 /* ioctl - I/O control */\r
760 static long light_dev_ioctl(struct file *file,\r
761                           unsigned int cmd, unsigned long arg)\r
762 {\r
763         struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];\r
764         struct i2c_client *client = sensor->client;\r
765         unsigned int *argp = (unsigned int *)arg;       \r
766         int result = 0;\r
767 \r
768         switch(cmd)\r
769         {\r
770                 case LIGHTSENSOR_IOCTL_GET_ENABLED:\r
771                         *argp = sensor->status_cur;\r
772                         break;\r
773                 case LIGHTSENSOR_IOCTL_ENABLE:          \r
774                         DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);\r
775                         mutex_lock(&sensor->operation_mutex);    \r
776                         if(*(unsigned int *)argp)\r
777                         {\r
778                                 if(sensor->status_cur == SENSOR_OFF)\r
779                                 {\r
780                                         if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {\r
781                                         mutex_unlock(&sensor->operation_mutex);\r
782                                         printk("%s:fail to active sensor,ret=%d\n",__func__,result);         \r
783                                         goto error;           \r
784                                         }       \r
785                                         if(sensor->pdata->irq_enable)\r
786                                         {\r
787                                                 if(!(sensor->ops->trig & IRQF_SHARED))\r
788                                                 {\r
789                                                         DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
790                                                         enable_irq(client->irq);        //enable irq\r
791                                                 }\r
792                                         }       \r
793                                         else\r
794                                         {\r
795                                                 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
796                                                 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
797                                         }\r
798                                         \r
799                                         sensor->status_cur = SENSOR_ON;\r
800                                 }       \r
801                         }\r
802                         else\r
803                         {\r
804                                 if(sensor->status_cur == SENSOR_ON)\r
805                                 {\r
806                                         if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {\r
807                                         mutex_unlock(&sensor->operation_mutex);              \r
808                                         goto error;\r
809                                         }\r
810                                         \r
811                                         if(sensor->pdata->irq_enable)\r
812                                         {                               \r
813                                                 if(!(sensor->ops->trig & IRQF_SHARED))\r
814                                                 {\r
815                                                         DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
816                                                         disable_irq_nosync(client->irq);//disable irq\r
817                                                 }\r
818                                         }\r
819                                         else\r
820                                         cancel_delayed_work_sync(&sensor->delaywork);   \r
821                                         \r
822                                         sensor->status_cur = SENSOR_OFF;\r
823                                 }\r
824                         }\r
825                         mutex_unlock(&sensor->operation_mutex);\r
826                         DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__);\r
827                         break;\r
828                 \r
829                 default:\r
830                         break;\r
831         }\r
832         \r
833 error:\r
834         return result;\r
835 }\r
836 \r
837 \r
838 static int proximity_dev_open(struct inode *inode, struct file *file)\r
839 {\r
840         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];\r
841         //struct i2c_client *client = sensor->client;   \r
842         int result = 0;\r
843 \r
844 \r
845         return result;\r
846 }\r
847 \r
848 \r
849 static int proximity_dev_release(struct inode *inode, struct file *file)\r
850 {\r
851         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];\r
852         //struct i2c_client *client = sensor->client;   \r
853         int result = 0;\r
854 \r
855 \r
856         return result;\r
857 }\r
858 \r
859 \r
860 /* ioctl - I/O control */\r
861 static long proximity_dev_ioctl(struct file *file,\r
862                           unsigned int cmd, unsigned long arg)\r
863 {\r
864         struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];\r
865         struct i2c_client *client = sensor->client;     \r
866         unsigned int *argp = (unsigned int *)arg;       \r
867         int result = 0;\r
868         switch(cmd)\r
869         {\r
870                 case PSENSOR_IOCTL_GET_ENABLED:\r
871                         *argp = sensor->status_cur;\r
872                         break;\r
873                 case PSENSOR_IOCTL_ENABLE:              \r
874                         DBG("%s:PSENSOR_IOCTL_ENABLE start\n", __func__);\r
875                         mutex_lock(&sensor->operation_mutex);    \r
876                         if(*(unsigned int *)argp)\r
877                         {\r
878                                 if(sensor->status_cur == SENSOR_OFF)\r
879                                 {\r
880                                         if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {\r
881                                         mutex_unlock(&sensor->operation_mutex);\r
882                                         printk("%s:fail to active sensor,ret=%d\n",__func__,result);         \r
883                                         goto error;           \r
884                                         }\r
885                                         \r
886                                         if(sensor->pdata->irq_enable)\r
887                                         {\r
888                                                 if(!(sensor->ops->trig & IRQF_SHARED))\r
889                                                 {\r
890                                                         DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
891                                                         enable_irq(client->irq);        //enable irq\r
892                                                 }\r
893                                         }       \r
894                                         else\r
895                                         {\r
896                                                 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
897                                                 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
898                                         }\r
899                                         \r
900                                         sensor->status_cur = SENSOR_ON;\r
901                                 }       \r
902                         }\r
903                         else\r
904                         {\r
905                                 if(sensor->status_cur == SENSOR_ON)\r
906                                 {\r
907                                         if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {\r
908                                         mutex_unlock(&sensor->operation_mutex);              \r
909                                         goto error;\r
910                                         }\r
911                                         if(sensor->pdata->irq_enable)\r
912                                         {                               \r
913                                                 if(!(sensor->ops->trig & IRQF_SHARED))\r
914                                                 {\r
915                                                         DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
916                                                         disable_irq_nosync(client->irq);//disable irq\r
917                                                 }\r
918                                         }\r
919                                         else\r
920                                         cancel_delayed_work_sync(&sensor->delaywork);           \r
921                                         sensor->status_cur = SENSOR_OFF;\r
922                                 }\r
923                         }\r
924                         mutex_unlock(&sensor->operation_mutex);\r
925                         DBG("%s:PSENSOR_IOCTL_ENABLE OK\n", __func__);\r
926                         break;\r
927                 \r
928                 default:\r
929                         break;\r
930         }\r
931         \r
932 error:\r
933         return result;\r
934 }\r
935 \r
936 static int temperature_dev_open(struct inode *inode, struct file *file)\r
937 {\r
938         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];\r
939         //struct i2c_client *client = sensor->client;\r
940 \r
941         int result = 0;\r
942 \r
943 \r
944         return result;\r
945 }\r
946 \r
947 \r
948 static int temperature_dev_release(struct inode *inode, struct file *file)\r
949 {\r
950         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];\r
951         //struct i2c_client *client = sensor->client;\r
952 \r
953         int result = 0;\r
954 \r
955 \r
956         return result;\r
957 }\r
958 \r
959 \r
960 /* ioctl - I/O control */\r
961 static long temperature_dev_ioctl(struct file *file,\r
962                           unsigned int cmd, unsigned long arg)\r
963 {\r
964         //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];\r
965         //struct i2c_client *client = sensor->client;\r
966         //void __user *argp = (void __user *)arg;\r
967         int result = 0;\r
968         \r
969 \r
970         return result;\r
971 }\r
972 \r
973 \r
974 static int sensor_misc_device_register(struct sensor_private_data *sensor, int type)\r
975 {\r
976         int result = 0;\r
977         \r
978         switch(type)\r
979         {\r
980                 case SENSOR_TYPE_ACCEL:\r
981                         if(!sensor->ops->misc_dev)\r
982                         {\r
983                                 sensor->fops.owner = THIS_MODULE;\r
984                                 sensor->fops.unlocked_ioctl = gsensor_dev_ioctl;\r
985                                 sensor->fops.open = gsensor_dev_open;\r
986                                 sensor->fops.release = gsensor_dev_release;\r
987 \r
988                                 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
989                                 sensor->miscdev.name = "mma8452_daemon";\r
990                                 sensor->miscdev.fops = &sensor->fops;\r
991                         }\r
992                         else\r
993                         {\r
994                                 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
995 \r
996                         }\r
997                                 \r
998                         break;\r
999 \r
1000                 case SENSOR_TYPE_COMPASS:                       \r
1001                         if(!sensor->ops->misc_dev)\r
1002                         {\r
1003                                 sensor->fops.owner = THIS_MODULE;\r
1004                                 sensor->fops.unlocked_ioctl = compass_dev_ioctl;\r
1005                                 sensor->fops.open = compass_dev_open;\r
1006                                 sensor->fops.release = compass_dev_release;\r
1007 \r
1008                                 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
1009                                 sensor->miscdev.name = "compass";\r
1010                                 sensor->miscdev.fops = &sensor->fops;\r
1011                         }\r
1012                         else\r
1013                         {\r
1014                                 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
1015 \r
1016                         }\r
1017 \r
1018                         break;\r
1019 \r
1020                 case SENSOR_TYPE_GYROSCOPE:                     \r
1021                         if(!sensor->ops->misc_dev)\r
1022                         {\r
1023                                 sensor->fops.owner = THIS_MODULE;\r
1024                                 sensor->fops.unlocked_ioctl = gyro_dev_ioctl;\r
1025                                 sensor->fops.open = gyro_dev_open;\r
1026                                 sensor->fops.release = gyro_dev_release;\r
1027 \r
1028                                 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
1029                                 sensor->miscdev.name = "gyrosensor";\r
1030                                 sensor->miscdev.fops = &sensor->fops;\r
1031                         }\r
1032                         else\r
1033                         {\r
1034                                 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
1035 \r
1036                         }\r
1037                         \r
1038                         break;\r
1039 \r
1040                 case SENSOR_TYPE_LIGHT:\r
1041                         if(!sensor->ops->misc_dev)\r
1042                         {\r
1043                                 sensor->fops.owner = THIS_MODULE;\r
1044                                 sensor->fops.unlocked_ioctl = light_dev_ioctl;\r
1045                                 sensor->fops.open = light_dev_open;\r
1046                                 sensor->fops.release = light_dev_release;\r
1047 \r
1048                                 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
1049                                 sensor->miscdev.name = "lightsensor";\r
1050                                 sensor->miscdev.fops = &sensor->fops;\r
1051                         }       \r
1052                         else\r
1053                         {\r
1054                                 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
1055 \r
1056                         }\r
1057                         break;\r
1058                 \r
1059                 case SENSOR_TYPE_PROXIMITY:\r
1060                         if(!sensor->ops->misc_dev)\r
1061                         {\r
1062                                 sensor->fops.owner = THIS_MODULE;\r
1063                                 sensor->fops.unlocked_ioctl = proximity_dev_ioctl;\r
1064                                 sensor->fops.open = proximity_dev_open;\r
1065                                 sensor->fops.release = proximity_dev_release;\r
1066 \r
1067                                 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
1068                                 sensor->miscdev.name = "psensor";\r
1069                                 sensor->miscdev.fops = &sensor->fops;\r
1070                         }       \r
1071                         else\r
1072                         {\r
1073                                 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
1074 \r
1075                         }\r
1076                         break;\r
1077 \r
1078                 case SENSOR_TYPE_TEMPERATURE:\r
1079                         if(!sensor->ops->misc_dev)\r
1080                         {\r
1081                                 sensor->fops.owner = THIS_MODULE;\r
1082                                 sensor->fops.unlocked_ioctl = temperature_dev_ioctl;\r
1083                                 sensor->fops.open = temperature_dev_open;\r
1084                                 sensor->fops.release = temperature_dev_release;\r
1085 \r
1086                                 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;\r
1087                                 sensor->miscdev.name = "temperature";\r
1088                                 sensor->miscdev.fops = &sensor->fops;\r
1089                         }       \r
1090                         else\r
1091                         {\r
1092                                 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));\r
1093 \r
1094                         }\r
1095                                 \r
1096                         break;\r
1097 \r
1098                 default:\r
1099                         printk("%s:unknow sensor type=%d\n",__func__,type);\r
1100                         result = -1;\r
1101                         goto error;\r
1102         }\r
1103                         \r
1104         sensor->miscdev.parent = &sensor->client->dev;\r
1105         result = misc_register(&sensor->miscdev);\r
1106         if (result < 0) {\r
1107                 dev_err(&sensor->client->dev,\r
1108                         "fail to register misc device %s\n", sensor->miscdev.name);\r
1109                 goto error;\r
1110         }\r
1111         \r
1112         printk("%s:miscdevice: %s\n",__func__,sensor->miscdev.name);\r
1113 \r
1114 error:  \r
1115         \r
1116         return result;\r
1117 \r
1118 }\r
1119 \r
1120 int sensor_register_slave(int type,struct i2c_client *client,\r
1121                         struct sensor_platform_data *slave_pdata,\r
1122                         struct sensor_operate *(*get_sensor_ops)(void))\r
1123 {\r
1124         int result = 0;\r
1125         struct sensor_operate *ops = get_sensor_ops();\r
1126         if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))\r
1127         {       \r
1128                 printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);\r
1129                 return -1;      \r
1130         }\r
1131         sensor_ops[ops->id_i2c] = ops;\r
1132         printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);\r
1133         return result;\r
1134 }\r
1135 \r
1136 \r
1137 int sensor_unregister_slave(int type,struct i2c_client *client,\r
1138                         struct sensor_platform_data *slave_pdata,\r
1139                         struct sensor_operate *(*get_sensor_ops)(void))\r
1140 {\r
1141         int result = 0;\r
1142         struct sensor_operate *ops = get_sensor_ops();\r
1143         if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))\r
1144         {       \r
1145                 printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);\r
1146                 return -1;      \r
1147         }\r
1148         printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);\r
1149         sensor_ops[ops->id_i2c] = NULL; \r
1150         return result;\r
1151 }\r
1152 \r
1153 \r
1154 int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)\r
1155 {\r
1156         struct sensor_private_data *sensor =\r
1157             (struct sensor_private_data *) i2c_get_clientdata(client);\r
1158         struct sensor_platform_data *pdata;\r
1159         int result = 0;\r
1160         int type = 0;\r
1161         dev_info(&client->adapter->dev, "%s: %s,0x%x\n", __func__, devid->name,(unsigned int)client);\r
1162 \r
1163         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {\r
1164                 result = -ENODEV;\r
1165                 goto out_no_free;\r
1166         }\r
1167 \r
1168         pdata = client->dev.platform_data;\r
1169         if (!pdata) {\r
1170                 dev_err(&client->adapter->dev,\r
1171                         "Missing platform data for slave %s\n", devid->name);\r
1172                 result = -EFAULT;\r
1173                 goto out_no_free;\r
1174         }\r
1175 \r
1176         sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);\r
1177         if (!sensor) {\r
1178                 result = -ENOMEM;\r
1179                 goto out_no_free;\r
1180         }\r
1181 \r
1182         type= pdata->type;      \r
1183         \r
1184         if((type >= SENSOR_NUM_TYPES) || (type <= SENSOR_TYPE_NULL))\r
1185         {       \r
1186                 dev_err(&client->adapter->dev, "sensor type is error %d\n", pdata->type);\r
1187                 result = -EFAULT;\r
1188                 goto out_no_free;       \r
1189         }\r
1190 \r
1191         if(((int)devid->driver_data >= SENSOR_NUM_ID) || ((int)devid->driver_data <= ID_INVALID))\r
1192         {       \r
1193                 dev_err(&client->adapter->dev, "sensor id is error %d\n", (int)devid->driver_data);\r
1194                 result = -EFAULT;\r
1195                 goto out_no_free;       \r
1196         }\r
1197         \r
1198         i2c_set_clientdata(client, sensor);\r
1199         sensor->client = client;        \r
1200         sensor->pdata = pdata;  \r
1201         sensor->type = type;\r
1202         sensor->i2c_id = (struct i2c_device_id *)devid;\r
1203 \r
1204         if (pdata->init_platform_hw) {\r
1205                 result = pdata->init_platform_hw();\r
1206                 if (result < 0)\r
1207                         goto out_free_memory;\r
1208         }\r
1209 \r
1210         memset(&(sensor->axis), 0, sizeof(struct sensor_axis) );\r
1211         atomic_set(&(sensor->data_ready), 0);\r
1212         init_waitqueue_head(&(sensor->data_ready_wq));\r
1213         mutex_init(&sensor->data_mutex);        \r
1214         mutex_init(&sensor->operation_mutex);   \r
1215         mutex_init(&sensor->sensor_mutex);\r
1216         mutex_init(&sensor->i2c_mutex);\r
1217 \r
1218         sensor->status_cur = SENSOR_OFF;\r
1219         sensor->axis.x = 0;\r
1220         sensor->axis.y = 0;\r
1221         sensor->axis.z = 0;\r
1222         \r
1223         result = sensor_chip_init(sensor->client);\r
1224         if(result < 0)\r
1225                 goto out_free_memory;\r
1226         \r
1227         sensor->input_dev = input_allocate_device();\r
1228         if (!sensor->input_dev) {\r
1229                 result = -ENOMEM;\r
1230                 dev_err(&client->dev,\r
1231                         "Failed to allocate input device %s\n", sensor->input_dev->name);\r
1232                 goto out_free_memory;\r
1233         }       \r
1234 \r
1235         switch(type)\r
1236         {\r
1237                 case SENSOR_TYPE_ACCEL: \r
1238                         sensor->input_dev->name = "gsensor";\r
1239                         set_bit(EV_ABS, sensor->input_dev->evbit);\r
1240                         /* x-axis acceleration */\r
1241                         input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
1242                         /* y-axis acceleration */\r
1243                         input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
1244                         /* z-axis acceleration */\r
1245                         input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range\r
1246                         break;          \r
1247                 case SENSOR_TYPE_COMPASS:       \r
1248                         sensor->input_dev->name = "compass";            \r
1249                         /* Setup input device */\r
1250                         set_bit(EV_ABS, sensor->input_dev->evbit);\r
1251                         /* yaw (0, 360) */\r
1252                         input_set_abs_params(sensor->input_dev, ABS_RX, 0, 23040, 0, 0);\r
1253                         /* pitch (-180, 180) */\r
1254                         input_set_abs_params(sensor->input_dev, ABS_RY, -11520, 11520, 0, 0);\r
1255                         /* roll (-90, 90) */\r
1256                         input_set_abs_params(sensor->input_dev, ABS_RZ, -5760, 5760, 0, 0);\r
1257                         /* x-axis acceleration (720 x 8G) */\r
1258                         input_set_abs_params(sensor->input_dev, ABS_X, -5760, 5760, 0, 0);\r
1259                         /* y-axis acceleration (720 x 8G) */\r
1260                         input_set_abs_params(sensor->input_dev, ABS_Y, -5760, 5760, 0, 0);\r
1261                         /* z-axis acceleration (720 x 8G) */\r
1262                         input_set_abs_params(sensor->input_dev, ABS_Z, -5760, 5760, 0, 0);\r
1263                         /* status of magnetic sensor */\r
1264                         input_set_abs_params(sensor->input_dev, ABS_RUDDER, -32768, 3, 0, 0);\r
1265                         /* status of acceleration sensor */\r
1266                         input_set_abs_params(sensor->input_dev, ABS_WHEEL, -32768, 3, 0, 0);\r
1267                         /* x-axis of raw magnetic vector (-4096, 4095) */\r
1268                         input_set_abs_params(sensor->input_dev, ABS_HAT0X, -20480, 20479, 0, 0);\r
1269                         /* y-axis of raw magnetic vector (-4096, 4095) */\r
1270                         input_set_abs_params(sensor->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0);\r
1271                         /* z-axis of raw magnetic vector (-4096, 4095) */\r
1272                         input_set_abs_params(sensor->input_dev, ABS_BRAKE, -20480, 20479, 0, 0);\r
1273                         break;          \r
1274                 case SENSOR_TYPE_GYROSCOPE:\r
1275                         sensor->input_dev->name = "gyro";\r
1276                         /* x-axis acceleration */\r
1277                         input_set_capability(sensor->input_dev, EV_REL, REL_RX);\r
1278                         input_set_abs_params(sensor->input_dev, ABS_RX, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
1279                         /* y-axis acceleration */       \r
1280                         input_set_capability(sensor->input_dev, EV_REL, REL_RY);\r
1281                         input_set_abs_params(sensor->input_dev, ABS_RY, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
1282                         /* z-axis acceleration */\r
1283                         input_set_capability(sensor->input_dev, EV_REL, REL_RZ);\r
1284                         input_set_abs_params(sensor->input_dev, ABS_RZ, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
1285                         break;\r
1286                 case SENSOR_TYPE_LIGHT:\r
1287                         sensor->input_dev->name = "lightsensor-level";\r
1288                         set_bit(EV_ABS, sensor->input_dev->evbit);\r
1289                         input_set_abs_params(sensor->input_dev, ABS_MISC, sensor->ops->range[0], sensor->ops->range[1], 0, 0);                  \r
1290                         input_set_abs_params(sensor->input_dev, ABS_TOOL_WIDTH ,  sensor->ops->brightness[0],sensor->ops->brightness[1], 0, 0);\r
1291                         break;\r
1292                 case SENSOR_TYPE_PROXIMITY:\r
1293                         sensor->input_dev->name = "proximity";  \r
1294                         set_bit(EV_ABS, sensor->input_dev->evbit);\r
1295                         input_set_abs_params(sensor->input_dev, ABS_DISTANCE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);\r
1296                         break;\r
1297                 case SENSOR_TYPE_TEMPERATURE:                           \r
1298                         sensor->input_dev->name = "temperature";\r
1299                         set_bit(EV_ABS, sensor->input_dev->evbit);              \r
1300                         input_set_abs_params(sensor->input_dev, ABS_THROTTLE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);\r
1301                         break;\r
1302                 default:\r
1303                         printk("%s:unknow sensor type=%d\n",__func__,type);\r
1304                         break;\r
1305 \r
1306         }\r
1307         sensor->input_dev->dev.parent = &client->dev;\r
1308 \r
1309         result = input_register_device(sensor->input_dev);\r
1310         if (result) {\r
1311                 dev_err(&client->dev,\r
1312                         "Unable to register input device %s\n", sensor->input_dev->name);\r
1313                 goto out_input_register_device_failed;\r
1314         }\r
1315 \r
1316         result = sensor_irq_init(sensor->client);\r
1317         if (result) {\r
1318                 dev_err(&client->dev,\r
1319                         "fail to init sensor irq,ret=%d\n",result);\r
1320                 goto out_input_register_device_failed;\r
1321         }\r
1322 \r
1323         \r
1324         sensor->miscdev.parent = &client->dev;\r
1325         result = sensor_misc_device_register(sensor, type);\r
1326         if (result) {\r
1327                 dev_err(&client->dev,\r
1328                         "fail to register misc device %s\n", sensor->miscdev.name);\r
1329                 goto out_misc_device_register_device_failed;\r
1330         }\r
1331         \r
1332         g_sensor[type] = sensor;\r
1333 \r
1334         if((type == SENSOR_TYPE_ACCEL) && (sensor->pdata->factory))     //only support  setting gsensor orientation online now  \r
1335         {\r
1336                 result = gsensor_class_init();\r
1337                 if (result) {\r
1338                         dev_err(&client->dev,\r
1339                                 "fail to register misc device %s\n", sensor->i2c_id->name);\r
1340                         goto out_misc_device_register_device_failed;\r
1341                 }\r
1342         }\r
1343         \r
1344 #ifdef CONFIG_HAS_EARLYSUSPEND\r
1345         if((sensor->ops->suspend) && (sensor->ops->resume))\r
1346         {\r
1347                 sensor->early_suspend.suspend = sensor_suspend;\r
1348                 sensor->early_suspend.resume = sensor_resume;\r
1349                 sensor->early_suspend.level = 0x02;\r
1350                 register_early_suspend(&sensor->early_suspend);\r
1351         }\r
1352 #endif\r
1353 \r
1354         printk("%s:initialized ok,sensor name:%s,type:%d,id=%d\n\n",__func__,sensor->ops->name,type,(int)sensor->i2c_id->driver_data);\r
1355 \r
1356         return result;\r
1357         \r
1358 out_misc_device_register_device_failed:\r
1359         input_unregister_device(sensor->input_dev);     \r
1360 out_input_register_device_failed:\r
1361         input_free_device(sensor->input_dev);   \r
1362 out_free_memory:\r
1363         kfree(sensor);\r
1364 out_no_free:\r
1365         dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result);\r
1366         return result;\r
1367 \r
1368 }\r
1369 \r
1370 static void sensor_shut_down(struct i2c_client *client)\r
1371 {\r
1372 #ifdef CONFIG_HAS_EARLYSUSPEND\r
1373         struct sensor_private_data *sensor =\r
1374             (struct sensor_private_data *) i2c_get_clientdata(client);\r
1375         if((sensor->ops->suspend) && (sensor->ops->resume))             \r
1376                 unregister_early_suspend(&sensor->early_suspend);\r
1377         DBG("%s:%s\n",__func__,sensor->i2c_id->name);\r
1378 #endif\r
1379 }\r
1380 \r
1381 static int sensor_remove(struct i2c_client *client)\r
1382 {\r
1383         struct sensor_private_data *sensor =\r
1384             (struct sensor_private_data *) i2c_get_clientdata(client);\r
1385         int result = 0;\r
1386         \r
1387         cancel_delayed_work_sync(&sensor->delaywork);\r
1388         misc_deregister(&sensor->miscdev);\r
1389         input_unregister_device(sensor->input_dev);     \r
1390         input_free_device(sensor->input_dev);   \r
1391         kfree(sensor);\r
1392 #ifdef CONFIG_HAS_EARLYSUSPEND\r
1393         if((sensor->ops->suspend) && (sensor->ops->resume))\r
1394                 unregister_early_suspend(&sensor->early_suspend);\r
1395 #endif  \r
1396         return result;\r
1397 }\r
1398 \r
1399 static const struct i2c_device_id sensor_id[] = {\r
1400         /*gsensor*/\r
1401         {"gsensor", ACCEL_ID_ALL},\r
1402         {"gs_mma8452", ACCEL_ID_MMA845X},       \r
1403         {"gs_kxtik", ACCEL_ID_KXTIK},\r
1404         {"gs_lis3dh", ACCEL_ID_LIS3DH},\r
1405         {"gs_mma7660", ACCEL_ID_MMA7660},\r
1406         {"gs_mxc6225", ACCEL_ID_MXC6225},\r
1407         /*compass*/\r
1408         {"compass", COMPASS_ID_ALL},\r
1409         {"ak8975", COMPASS_ID_AK8975},\r
1410         {"mmc314x", COMPASS_ID_MMC314X},\r
1411         /*gyroscope*/\r
1412         {"gyro", GYRO_ID_ALL},  \r
1413         {"l3g4200d_gryo", GYRO_ID_L3G4200D},\r
1414         {"k3g", GYRO_ID_K3G},\r
1415         /*light sensor*/\r
1416         {"lightsensor", LIGHT_ID_ALL},  \r
1417         {"light_cm3217", LIGHT_ID_CM3217},\r
1418         {"light_al3006", LIGHT_ID_AL3006},\r
1419         {"ls_stk3171", LIGHT_ID_STK3171},\r
1420         {"ls_isl29023", LIGHT_ID_ISL29023},\r
1421         {"ls_ap321xx", LIGHT_ID_AP321XX},\r
1422         {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR},\r
1423         /*proximity sensor*/\r
1424         {"psensor", PROXIMITY_ID_ALL},\r
1425         {"proximity_al3006", PROXIMITY_ID_AL3006},      \r
1426         {"ps_stk3171", PROXIMITY_ID_STK3171},\r
1427         {"ps_ap321xx", PROXIMITY_ID_AP321XX},\r
1428         /*temperature*/\r
1429         {"temperature", TEMPERATURE_ID_ALL},\r
1430         {},\r
1431 };\r
1432 \r
1433 \r
1434 static struct i2c_driver sensor_driver = {\r
1435         .probe = sensor_probe,\r
1436         .remove = sensor_remove,\r
1437         .shutdown = sensor_shut_down,\r
1438         .id_table = sensor_id,\r
1439         .driver = {\r
1440                    .owner = THIS_MODULE,\r
1441                    .name = "sensors",\r
1442                    },\r
1443 };\r
1444 \r
1445 static int __init sensor_init(void)\r
1446 {\r
1447         int res = i2c_add_driver(&sensor_driver);\r
1448         pr_info("%s: Probe name %s\n", __func__, sensor_driver.driver.name);\r
1449         if (res)\r
1450                 pr_err("%s failed\n", __func__);\r
1451         \r
1452         printk("%s\n", SENSOR_VERSION_AND_TIME);\r
1453         return res;\r
1454 }\r
1455 \r
1456 static void __exit sensor_exit(void)\r
1457 {\r
1458         pr_info("%s\n", __func__);\r
1459         i2c_del_driver(&sensor_driver);\r
1460 }\r
1461 \r
1462 late_initcall(sensor_init);\r
1463 module_exit(sensor_exit);\r
1464 \r
1465 MODULE_AUTHOR("ROCKCHIP Corporation:lw@rock-chips.com");\r
1466 MODULE_DESCRIPTION("User space character device interface for sensors");\r
1467 MODULE_LICENSE("GPL");\r
1468 \r