1 /* drivers/input/sensors/sensor-dev.c - handle all gsensor in this file
\r
3 * Copyright (C) 2012-2015 ROCKCHIP.
\r
4 * Author: luowei <lw@rock-chips.com>
\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
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
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 <linux/proc_fs.h>
\r
30 #include <mach/gpio.h>
\r
31 #include <mach/board.h>
\r
32 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
33 #include <linux/earlysuspend.h>
\r
35 #include <linux/l3g4200d.h>
\r
36 #include <linux/sensor-dev.h>
\r
40 sensor-dev.c v1.1 add pressure and temperature support 2013-2-27
\r
41 sensor-dev.c v1.2 add akm8963 support 2013-3-10
\r
42 sensor-dev.c v1.3 add sensor debug support 2013-3-15
\r
43 sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01
\r
46 #define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.4 add angle calculation support between two gsensors 2013-09-01"
\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
53 static ssize_t sensor_proc_write(struct file *file, const char __user *buffer,
\r
54 size_t count, loff_t *data)
\r
60 rc = get_user(c, buffer);
\r
63 for(i=SENSOR_TYPE_NULL+1; i<SENSOR_NUM_TYPES; i++)
\r
64 atomic_set(&g_sensor[i]->flags.debug_flag, SENSOR_TYPE_NULL);
\r
71 printk("%s command list:close:%d,angle:%d accel:%d, compass:%d, gyro:%d, light:%d, psensor:%d, temp:%d, pressure:%d,total:%d,num=%d\n",__func__,
\r
73 SENSOR_TYPE_NULL, SENSOR_TYPE_ANGLE, SENSOR_TYPE_ACCEL,SENSOR_TYPE_COMPASS,SENSOR_TYPE_GYROSCOPE,SENSOR_TYPE_LIGHT,SENSOR_TYPE_PROXIMITY,
\r
75 SENSOR_TYPE_TEMPERATURE,SENSOR_TYPE_PRESSURE,SENSOR_NUM_TYPES,num);
\r
77 if((num > SENSOR_NUM_TYPES) || (num < SENSOR_TYPE_NULL))
\r
79 printk("%s:error! only support %d to %d\n",__func__, SENSOR_TYPE_NULL,SENSOR_NUM_TYPES);
\r
83 for(i=SENSOR_TYPE_NULL+1; i<SENSOR_NUM_TYPES; i++)
\r
86 atomic_set(&g_sensor[i]->flags.debug_flag, num);
\r
92 static const struct file_operations sensor_proc_fops = {
\r
93 .owner = THIS_MODULE,
\r
94 .write = sensor_proc_write,
\r
99 static int sensor_get_id(struct i2c_client *client, int *value)
\r
101 struct sensor_private_data *sensor =
\r
102 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
104 char temp = sensor->ops->id_reg;
\r
107 if(sensor->ops->id_reg >= 0)
\r
111 result = sensor_rx_data(client, &temp, 1);
\r
120 if(*value != sensor->ops->id_data)
\r
122 printk("%s:id=0x%x is not 0x%x\n",__func__,*value, sensor->ops->id_data);
\r
126 DBG("%s:devid=0x%x\n",__func__,*value);
\r
132 static int sensor_initial(struct i2c_client *client)
\r
134 struct sensor_private_data *sensor =
\r
135 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
138 //register setting according to chip datasheet
\r
139 result = sensor->ops->init(client);
\r
142 printk("%s:fail to init sensor\n",__func__);
\r
147 DBG("%s:ctrl_data=0x%x\n",__func__,sensor->ops->ctrl_data);
\r
153 static int sensor_chip_init(struct i2c_client *client)
\r
155 struct sensor_private_data *sensor =
\r
156 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
157 struct sensor_operate *ops = sensor_ops[(int)sensor->i2c_id->driver_data];
\r
166 printk("%s:ops is null,sensor name is %s\n",__func__,sensor->i2c_id->name);
\r
171 if((sensor->type != ops->type) || ((int)sensor->i2c_id->driver_data != ops->id_i2c))
\r
173 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
178 if(!ops->init || !ops->active || !ops->report)
\r
180 printk("%s:error:some function is needed\n",__func__);
\r
185 result = sensor_get_id(sensor->client, &sensor->devid);//get id
\r
188 printk("%s:fail to read %s devid:0x%x\n",__func__, sensor->i2c_id->name, sensor->devid);
\r
192 printk("%s:%s:devid=0x%x,ops=0x%p\n",__func__, sensor->i2c_id->name, sensor->devid,sensor->ops);
\r
194 result = sensor_initial(sensor->client); //init sensor
\r
197 printk("%s:fail to init sensor\n",__func__);
\r
208 static int sensor_reset_rate(struct i2c_client *client, int rate)
\r
210 struct sensor_private_data *sensor =
\r
211 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
214 result = sensor->ops->active(client,SENSOR_OFF,rate);
\r
215 sensor->ops->init(client);
\r
216 result = sensor->ops->active(client,SENSOR_ON,rate);
\r
221 static int sensor_get_data(struct i2c_client *client)
\r
223 struct sensor_private_data *sensor =
\r
224 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
227 result = sensor->ops->report(client);
\r
231 /* set data_ready */
\r
232 atomic_set(&sensor->data_ready, 1);
\r
233 /*wake up data_ready work queue*/
\r
234 wake_up(&sensor->data_ready_wq);
\r
241 int sensor_get_cached_data(struct i2c_client* client, char *buffer, int length, struct sensor_axis *axis)
\r
243 struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(client);
\r
244 wait_event_interruptible_timeout(sensor->data_ready_wq,
\r
245 atomic_read(&(sensor->data_ready) ),
\r
246 msecs_to_jiffies(1000) );
\r
247 if ( 0 == atomic_read(&(sensor->data_ready) ) ) {
\r
248 printk("waiting 'data_ready_wq' timed out.");
\r
253 mutex_lock(&sensor->data_mutex);
\r
255 switch(sensor->type)
\r
257 case SENSOR_TYPE_ACCEL:
\r
258 *axis = sensor->axis;
\r
261 case SENSOR_TYPE_COMPASS:
\r
262 memcpy(buffer, sensor->sensor_data, length);
\r
266 mutex_unlock(&sensor->data_mutex);
\r
275 static void sensor_delaywork_func(struct work_struct *work)
\r
277 struct delayed_work *delaywork = container_of(work, struct delayed_work, work);
\r
278 struct sensor_private_data *sensor = container_of(delaywork, struct sensor_private_data, delaywork);
\r
279 struct i2c_client *client = sensor->client;
\r
281 mutex_lock(&sensor->sensor_mutex);
\r
282 if (sensor_get_data(client) < 0)
\r
283 DBG(KERN_ERR "%s: Get data failed\n",__func__);
\r
285 if(!sensor->pdata->irq_enable)//restart work while polling
\r
286 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
289 //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH))
\r
290 //enable_irq(sensor->client->irq);
\r
292 mutex_unlock(&sensor->sensor_mutex);
\r
294 DBG("%s:%s\n",__func__,sensor->i2c_id->name);
\r
298 * This is a threaded IRQ handler so can access I2C/SPI. Since all
\r
299 * interrupts are clear on read the IRQ line will be reasserted and
\r
300 * the physical IRQ will be handled again if another interrupt is
\r
301 * asserted while we run - in the normal course of events this is a
\r
302 * rare occurrence so we save I2C/SPI reads. We're also assuming that
\r
303 * it's rare to get lots of interrupts firing simultaneously so try to
\r
306 static irqreturn_t sensor_interrupt(int irq, void *dev_id)
\r
308 struct sensor_private_data *sensor = (struct sensor_private_data *)dev_id;
\r
311 if (sensor_get_data(sensor->client) < 0)
\r
312 DBG(KERN_ERR "%s: Get data failed\n",__func__);
\r
313 msleep(sensor->pdata->poll_delay_ms);
\r
316 //if((sensor->ops->trig == IRQF_TRIGGER_LOW) || (sensor->ops->trig == IRQF_TRIGGER_HIGH))
\r
317 //disable_irq_nosync(irq);
\r
318 //schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
319 DBG("%s:irq=%d\n",__func__,irq);
\r
320 return IRQ_HANDLED;
\r
324 static int sensor_irq_init(struct i2c_client *client)
\r
326 struct sensor_private_data *sensor =
\r
327 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
330 if((sensor->pdata->irq_enable)&&(sensor->ops->trig != SENSOR_UNKNOW_DATA))
\r
332 //INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
333 if(sensor->pdata->poll_delay_ms < 0)
\r
334 sensor->pdata->poll_delay_ms = 30;
\r
336 result = gpio_request(client->irq, sensor->i2c_id->name);
\r
339 printk("%s:fail to request gpio :%d\n",__func__,client->irq);
\r
342 gpio_pull_updown(client->irq, PullEnable);
\r
343 irq = gpio_to_irq(client->irq);
\r
344 //result = request_irq(irq, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor);
\r
345 result = request_threaded_irq(irq, NULL, sensor_interrupt, sensor->ops->trig, sensor->ops->name, sensor);
\r
347 printk(KERN_ERR "%s:fail to request irq = %d, ret = 0x%x\n",__func__, irq, result);
\r
351 if((sensor->pdata->type == SENSOR_TYPE_GYROSCOPE) || (sensor->pdata->type == SENSOR_TYPE_ACCEL) || (sensor->pdata->type == SENSOR_TYPE_ANGLE))
\r
352 disable_irq_nosync(client->irq);//disable irq
\r
353 if(((sensor->pdata->type == SENSOR_TYPE_LIGHT) || (sensor->pdata->type == SENSOR_TYPE_PROXIMITY))&& (!(sensor->ops->trig & IRQF_SHARED)))
\r
354 disable_irq_nosync(client->irq);//disable irq
\r
355 if(((sensor->pdata->type == SENSOR_TYPE_TEMPERATURE) || (sensor->pdata->type == SENSOR_TYPE_PRESSURE))&& (!(sensor->ops->trig & IRQF_SHARED)))
\r
356 disable_irq_nosync(client->irq);//disable irq
\r
357 printk("%s:use irq=%d\n",__func__,irq);
\r
359 else if(!sensor->pdata->irq_enable)
\r
361 INIT_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
362 if(sensor->pdata->poll_delay_ms < 0)
\r
363 sensor->pdata->poll_delay_ms = 30;
\r
365 printk("%s:use polling,delay=%d ms\n",__func__,sensor->pdata->poll_delay_ms);
\r
372 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
373 static void sensor_suspend(struct early_suspend *h)
\r
375 struct sensor_private_data *sensor =
\r
376 container_of(h, struct sensor_private_data, early_suspend);
\r
378 if(sensor->ops->suspend)
\r
379 sensor->ops->suspend(sensor->client);
\r
383 static void sensor_resume(struct early_suspend *h)
\r
385 struct sensor_private_data *sensor =
\r
386 container_of(h, struct sensor_private_data, early_suspend);
\r
388 if(sensor->ops->resume)
\r
389 sensor->ops->resume(sensor->client);
\r
393 static int angle_dev_open(struct inode *inode, struct file *file)
\r
395 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];
\r
396 //struct i2c_client *client = sensor->client;
\r
405 static int angle_dev_release(struct inode *inode, struct file *file)
\r
407 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE];
\r
408 //struct i2c_client *client = sensor->client;
\r
416 /* ioctl - I/O control */
\r
417 static long angle_dev_ioctl(struct file *file,
\r
418 unsigned int cmd, unsigned long arg)
\r
420 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ANGLE];
\r
421 struct i2c_client *client = sensor->client;
\r
422 void __user *argp = (void __user *)arg;
\r
423 struct sensor_axis axis = {0};
\r
428 case GSENSOR_IOCTL_APP_SET_RATE:
\r
429 if (copy_from_user(&rate, argp, sizeof(rate)))
\r
440 case GSENSOR_IOCTL_START:
\r
441 DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur);
\r
442 mutex_lock(&sensor->operation_mutex);
\r
443 if(++sensor->start_count == 1)
\r
445 if(sensor->status_cur == SENSOR_OFF)
\r
447 atomic_set(&(sensor->data_ready), 0);
\r
448 if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) {
\r
449 mutex_unlock(&sensor->operation_mutex);
\r
450 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
453 if(sensor->pdata->irq_enable)
\r
455 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
456 enable_irq(client->irq); //enable irq
\r
460 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
461 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
463 sensor->status_cur = SENSOR_ON;
\r
466 mutex_unlock(&sensor->operation_mutex);
\r
467 DBG("%s:GSENSOR_IOCTL_START OK\n", __func__);
\r
470 case GSENSOR_IOCTL_CLOSE:
\r
471 DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur);
\r
472 mutex_lock(&sensor->operation_mutex);
\r
473 if(--sensor->start_count == 0)
\r
475 if(sensor->status_cur == SENSOR_ON)
\r
477 atomic_set(&(sensor->data_ready), 0);
\r
478 if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {
\r
479 mutex_unlock(&sensor->operation_mutex);
\r
483 if(sensor->pdata->irq_enable)
\r
485 DBG("%s:disable irq,irq=%d\n",__func__,client->irq);
\r
486 disable_irq_nosync(client->irq);//disable irq
\r
489 cancel_delayed_work_sync(&sensor->delaywork);
\r
490 sensor->status_cur = SENSOR_OFF;
\r
493 DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__);
\r
496 mutex_unlock(&sensor->operation_mutex);
\r
499 case GSENSOR_IOCTL_APP_SET_RATE:
\r
500 DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__);
\r
501 mutex_lock(&sensor->operation_mutex);
\r
502 result = sensor_reset_rate(client, rate);
\r
504 mutex_unlock(&sensor->operation_mutex);
\r
508 sensor->status_cur = SENSOR_ON;
\r
509 mutex_unlock(&sensor->operation_mutex);
\r
510 DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__);
\r
513 case GSENSOR_IOCTL_GETDATA:
\r
514 mutex_lock(&sensor->data_mutex);
\r
515 memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer
\r
516 mutex_unlock(&sensor->data_mutex);
\r
524 case GSENSOR_IOCTL_GETDATA:
\r
525 if ( copy_to_user(argp, &axis, sizeof(axis) ) ) {
\r
526 printk("failed to copy sense data to user space.");
\r
530 DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__);
\r
541 static int gsensor_dev_open(struct inode *inode, struct file *file)
\r
543 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];
\r
544 //struct i2c_client *client = sensor->client;
\r
553 static int gsensor_dev_release(struct inode *inode, struct file *file)
\r
555 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];
\r
556 //struct i2c_client *client = sensor->client;
\r
564 /* ioctl - I/O control */
\r
565 static long gsensor_dev_ioctl(struct file *file,
\r
566 unsigned int cmd, unsigned long arg)
\r
568 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];
\r
569 struct i2c_client *client = sensor->client;
\r
570 void __user *argp = (void __user *)arg;
\r
571 struct sensor_axis axis = {0};
\r
576 case GSENSOR_IOCTL_APP_SET_RATE:
\r
577 if (copy_from_user(&rate, argp, sizeof(rate)))
\r
588 case GSENSOR_IOCTL_START:
\r
589 DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur);
\r
590 mutex_lock(&sensor->operation_mutex);
\r
591 if(++sensor->start_count == 1)
\r
593 if(sensor->status_cur == SENSOR_OFF)
\r
595 atomic_set(&(sensor->data_ready), 0);
\r
596 if ( (result = sensor->ops->active(client, 1, 0) ) < 0 ) {
\r
597 mutex_unlock(&sensor->operation_mutex);
\r
598 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
601 if(sensor->pdata->irq_enable)
\r
603 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
604 enable_irq(client->irq); //enable irq
\r
608 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
609 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
611 sensor->status_cur = SENSOR_ON;
\r
614 mutex_unlock(&sensor->operation_mutex);
\r
615 DBG("%s:GSENSOR_IOCTL_START OK\n", __func__);
\r
618 case GSENSOR_IOCTL_CLOSE:
\r
619 DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur);
\r
620 mutex_lock(&sensor->operation_mutex);
\r
621 if(--sensor->start_count == 0)
\r
623 if(sensor->status_cur == SENSOR_ON)
\r
625 atomic_set(&(sensor->data_ready), 0);
\r
626 if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {
\r
627 mutex_unlock(&sensor->operation_mutex);
\r
631 if(sensor->pdata->irq_enable)
\r
633 DBG("%s:disable irq,irq=%d\n",__func__,client->irq);
\r
634 disable_irq_nosync(client->irq);//disable irq
\r
637 cancel_delayed_work_sync(&sensor->delaywork);
\r
638 sensor->status_cur = SENSOR_OFF;
\r
641 DBG("%s:GSENSOR_IOCTL_CLOSE OK\n", __func__);
\r
644 mutex_unlock(&sensor->operation_mutex);
\r
647 case GSENSOR_IOCTL_APP_SET_RATE:
\r
648 DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__);
\r
649 mutex_lock(&sensor->operation_mutex);
\r
650 result = sensor_reset_rate(client, rate);
\r
652 mutex_unlock(&sensor->operation_mutex);
\r
656 sensor->status_cur = SENSOR_ON;
\r
657 mutex_unlock(&sensor->operation_mutex);
\r
658 DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__);
\r
661 case GSENSOR_IOCTL_GETDATA:
\r
662 mutex_lock(&sensor->data_mutex);
\r
663 memcpy(&axis, &sensor->axis, sizeof(sensor->axis)); //get data from buffer
\r
664 mutex_unlock(&sensor->data_mutex);
\r
672 case GSENSOR_IOCTL_GETDATA:
\r
673 if ( copy_to_user(argp, &axis, sizeof(axis) ) ) {
\r
674 printk("failed to copy sense data to user space.");
\r
678 DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__);
\r
688 static ssize_t gsensor_set_orientation_online(struct class *class,
\r
689 struct class_attribute *attr, const char *buf, size_t count)
\r
692 char orientation[20];
\r
695 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];
\r
696 struct sensor_platform_data *pdata = sensor->pdata;
\r
699 char *p = strstr(buf,"gsensor_class");
\r
700 int start = strcspn(p,"{");
\r
701 int end = strcspn(p,"}");
\r
703 strncpy(orientation,p+start,end-start+1);
\r
707 while(strncmp(tmp,"}",1)!=0)
\r
709 if((strncmp(tmp,",",1)==0)||(strncmp(tmp,"{",1)==0))
\r
715 else if(strncmp(tmp,"-",1)==0)
\r
717 pdata->orientation[i++]=-1;
\r
718 DBG("i=%d,data=%d\n",i,pdata->orientation[i]);
\r
723 pdata->orientation[i++]=tmp[0]-48;
\r
724 DBG("----i=%d,data=%d\n",i,pdata->orientation[i]);
\r
732 DBG("i=%d gsensor_info=%d\n",i,pdata->orientation[i]);
\r
737 static CLASS_ATTR(orientation, 0660, NULL, gsensor_set_orientation_online);
\r
739 static int gsensor_class_init(void)
\r
742 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];
\r
743 g_sensor_class[SENSOR_TYPE_ACCEL] = class_create(THIS_MODULE, "gsensor_class");
\r
744 ret = class_create_file(g_sensor_class[SENSOR_TYPE_ACCEL], &class_attr_orientation);
\r
747 printk("%s:Fail to creat class\n",__func__);
\r
750 printk("%s:%s\n",__func__,sensor->i2c_id->name);
\r
756 static int compass_dev_open(struct inode *inode, struct file *file)
\r
758 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];
\r
759 //struct i2c_client *client = sensor->client;
\r
763 flag = atomic_read(&sensor->flags.open_flag);
\r
766 atomic_set(&sensor->flags.open_flag, 1);
\r
767 wake_up(&sensor->flags.open_wq);
\r
770 DBG("%s\n", __func__);
\r
776 static int compass_dev_release(struct inode *inode, struct file *file)
\r
778 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];
\r
779 //struct i2c_client *client = sensor->client;
\r
780 //void __user *argp = (void __user *)arg;
\r
783 flag = atomic_read(&sensor->flags.open_flag);
\r
786 atomic_set(&sensor->flags.open_flag, 0);
\r
787 wake_up(&sensor->flags.open_wq);
\r
790 DBG("%s\n", __func__);
\r
796 /* ioctl - I/O control */
\r
797 static long compass_dev_ioctl(struct file *file,
\r
798 unsigned int cmd, unsigned long arg)
\r
800 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];
\r
801 //struct i2c_client *client = sensor->client;
\r
802 void __user *argp = (void __user *)arg;
\r
807 case ECS_IOCTL_APP_SET_MFLAG:
\r
808 case ECS_IOCTL_APP_SET_AFLAG:
\r
809 case ECS_IOCTL_APP_SET_MVFLAG:
\r
810 if (copy_from_user(&flag, argp, sizeof(flag))) {
\r
813 if (flag < 0 || flag > 1) {
\r
817 case ECS_IOCTL_APP_SET_DELAY:
\r
818 if (copy_from_user(&flag, argp, sizeof(flag))) {
\r
827 case ECS_IOCTL_APP_SET_MFLAG:
\r
828 atomic_set(&sensor->flags.m_flag, flag);
\r
829 DBG("%s:ECS_IOCTL_APP_SET_MFLAG,flag=%d\n", __func__,flag);
\r
831 case ECS_IOCTL_APP_GET_MFLAG:
\r
832 flag = atomic_read(&sensor->flags.m_flag);
\r
833 DBG("%s:ECS_IOCTL_APP_GET_MFLAG,flag=%d\n", __func__,flag);
\r
835 case ECS_IOCTL_APP_SET_AFLAG:
\r
836 atomic_set(&sensor->flags.a_flag, flag);
\r
837 DBG("%s:ECS_IOCTL_APP_SET_AFLAG,flag=%d\n", __func__,flag);
\r
839 case ECS_IOCTL_APP_GET_AFLAG:
\r
840 flag = atomic_read(&sensor->flags.a_flag);
\r
841 DBG("%s:ECS_IOCTL_APP_GET_AFLAG,flag=%d\n", __func__,flag);
\r
843 case ECS_IOCTL_APP_SET_MVFLAG:
\r
844 atomic_set(&sensor->flags.mv_flag, flag);
\r
845 DBG("%s:ECS_IOCTL_APP_SET_MVFLAG,flag=%d\n", __func__,flag);
\r
847 case ECS_IOCTL_APP_GET_MVFLAG:
\r
848 flag = atomic_read(&sensor->flags.mv_flag);
\r
849 DBG("%s:ECS_IOCTL_APP_GET_MVFLAG,flag=%d\n", __func__,flag);
\r
851 case ECS_IOCTL_APP_SET_DELAY:
\r
852 sensor->flags.delay = flag;
\r
854 case ECS_IOCTL_APP_GET_DELAY:
\r
855 flag = sensor->flags.delay;
\r
862 case ECS_IOCTL_APP_GET_MFLAG:
\r
863 case ECS_IOCTL_APP_GET_AFLAG:
\r
864 case ECS_IOCTL_APP_GET_MVFLAG:
\r
865 case ECS_IOCTL_APP_GET_DELAY:
\r
866 if (copy_to_user(argp, &flag, sizeof(flag))) {
\r
877 static int gyro_dev_open(struct inode *inode, struct file *file)
\r
879 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];
\r
880 //struct i2c_client *client = sensor->client;
\r
889 static int gyro_dev_release(struct inode *inode, struct file *file)
\r
891 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];
\r
892 //struct i2c_client *client = sensor->client;
\r
901 /* ioctl - I/O control */
\r
902 static long gyro_dev_ioctl(struct file *file,
\r
903 unsigned int cmd, unsigned long arg)
\r
905 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_GYROSCOPE];
\r
906 struct i2c_client *client = sensor->client;
\r
907 void __user *argp = (void __user *)arg;
\r
911 case L3G4200D_IOCTL_GET_ENABLE:
\r
912 result = !sensor->status_cur;
\r
913 if (copy_to_user(argp, &result, sizeof(result)))
\r
915 printk("%s:failed to copy status to user space.\n",__FUNCTION__);
\r
919 DBG("%s :L3G4200D_IOCTL_GET_ENABLE,status=%d\n",__FUNCTION__,result);
\r
921 case L3G4200D_IOCTL_SET_ENABLE:
\r
922 DBG("%s :L3G4200D_IOCTL_SET_ENABLE,flag=%d\n",__FUNCTION__,*(unsigned int *)argp);
\r
923 mutex_lock(&sensor->operation_mutex);
\r
924 if(*(unsigned int *)argp)
\r
926 if(sensor->status_cur == SENSOR_OFF)
\r
928 if ( (result = sensor->ops->active(client, 1, ODR100_BW12_5) ) < 0 ) {
\r
929 mutex_unlock(&sensor->operation_mutex);
\r
930 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
933 if(sensor->pdata->irq_enable)
\r
935 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
936 enable_irq(client->irq); //enable irq
\r
940 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
941 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
943 sensor->status_cur = SENSOR_ON;
\r
948 if(sensor->status_cur == SENSOR_ON)
\r
950 if ( (result = sensor->ops->active(client, 0, 0) ) < 0 ) {
\r
951 mutex_unlock(&sensor->operation_mutex);
\r
955 if(sensor->pdata->irq_enable)
\r
957 DBG("%s:disable irq,irq=%d\n",__func__,client->irq);
\r
958 disable_irq_nosync(client->irq);//disable irq
\r
961 cancel_delayed_work_sync(&sensor->delaywork);
\r
962 sensor->status_cur = SENSOR_OFF;
\r
966 result = sensor->status_cur;
\r
967 if (copy_to_user(argp, &result, sizeof(result)))
\r
969 printk("%s:failed to copy sense data to user space.\n",__FUNCTION__);
\r
973 mutex_unlock(&sensor->operation_mutex);
\r
974 DBG("%s:L3G4200D_IOCTL_SET_ENABLE OK\n", __func__);
\r
976 case L3G4200D_IOCTL_SET_DELAY:
\r
977 mutex_lock(&sensor->operation_mutex);
\r
978 if (copy_from_user(&rate, argp, sizeof(rate)))
\r
980 if(sensor->status_cur == SENSOR_OFF)
\r
982 if ( (result = sensor->ops->active(client, 1, rate) ) < 0 ) {
\r
983 mutex_unlock(&sensor->operation_mutex);
\r
984 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
988 if(sensor->pdata->irq_enable)
\r
990 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
991 enable_irq(client->irq); //enable irq
\r
995 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
996 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
998 sensor->status_cur = SENSOR_ON;
\r
1001 mutex_unlock(&sensor->operation_mutex);
\r
1002 DBG("%s :L3G4200D_IOCTL_SET_DELAY,rate=%d\n",__FUNCTION__,rate);
\r
1006 printk("%s:error,cmd=0x%x\n",__func__,cmd);
\r
1010 DBG("%s:line=%d,cmd=0x%x\n",__func__,__LINE__,cmd);
\r
1016 static int light_dev_open(struct inode *inode, struct file *file)
\r
1018 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];
\r
1019 //struct i2c_client *client = sensor->client;
\r
1029 static int light_dev_release(struct inode *inode, struct file *file)
\r
1031 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];
\r
1032 //struct i2c_client *client = sensor->client;
\r
1040 /* ioctl - I/O control */
\r
1041 static long light_dev_ioctl(struct file *file,
\r
1042 unsigned int cmd, unsigned long arg)
\r
1044 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_LIGHT];
\r
1045 struct i2c_client *client = sensor->client;
\r
1046 unsigned int *argp = (unsigned int *)arg;
\r
1051 case LIGHTSENSOR_IOCTL_GET_ENABLED:
\r
1052 *argp = sensor->status_cur;
\r
1054 case LIGHTSENSOR_IOCTL_ENABLE:
\r
1055 DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);
\r
1056 mutex_lock(&sensor->operation_mutex);
\r
1057 if(*(unsigned int *)argp)
\r
1059 if(sensor->status_cur == SENSOR_OFF)
\r
1061 if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {
\r
1062 mutex_unlock(&sensor->operation_mutex);
\r
1063 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
1066 if(sensor->pdata->irq_enable)
\r
1068 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1070 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
1071 enable_irq(client->irq); //enable irq
\r
1076 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
1077 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
1080 sensor->status_cur = SENSOR_ON;
\r
1085 if(sensor->status_cur == SENSOR_ON)
\r
1087 if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {
\r
1088 mutex_unlock(&sensor->operation_mutex);
\r
1092 if(sensor->pdata->irq_enable)
\r
1094 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1096 DBG("%s:disable irq,irq=%d\n",__func__,client->irq);
\r
1097 disable_irq_nosync(client->irq);//disable irq
\r
1101 cancel_delayed_work_sync(&sensor->delaywork);
\r
1103 sensor->status_cur = SENSOR_OFF;
\r
1106 mutex_unlock(&sensor->operation_mutex);
\r
1107 DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__);
\r
1119 static int proximity_dev_open(struct inode *inode, struct file *file)
\r
1121 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];
\r
1122 //struct i2c_client *client = sensor->client;
\r
1130 static int proximity_dev_release(struct inode *inode, struct file *file)
\r
1132 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];
\r
1133 //struct i2c_client *client = sensor->client;
\r
1141 /* ioctl - I/O control */
\r
1142 static long proximity_dev_ioctl(struct file *file,
\r
1143 unsigned int cmd, unsigned long arg)
\r
1145 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PROXIMITY];
\r
1146 struct i2c_client *client = sensor->client;
\r
1147 unsigned int *argp = (unsigned int *)arg;
\r
1151 case PSENSOR_IOCTL_GET_ENABLED:
\r
1152 *argp = sensor->status_cur;
\r
1154 case PSENSOR_IOCTL_ENABLE:
\r
1155 DBG("%s:PSENSOR_IOCTL_ENABLE start\n", __func__);
\r
1156 mutex_lock(&sensor->operation_mutex);
\r
1157 if(*(unsigned int *)argp)
\r
1159 if(sensor->status_cur == SENSOR_OFF)
\r
1161 if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {
\r
1162 mutex_unlock(&sensor->operation_mutex);
\r
1163 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
1167 if(sensor->pdata->irq_enable)
\r
1169 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1171 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
1172 enable_irq(client->irq); //enable irq
\r
1177 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
1178 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
1181 sensor->status_cur = SENSOR_ON;
\r
1186 if(sensor->status_cur == SENSOR_ON)
\r
1188 if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {
\r
1189 mutex_unlock(&sensor->operation_mutex);
\r
1192 if(sensor->pdata->irq_enable)
\r
1194 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1196 DBG("%s:disable irq,irq=%d\n",__func__,client->irq);
\r
1197 disable_irq_nosync(client->irq);//disable irq
\r
1201 cancel_delayed_work_sync(&sensor->delaywork);
\r
1202 sensor->status_cur = SENSOR_OFF;
\r
1205 mutex_unlock(&sensor->operation_mutex);
\r
1206 DBG("%s:PSENSOR_IOCTL_ENABLE OK\n", __func__);
\r
1217 static int temperature_dev_open(struct inode *inode, struct file *file)
\r
1219 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];
\r
1220 //struct i2c_client *client = sensor->client;
\r
1229 static int temperature_dev_release(struct inode *inode, struct file *file)
\r
1231 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];
\r
1232 //struct i2c_client *client = sensor->client;
\r
1241 /* ioctl - I/O control */
\r
1242 static long temperature_dev_ioctl(struct file *file,
\r
1243 unsigned int cmd, unsigned long arg)
\r
1245 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_TEMPERATURE];
\r
1246 struct i2c_client *client = sensor->client;
\r
1247 unsigned int *argp = (unsigned int *)arg;
\r
1252 case TEMPERATURE_IOCTL_GET_ENABLED:
\r
1253 *argp = sensor->status_cur;
\r
1255 case TEMPERATURE_IOCTL_ENABLE:
\r
1256 DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);
\r
1257 mutex_lock(&sensor->operation_mutex);
\r
1258 if(*(unsigned int *)argp)
\r
1260 if(sensor->status_cur == SENSOR_OFF)
\r
1262 if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {
\r
1263 mutex_unlock(&sensor->operation_mutex);
\r
1264 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
1267 if(sensor->pdata->irq_enable)
\r
1269 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1271 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
1272 enable_irq(client->irq); //enable irq
\r
1277 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
1278 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
1281 sensor->status_cur = SENSOR_ON;
\r
1286 if(sensor->status_cur == SENSOR_ON)
\r
1288 if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {
\r
1289 mutex_unlock(&sensor->operation_mutex);
\r
1293 if(sensor->pdata->irq_enable)
\r
1295 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1297 DBG("%s:disable irq,irq=%d\n",__func__,client->irq);
\r
1298 disable_irq_nosync(client->irq);//disable irq
\r
1302 cancel_delayed_work_sync(&sensor->delaywork);
\r
1304 sensor->status_cur = SENSOR_OFF;
\r
1307 mutex_unlock(&sensor->operation_mutex);
\r
1308 DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__);
\r
1320 static int pressure_dev_open(struct inode *inode, struct file *file)
\r
1322 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE];
\r
1323 //struct i2c_client *client = sensor->client;
\r
1332 static int pressure_dev_release(struct inode *inode, struct file *file)
\r
1334 //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE];
\r
1335 //struct i2c_client *client = sensor->client;
\r
1344 /* ioctl - I/O control */
\r
1345 static long pressure_dev_ioctl(struct file *file,
\r
1346 unsigned int cmd, unsigned long arg)
\r
1348 struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_PRESSURE];
\r
1349 struct i2c_client *client = sensor->client;
\r
1350 unsigned int *argp = (unsigned int *)arg;
\r
1355 case PRESSURE_IOCTL_GET_ENABLED:
\r
1356 *argp = sensor->status_cur;
\r
1358 case PRESSURE_IOCTL_ENABLE:
\r
1359 DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);
\r
1360 mutex_lock(&sensor->operation_mutex);
\r
1361 if(*(unsigned int *)argp)
\r
1363 if(sensor->status_cur == SENSOR_OFF)
\r
1365 if ( (result = sensor->ops->active(client, SENSOR_ON, 0) ) < 0 ) {
\r
1366 mutex_unlock(&sensor->operation_mutex);
\r
1367 printk("%s:fail to active sensor,ret=%d\n",__func__,result);
\r
1370 if(sensor->pdata->irq_enable)
\r
1372 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1374 DBG("%s:enable irq,irq=%d\n",__func__,client->irq);
\r
1375 enable_irq(client->irq); //enable irq
\r
1380 PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);
\r
1381 schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
\r
1384 sensor->status_cur = SENSOR_ON;
\r
1389 if(sensor->status_cur == SENSOR_ON)
\r
1391 if ( (result = sensor->ops->active(client, SENSOR_OFF, 0) ) < 0 ) {
\r
1392 mutex_unlock(&sensor->operation_mutex);
\r
1396 if(sensor->pdata->irq_enable)
\r
1398 if(!(sensor->ops->trig & IRQF_SHARED))
\r
1400 DBG("%s:disable irq,irq=%d\n",__func__,client->irq);
\r
1401 disable_irq_nosync(client->irq);//disable irq
\r
1405 cancel_delayed_work_sync(&sensor->delaywork);
\r
1407 sensor->status_cur = SENSOR_OFF;
\r
1410 mutex_unlock(&sensor->operation_mutex);
\r
1411 DBG("%s:LIGHTSENSOR_IOCTL_ENABLE OK\n", __func__);
\r
1425 static int sensor_misc_device_register(struct sensor_private_data *sensor, int type)
\r
1431 case SENSOR_TYPE_ANGLE:
\r
1432 if(!sensor->ops->misc_dev)
\r
1434 sensor->fops.owner = THIS_MODULE;
\r
1435 sensor->fops.unlocked_ioctl = angle_dev_ioctl;
\r
1436 sensor->fops.open = angle_dev_open;
\r
1437 sensor->fops.release = angle_dev_release;
\r
1439 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1440 sensor->miscdev.name = "angle";
\r
1441 sensor->miscdev.fops = &sensor->fops;
\r
1445 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1451 case SENSOR_TYPE_ACCEL:
\r
1452 if(!sensor->ops->misc_dev)
\r
1454 sensor->fops.owner = THIS_MODULE;
\r
1455 sensor->fops.unlocked_ioctl = gsensor_dev_ioctl;
\r
1456 sensor->fops.open = gsensor_dev_open;
\r
1457 sensor->fops.release = gsensor_dev_release;
\r
1459 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1460 sensor->miscdev.name = "mma8452_daemon";
\r
1461 sensor->miscdev.fops = &sensor->fops;
\r
1465 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1471 case SENSOR_TYPE_COMPASS:
\r
1472 if(!sensor->ops->misc_dev)
\r
1474 sensor->fops.owner = THIS_MODULE;
\r
1475 sensor->fops.unlocked_ioctl = compass_dev_ioctl;
\r
1476 sensor->fops.open = compass_dev_open;
\r
1477 sensor->fops.release = compass_dev_release;
\r
1479 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1480 sensor->miscdev.name = "compass";
\r
1481 sensor->miscdev.fops = &sensor->fops;
\r
1485 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1491 case SENSOR_TYPE_GYROSCOPE:
\r
1492 if(!sensor->ops->misc_dev)
\r
1494 sensor->fops.owner = THIS_MODULE;
\r
1495 sensor->fops.unlocked_ioctl = gyro_dev_ioctl;
\r
1496 sensor->fops.open = gyro_dev_open;
\r
1497 sensor->fops.release = gyro_dev_release;
\r
1499 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1500 sensor->miscdev.name = "gyrosensor";
\r
1501 sensor->miscdev.fops = &sensor->fops;
\r
1505 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1511 case SENSOR_TYPE_LIGHT:
\r
1512 if(!sensor->ops->misc_dev)
\r
1514 sensor->fops.owner = THIS_MODULE;
\r
1515 sensor->fops.unlocked_ioctl = light_dev_ioctl;
\r
1516 sensor->fops.open = light_dev_open;
\r
1517 sensor->fops.release = light_dev_release;
\r
1519 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1520 sensor->miscdev.name = "lightsensor";
\r
1521 sensor->miscdev.fops = &sensor->fops;
\r
1525 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1530 case SENSOR_TYPE_PROXIMITY:
\r
1531 if(!sensor->ops->misc_dev)
\r
1533 sensor->fops.owner = THIS_MODULE;
\r
1534 sensor->fops.unlocked_ioctl = proximity_dev_ioctl;
\r
1535 sensor->fops.open = proximity_dev_open;
\r
1536 sensor->fops.release = proximity_dev_release;
\r
1538 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1539 sensor->miscdev.name = "psensor";
\r
1540 sensor->miscdev.fops = &sensor->fops;
\r
1544 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1549 case SENSOR_TYPE_TEMPERATURE:
\r
1550 if(!sensor->ops->misc_dev)
\r
1552 sensor->fops.owner = THIS_MODULE;
\r
1553 sensor->fops.unlocked_ioctl = temperature_dev_ioctl;
\r
1554 sensor->fops.open = temperature_dev_open;
\r
1555 sensor->fops.release = temperature_dev_release;
\r
1557 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1558 sensor->miscdev.name = "temperature";
\r
1559 sensor->miscdev.fops = &sensor->fops;
\r
1563 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1569 case SENSOR_TYPE_PRESSURE:
\r
1570 if(!sensor->ops->misc_dev)
\r
1572 sensor->fops.owner = THIS_MODULE;
\r
1573 sensor->fops.unlocked_ioctl = pressure_dev_ioctl;
\r
1574 sensor->fops.open = pressure_dev_open;
\r
1575 sensor->fops.release = pressure_dev_release;
\r
1577 sensor->miscdev.minor = MISC_DYNAMIC_MINOR;
\r
1578 sensor->miscdev.name = "pressure";
\r
1579 sensor->miscdev.fops = &sensor->fops;
\r
1583 memcpy(&sensor->miscdev, sensor->ops->misc_dev, sizeof(*sensor->ops->misc_dev));
\r
1590 printk("%s:unknow sensor type=%d\n",__func__,type);
\r
1595 sensor->miscdev.parent = &sensor->client->dev;
\r
1596 result = misc_register(&sensor->miscdev);
\r
1598 dev_err(&sensor->client->dev,
\r
1599 "fail to register misc device %s\n", sensor->miscdev.name);
\r
1603 printk("%s:miscdevice: %s\n",__func__,sensor->miscdev.name);
\r
1611 int sensor_register_slave(int type,struct i2c_client *client,
\r
1612 struct sensor_platform_data *slave_pdata,
\r
1613 struct sensor_operate *(*get_sensor_ops)(void))
\r
1616 struct sensor_operate *ops = get_sensor_ops();
\r
1617 if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))
\r
1619 printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);
\r
1622 sensor_ops[ops->id_i2c] = ops;
\r
1623 printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);
\r
1628 int sensor_unregister_slave(int type,struct i2c_client *client,
\r
1629 struct sensor_platform_data *slave_pdata,
\r
1630 struct sensor_operate *(*get_sensor_ops)(void))
\r
1633 struct sensor_operate *ops = get_sensor_ops();
\r
1634 if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))
\r
1636 printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);
\r
1639 printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);
\r
1640 sensor_ops[ops->id_i2c] = NULL;
\r
1645 int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
\r
1647 struct sensor_private_data *sensor =
\r
1648 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
1649 struct sensor_platform_data *pdata;
\r
1653 dev_info(&client->adapter->dev, "%s: %s,0x%x\n", __func__, devid->name,(unsigned int)client);
\r
1655 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
\r
1660 pdata = client->dev.platform_data;
\r
1662 dev_err(&client->adapter->dev,
\r
1663 "Missing platform data for slave %s\n", devid->name);
\r
1668 sensor = kzalloc(sizeof(*sensor), GFP_KERNEL);
\r
1674 type= pdata->type;
\r
1676 if((type >= SENSOR_NUM_TYPES) || (type <= SENSOR_TYPE_NULL))
\r
1678 dev_err(&client->adapter->dev, "sensor type is error %d\n", pdata->type);
\r
1680 goto out_no_free;
\r
1683 if(((int)devid->driver_data >= SENSOR_NUM_ID) || ((int)devid->driver_data <= ID_INVALID))
\r
1685 dev_err(&client->adapter->dev, "sensor id is error %d\n", (int)devid->driver_data);
\r
1687 goto out_no_free;
\r
1690 i2c_set_clientdata(client, sensor);
\r
1691 sensor->client = client;
\r
1692 sensor->pdata = pdata;
\r
1693 sensor->type = type;
\r
1694 sensor->i2c_id = (struct i2c_device_id *)devid;
\r
1696 if (pdata->init_platform_hw) {
\r
1697 result = pdata->init_platform_hw();
\r
1699 goto out_free_memory;
\r
1702 if(pdata->reset_pin)
\r
1703 gpio_request(pdata->reset_pin,"sensor_reset_pin");
\r
1705 if(pdata->power_pin)
\r
1706 gpio_request(pdata->power_pin,"sensor_power_pin");
\r
1708 memset(&(sensor->axis), 0, sizeof(struct sensor_axis) );
\r
1709 atomic_set(&(sensor->data_ready), 0);
\r
1710 init_waitqueue_head(&(sensor->data_ready_wq));
\r
1711 mutex_init(&sensor->data_mutex);
\r
1712 mutex_init(&sensor->operation_mutex);
\r
1713 mutex_init(&sensor->sensor_mutex);
\r
1714 mutex_init(&sensor->i2c_mutex);
\r
1716 /* As default, report all information */
\r
1717 atomic_set(&sensor->flags.m_flag, 1);
\r
1718 atomic_set(&sensor->flags.a_flag, 1);
\r
1719 atomic_set(&sensor->flags.mv_flag, 1);
\r
1720 atomic_set(&sensor->flags.open_flag, 0);
\r
1721 atomic_set(&sensor->flags.debug_flag, 0);
\r
1722 init_waitqueue_head(&sensor->flags.open_wq);
\r
1723 sensor->flags.delay = 100;
\r
1725 sensor->status_cur = SENSOR_OFF;
\r
1726 sensor->axis.x = 0;
\r
1727 sensor->axis.y = 0;
\r
1728 sensor->axis.z = 0;
\r
1730 result = sensor_chip_init(sensor->client);
\r
1732 goto out_free_memory;
\r
1734 sensor->input_dev = input_allocate_device();
\r
1735 if (!sensor->input_dev) {
\r
1737 dev_err(&client->dev,
\r
1738 "Failed to allocate input device %s\n", sensor->input_dev->name);
\r
1739 goto out_free_memory;
\r
1744 case SENSOR_TYPE_ANGLE:
\r
1745 sensor->input_dev->name = "angle";
\r
1746 set_bit(EV_ABS, sensor->input_dev->evbit);
\r
1747 /* x-axis acceleration */
\r
1748 input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
\r
1749 /* y-axis acceleration */
\r
1750 input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
\r
1751 /* z-axis acceleration */
\r
1752 input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
\r
1755 case SENSOR_TYPE_ACCEL:
\r
1756 sensor->input_dev->name = "gsensor";
\r
1757 set_bit(EV_ABS, sensor->input_dev->evbit);
\r
1758 /* x-axis acceleration */
\r
1759 input_set_abs_params(sensor->input_dev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
\r
1760 /* y-axis acceleration */
\r
1761 input_set_abs_params(sensor->input_dev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
\r
1762 /* z-axis acceleration */
\r
1763 input_set_abs_params(sensor->input_dev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0); //2g full scale range
\r
1765 case SENSOR_TYPE_COMPASS:
\r
1766 sensor->input_dev->name = "compass";
\r
1767 /* Setup input device */
\r
1768 set_bit(EV_ABS, sensor->input_dev->evbit);
\r
1769 /* yaw (0, 360) */
\r
1770 input_set_abs_params(sensor->input_dev, ABS_RX, 0, 23040, 0, 0);
\r
1771 /* pitch (-180, 180) */
\r
1772 input_set_abs_params(sensor->input_dev, ABS_RY, -11520, 11520, 0, 0);
\r
1773 /* roll (-90, 90) */
\r
1774 input_set_abs_params(sensor->input_dev, ABS_RZ, -5760, 5760, 0, 0);
\r
1775 /* x-axis acceleration (720 x 8G) */
\r
1776 input_set_abs_params(sensor->input_dev, ABS_X, -5760, 5760, 0, 0);
\r
1777 /* y-axis acceleration (720 x 8G) */
\r
1778 input_set_abs_params(sensor->input_dev, ABS_Y, -5760, 5760, 0, 0);
\r
1779 /* z-axis acceleration (720 x 8G) */
\r
1780 input_set_abs_params(sensor->input_dev, ABS_Z, -5760, 5760, 0, 0);
\r
1781 /* status of magnetic sensor */
\r
1782 input_set_abs_params(sensor->input_dev, ABS_RUDDER, -32768, 3, 0, 0);
\r
1783 /* status of acceleration sensor */
\r
1784 input_set_abs_params(sensor->input_dev, ABS_WHEEL, -32768, 3, 0, 0);
\r
1785 /* x-axis of raw magnetic vector (-4096, 4095) */
\r
1786 input_set_abs_params(sensor->input_dev, ABS_HAT0X, -20480, 20479, 0, 0);
\r
1787 /* y-axis of raw magnetic vector (-4096, 4095) */
\r
1788 input_set_abs_params(sensor->input_dev, ABS_HAT0Y, -20480, 20479, 0, 0);
\r
1789 /* z-axis of raw magnetic vector (-4096, 4095) */
\r
1790 input_set_abs_params(sensor->input_dev, ABS_BRAKE, -20480, 20479, 0, 0);
\r
1792 case SENSOR_TYPE_GYROSCOPE:
\r
1793 sensor->input_dev->name = "gyro";
\r
1794 /* x-axis acceleration */
\r
1795 input_set_capability(sensor->input_dev, EV_REL, REL_RX);
\r
1796 input_set_abs_params(sensor->input_dev, ABS_RX, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
\r
1797 /* y-axis acceleration */
\r
1798 input_set_capability(sensor->input_dev, EV_REL, REL_RY);
\r
1799 input_set_abs_params(sensor->input_dev, ABS_RY, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
\r
1800 /* z-axis acceleration */
\r
1801 input_set_capability(sensor->input_dev, EV_REL, REL_RZ);
\r
1802 input_set_abs_params(sensor->input_dev, ABS_RZ, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
\r
1804 case SENSOR_TYPE_LIGHT:
\r
1805 sensor->input_dev->name = "lightsensor-level";
\r
1806 set_bit(EV_ABS, sensor->input_dev->evbit);
\r
1807 input_set_abs_params(sensor->input_dev, ABS_MISC, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
\r
1808 input_set_abs_params(sensor->input_dev, ABS_TOOL_WIDTH , sensor->ops->brightness[0],sensor->ops->brightness[1], 0, 0);
\r
1810 case SENSOR_TYPE_PROXIMITY:
\r
1811 sensor->input_dev->name = "proximity";
\r
1812 set_bit(EV_ABS, sensor->input_dev->evbit);
\r
1813 input_set_abs_params(sensor->input_dev, ABS_DISTANCE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
\r
1815 case SENSOR_TYPE_TEMPERATURE:
\r
1816 sensor->input_dev->name = "temperature";
\r
1817 set_bit(EV_ABS, sensor->input_dev->evbit);
\r
1818 input_set_abs_params(sensor->input_dev, ABS_THROTTLE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
\r
1820 case SENSOR_TYPE_PRESSURE:
\r
1821 sensor->input_dev->name = "pressure";
\r
1822 set_bit(EV_ABS, sensor->input_dev->evbit);
\r
1823 input_set_abs_params(sensor->input_dev, ABS_PRESSURE, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
\r
1826 printk("%s:unknow sensor type=%d\n",__func__,type);
\r
1830 sensor->input_dev->dev.parent = &client->dev;
\r
1832 result = input_register_device(sensor->input_dev);
\r
1834 dev_err(&client->dev,
\r
1835 "Unable to register input device %s\n", sensor->input_dev->name);
\r
1836 goto out_input_register_device_failed;
\r
1839 result = sensor_irq_init(sensor->client);
\r
1841 dev_err(&client->dev,
\r
1842 "fail to init sensor irq,ret=%d\n",result);
\r
1843 goto out_input_register_device_failed;
\r
1847 sensor->miscdev.parent = &client->dev;
\r
1848 result = sensor_misc_device_register(sensor, type);
\r
1850 dev_err(&client->dev,
\r
1851 "fail to register misc device %s\n", sensor->miscdev.name);
\r
1852 goto out_misc_device_register_device_failed;
\r
1855 g_sensor[type] = sensor;
\r
1857 if((type == SENSOR_TYPE_ACCEL) && (sensor->pdata->factory)) //only support setting gsensor orientation online now
\r
1859 result = gsensor_class_init();
\r
1861 dev_err(&client->dev,
\r
1862 "fail to register misc device %s\n", sensor->i2c_id->name);
\r
1863 goto out_misc_device_register_device_failed;
\r
1867 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
1868 if((sensor->ops->suspend) && (sensor->ops->resume))
\r
1870 sensor->early_suspend.suspend = sensor_suspend;
\r
1871 sensor->early_suspend.resume = sensor_resume;
\r
1872 sensor->early_suspend.level = 0x02;
\r
1873 register_early_suspend(&sensor->early_suspend);
\r
1877 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
1881 out_misc_device_register_device_failed:
\r
1882 input_unregister_device(sensor->input_dev);
\r
1883 out_input_register_device_failed:
\r
1884 input_free_device(sensor->input_dev);
\r
1888 dev_err(&client->adapter->dev, "%s failed %d\n\n", __func__, result);
\r
1893 static void sensor_shut_down(struct i2c_client *client)
\r
1895 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
1896 struct sensor_private_data *sensor =
\r
1897 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
1898 if((sensor->ops->suspend) && (sensor->ops->resume))
\r
1899 unregister_early_suspend(&sensor->early_suspend);
\r
1900 DBG("%s:%s\n",__func__,sensor->i2c_id->name);
\r
1904 static int sensor_remove(struct i2c_client *client)
\r
1906 struct sensor_private_data *sensor =
\r
1907 (struct sensor_private_data *) i2c_get_clientdata(client);
\r
1910 cancel_delayed_work_sync(&sensor->delaywork);
\r
1911 misc_deregister(&sensor->miscdev);
\r
1912 input_unregister_device(sensor->input_dev);
\r
1913 input_free_device(sensor->input_dev);
\r
1915 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
1916 if((sensor->ops->suspend) && (sensor->ops->resume))
\r
1917 unregister_early_suspend(&sensor->early_suspend);
\r
1922 static const struct i2c_device_id sensor_id[] = {
\r
1924 {"angle_kxtik", ANGLE_ID_KXTIK},
\r
1925 {"angle_lis3dh", ANGLE_ID_LIS3DH},
\r
1927 {"gsensor", ACCEL_ID_ALL},
\r
1928 {"gs_mma8452", ACCEL_ID_MMA845X},
\r
1929 {"gs_kxtik", ACCEL_ID_KXTIK},
\r
1930 {"gs_kxtj9", ACCEL_ID_KXTJ9},
\r
1931 {"gs_lis3dh", ACCEL_ID_LIS3DH},
\r
1932 {"gs_mma7660", ACCEL_ID_MMA7660},
\r
1933 {"gs_mxc6225", ACCEL_ID_MXC6225},
\r
1934 {"gs_dmard10", ACCEL_ID_DMARD10},
\r
1935 {"gs_lsm303d", ACCEL_ID_LSM303D},
\r
1937 {"compass", COMPASS_ID_ALL},
\r
1938 {"ak8975", COMPASS_ID_AK8975},
\r
1939 {"ak8963", COMPASS_ID_AK8963},
\r
1940 {"ak09911", COMPASS_ID_AK09911},
\r
1941 {"mmc314x", COMPASS_ID_MMC314X},
\r
1943 {"gyro", GYRO_ID_ALL},
\r
1944 {"l3g4200d_gyro", GYRO_ID_L3G4200D},
\r
1945 {"l3g20d_gyro", GYRO_ID_L3G20D},
\r
1946 {"ewtsa_gyro", GYRO_ID_EWTSA},
\r
1947 {"k3g", GYRO_ID_K3G},
\r
1949 {"lightsensor", LIGHT_ID_ALL},
\r
1950 {"light_cm3217", LIGHT_ID_CM3217},
\r
1951 {"light_cm3232", LIGHT_ID_CM3232},
\r
1952 {"light_al3006", LIGHT_ID_AL3006},
\r
1953 {"ls_stk3171", LIGHT_ID_STK3171},
\r
1954 {"ls_isl29023", LIGHT_ID_ISL29023},
\r
1955 {"ls_ap321xx", LIGHT_ID_AP321XX},
\r
1956 {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR},
\r
1957 {"ls_us5152", LIGHT_ID_US5152},
\r
1958 /*proximity sensor*/
\r
1959 {"psensor", PROXIMITY_ID_ALL},
\r
1960 {"proximity_al3006", PROXIMITY_ID_AL3006},
\r
1961 {"ps_stk3171", PROXIMITY_ID_STK3171},
\r
1962 {"ps_ap321xx", PROXIMITY_ID_AP321XX},
\r
1965 {"temperature", TEMPERATURE_ID_ALL},
\r
1966 {"tmp_ms5607", TEMPERATURE_ID_MS5607},
\r
1969 {"pressure", PRESSURE_ID_ALL},
\r
1970 {"pr_ms5607", PRESSURE_ID_MS5607},
\r
1976 static struct i2c_driver sensor_driver = {
\r
1977 .probe = sensor_probe,
\r
1978 .remove = sensor_remove,
\r
1979 .shutdown = sensor_shut_down,
\r
1980 .id_table = sensor_id,
\r
1982 .owner = THIS_MODULE,
\r
1983 .name = "sensors",
\r
1987 static int __init sensor_init(void)
\r
1989 int res = i2c_add_driver(&sensor_driver);
\r
1990 struct proc_dir_entry *sensor_proc_entry;
\r
1991 pr_info("%s: Probe name %s\n", __func__, sensor_driver.driver.name);
\r
1993 pr_err("%s failed\n", __func__);
\r
1995 sensor_proc_entry = proc_create("driver/sensor_dbg", 0660, NULL, &sensor_proc_fops);
\r
1996 printk("%s\n", SENSOR_VERSION_AND_TIME);
\r
2000 static void __exit sensor_exit(void)
\r
2002 pr_info("%s\n", __func__);
\r
2003 i2c_del_driver(&sensor_driver);
\r
2006 late_initcall(sensor_init);
\r
2007 module_exit(sensor_exit);
\r
2009 MODULE_AUTHOR("ROCKCHIP Corporation:lw@rock-chips.com");
\r
2010 MODULE_DESCRIPTION("User space character device interface for sensors");
\r
2011 MODULE_LICENSE("GPL");
\r