android sensors 总结(三)

来源:互联网 发布:知定静安虑得七境解读 编辑:程序博客网 时间:2024/05/21 07:46

3 sensor driver

 

相关结构体

//Sensor device 抽象

struct hwmdev_object {

         structinput_dev   *idev;

         structmiscdevice   mdev;

         structdev_context *dc;

         structwork_struct  report;

         atomic_t            delay; /*polling period for reportinginput event*/

         atomic_t            wake;  /*user-space request to wake-up, used withstop*/

         structtimer_list   timer;  /* polling timer */

         atomic_t            trace;

         uint32_t                     active_sensor;                            // Active, buthwmsen don't need data sensor.                                                                                         //Maybeother need it's data.

         uint32_t                     active_data_sensor;                 // Active and hwmsen need datasensor.

         //addfor fix resume issue

         structearly_suspend    early_drv;

         structwake_lock        read_data_wake_lock;

         atomic_t                early_suspend;

         //addfor fix resume end

};

 

struct dev_context {

   int              polling_running;

   struct mutex lock;

   struct hwmsen_context* cxt[MAX_ANDROID_SENSOR_NUM+1];

};

 

struct hwmsen_context { /*sensor context*/

         atomic_t                enable;

         atomic_tdelay;

         uint32_tdelayCountSet;

         uint32_tdelayCount;

        

         structhwmsen_object    obj;

};

 

/*------------sensorsdata----------------------------------------------------*/

typedef struct {

         /*sensor identifier */

         int  sensor;

         /*sensor values */

         int    values[3];

         /*sensor values divide */

         uint32_tvalue_divide;

         /*sensor accuracy*/

         int8_tstatus;

         /*whether updata? */

         int    update;

         /*time is in nanosecond */

         int64_t     time;

 

         uint32_t   reserved;

}hwm_sensor_data;

 

typedef struct {

         hwm_sensor_datadata[MAX_ANDROID_SENSOR_NUM];

         intdate_type;

}hwm_trans_data;

 

 

static int hwmsen_probe(structplatform_device *pdev)

{

 

         interr;

         //HWM_LOG("+++++++++++++++++hwmsen_probe!!\n");

 

         HWM_FUN(f);

         init_static_data();  

         hwm_obj= hwmsen_alloc_object();        //alloc& init hwmsensor obj

         if(!hwm_obj)

         {

                   err= -ENOMEM;

                   HWM_ERR("unableto allocate devobj!\n");

                   gotoexit_alloc_data_failed;

         }

 

         hwm_obj->idev= input_allocate_device();      //alloc inputdevice

         if(!hwm_obj->idev)

         {

                   err= -ENOMEM;

                   HWM_ERR("unableto allocate input device!\n");

                   gotoexit_alloc_input_dev_failed;

         }

 

         set_bit(EV_REL,hwm_obj->idev->evbit);

         set_bit(EV_SYN,hwm_obj->idev->evbit);

 

         input_set_capability(hwm_obj->idev,EV_REL, EVENT_TYPE_SENSOR);         ///setevent type

         hwm_obj->idev->name= HWM_INPUTDEV_NAME;

         if((err= input_register_device(hwm_obj->idev)))                      ///

         {

                   HWM_ERR("unableto register input device!\n");

                   gotoexit_input_register_device_failed;

         }

         input_set_drvdata(hwm_obj->idev,hwm_obj);

 

         hwm_obj->mdev.minor= MISC_DYNAMIC_MINOR;

         hwm_obj->mdev.name  = HWM_SENSOR_DEV_NAME;

         hwm_obj->mdev.fops  = &hwmsen_fops;

         if((err= misc_register(&hwm_obj->mdev)))                      //注册为一个杂项设备,提供ops

         {

                   HWM_ERR("unableto register sensor device!!\n");

                   gotoexit_misc_register_failed;

         }

         dev_set_drvdata(hwm_obj->mdev.this_device,hwm_obj);

 

         //add for fix resume bug

   atomic_set(&(hwm_obj->early_suspend), 0);

         hwm_obj->early_drv.level    = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1,

         hwm_obj->early_drv.suspend  = hwmsen_early_suspend,

         hwm_obj->early_drv.resume   = hwmsen_late_resume,   

         register_early_suspend(&hwm_obj->early_drv);

         wake_lock_init(&(hwm_obj->read_data_wake_lock),WAKE_LOCK_SUSPEND,"read_data_wake_lock");

         //add for fix resume bug end

         return0;

 

         exit_hwmsen_create_attr_failed:

         exit_misc_register_failed:   

//      exit_get_hwmsen_info_failed:

         exit_input_register_device_failed:

         input_free_device(hwm_obj->idev);

        

         exit_alloc_input_dev_failed:   

         kfree(hwm_obj);

        

         exit_alloc_data_failed:

         returnerr;

}

 

