static ssize_t batch_store_batch(struct device* dev, struct device_attribute *attr, const char *buf, size_t count) { int handle, flags, samplingPeriodNs, maxBatchReportLatencyNs; int res, delay; struct batch_context *cxt = NULL; cxt = batch_context_obj; BATCH_LOG("write value: buf = %s\n", buf); if((res = sscanf(buf, "%d,%d,%d,%d", &handle, &flags, &samplingPeriodNs, &maxBatchReportLatencyNs))!=4) { BATCH_ERR(" batch_store_delay param error: res = %d\n", res); } BATCH_LOG(" batch_store_delay param: handle %d, flag:%d samplingPeriodNs:%d, maxBatchReportLatencyNs: %d\n",handle, flags, samplingPeriodNs, maxBatchReportLatencyNs); if(flags & SENSORS_BATCH_DRY_RUN ) { if(cxt->dev_list.data_dev[handle].is_batch_supported != 0) { cxt->batch_result = 0; }else{ cxt->batch_result = -1; } }else if(flags & SENSORS_BATCH_WAKE_UPON_FIFO_FULL){ register_eint_unmask(); } if(maxBatchReportLatencyNs == 0){ cxt->active_sensor = cxt->active_sensor & (~(0x01 << handle));//every active_sensor bit stands for a sensor type, bit = 0 stands for batch disabled if(cxt->active_sensor == 0){ cxt->is_polling_run = false; del_timer_sync(&cxt->timer); cancel_work_sync(&cxt->report); }else{ cxt->dev_list.data_dev[handle].delay = 0; delay = batch_update_polling_rate(); atomic_set(&cxt->delay, delay); mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ)); cxt->is_polling_run = true; } }else if(maxBatchReportLatencyNs != 0){ cxt->active_sensor = cxt->active_sensor |(0x01 << handle); cxt->dev_list.data_dev[handle].delay = (int)maxBatchReportLatencyNs/1000/1000; delay = batch_update_polling_rate(); atomic_set(&cxt->delay, delay); mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ)); cxt->is_polling_run = true; } BATCH_ERR(" active_sensor param 0x%x\n", cxt->active_sensor); cxt->batch_result = 0; return count; }
static int __init batch_init(void) { BATCH_FUN(); if(platform_driver_register(&batch_driver)) { BATCH_ERR("failed to register batch driver\n"); return -ENODEV; } return 0; }
static int batch_misc_init(struct batch_context *cxt) { int err=0; cxt->mdev.minor = MISC_DYNAMIC_MINOR; cxt->mdev.name = BATCH_MISC_DEV_NAME; if((err = misc_register(&cxt->mdev))) { BATCH_ERR("unable to register batch misc device!!\n"); } return err; }
int batch_register_control_path(int handle, struct batch_control_path *ctl) { struct batch_context *cxt = NULL; cxt = batch_context_obj; if(ctl == NULL){ BATCH_ERR("ctl pointer is null!\n"); return -1; } if(handle >= 0 && handle <=(MAX_ANDROID_SENSOR_NUM)){ cxt ->dev_list.ctl_dev[handle].flush= ctl->flush; return 0; } return -1; }
int batch_register_support_info(int handle, int support) { struct batch_context *cxt = NULL; //int err =0; cxt = batch_context_obj; if(cxt == NULL){ BATCH_ERR("cxt pointer is null!\n"); return -1; } if(handle >= 0 && handle <=(MAX_ANDROID_SENSOR_NUM)){ cxt ->dev_list.data_dev[handle].is_batch_supported = support; return 0; } return -1; }
static int batch_remove(struct platform_device *pdev) { int err=0; BATCH_FUN(f); input_unregister_device(batch_context_obj->idev); sysfs_remove_group(&batch_context_obj->idev->dev.kobj, &batch_attribute_group); if((err = misc_deregister(&batch_context_obj->mdev))) { BATCH_ERR("misc_deregister fail: %d\n", err); } kfree(batch_context_obj); return 0; }
int batch_register_data_path(int handle, struct batch_data_path *data) { struct batch_context *cxt = NULL; //int err =0; cxt = batch_context_obj; if(data == NULL){ BATCH_ERR("data pointer is null!\n"); return -1; } if(handle >= 0 && handle <=(MAX_ANDROID_SENSOR_NUM)){ cxt ->dev_list.data_dev[handle].get_data = data->get_data; cxt ->dev_list.data_dev[handle].flags = data->flags; cxt ->dev_list.data_dev[handle].is_batch_supported = data->is_batch_supported; return 0; } return -1; }
static ssize_t batch_store_flush(struct device* dev, struct device_attribute *attr, const char *buf, size_t count) { struct batch_context *cxt = NULL; int handle; cxt = batch_context_obj; if (1 != sscanf(buf, "%d", &handle)) { BATCH_ERR("invalid format!!\n"); return count; } report_data_once(handle);//handle need to use of this function BATCH_LOG(" batch_store_delay sucess\n"); return count; }
static struct batch_context *batch_context_alloc_object(void) { struct batch_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL); BATCH_LOG("batch_context_alloc_object++++\n"); if(!obj) { BATCH_ERR("Alloc batch object error!\n"); return NULL; } atomic_set(&obj->delay, 200); /*5Hz*/// set work queue delay time 200ms atomic_set(&obj->wake, 0); INIT_WORK(&obj->report, batch_work_func); init_timer(&obj->timer); obj->timer.expires = jiffies + atomic_read(&obj->delay)/(1000/HZ); obj->timer.function = batch_poll; obj->timer.data = (unsigned long)obj; obj->is_first_data_after_enable = false; obj->is_polling_run = false; obj->active_sensor = 0; mutex_init(&obj->batch_op_mutex); BATCH_LOG("batch_context_alloc_object----\n"); return obj; }
static int batch_probe(struct platform_device *pdev) { int err; BATCH_LOG("+++++++++++++batch_probe!!\n"); batch_context_obj = batch_context_alloc_object(); if (!batch_context_obj) { err = -ENOMEM; BATCH_ERR("unable to allocate devobj!\n"); goto exit_alloc_data_failed; } //init input dev err = batch_input_init(batch_context_obj); if(err) { BATCH_ERR("unable to register batch input device!\n"); goto exit_alloc_input_dev_failed; } atomic_set(&(batch_context_obj->early_suspend), 0); batch_context_obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1, batch_context_obj->early_drv.suspend = batch_early_suspend, batch_context_obj->early_drv.resume = batch_late_resume, register_early_suspend(&batch_context_obj->early_drv); wake_lock_init(&(batch_context_obj->read_data_wake_lock),WAKE_LOCK_SUSPEND,"read_data_wake_lock"); //add misc dev for sensor hal control cmd err = batch_misc_init(batch_context_obj); if(err) { BATCH_ERR("unable to register batch misc device!!\n"); goto exit_err_sysfs; } err = sysfs_create_group(&batch_context_obj->mdev.this_device->kobj, &batch_attribute_group); if (err < 0) { BATCH_ERR("unable to create batch attribute file\n"); goto exit_misc_register_failed; } kobject_uevent(&batch_context_obj->mdev.this_device->kobj, KOBJ_ADD); BATCH_LOG("----batch_probe OK !!\n"); return 0; //exit_hwmsen_create_attr_failed: exit_misc_register_failed: if((err = misc_deregister(&batch_context_obj->mdev))) { BATCH_ERR("misc_deregister fail: %d\n", err); } exit_err_sysfs: if (err) { BATCH_ERR("sysfs node creation error \n"); batch_input_destroy(batch_context_obj); } exit_alloc_input_dev_failed: kfree(batch_context_obj); exit_alloc_data_failed: BATCH_LOG("----batch_probe fail !!!\n"); return err; }