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