static void hwmsen_poll(unsigned long data)

{

         structhwmdev_object *obj = (struct hwmdev_object *)data;

         if(obj!= NULL)

         {

                   queue_work(sensor_workqueue,&obj->report);

         }

}

 

static struct hwmdev_object*hwmsen_alloc_object(void)

{

        

         structhwmdev_object *obj = kzalloc(sizeof(*obj), GFP_KERNEL);

         HWM_FUN(f);

        

         if(!obj)

         {

                   HWM_ERR("Allochwmsen object error!\n");

                   returnNULL;

         }       

 

         obj->dc= &dev_cxt;

         obj->active_data_sensor= 0;

         obj->active_sensor= 0;

         atomic_set(&obj->delay,200); /*5Hz*/// set work queue delay time 200ms

         atomic_set(&obj->wake,0);

         sensor_workqueue= create_singlethread_workqueue("sensor_polling");

         INIT_WORK(&obj->report,hwmsen_work_func);

         init_timer(&obj->timer);

         obj->timer.expires   = jiffies + atomic_read(&obj->delay)/(1000/HZ);

         obj->timer.function = hwmsen_poll;

         obj->timer.data                 = (unsigned long)obj;

         returnobj;

}

 

 

////ioctrl 分析,只要提供ioctrl cmd给sensor hal

static long hwmsen_unlocked_ioctl(structfile *fp, unsigned int cmd, unsigned long arg)

{

         //HWM_LOG("IOparament %d!\r\n", cmd);

         void__user *argp = (void __user*)arg;

         uint32_tflag;

         structsensor_delay delayPara;

         hwm_trans_datahwm_sensors_data; 

         inti = 0;

         atomic_tdelaytemp;

         atomic_set(&delaytemp,200);//used to finding fastest sensor polling rate

         //intdelaytemp=200;//used to finding fastest sensor polling rate

 

         if(!hwm_obj)

         {

                   HWM_ERR("nullpointer!!\n");

                   return-EINVAL;

         }

 

         switch(cmd)

         {

                   caseHWM_IO_SET_DELAY:

                             // android2.3 sensor system has 4 sample delay0ms 20ms 60ms 200ms

                            if(copy_from_user(&delayPara,argp, sizeof(delayPara)))

                            {

                                     HWM_ERR("copy_from_userfail!!\n");

                                     return-EFAULT;

                            }

                            HWM_LOG("ioctldelay handle=%d,delay =%d\n",delayPara.handle,delayPara.delay);

                            hwmsen_set_delay(delayPara.delay,delayPara.handle);//modifiedfor android2.3

                            update_workqueue_polling_rate(delayPara.delay);

               

                break;

 

                   caseHWM_IO_SET_WAKE:

                            hwmsen_wakeup(hwm_obj);

                            break;

 

                   caseHWM_IO_ENABLE_SENSOR:                     //打开相应的sensor,并poll sensor数据

                            if(copy_from_user(&flag,argp, sizeof(flag)))

                            {

                                     HWM_ERR("copy_from_userfail!!\n");

                                     return-EFAULT;

                            }

                            hwmsen_enable(hwm_obj,flag, 1);

                            break;

 

                   caseHWM_IO_DISABLE_SENSOR:         //关闭相应的sensor,flag 为sensor type

                            if(copy_from_user(&flag,argp, sizeof(flag)))

                            {

                                     HWM_ERR("copy_from_userfail!!\n");

                                     return-EFAULT;

                            }

                            hwmsen_enable(hwm_obj,flag, 0);

                            break;

 

                   caseHWM_IO_GET_SENSORS_DATA:    //获取sensorsdata                 

                            if(copy_from_user(&hwm_sensors_data,argp, sizeof(hwm_sensors_data)))

                            {

                                     HWM_ERR("copy_from_userfail!!\n");

                                     return-EFAULT;

                            }

                            mutex_lock(&obj_data.lock);                   

                            memcpy(hwm_sensors_data.data,&(obj_data.sensors_data),sizeof(hwm_sensor_data) * MAX_ANDROID_SENSOR_NUM);

                            for(i= 0; i < MAX_ANDROID_SENSOR_NUM; i++)

                            {

                                     if(hwm_sensors_data.date_type& 1<<i)

                                     {                                            

                                               hwm_sensors_data.data[i].update= 1;

                                     }

                                     else

                                     {

                                               hwm_sensors_data.data[i].update= 0;

                                     }

                            }

                            mutex_unlock(&obj_data.lock);

                            if(copy_to_user(argp,&hwm_sensors_data, sizeof(hwm_sensors_data)))

                            {

                                     HWM_ERR("copy_to_userfail!!\n");

                                     return-EFAULT;

                            }

                            break;

                  

                   caseHWM_IO_ENABLE_SENSOR_NODATA:  //仅仅打开sensor

                            if(copy_from_user(&flag,argp, sizeof(flag)))

                            {

                                     HWM_ERR("copy_from_userfail!!\n");

                                     return -EFAULT;

                            }

                            hwmsen_enable_nodata(hwm_obj,flag, 1);

                            break;

 

                   caseHWM_IO_DISABLE_SENSOR_NODATA:

                            if(copy_from_user(&flag,argp, sizeof(flag)))

                            {

                                     HWM_ERR("copy_from_userfail!!\n");

                                     return-EFAULT;

                            }

                            hwmsen_enable_nodata(hwm_obj,flag, 0);

                            break;

                           

                   default:

                            HWM_ERR("haveno this paramenter %d!!\n", cmd);

                            return-ENOIOCTLCMD;

         }

 

         return0;       

}

 

