#include <linux/l3g4200d.h>\r
#include <linux/sensor-dev.h>\r
\r
-#define SENSOR_ON 1\r
-#define SENSOR_OFF 0\r
\r
#if 0\r
#define SENSOR_DEBUG_TYPE SENSOR_TYPE_ACCEL\r
#define DBG(x...)\r
#endif\r
\r
+#define SENSOR_VERSION_AND_TIME "sensor-dev.c v1.0 2013-2-18"\r
+\r
+\r
struct sensor_private_data *g_sensor[SENSOR_NUM_TYPES];\r
-static struct sensor_operate *sensor_ops[SENSOR_NUM_TYPES]; \r
+static struct sensor_operate *sensor_ops[SENSOR_NUM_ID]; \r
+static struct class *g_sensor_class[SENSOR_NUM_TYPES];\r
+\r
\r
static int sensor_get_id(struct i2c_client *client, int *value)\r
{\r
{\r
struct sensor_private_data *sensor =\r
(struct sensor_private_data *) i2c_get_clientdata(client); \r
- struct sensor_operate *ops = sensor_ops[sensor->type];\r
+ struct sensor_operate *ops = sensor_ops[(int)sensor->i2c_id->driver_data];\r
int result = 0;\r
\r
if(ops)\r
goto error;\r
}\r
\r
- if(sensor->type != ops->type)\r
+ if((sensor->type != ops->type) || ((int)sensor->i2c_id->driver_data != ops->id_i2c))\r
{\r
- printk("%s:type is different:%d,%d\n",__func__,sensor->type, sensor->type);\r
+ 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
result = -1;\r
goto error;\r
}\r
result = sensor_get_id(sensor->client, &sensor->devid);//get id\r
if(result < 0)\r
{ \r
- printk("%s:fail to read devid:0x%x\n",__func__,sensor->devid); \r
+ printk("%s:fail to read %s devid:0x%x\n",__func__, sensor->i2c_id->name, sensor->devid); \r
goto error;\r
}\r
\r
- printk("%s:sensor->devid=0x%x,ops=0x%p\n",__func__,sensor->devid,sensor->ops);\r
+ printk("%s:%s:devid=0x%x,ops=0x%p\n",__func__, sensor->i2c_id->name, sensor->devid,sensor->ops);\r
\r
result = sensor_initial(sensor->client); //init sensor\r
if(result < 0)\r
goto error; \r
}\r
client->irq = irq;\r
- if((sensor->pdata->type == SENSOR_TYPE_GYROSCOPE))\r
+ if((sensor->pdata->type == SENSOR_TYPE_GYROSCOPE) || (sensor->pdata->type == SENSOR_TYPE_ACCEL))\r
+ disable_irq_nosync(client->irq);//disable irq\r
+ if(((sensor->pdata->type == SENSOR_TYPE_LIGHT) || (sensor->pdata->type == SENSOR_TYPE_PROXIMITY))&& (!(sensor->ops->trig & IRQF_SHARED))) \r
disable_irq_nosync(client->irq);//disable irq\r
printk("%s:use irq=%d\n",__func__,irq);\r
}\r
return result;\r
}\r
\r
-\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
static void sensor_suspend(struct early_suspend *h)\r
{\r
struct sensor_private_data *sensor = \r
if(sensor->ops->resume)\r
sensor->ops->resume(sensor->client);\r
}\r
+#endif\r
\r
static int gsensor_dev_open(struct inode *inode, struct file *file)\r
{\r
break;\r
default:\r
break;\r
- }
-
- switch (cmd) {
+ }\r
+\r
+ switch (cmd) {\r
case GSENSOR_IOCTL_START: \r
DBG("%s:GSENSOR_IOCTL_START start,status=%d\n", __func__,sensor->status_cur);\r
mutex_lock(&sensor->operation_mutex); \r
} \r
if(sensor->pdata->irq_enable)\r
{\r
- //printk("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- //enable_irq(client->irq); //enable irq\r
+ DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
+ enable_irq(client->irq); //enable irq\r
} \r
else\r
{\r
mutex_unlock(&sensor->operation_mutex);\r
DBG("%s:GSENSOR_IOCTL_START OK\n", __func__);\r
break;\r
-
+\r
case GSENSOR_IOCTL_CLOSE: \r
DBG("%s:GSENSOR_IOCTL_CLOSE start,status=%d\n", __func__,sensor->status_cur);\r
mutex_lock(&sensor->operation_mutex); \r
\r
if(sensor->pdata->irq_enable)\r
{ \r
- //printk("%s:disable irq,irq=%d\n",__func__,client->irq);\r
- //disable_irq_nosync(client->irq);//disable irq\r
+ DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
+ disable_irq_nosync(client->irq);//disable irq\r
}\r
else\r
cancel_delayed_work_sync(&sensor->delaywork); \r
\r
mutex_unlock(&sensor->operation_mutex); \r
break;\r
-
+\r
case GSENSOR_IOCTL_APP_SET_RATE: \r
DBG("%s:GSENSOR_IOCTL_APP_SET_RATE start\n", __func__); \r
mutex_lock(&sensor->operation_mutex); \r
mutex_unlock(&sensor->operation_mutex);\r
goto error;\r
}\r
- if(sensor->status_cur == SENSOR_OFF)\r
- { \r
- if(sensor->pdata->irq_enable)\r
- {\r
- //printk("%s:enable irq,irq=%d\n",__func__,client->irq);\r
- //enable_irq(client->irq); //enable irq\r
- } \r
- else\r
- {\r
- PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
- schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
- }\r
- sensor->status_cur = SENSOR_ON;\r
- } \r
+\r
+ sensor->status_cur = SENSOR_ON;\r
mutex_unlock(&sensor->operation_mutex); \r
DBG("%s:GSENSOR_IOCTL_APP_SET_RATE OK\n", __func__);\r
break;\r
default:\r
result = -ENOTTY;\r
goto error;\r
- }
-
- switch (cmd) {
+ }\r
+\r
+ switch (cmd) {\r
case GSENSOR_IOCTL_GETDATA:\r
if ( copy_to_user(argp, &axis, sizeof(axis) ) ) {\r
printk("failed to copy sense data to user space.");\r
goto error;\r
} \r
DBG("%s:GSENSOR_IOCTL_GETDATA OK\n", __func__);\r
- break;
- default:
- break;
+ break;\r
+ default:\r
+ break;\r
}\r
\r
error:\r
return result;\r
}\r
\r
+static ssize_t gsensor_set_orientation_online(struct class *class,\r
+ struct class_attribute *attr, const char *buf, size_t count)\r
+{\r
+ int i=0;\r
+ char orientation[20];\r
+ char *tmp;\r
+ \r
+ struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];\r
+ struct sensor_platform_data *pdata = sensor->pdata;\r
+\r
+ \r
+ char *p = strstr(buf,"gsensor_class");\r
+ int start = strcspn(p,"{");\r
+ int end = strcspn(p,"}");\r
+ \r
+ strncpy(orientation,p+start,end-start+1);\r
+ tmp = orientation;\r
+ \r
+\r
+ while(strncmp(tmp,"}",1)!=0)\r
+ {\r
+ if((strncmp(tmp,",",1)==0)||(strncmp(tmp,"{",1)==0))\r
+ {\r
+ \r
+ tmp++; \r
+ continue;\r
+ } \r
+ else if(strncmp(tmp,"-",1)==0)\r
+ {\r
+ pdata->orientation[i++]=-1;\r
+ DBG("i=%d,data=%d\n",i,pdata->orientation[i]);\r
+ tmp++;\r
+ } \r
+ else\r
+ {\r
+ pdata->orientation[i++]=tmp[0]-48; \r
+ DBG("----i=%d,data=%d\n",i,pdata->orientation[i]); \r
+ } \r
+ tmp++;\r
+ \r
+ \r
+ }\r
+\r
+ for(i=0;i<9;i++)\r
+ DBG("i=%d gsensor_info=%d\n",i,pdata->orientation[i]);\r
+ return 0;\r
+\r
+}\r
+\r
+static CLASS_ATTR(orientation, 0660, NULL, gsensor_set_orientation_online);\r
+\r
+static int gsensor_class_init(void)\r
+{\r
+ int ret ;\r
+ struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL]; \r
+ g_sensor_class[SENSOR_TYPE_ACCEL] = class_create(THIS_MODULE, "gsensor_class");\r
+ ret = class_create_file(g_sensor_class[SENSOR_TYPE_ACCEL], &class_attr_orientation);\r
+ if (ret)\r
+ {\r
+ printk("%s:Fail to creat class\n",__func__);\r
+ return ret;\r
+ }\r
+ printk("%s:%s\n",__func__,sensor->i2c_id->name);\r
+ return 0;\r
+}\r
+\r
+\r
\r
static int compass_dev_open(struct inode *inode, struct file *file)\r
{\r
\r
switch(cmd)\r
{\r
- case LIGHTSENSOR_IOCTL_GET_ENABLED:
+ case LIGHTSENSOR_IOCTL_GET_ENABLED:\r
*argp = sensor->status_cur;\r
- break;
+ break;\r
case LIGHTSENSOR_IOCTL_ENABLE: \r
DBG("%s:LIGHTSENSOR_IOCTL_ENABLE start\n", __func__);\r
mutex_lock(&sensor->operation_mutex); \r
printk("%s:fail to active sensor,ret=%d\n",__func__,result); \r
goto error; \r
} \r
- \r
- if(!sensor->pdata->irq_enable)\r
+ if(sensor->pdata->irq_enable)\r
+ {\r
+ if(!(sensor->ops->trig & IRQF_SHARED))\r
+ {\r
+ DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
+ enable_irq(client->irq); //enable irq\r
+ }\r
+ } \r
+ else\r
{\r
PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
}\r
+ \r
sensor->status_cur = SENSOR_ON;\r
} \r
}\r
goto error;\r
}\r
\r
- if(!sensor->pdata->irq_enable)\r
- cancel_delayed_work_sync(&sensor->delaywork); \r
+ if(sensor->pdata->irq_enable)\r
+ { \r
+ if(!(sensor->ops->trig & IRQF_SHARED))\r
+ {\r
+ DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
+ disable_irq_nosync(client->irq);//disable irq\r
+ }\r
+ }\r
+ else\r
+ cancel_delayed_work_sync(&sensor->delaywork); \r
+ \r
sensor->status_cur = SENSOR_OFF;\r
}\r
}\r
{\r
case PSENSOR_IOCTL_GET_ENABLED:\r
*argp = sensor->status_cur;\r
- break;
+ break;\r
case PSENSOR_IOCTL_ENABLE: \r
DBG("%s:PSENSOR_IOCTL_ENABLE start\n", __func__);\r
mutex_lock(&sensor->operation_mutex); \r
goto error; \r
}\r
\r
- if(!sensor->pdata->irq_enable)\r
+ if(sensor->pdata->irq_enable)\r
+ {\r
+ if(!(sensor->ops->trig & IRQF_SHARED))\r
+ {\r
+ DBG("%s:enable irq,irq=%d\n",__func__,client->irq);\r
+ enable_irq(client->irq); //enable irq\r
+ }\r
+ } \r
+ else\r
{\r
PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
}\r
+ \r
sensor->status_cur = SENSOR_ON;\r
} \r
}\r
mutex_unlock(&sensor->operation_mutex); \r
goto error;\r
}\r
- if(!sensor->pdata->irq_enable)\r
+ if(sensor->pdata->irq_enable)\r
+ { \r
+ if(!(sensor->ops->trig & IRQF_SHARED))\r
+ {\r
+ DBG("%s:disable irq,irq=%d\n",__func__,client->irq);\r
+ disable_irq_nosync(client->irq);//disable irq\r
+ }\r
+ }\r
+ else\r
cancel_delayed_work_sync(&sensor->delaywork); \r
sensor->status_cur = SENSOR_OFF;\r
}\r
struct sensor_operate *(*get_sensor_ops)(void))\r
{\r
int result = 0;\r
- sensor_ops[type] = get_sensor_ops();\r
- printk("%s:%s\n",__func__,sensor_ops[type]->name);\r
+ struct sensor_operate *ops = get_sensor_ops();\r
+ if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))\r
+ { \r
+ printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);\r
+ return -1; \r
+ }\r
+ sensor_ops[ops->id_i2c] = ops;\r
+ printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);\r
return result;\r
}\r
\r
struct sensor_operate *(*get_sensor_ops)(void))\r
{\r
int result = 0;\r
- printk("%s:%s\n",__func__,sensor_ops[type]->name);\r
- sensor_ops[type] = NULL; \r
+ struct sensor_operate *ops = get_sensor_ops();\r
+ if((ops->id_i2c >= SENSOR_NUM_ID) || (ops->id_i2c <= ID_INVALID))\r
+ { \r
+ printk("%s:%s id is error %d\n", __func__, ops->name, ops->id_i2c);\r
+ return -1; \r
+ }\r
+ printk("%s:%s,id=%d\n",__func__,sensor_ops[ops->id_i2c]->name, ops->id_i2c);\r
+ sensor_ops[ops->id_i2c] = NULL; \r
return result;\r
}\r
\r
result = -EFAULT;\r
goto out_no_free; \r
}\r
+\r
+ if(((int)devid->driver_data >= SENSOR_NUM_ID) || ((int)devid->driver_data <= ID_INVALID))\r
+ { \r
+ dev_err(&client->adapter->dev, "sensor id is error %d\n", (int)devid->driver_data);\r
+ result = -EFAULT;\r
+ goto out_no_free; \r
+ }\r
\r
i2c_set_clientdata(client, sensor);\r
sensor->client = client; \r
sensor->input_dev->name = "lightsensor-level";\r
set_bit(EV_ABS, sensor->input_dev->evbit);\r
input_set_abs_params(sensor->input_dev, ABS_MISC, sensor->ops->range[0], sensor->ops->range[1], 0, 0); \r
+ input_set_abs_params(sensor->input_dev, ABS_TOOL_WIDTH , sensor->ops->brightness[0],sensor->ops->brightness[1], 0, 0);\r
break;\r
case SENSOR_TYPE_PROXIMITY:\r
sensor->input_dev->name = "proximity"; \r
\r
}\r
sensor->input_dev->dev.parent = &client->dev;\r
-
+\r
result = input_register_device(sensor->input_dev);\r
if (result) {\r
dev_err(&client->dev,\r
\r
g_sensor[type] = sensor;\r
\r
+ if((type == SENSOR_TYPE_ACCEL) && (sensor->pdata->factory)) //only support setting gsensor orientation online now \r
+ {\r
+ result = gsensor_class_init();\r
+ if (result) {\r
+ dev_err(&client->dev,\r
+ "fail to register misc device %s\n", sensor->i2c_id->name);\r
+ goto out_misc_device_register_device_failed;\r
+ }\r
+ }\r
+ \r
#ifdef CONFIG_HAS_EARLYSUSPEND\r
if((sensor->ops->suspend) && (sensor->ops->resume))\r
{\r
}\r
#endif\r
\r
- printk("%s:initialized ok,sensor name:%s,type:%d\n",__func__,sensor->ops->name,type);\r
+ 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
\r
return result;\r
\r
\r
static void sensor_shut_down(struct i2c_client *client)\r
{\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
struct sensor_private_data *sensor =\r
(struct sensor_private_data *) i2c_get_clientdata(client);\r
if((sensor->ops->suspend) && (sensor->ops->resume)) \r
unregister_early_suspend(&sensor->early_suspend);\r
DBG("%s:%s\n",__func__,sensor->i2c_id->name);\r
+#endif\r
}\r
\r
static int sensor_remove(struct i2c_client *client)\r
kfree(sensor);\r
#ifdef CONFIG_HAS_EARLYSUSPEND\r
if((sensor->ops->suspend) && (sensor->ops->resume))\r
- unregister_early_suspend(&sensor->early_suspend);\r
+ unregister_early_suspend(&sensor->early_suspend);\r
#endif \r
return result;\r
}\r
{"gs_mma8452", ACCEL_ID_MMA845X}, \r
{"gs_kxtik", ACCEL_ID_KXTIK},\r
{"gs_lis3dh", ACCEL_ID_LIS3DH},\r
+ {"gs_mma7660", ACCEL_ID_MMA7660},\r
+ {"gs_mxc6225", ACCEL_ID_MXC6225},\r
/*compass*/\r
{"compass", COMPASS_ID_ALL},\r
{"ak8975", COMPASS_ID_AK8975},\r
{"k3g", GYRO_ID_K3G},\r
/*light sensor*/\r
{"lightsensor", LIGHT_ID_ALL}, \r
+ {"light_cm3217", LIGHT_ID_CM3217},\r
{"light_al3006", LIGHT_ID_AL3006},\r
{"ls_stk3171", LIGHT_ID_STK3171},\r
+ {"ls_isl29023", LIGHT_ID_ISL29023},\r
+ {"ls_ap321xx", LIGHT_ID_AP321XX},\r
+ {"ls_photoresistor", LIGHT_ID_PHOTORESISTOR},\r
/*proximity sensor*/\r
{"psensor", PROXIMITY_ID_ALL},\r
{"proximity_al3006", PROXIMITY_ID_AL3006}, \r
{"ps_stk3171", PROXIMITY_ID_STK3171},\r
+ {"ps_ap321xx", PROXIMITY_ID_AP321XX},\r
/*temperature*/\r
{"temperature", TEMPERATURE_ID_ALL},\r
{},\r
pr_info("%s: Probe name %s\n", __func__, sensor_driver.driver.name);\r
if (res)\r
pr_err("%s failed\n", __func__);\r
+ \r
+ printk("%s\n", SENSOR_VERSION_AND_TIME);\r
return res;\r
}\r
\r