add sensor version info
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / sensor-dev.c
index 3b20fcbb33ff36e610c6321888da4400c24fba52..db8438acb6372b5ec1887352800211cb64ae58ee 100755 (executable)
@@ -35,8 +35,6 @@
 #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
@@ -106,7 +109,7 @@ static int sensor_chip_init(struct i2c_client *client)
 {\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
@@ -120,9 +123,9 @@ static int sensor_chip_init(struct i2c_client *client)
                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
@@ -137,11 +140,11 @@ static int sensor_chip_init(struct i2c_client *client)
        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
@@ -300,7 +303,9 @@ static int sensor_irq_init(struct i2c_client *client)
                        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
@@ -317,7 +322,7 @@ error:
        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
@@ -336,6 +341,7 @@ static void sensor_resume(struct early_suspend *h)
        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
@@ -381,9 +387,9 @@ static long gsensor_dev_ioctl(struct file *file,
                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
@@ -399,8 +405,8 @@ static long gsensor_dev_ioctl(struct file *file,
                                }                       \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
@@ -413,7 +419,7 @@ static long gsensor_dev_ioctl(struct file *file,
                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
@@ -429,8 +435,8 @@ static long gsensor_dev_ioctl(struct file *file,
                                \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
@@ -442,27 +448,17 @@ static long gsensor_dev_ioctl(struct file *file,
                \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
                result = sensor_reset_rate(client, rate);\r
-               if (result < 0)\r
-               goto error;\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
+               if (result < 0){\r
+                       mutex_unlock(&sensor->operation_mutex);\r
+                       goto error;\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
@@ -475,9 +471,9 @@ static long gsensor_dev_ioctl(struct file *file,
        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
@@ -485,15 +481,82 @@ static long gsensor_dev_ioctl(struct file *file,
                                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
@@ -704,9 +767,9 @@ static long light_dev_ioctl(struct file *file,
 \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
@@ -719,12 +782,20 @@ static long light_dev_ioctl(struct file *file,
                                        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
@@ -737,8 +808,17 @@ static long light_dev_ioctl(struct file *file,
                                        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
@@ -789,7 +869,7 @@ static long proximity_dev_ioctl(struct file *file,
        {\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
@@ -803,11 +883,20 @@ static long proximity_dev_ioctl(struct file *file,
                                        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
@@ -819,7 +908,15 @@ static long proximity_dev_ioctl(struct file *file,
                                        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
@@ -1025,8 +1122,14 @@ int sensor_register_slave(int type,struct i2c_client *client,
                        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
@@ -1036,8 +1139,14 @@ int sensor_unregister_slave(int type,struct i2c_client *client,
                        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
@@ -1078,6 +1187,13 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
                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
@@ -1171,6 +1287,7 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
                        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
@@ -1188,7 +1305,7 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
 \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
@@ -1214,6 +1331,16 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
        \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
@@ -1224,7 +1351,7 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
        }\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
@@ -1242,11 +1369,13 @@ out_no_free:
 \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
@@ -1262,7 +1391,7 @@ static int sensor_remove(struct i2c_client *client)
        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
@@ -1273,6 +1402,8 @@ static const struct i2c_device_id sensor_id[] = {
        {"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
@@ -1283,12 +1414,17 @@ static const struct i2c_device_id sensor_id[] = {
        {"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
@@ -1312,6 +1448,8 @@ static int __init sensor_init(void)
        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