static int hwmsen_enable(structhwmdev_object *obj, int sensor, int enable)

{

         structhwmsen_context *cxt = NULL;

         interr = 0;

         uint32_tsensor_type;

 

         sensor_type= 1 << sensor;

        

         if(!obj)

         {

                   HWM_ERR("hwmdevobj pointer is NULL!\n");

                   return-EINVAL;

         }

         elseif(obj->dc->cxt[sensor] == NULL)

         {

                   HWM_ERR("thesensor (%d) is not attached!!\n", sensor);

                   return-ENODEV;

         }

        

 

         mutex_lock(&obj->dc->lock);

         cxt= obj->dc->cxt[sensor];   

        

        

         if(enable== 1)

         {

                   enable_again= true;

                   obj->active_data_sensor|= sensor_type;

                   if((obj->active_sensor& sensor_type) == 0)   // no no-data active

                   {                

                            if(cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE,&enable,sizeof(int), NULL, 0, NULL) != 0) //通过sensor type,打开特定sensor(accelerometor、proximity etc)

                            {

                                     if(cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable,sizeof(int),NULL, 0, NULL) != 0)

                                     {

                                               if(cxt->obj.sensor_operate(cxt->obj.self, SENSOR_ENABLE,&enable,sizeof(int), NULL, 0, NULL) != 0)

                                               {

                                                        HWM_ERR("activatesensor(%d) 3 times err = %d\n", sensor, err);

                                                        err= -EINVAL;

                                                        gotoexit;

                                               }

                                     }

                                    

                            }

 

                            atomic_set(&cxt->enable,1);                  

                   }

 

                   //Need to complete the interrupt sensor work

                   if((0== obj->dc->polling_running) && (obj->active_data_sensor !=0))

                   {

                            obj->dc->polling_running= 1;

                            //obj->timer.expires= jiffies + atomic_read(&obj->delay)/(1000/HZ);

                            //add_timer(&obj->timer);

                            mod_timer(&obj->timer,jiffies + atomic_read(&obj->delay)/(1000/HZ)); //启动poll timer

                           

                   }

                  

         }

         else

         {

                   obj->active_data_sensor&= ~sensor_type;

                   if((obj->active_sensor& sensor_type) == 0)   // no no-dataactive

                   {

                            if(cxt->obj.sensor_operate(cxt->obj.self,SENSOR_ENABLE, &enable,sizeof(int), NULL, 0, NULL) != 0)

                            {

                                     HWM_ERR("deactivasensor(%d) err = %d\n", sensor, err);

                                     err= -EINVAL;

                                     gotoexit;

                            }

 

                            atomic_set(&cxt->enable, 0);

                            update_workqueue_polling_rate(200);//re-update workqueue polling rate

                   }                

                                

                   if((1== obj->dc->polling_running) && (obj->active_data_sensor ==0))

                   {

                            obj->dc->polling_running= 0;

                            del_timer_sync(&obj->timer);

                            cancel_work_sync(&obj->report);

                           

                   }

 

                   obj_data.sensors_data[sensor].values[0]= SENSOR_INVALID_VALUE;

                   obj_data.sensors_data[sensor].values[1]= SENSOR_INVALID_VALUE;

                   obj_data.sensors_data[sensor].values[2]= SENSOR_INVALID_VALUE;

                  

         }       

           

         HWM_LOG("sensor(%d),flag(%d)\n", sensor, enable);

 

         exit:

                  

         mutex_unlock(&obj->dc->lock);

         returnerr;

}

 

hwmsen_enable 打开特定sensor后,启动polltimer,timer 时间到会调用hwmsen_poll 启动sensor_workqueue ,继而进入hwmsen_work_func 获取sensor data,并上报sensor type input 时间:

static void hwmsen_work_func(structwork_struct *work)

{

         //structhwmdev_object *obj = container_of(work, struct hwmdev_object, report);

         structhwmdev_object *obj = hwm_obj;

         structhwmsen_context *cxt = NULL;

         intout_size;

         hwm_sensor_datasensor_data;

         uint32_tevent_type = 0;

         int64_t  nt;

         structtimespec time;

         interr, idx;       

         //inttrc = atomic_read(&obj->trace);

        

         if(obj == NULL)

         {

                   HWM_ERR("objpoint is NULL!\n");

                   return;

         }

                 

 

         if(atomic_read(&obj->wake))

         {

                   input_event(obj->idev,EV_SYN, SYN_CONFIG, 0);

                   atomic_set(&obj->wake,0);            

                   return;

         }

        

         memset(&sensor_data,0, sizeof(sensor_data)); 

         time.tv_sec= time.tv_nsec = 0;   

         time= get_monotonic_coarse();

         nt= time.tv_sec*1000000000LL+time.tv_nsec;

         //mutex_lock(&obj_data.lock);

         for(idx= 0; idx < MAX_ANDROID_SENSOR_NUM; idx++)

         {

                   cxt= obj->dc->cxt[idx];

                   if((cxt== NULL) || (cxt->obj.sensor_operate == NULL)

                            ||!(obj->active_data_sensor&(0x01<<idx)))

                   {

                            continue;

                   }

                   //Interrupt sensor

                   if(cxt->obj.polling== 0)

                   {

                            if(obj_data.data_updata[idx]== 1)

                            {

                                     mutex_lock(&obj_data.lock);

                                     event_type|= (1 << idx);

                                     obj_data.data_updata[idx]= 0;

                                     mutex_unlock(&obj_data.lock);

                            }

                            continue;

                   }

                  

                  

                   //addedto surpport set delay to specified sensor

                   if(cxt->delayCount> 0)

                   {

                     //HWM_LOG("sensor(%d) delayCount =%d\n",idx,cxt->delayCount);

                     cxt->delayCount--;

                     if(0 == cxt->delayCount)

                     {

                       cxt->delayCount = cxt->delayCountSet;

                            //HWM_LOG("sensor(%d)go to get data\n",idx);

                     }

                     else

                     {

                       //HWM_LOG("sensor(%d) wait for nextwork\n",idx);

                       continue;

                     }

                   }

                  

                   err= cxt->obj.sensor_operate(cxt->obj.self,SENSOR_GET_DATA, NULL, 0,

                            &sensor_data,sizeof(hwm_sensor_data), &out_size);

                  

                   if(err)

                   {

                            HWM_ERR("getdata from sensor (%d) fails!!\n", idx);

                            continue;

                   }

                   else

                   {

                            if((idx== ID_LIGHT) ||(idx == ID_PRESSURE)

                            ||(idx== ID_PROXIMITY) || (idx == ID_TEMPRERATURE))

                            {

                                     //data changed, update the data

                                     if(sensor_data.values[0]!= obj_data.sensors_data[idx].values[0])

                                     {

                                               mutex_lock(&obj_data.lock);

                                               obj_data.sensors_data[idx].values[0]= sensor_data.values[0];

                                               obj_data.sensors_data[idx].value_divide= sensor_data.value_divide;

                                               obj_data.sensors_data[idx].status= sensor_data.status;

                                               obj_data.sensors_data[idx].time= nt;

                                               event_type|= (1 << idx);

                                               mutex_unlock(&obj_data.lock);

                                               //HWM_LOG("get%d sensor, values: %d!\n", idx, sensor_data.values[0]);

                                     }

                            }

                            Else

                            {

                                     //data changed, update the data

                                     if((sensor_data.values[0]!= obj_data.sensors_data[idx].values[0])

                                               ||(sensor_data.values[1] != obj_data.sensors_data[idx].values[1])

                                               ||(sensor_data.values[2] != obj_data.sensors_data[idx].values[2]))

                                     {       

                                         if( 0 == sensor_data.values[0] &&0==sensor_data.values[1]

                                                        &&0 == sensor_data.values[2])

                                         {

                                                 

                                            continue;

                                         }

                                               mutex_lock(&obj_data.lock);

                                               obj_data.sensors_data[idx].values[0]= sensor_data.values[0];

                                               obj_data.sensors_data[idx].values[1]= sensor_data.values[1];

                                               obj_data.sensors_data[idx].values[2]= sensor_data.values[2];

                                               obj_data.sensors_data[idx].value_divide= sensor_data.value_divide;

                                               obj_data.sensors_data[idx].status= sensor_data.status;

                                               obj_data.sensors_data[idx].time= nt;

                                               event_type|= (1 << idx);

                                               mutex_unlock(&obj_data.lock);

                                               //HWM_LOG("get%d sensor, values: %d, %d, %d!\n", idx,

                                                        //sensor_data.values[0],sensor_data.values[1], sensor_data.values[2]);

                                     }

                            }

                   }                          

         }

         if(enable_again== true)

         {

                   event_type= obj->active_data_sensor;

                   enable_again= false;

                   //filter-1 value

                   for(idx= 0; idx <= MAX_ANDROID_SENSOR_NUM; idx++)

             {

                if(ID_ACCELEROMETER==idx || ID_MAGNETIC==idx|| ID_ORIENTATION==idx

                          ||ID_GYROSCOPE==idx || ID_TEMPRERATURE==idx

                          ||ID_LINEAR_ACCELERATION==idx ||ID_ROTATION_VECTOR==idx

                          ||ID_GRAVITY==idx)

                {

                   if(SENSOR_INVALID_VALUE ==obj_data.sensors_data[idx].values[0] ||

                             SENSOR_INVALID_VALUE ==obj_data.sensors_data[idx].values[1] ||

                             SENSOR_INVALID_VALUE ==obj_data.sensors_data[idx].values[2])

                    {

                       event_type &= ~(1 << idx);

                                 //HWM_LOG("idx=%d,obj->active_sensorafter clear: %d\n",idx);

                    }

                }

 

                      if(ID_PROXIMITY==idx || ID_LIGHT==idx ||ID_PRESSURE==idx)

                {

                   if(SENSOR_INVALID_VALUE ==obj_data.sensors_data[idx].values[0])

                   {

                     event_type &= ~(1 << idx);

                               //HWM_LOG("idx=%d,obj->active_sensorafter clear: %d\n",idx);

                   }

                }

             }

                   //HWM_LOG("eventtype after enable: %d\n", event_type);

         }

        

         if((event_type&(1<< ID_PROXIMITY))&& SENSOR_INVALID_VALUE ==obj_data.sensors_data[ID_PROXIMITY].values[0])

         {

             event_type &= ~(1 <<ID_PROXIMITY);  

                   //HWM_LOG("removeps event!!!!!!!!!!!\n");

         }

        

         if(event_type!= 0)

         {                

                   input_report_rel(obj->idev,EVENT_TYPE_SENSOR, event_type);

                   input_sync(obj->idev);//modified

                   //HWM_LOG("eventtype: %d\n", event_type);

         }

         else

         {

                   //HWM_LOG("noavailable sensor!!\n");

         }

 

         if(obj->dc->polling_running== 1)

         {

                   mod_timer(&obj->timer,jiffies + atomic_read(&obj->delay)/(1000/HZ));

         }

}

 

 

下面介绍几个hwmsen driver提供给特定physical sensor driver的接口:

 

/*Sensor device driver attach to hwmsendevice------------------------------------------------*/

int hwmsen_attach(int sensor, structhwmsen_object *obj)

{

        

         structdev_context *mcxt = &dev_cxt;

         interr = 0;

         HWM_FUN(f);

         if((mcxt== NULL) || (sensor > MAX_ANDROID_SENSOR_NUM))

         {

                   err= -EINVAL;

                   gotoerr_exit;

         }

        

         mutex_lock(&mcxt->lock);

         if(mcxt->cxt[sensor]!= NULL)

         {

                   err= -EEXIST;

                   gotoerr_exit;

         }

         else

    {       

                   mcxt->cxt[sensor]= kzalloc(sizeof(struct hwmsen_context), GFP_KERNEL);

                   if(mcxt->cxt[sensor]== NULL)

                   {

                            err= -EPERM;

                            gotoerr_exit;

                   }                                   

                   atomic_set(&mcxt->cxt[sensor]->enable,0);

                   memcpy(&mcxt->cxt[sensor]->obj,obj, sizeof(*obj));

        

             // add for android2.3 set  sensors default polling delay time is 200ms

            atomic_set(&mcxt->cxt[sensor]->delay, 200);

          

         }

 

         err_exit:

         mutex_unlock(&mcxt->lock); 

         returnerr;

}

 

int hwmsen_detach(int sensor)

{

        

         interr = 0;

         structdev_context *mcxt = &dev_cxt;

         HWM_FUN(f);

         if((sensor > MAX_ANDROID_SENSOR_NUM) || (mcxt->cxt[sensor] == NULL))

         {

                   err= -EINVAL;

                   gotoerr_exit;

         }

 

         mutex_lock(&mcxt->lock);

         kfree(mcxt->cxt[sensor]);

         mcxt->cxt[sensor]= NULL;

 

         err_exit:

         mutex_unlock(&mcxt->lock);

         return0;

}

 

//中断模式,获取sensors data接口

int hwmsen_get_interrupt_data(int sensor,hwm_sensor_data *data)

{

         //HWM_LOG("++++++++++++++++++++++++++++hwmsen_get_interrupt_datafunction sensor = %d\n",sensor);

         structdev_context *mcxt = &dev_cxt;

         structhwmdev_object *obj = hwm_obj;

         int64_t  nt;

         structtimespec time;

 

         if((sensor> MAX_ANDROID_SENSOR_NUM) || (mcxt->cxt[sensor] == NULL)

                   ||(mcxt->cxt[sensor]->obj.polling != 0))

         {

                   HWM_ERR("sensor%d!\n", sensor);

                   return-EINVAL;

         }

         else

         {                

                   time.tv_sec= time.tv_nsec = 0;   

                   time= get_monotonic_coarse();

                   nt= time.tv_sec*1000000000LL+time.tv_nsec; 

                   if((sensor== ID_LIGHT) ||(sensor == ID_PRESSURE)

                            ||(sensor== ID_PROXIMITY) || (sensor == ID_TEMPRERATURE))

                   {

                            //data changed, update the data

                            if(data->values[0]!= obj_data.sensors_data[sensor].values[0])

                            {

                                     mutex_lock(&obj_data.lock);

                                     obj_data.data_updata[sensor]= 1;

                                     obj_data.sensors_data[sensor].values[0]= data->values[0];

                                     obj_data.sensors_data[sensor].time= nt;

                                     obj_data.sensors_data[sensor].value_divide= data->value_divide;

                                     mutex_unlock(&obj_data.lock);

                            }

                   }

                   else

                   {

                            //data changed, update the data

                            if((data->values[0]!= obj_data.sensors_data[sensor].values[0])

                                     ||(data->values[1] != obj_data.sensors_data[sensor].values[1])

                                     ||(data->values[2] != obj_data.sensors_data[sensor].values[2]))

                            {

                                     mutex_lock(&obj_data.lock);

                                     obj_data.sensors_data[sensor].values[0]= data->values[0];

                                     obj_data.sensors_data[sensor].values[1]= data->values[1];

                                     obj_data.sensors_data[sensor].values[2]= data->values[2];

                                     obj_data.sensors_data[sensor].value_divide= data->value_divide;

                                     obj_data.data_updata[sensor]= 1;

                                     obj_data.sensors_data[sensor].time= nt;

                                     mutex_unlock(&obj_data.lock);

                            }

                   }

 

                   if(obj->dc->polling_running== 1)

                   {

                            hwmsen_work_func(NULL);

                   }

                  

                   return0;

         }

}

0 0