| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666 |
- /*
- * Copyright(C)2014 MediaTek Inc.
- * Modification based on code covered by the below mentioned copyright
- * and/or permission notice(S).
- */
- #include <linux/interrupt.h>
- #include <linux/miscdevice.h>
- #include <linux/platform_device.h>
- #include <linux/uaccess.h>
- #include <linux/delay.h>
- #include <linux/input.h>
- #include <linux/workqueue.h>
- #include <linux/wait.h>
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <hwmsensor.h>
- #include <hwmsen_helper.h>
- #include <hwmsen_dev.h>
- /* add for fix resume issue */
- #ifdef CONFIG_PM_WAKELOCKS
- #include <linux/pm_wakeup.h>
- #else
- #include <linux/wakelock.h>
- #endif
- /* add for fix resume issue end */
- #include <cust_alsps.h>
- #include <aal_control.h>
- #define SENSOR_INVALID_VALUE -1
- #define MAX_CHOOSE_G_NUM 5
- #define MAX_CHOOSE_M_NUM 5
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- static void hwmsen_early_suspend(struct early_suspend *h);
- static void hwmsen_late_resume(struct early_suspend *h);
- #endif
- static void update_workqueue_polling_rate(int newDelay);
- struct workqueue_struct *sensor_workqueue = NULL;
- /******************************************************************************
- * structure / enumeration / macro / definition
- *****************************************************************************/
- struct sensor_delay {
- int handle;
- uint32_t delay;
- };
- struct hwmsen_context { /*sensor context */
- atomic_t enable;
- atomic_t delay;
- uint32_t delayCountSet;
- uint32_t delayCount;
- struct hwmsen_object obj;
- };
- #if defined(CONFIG_MTK_AUTO_DETECT_ACCELEROMETER)
- static char gsensor_name[25];
- static struct sensor_init_info *gsensor_init_list[MAX_CHOOSE_G_NUM] = { 0 }; /*modified*/
- #endif
- #if defined(CONFIG_MTK_AUTO_DETECT_MAGNETOMETER)
- static char msensor_name[25];
- static struct sensor_init_info *msensor_init_list[MAX_CHOOSE_G_NUM] = { 0 }; /*modified*/
- #endif
- #if defined(CONFIG_MTK_AUTO_DETECT_ALSPS)
- static char alsps_name[25];
- static struct sensor_init_info *alsps_init_list[MAX_CHOOSE_G_NUM] = { 0 }; /*modified*/
- #endif
- /*----------------------------------------------------------------------------*/
- struct dev_context {
- int polling_running;
- struct mutex lock;
- struct hwmsen_context *cxt[MAX_ANDROID_SENSOR_NUM + 1];
- };
- /*-------------Sensor daa-----------------------------------------------------*/
- struct hwmsen_data {
- struct hwm_sensor_data sensors_data[MAX_ANDROID_SENSOR_NUM + 1];
- int data_updata[MAX_ANDROID_SENSOR_NUM + 1];
- struct mutex lock;
- };
- /*----------------------------------------------------------------------------*/
- enum HWM_TRC {
- HWM_TRC_REPORT_NUM = 0x0001,
- HWM_TRC_REPORT_EVT = 0x0002,
- HWM_TRC_REPORT_INF = 0X0004,
- };
- /*----------------------------------------------------------------------------*/
- #define C_MAX_OBJECT_NUM 1
- struct hwmdev_object {
- struct input_dev *idev;
- struct miscdevice mdev;
- struct dev_context *dc;
- struct work_struct report;
- atomic_t delay; /*polling period for reporting input event */
- atomic_t wake; /*user-space request to wake-up, used with stop */
- struct hrtimer hrTimer;
- ktime_t target_ktime;
- atomic_t trace;
- struct workqueue_struct *hwmsen_workqueue;
- uint64_t active_sensor; /* Active, but hwmsen don't need data sensor. Maybe other need it's data.*/
- uint64_t active_data_sensor; /* Active and hwmsen need data sensor.*/
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- /* add for fix resume issue */
- struct early_suspend early_drv;
- #ifdef CONFIG_PM_WAKELOCKS
- struct wakeup_source read_data_wake_lock;
- #else
- struct wake_lock read_data_wake_lock;
- #endif
- atomic_t early_suspend;
- /* add for fix resume end */
- #endif /*#if defined(CONFIG_HAS_EARLYSUSPEND)*/
- };
- static bool enable_again;
- static struct hwmdev_object *hwm_obj;
- /******************************************************************************
- * static variables
- *****************************************************************************/
- static struct hwmsen_data obj_data = {
- .lock = __MUTEX_INITIALIZER(obj_data.lock),
- };
- static struct dev_context dev_cxt = {
- .lock = __MUTEX_INITIALIZER(dev_cxt.lock),
- };
- /*----------------------------------------------------------------------------*/
- static void initTimer(struct hrtimer *timer, enum hrtimer_restart (*callback)(struct hrtimer *))
- {
- hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
- timer->function = callback;
- }
- static void startTimer(struct hrtimer *timer, int delay_ms, bool first)
- {
- struct hwmdev_object *obj = (struct hwmdev_object *)container_of(timer, struct hwmdev_object, hrTimer);
- if (obj == NULL) {
- HWM_ERR("NULL pointer\n");
- return;
- }
- if (first)
- obj->target_ktime = ktime_add_ns(ktime_get(), (int64_t)delay_ms*1000000);
- else
- obj->target_ktime = ktime_add_ns(obj->target_ktime, (int64_t)delay_ms*1000000);
- hrtimer_start(timer, obj->target_ktime, HRTIMER_MODE_ABS);
- }
- static void stopTimer(struct hrtimer *timer)
- {
- hrtimer_cancel(timer);
- }
- /* AAL functions********************************************************************** */
- int hwmsen_aal_enable(int en)
- {
- struct hwmsen_context *cxt = NULL;
- int err = 0;
- if (!hwm_obj) {
- HWM_ERR("AAL hwmdev obj pointer is NULL!\n");
- return -EINVAL;
- } else if ((hwm_obj->dc->cxt[ID_LIGHT]) == NULL) {
- HWM_ERR("the sensor (%d) is not attached!!\n", ID_LIGHT);
- return -ENODEV;
- }
- mutex_lock(&hwm_obj->dc->lock);
- cxt = hwm_obj->dc->cxt[ID_LIGHT];
- if (en == 1) {
- if ((hwm_obj->active_data_sensor & (1LL << ID_LIGHT)) == 0) {
- HWM_LOG("enable sensor(%d) by AAL operation\n", ID_LIGHT);
- if (cxt->obj.
- sensor_operate(cxt->obj.self, SENSOR_ENABLE, &en, sizeof(int), NULL, 0,
- NULL) != 0) {
- HWM_ERR("enable sensor(%d) err = %d\n", ID_LIGHT, err);
- err = -EINVAL;
- }
- }
- } else {
- if ((hwm_obj->active_data_sensor & (1LL << ID_LIGHT)) == 0) {
- HWM_LOG("disable sensor(%d) by AAL operation\n", ID_LIGHT);
- if (cxt->obj.
- sensor_operate(cxt->obj.self, SENSOR_ENABLE, &en, sizeof(int), NULL, 0,
- NULL) != 0) {
- HWM_ERR("disable sensor(%d) err = %d\n", ID_LIGHT, err);
- err = -EINVAL;
- }
- }
- }
- mutex_unlock(&hwm_obj->dc->lock);
- return err;
- }
- int hwmsen_aal_get_data(void)
- {
- struct hwmsen_context *cxt = NULL;
- int err = 0;
- int out_size;
- struct hwm_sensor_data sensor_data;
- int als_data = 0;
- HWM_LOG("hwmsen_aal_get_data1\n");
- if (!hwm_obj) {
- HWM_ERR("AAL hwmdev obj pointer is NULL!\n");
- return -EINVAL;
- } else if ((hwm_obj->dc->cxt[ID_LIGHT]) == NULL) {
- HWM_ERR("the sensor (%d) is not attached!!\n", ID_LIGHT);
- return -ENODEV;
- }
- mutex_lock(&hwm_obj->dc->lock);
- cxt = hwm_obj->dc->cxt[ID_LIGHT];
- HWM_LOG("hwmsen_aal_get_data2\n");
- err = cxt->obj.sensor_operate(cxt->obj.self, SENSOR_GET_DATA, NULL, 0,
- &sensor_data, sizeof(struct hwm_sensor_data), &out_size);
- if (err) {
- mutex_unlock(&hwm_obj->dc->lock);
- HWM_ERR("get data from sensor (%d) fails!!\n", ID_LIGHT);
- return -ENODEV;
- }
- als_data = sensor_data.values[0];
- mutex_unlock(&hwm_obj->dc->lock);
- HWM_LOG("hwmsen_aal_get_data3\n");
- return als_data;
- }
- int hwmsen_aal_get_status(void)
- {
- return 0;
- }
- /* ************************************************************************************ */
- /******************************************************************************
- * Local functions
- *****************************************************************************/
- static void hwmsen_work_func(struct work_struct *work)
- {
- /* HWM_LOG("+++++++++++++++++++++++++hwmsen_work_func workqueue performed!+++++++++++++++++++++++++++++\n"); */
- /* struct hwmdev_object *obj = container_of(work, struct hwmdev_object, report); */
- struct hwmdev_object *obj = hwm_obj;
- struct hwmsen_context *cxt = NULL;
- int out_size;
- struct hwm_sensor_data sensor_data;
- uint64_t event_type = 0;
- int64_t nt;
- struct timespec time;
- int err, idx;
- /* int trc = atomic_read(&obj->trace); */
- if (obj == NULL) {
- HWM_ERR("obj point 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;
- get_monotonic_boottime(&time);
- 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 & (1LL << idx))) {
- continue;
- }
- /* Interrupt sensor */
- if (cxt->obj.polling == 0) {
- if (obj_data.data_updata[idx] == 1) {
- mutex_lock(&obj_data.lock);
- event_type |= (1LL << idx);
- obj_data.data_updata[idx] = 0;
- mutex_unlock(&obj_data.lock);
- }
- /* Evne if interrupt mode, try to take the initiative in querying a valid sensor data. */
- else if (obj_data.sensors_data[idx].values[0] != SENSOR_INVALID_VALUE)
- continue;
- }
- /* added to 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 next work\n",idx);*/
- continue;
- }
- }
- err = cxt->obj.sensor_operate(cxt->obj.self, SENSOR_GET_DATA, NULL, 0,
- &sensor_data, sizeof(struct hwm_sensor_data), &out_size);
- if (err) {
- HWM_ERR("get data 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 |= (1LL << 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])
- || (idx == ID_MAGNETIC) || (idx == ID_ACCELEROMETER)
- || (idx == ID_GYROSCOPE) || (idx == ID_ORIENTATION)) {
- if ((0 == sensor_data.values[0]
- && 0 == sensor_data.values[1]
- && 0 == sensor_data.values[2])
- && (idx != ID_GYROSCOPE)) {
- 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 |= (1LL << 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]);*/
- }
- }
- }
- }
- /* */
- /* mutex_unlock(&obj_data.lock); */
- 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 &= ~(1LL << idx);
- /*HWM_LOG("idx=%d,obj->active_sensor after 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 &= ~(1LL << idx);
- /*HWM_LOG("idx=%d,obj->active_sensor after clear: %d\n",idx);*/
- }
- }
- }
- /* HWM_LOG("event type after enable: %d\n", event_type); */
- }
- if ((event_type & (1LL << ID_PROXIMITY))
- && SENSOR_INVALID_VALUE == obj_data.sensors_data[ID_PROXIMITY].values[0]) {
- event_type &= ~(1LL << ID_PROXIMITY);
- /* HWM_LOG("remove ps event!!!!!!!!!!!\n"); */
- }
- if (event_type != 0) {
- input_report_rel(obj->idev, EVENT_TYPE_SENSOR, event_type);
- input_report_rel(obj->idev, EVENT_TYPE_SENSOR_EXT, event_type >> 32);
- input_sync(obj->idev); /*modified*/
- /*HWM_LOG("event type: %d\n", event_type);*/
- } else {
- /*HWM_LOG("no available sensor!!\n");*/
- }
- if (obj->dc->polling_running == 1)
- startTimer(&obj->hrTimer, atomic_read(&obj->delay), false);
- }
- /******************************************************************************
- * export functions
- *****************************************************************************/
- int hwmsen_get_interrupt_data(int sensor, struct hwm_sensor_data *data)
- {
- /*HWM_LOG("++++++++++++++++++++++++++++hwmsen_get_interrupt_data function sensor = %d\n",sensor);*/
- struct dev_context *mcxt = &dev_cxt;
- struct hwmdev_object *obj = hwm_obj;
- int64_t nt;
- struct timespec 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;
- }
- time.tv_sec = time.tv_nsec = 0;
- get_monotonic_boottime(&time);
- 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);
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- EXPORT_SYMBOL_GPL(hwmsen_get_interrupt_data);
- /*----------------------------------------------------------------------------*/
- enum hrtimer_restart hwmsen_poll(struct hrtimer *timer)
- {
- struct hwmdev_object *obj = (struct hwmdev_object *)container_of(timer, struct hwmdev_object, hrTimer);
- queue_work(obj->hwmsen_workqueue, &obj->report);
- return HRTIMER_NORESTART;
- }
- /*----------------------------------------------------------------------------*/
- static struct hwmdev_object *hwmsen_alloc_object(void)
- {
- struct hwmdev_object *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
- HWM_FUN(f);
- if (!obj) {
- HWM_ERR("Alloc hwmsen object error!\n");
- return NULL;
- }
- 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");
- if (!sensor_workqueue) {
- kfree(obj);
- return NULL;
- }
- INIT_WORK(&obj->report, hwmsen_work_func);
- obj->hwmsen_workqueue = NULL;
- obj->hwmsen_workqueue = create_workqueue("hwmsen_polling");
- if (!obj->hwmsen_workqueue) {
- kfree(obj);
- return NULL;
- }
- initTimer(&obj->hrTimer, hwmsen_poll);
- return obj;
- }
- /*Sensor device driver attach to hwmsen device------------------------------------------------*/
- int hwmsen_attach(int sensor, struct hwmsen_object *obj)
- {
- struct dev_context *mcxt = &dev_cxt;
- int err = 0;
- HWM_FUN(f);
- if ((mcxt == NULL) || (sensor > MAX_ANDROID_SENSOR_NUM)) {
- err = -EINVAL;
- goto err_exit;
- }
- mutex_lock(&mcxt->lock);
- if (mcxt->cxt[sensor] != NULL) {
- err = -EEXIST;
- goto err_exit;
- } else {
- mcxt->cxt[sensor] = kzalloc(sizeof(struct hwmsen_context), GFP_KERNEL);
- if (mcxt->cxt[sensor] == NULL) {
- err = -EPERM;
- goto err_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);
- return err;
- }
- /*----------------------------------------------------------------------------*/
- EXPORT_SYMBOL_GPL(hwmsen_attach);
- /*----------------------------------------------------------------------------*/
- int hwmsen_detach(int sensor)
- {
- int err = 0;
- struct dev_context *mcxt = &dev_cxt;
- HWM_FUN(f);
- if ((sensor > MAX_ANDROID_SENSOR_NUM) || (mcxt->cxt[sensor] == NULL)) {
- err = -EINVAL;
- goto err_exit;
- }
- mutex_lock(&mcxt->lock);
- kfree(mcxt->cxt[sensor]);
- mcxt->cxt[sensor] = NULL;
- err_exit:
- mutex_unlock(&mcxt->lock);
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- EXPORT_SYMBOL_GPL(hwmsen_detach);
- /*----------------------------------------------------------------------------*/
- static int hwmsen_enable(struct hwmdev_object *obj, int sensor, int enable)
- {
- struct hwmsen_context *cxt = NULL;
- int err = 0;
- uint64_t sensor_type;
- sensor_type = 1LL << sensor;
- if (sensor > MAX_ANDROID_SENSOR_NUM || sensor < 0) {
- HWM_ERR("handle %d!\n", sensor);
- return -EINVAL;
- }
- if (!obj) {
- HWM_ERR("hwmdev obj pointer is NULL!\n");
- return -EINVAL;
- } else if (obj->dc->cxt[sensor] == NULL) {
- HWM_ERR("the sensor (%d) is not attached!!\n", sensor);
- return -ENODEV;
- }
- if (sensor > MAX_ANDROID_SENSOR_NUM) {
- HWM_ERR("sensor %d!\n", sensor);
- return -EINVAL;
- }
- mutex_lock(&obj->dc->lock);
- cxt = obj->dc->cxt[sensor];
- if (enable == 1) {
- /*{@for mt6582 blocking issue work around*/
- if (sensor == 7) {
- HWM_LOG("P-sensor disable LDO low power\n");
- pmic_ldo_suspend_enable(0);
- }
- /*@}*/
- 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) {
- 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("activate sensor(%d) 3 times err = %d\n",
- sensor, err);
- err = -EINVAL;
- goto exit;
- }
- }
- }
- update_workqueue_polling_rate(200);
- 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); */
- startTimer(&obj->hrTimer, atomic_read(&obj->delay), true);
- }
- } else if ((enable == 0)) {
- /*{@for mt6582 blocking issue work around*/
- if (sensor == 7) {
- HWM_LOG("P-sensor enable LDO low power\n");
- pmic_ldo_suspend_enable(1);
- }
- /*@}*/
- obj->active_data_sensor &= ~sensor_type;
- if ((obj->active_sensor & sensor_type) == 0) {/* no no-data active*/
- #ifdef CONFIG_CUSTOM_KERNEL_ALSPS
- if (sensor == 4 && aal_use == 1) {
- HWM_ERR("AAL is used ingnore common light disable\n");
- err = 0;
- } else
- #endif
- {
- if (cxt->obj.
- sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable,
- sizeof(int), NULL, 0, NULL) != 0) {
- HWM_ERR("deactiva sensor(%d) err = %d\n", sensor, err);
- err = -EINVAL;
- goto exit;
- }
- }
- 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;
- stopTimer(&obj->hrTimer);
- 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);
- return err;
- }
- /*-------------no data sensor enable/disable--------------------------------------*/
- static int hwmsen_enable_nodata(struct hwmdev_object *obj, int sensor, int enable)
- {
- struct hwmsen_context *cxt = NULL;
- int err = 0;
- uint64_t sensor_type;
- HWM_FUN(f);
- sensor_type = 1LL << sensor;
- if (sensor > MAX_ANDROID_SENSOR_NUM || sensor < 0) {
- HWM_ERR("handle %d!\n", sensor);
- return -EINVAL;
- }
- if (NULL == obj) {
- HWM_ERR("hwmdev obj pointer is NULL!\n");
- return -EINVAL;
- } else if (obj->dc->cxt[sensor] == NULL) {
- HWM_ERR("the sensor (%d) is not attached!!\n", sensor);
- return -ENODEV;
- }
- if (sensor > MAX_ANDROID_SENSOR_NUM) {
- HWM_ERR("sensor %d!\n", sensor);
- return -EINVAL;
- }
- mutex_lock(&obj->dc->lock);
- cxt = obj->dc->cxt[sensor];
- if (enable == 1) {
- obj->active_sensor |= sensor_type;
- if ((obj->active_data_sensor & sensor_type) == 0) {/* no data active*/
- if (cxt->obj.
- sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable, sizeof(int), NULL,
- 0, NULL) != 0) {
- HWM_ERR("activate sensor(%d) err = %d\n", sensor, err);
- err = -EINVAL;
- goto exit;
- }
- atomic_set(&cxt->enable, 1);
- }
- } else {
- obj->active_sensor &= ~sensor_type;
- if ((obj->active_data_sensor & sensor_type) == 0) {/* no data active*/
- if (cxt->obj.
- sensor_operate(cxt->obj.self, SENSOR_ENABLE, &enable, sizeof(int), NULL,
- 0, NULL) != 0) {
- HWM_ERR("Deactivate sensor(%d) err = %d\n", sensor, err);
- err = -EINVAL;
- goto exit;
- }
- atomic_set(&cxt->enable, 0);
- }
- }
- exit:
- mutex_unlock(&obj->dc->lock);
- return err;
- }
- /*------------set delay--------------------------------------------------------*/
- static int hwmsen_set_delay(int delay, int handle)
- {
- int err = 0;
- struct hwmsen_context *cxt = NULL;
- if (handle > MAX_ANDROID_SENSOR_NUM || handle < 0) {
- HWM_ERR("handle %d!\n", handle);
- return -EINVAL;
- }
- if (handle > MAX_ANDROID_SENSOR_NUM) {
- HWM_ERR("handle %d!\n", handle);
- return -EINVAL;
- }
- cxt = hwm_obj->dc->cxt[handle];
- if (NULL == cxt || (cxt->obj.sensor_operate == NULL)) {
- HWM_ERR("have no this sensor %d or operator point is null!\r\n", handle);
- } else {/*if(atomic_read(&cxt->enable) != 0)*/ /*always update delay even sensor is not enabled.*/
- if (cxt->obj.
- sensor_operate(cxt->obj.self, SENSOR_DELAY, &delay, sizeof(int), NULL, 0,
- NULL) != 0) {
- HWM_ERR("%d sensor's sensor_operate function error %d!\r\n", handle, err);
- return err;
- }
- /* record sensor delay */
- atomic_set(&cxt->delay, delay);
- }
- return err;
- }
- /*----------------------------------------------------------------------------*/
- static int hwmsen_wakeup(struct hwmdev_object *obj)
- {
- HWM_LOG("hwmsen_wakeup\n");
- if (obj == NULL) {
- HWM_ERR("null pointer!!\n");
- return -EINVAL;
- }
- input_event(obj->idev, EV_SYN, SYN_CONFIG, 0);
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_show_hwmdev(struct device *dev, struct device_attribute *attr, char *buf)
- {
- int len = 0;
- HWM_LOG("sensor test: hwmsen_show_hwmdev function!\n");
- /*
- if (!devobj || !devobj->dc) {
- HWM_ERR("null pointer: %p, %p", devobj, (!devobj) ? (NULL) : (devobj->dc));
- return 0;
- }
- for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
- len += snprintf(buf+len, PAGE_SIZE-len, " %d", idx);
- len += snprintf(buf+len, PAGE_SIZE-len, "\n");
- for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
- len += snprintf(buf+len, PAGE_SIZE-len, " %d", atomic_read(&devobj->dc->cxt[idx].enable));
- len += snprintf(buf+len, PAGE_SIZE-len, "\n");
- */
- return len;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_store_active(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- /*
- printk("sensor test: hwmsen_store_active function!\n");
- struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
- int sensor, enable, err, idx;
- if (!devobj || !devobj->dc) {
- HWM_ERR("null pointer!!\n");
- return count;
- }
- if (!strncmp(buf, "all-start", 9)) {
- for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
- hwmsen_enable(devobj, idx, 1);
- } else if (!strncmp(buf, "all-stop", 8)) {
- for (idx = 0; idx < C_MAX_HWMSEN_NUM; idx++)
- hwmsen_enable(devobj, idx, 0);
- } else if (2 == sscanf(buf, "%d %d", &sensor, &enable)) {
- if ((err = hwmsen_enable(devobj, sensor, enable)))
- HWM_ERR("sensor enable failed: %d\n", err);
- }
- */
- return count;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_show_delay(struct device *dev, struct device_attribute *attr, char *buf)
- {
- /*
- struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
- printk("sensor test: hwmsen_show_delay function!\n");
- if (!devobj || !devobj->dc) {
- HWM_ERR("null pointer!!\n");
- return 0;
- }
- return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&devobj->delay));
- */
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_store_delay(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- /*
- struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
- int delay;
- printk("sensor test: hwmsen_show_delay function!\n");
- if (!devobj || !devobj->dc) {
- HWM_ERR("null pointer!!\n");
- return count;
- }
- if (1 != sscanf(buf, "%d", &delay)) {
- HWM_ERR("invalid format!!\n");
- return count;
- }
- atomic_set(&devobj->delay, delay);
- */
- return count;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_show_wake(struct device *dev, struct device_attribute *attr, char *buf)
- {
- /*
- printk("sensor test: hwmsen_show_wake function!\n");
- struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
- if (!devobj || !devobj->dc) {
- HWM_ERR("null pointer!!\n");
- return 0;
- }
- return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&devobj->wake));
- */
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_store_wake(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
- {
- /*
- struct hwmdev_object *devobj = (struct hwmdev_object*)dev_get_drvdata(dev);
- int wake, err;
- printk("sensor test: hwmsen_store_wake function!\n");
- if (!devobj || !devobj->dc) {
- HWM_ERR("null pointer!!\n");
- return count;
- }
- if (1 != sscanf(buf, "%d", &wake)) {
- HWM_ERR("invalid format!!\n");
- return count;
- }
- if ((err = hwmsen_wakeup(devobj))) {
- HWM_ERR("wakeup sensor fail, %d\n", err);
- return count;
- }
- */
- return count;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_show_trace(struct device *dev, struct device_attribute *attr, char *buf)
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct hwmdev_object *obj = i2c_get_clientdata(client);
- HWM_FUN(f);
- return snprintf(buf, PAGE_SIZE, "0x%08X\n", atomic_read(&obj->trace));
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_store_trace(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- struct i2c_client *client = to_i2c_client(dev);
- struct hwmdev_object *obj = i2c_get_clientdata(client);
- int trc;
- HWM_FUN(f);
- if (1 == sscanf(buf, "0x%x\n", &trc))
- atomic_set(&obj->trace, trc);
- else
- HWM_ERR("set trace level fail!!\n");
- return count;
- }
- /*----------------------------------------------------------------------------*/
- static ssize_t hwmsen_show_sensordevnum(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- const char *devname = NULL;
- devname = dev_name(&hwm_obj->idev->dev);
- return snprintf(buf, PAGE_SIZE, "%s\n", devname + 5);
- }
- DEVICE_ATTR(hwmdev, S_IRUGO, hwmsen_show_hwmdev, NULL);
- DEVICE_ATTR(active, S_IWUSR | S_IRUGO, hwmsen_show_hwmdev, hwmsen_store_active);
- DEVICE_ATTR(delay, S_IWUSR | S_IRUGO, hwmsen_show_delay, hwmsen_store_delay);
- DEVICE_ATTR(wake, S_IWUSR | S_IRUGO, hwmsen_show_wake, hwmsen_store_wake);
- DEVICE_ATTR(trace, S_IWUSR | S_IRUGO, hwmsen_show_trace, hwmsen_store_trace);
- DEVICE_ATTR(hwmsensordevnum, S_IRUGO, hwmsen_show_sensordevnum, NULL);
- /*----------------------------------------------------------------------------*/
- static struct device_attribute *hwmsen_attr_list[] = {
- &dev_attr_hwmdev,
- &dev_attr_active,
- &dev_attr_delay,
- &dev_attr_wake,
- &dev_attr_trace,
- &dev_attr_hwmsensordevnum,
- };
- /*----------------------------------------------------------------------------*/
- static int hwmsen_create_attr(struct device *dev)
- {
- int idx, err = 0;
- int num = (int)(sizeof(hwmsen_attr_list) / sizeof(hwmsen_attr_list[0]));
- HWM_FUN();
- if (!dev)
- return -EINVAL;
- for (idx = 0; idx < num; idx++) {
- err = device_create_file(dev, hwmsen_attr_list[idx]);
- if (err) {
- HWM_ERR("device_create_file (%s) = %d\n", hwmsen_attr_list[idx]->attr.name,
- err);
- break;
- }
- }
- return err;
- }
- /*----------------------------------------------------------------------------*/
- static int hwmsen_delete_attr(struct device *dev)
- {
- int idx, err = 0;
- int num = (int)(sizeof(hwmsen_attr_list) / sizeof(hwmsen_attr_list[0]));
- HWM_FUN(f);
- if (!dev)
- return -EINVAL;
- for (idx = 0; idx < num; idx++)
- device_remove_file(dev, hwmsen_attr_list[idx]);
- return err;
- }
- /*----------------------------------------------------------------*/
- static int init_static_data(void)
- {
- int i = 0;
- /* memset(&obj_data, 0, sizeof(struct hwmsen_data));*/
- /* obj_data.lock = __MUTEX_INITIALIZER(obj_data.lock); */
- for (i = 0; i < MAX_ANDROID_SENSOR_NUM; i++) {
- /*dev_cxt.cxt[i] = NULL; */
- memset(&obj_data.sensors_data[i], SENSOR_INVALID_VALUE, sizeof(struct hwm_sensor_data));
- obj_data.sensors_data[i].sensor = i;
- }
- return 0;
- }
- /*----------------------------------------------------------------*/
- static int hwmsen_open(struct inode *node, struct file *fp)
- {
- HWM_FUN(f);
- /*struct file_private* data = kzalloc(sizeof(struct file_private), GFP_KERNEL);*/
- /* fp->private_data = data;*/
- fp->private_data = NULL;
- return nonseekable_open(node, fp);
- }
- /*----------------------------------------------------------------------------*/
- static int hwmsen_release(struct inode *node, struct file *fp)
- {
- HWM_FUN(f);
- kfree(fp->private_data);
- fp->private_data = NULL;
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- static void update_workqueue_polling_rate(int newDelay)
- {
- atomic_t delaytemp;
- int i = 0;
- int idx = 0;
- struct hwmsen_context *cxt = NULL;
- struct hwmdev_object *obj = hwm_obj;
- HWM_FUN(f);
- atomic_set(&delaytemp, 200); /*used to finding fastest sensor polling rate*/
- for (i = 0; i < MAX_ANDROID_SENSOR_NUM; i++) {
- if (hwm_obj->active_data_sensor & 1LL << i) {
- if (atomic_read(&delaytemp) > atomic_read(&(hwm_obj->dc->cxt[i]->delay)))
- /* work queue polling delay base time*/
- atomic_set(&delaytemp, atomic_read(&(hwm_obj->dc->cxt[i]->delay)));
- }
- }
- /*use the fastest sensor polling delay as work queue polling delay base time*/
- if (atomic_read(&delaytemp) > newDelay) {
- atomic_set(&hwm_obj->delay, newDelay); /* work queue polling delay base time*/
- HWM_LOG("set new workqueue base time=%d\n", atomic_read(&hwm_obj->delay));
- } else {
- atomic_set(&hwm_obj->delay, atomic_read(&delaytemp));
- HWM_LOG("set old fastest sensor delay as workqueue base time=%d\n",
- atomic_read(&hwm_obj->delay));
- }
- /*upadate all sensors delayCountSet*/
- 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 & (1LL << idx))) {
- continue;
- }
- if (0 == atomic_read(&cxt->delay)) {
- cxt->delayCount = cxt->delayCountSet = 0;
- HWM_LOG("%s,set delayCountSet=0 delay =%d handle=%d\r\n", __func__,
- atomic_read(&cxt->delay), idx);
- }
- if (atomic_read(&cxt->delay) <= atomic_read(&hwm_obj->delay)) {
- cxt->delayCount = cxt->delayCountSet = 0;
- HWM_LOG("%s,set delayCountSet=0 delay =%d handle=%d\r\n", __func__,
- atomic_read(&cxt->delay), idx);
- } else {
- i = atomic_read(&cxt->delay) / atomic_read(&hwm_obj->delay);
- cxt->delayCount = cxt->delayCountSet = i;
- HWM_LOG("%s:set delayCountSet=%d delay =%d handle=%d\r\n", __func__, i,
- atomic_read(&cxt->delay), idx);
- #if 0
- switch (i) {
- case 3:
- /* 200/60 ;60/20 */
- cxt->delayCount = cxt->delayCountSet = 3;
- HWM_LOG("%s:set delayCountSet=3 delay =%d handle=%d\r\n", __func__,
- atomic_read(&cxt->delay), idx);
- break;
- case 10:
- /* 200/20 */
- cxt->delayCount = cxt->delayCountSet = 10;
- HWM_LOG("%s:set delayCountSet=10 delay =%d handle=%d\r\n", __func__,
- atomic_read(&cxt->delay), idx);
- break;
- }
- #endif
- }
- }
- }
- /* static int hwmsen_ioctl(struct inode *node, struct file *fp, */
- /* unsigned int cmd, unsigned long arg) */
- static long hwmsen_unlocked_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
- {
- /*HWM_LOG("IO parament %d!\r\n", cmd); */
- void __user *argp = (void __user *)arg;
- uint32_t flag;
- struct sensor_delay delayPara;
- struct hwm_trans_data hwm_sensors_data;
- int i = 0;
- int idx = 0;
- atomic_t delaytemp;
- atomic_set(&delaytemp, 200); /*used to finding fastest sensor polling rate*/
- /*int delaytemp=200;*/ /*used to finding fastest sensor polling rate*/
- if (!hwm_obj) {
- HWM_ERR("null pointer!!\n");
- return -EINVAL;
- }
- switch (cmd) {
- case HWM_IO_SET_DELAY:
- /* android2.3 sensor system has 4 sample delay 0ms 20ms 60ms 200ms */
- if (copy_from_user(&delayPara, argp, sizeof(delayPara))) {
- HWM_ERR("copy_from_user fail!!\n");
- return -EFAULT;
- }
- HWM_LOG("ioctl delay handle=%d,delay =%d\n", delayPara.handle, delayPara.delay);
- hwmsen_set_delay(delayPara.delay, delayPara.handle); /*modified for android2.3*/
- update_workqueue_polling_rate(delayPara.delay);
- break;
- case HWM_IO_SET_WAKE:
- hwmsen_wakeup(hwm_obj);
- break;
- case HWM_IO_ENABLE_SENSOR:
- if (copy_from_user(&flag, argp, sizeof(flag))) {
- HWM_ERR("copy_from_user fail!!\n");
- return -EFAULT;
- }
- hwmsen_enable(hwm_obj, flag, 1);
- break;
- case HWM_IO_DISABLE_SENSOR:
- if (copy_from_user(&flag, argp, sizeof(flag))) {
- HWM_ERR("copy_from_user fail!!\n");
- return -EFAULT;
- }
- hwmsen_enable(hwm_obj, flag, 0);
- break;
- case HWM_IO_GET_SENSORS_DATA:
- if (copy_from_user(&hwm_sensors_data, argp, sizeof(hwm_sensors_data))) {
- HWM_ERR("copy_from_user fail!!\n");
- return -EFAULT;
- }
- mutex_lock(&obj_data.lock);
- /*memcpy(hwm_sensors_data.data, &(obj_data.sensors_data),
- sizeof(struct hwm_sensor_data) * MAX_ANDROID_SENSOR_NUM);*/
- for (i = 0, idx = 0;
- i < MAX_ANDROID_SENSOR_NUM && idx < MAX_SENSOR_DATA_UPDATE_ONCE; i++) {
- if (hwm_sensors_data.data_type & (1LL << i)) {
- memcpy(&hwm_sensors_data.data[idx], &(obj_data.sensors_data[i]),
- sizeof(struct hwm_sensor_data));
- hwm_sensors_data.data[idx].update = 1;
- idx++;
- }
- }
- if (idx < MAX_SENSOR_DATA_UPDATE_ONCE)
- hwm_sensors_data.data[idx].update = 0;
- mutex_unlock(&obj_data.lock);
- if (copy_to_user(argp, &hwm_sensors_data, sizeof(hwm_sensors_data))) {
- HWM_ERR("copy_to_user fail!!\n");
- return -EFAULT;
- }
- break;
- case HWM_IO_ENABLE_SENSOR_NODATA:
- if (copy_from_user(&flag, argp, sizeof(flag))) {
- HWM_ERR("copy_from_user fail!!\n");
- return -EFAULT;
- }
- hwmsen_enable_nodata(hwm_obj, flag, 1);
- break;
- case HWM_IO_DISABLE_SENSOR_NODATA:
- if (copy_from_user(&flag, argp, sizeof(flag))) {
- HWM_ERR("copy_from_user fail!!\n");
- return -EFAULT;
- }
- hwmsen_enable_nodata(hwm_obj, flag, 0);
- break;
- default:
- HWM_ERR("have no this paramenter %d!!\n", cmd);
- return -ENOIOCTLCMD;
- }
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- static const struct file_operations hwmsen_fops = {
- /* .owner = THIS_MODULE,*/
- .open = hwmsen_open,
- .release = hwmsen_release,
- /* .ioctl = hwmsen_ioctl,*/
- .unlocked_ioctl = hwmsen_unlocked_ioctl,
- };
- /*----------------------------------------------------------------------------*/
- static int hwmsen_probe(void)
- {
- int err;
- /* HWM_LOG("+++++++++++++++++hwmsen_probe!!\n"); */
- HWM_FUN(f);
- init_static_data();
- hwm_obj = hwmsen_alloc_object();
- if (!hwm_obj) {
- err = -ENOMEM;
- HWM_ERR("unable to allocate devobj!\n");
- goto exit_alloc_data_failed;
- }
- hwm_obj->idev = input_allocate_device();
- if (!hwm_obj->idev) {
- err = -ENOMEM;
- HWM_ERR("unable to allocate input device!\n");
- goto exit_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);
- input_set_capability(hwm_obj->idev, EV_REL, EVENT_TYPE_SENSOR_EXT);
- hwm_obj->idev->name = HWM_INPUTDEV_NAME;
- err = input_register_device(hwm_obj->idev);
- if (err) {
- HWM_ERR("unable to register input device!\n");
- goto exit_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;
- err = misc_register(&hwm_obj->mdev);
- if (err) {
- HWM_ERR("unable to register sensor device!!\n");
- goto exit_misc_register_failed;
- }
- dev_set_drvdata(hwm_obj->mdev.this_device, hwm_obj);
- if (hwmsen_create_attr(hwm_obj->mdev.this_device) != 0) {
- HWM_ERR("unable to create attributes!!\n");
- goto exit_hwmsen_create_attr_failed;
- }
- #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_EARLYSUSPEND)
- /* 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);
- #ifdef CONFIG_PM_WAKELOCKS
- wakeup_source_init(&(hwm_obj->read_data_wake_lock), "read_data_wake_lock");
- #else
- wake_lock_init(&(hwm_obj->read_data_wake_lock), WAKE_LOCK_SUSPEND, "read_data_wake_lock");
- #endif
- /* add for fix resume bug end*/
- #endif /*#if defined(CONFIG_HAS_EARLYSUSPEND)*/
- return 0;
- 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:
- return err;
- }
- /*----------------------------------------------------------------------------*/
- static int hwmsen_remove(void)
- {
- HWM_FUN(f);
- input_unregister_device(hwm_obj->idev);
- hwmsen_delete_attr(hwm_obj->mdev.this_device);
- misc_deregister(&hwm_obj->mdev);
- kfree(hwm_obj);
- return 0;
- }
- #if defined(CONFIG_HAS_EARLYSUSPEND)
- static void hwmsen_early_suspend(struct early_suspend *h)
- {
- /*HWM_FUN(f);*/
- atomic_set(&(hwm_obj->early_suspend), 1);
- HWM_LOG(" hwmsen_early_suspend ok------->hwm_obj->early_suspend=%d.\n",
- atomic_read(&hwm_obj->early_suspend));
- }
- /*----------------------------------------------------------------------------*/
- static void hwmsen_late_resume(struct early_suspend *h)
- {
- /*HWM_FUN(f);*/
- atomic_set(&(hwm_obj->early_suspend), 0);
- HWM_LOG(" hwmsen_late_resume ok------->hwm_obj->early_suspend=%d.\n",
- atomic_read(&hwm_obj->early_suspend));
- }
- #endif /*#if defined(CONFIG_HAS_EARLYSUSPEND)*/
- /*----------------------------------------------------------------------------*/
- #if defined(CONFIG_MTK_AUTO_DETECT_MAGNETOMETER)
- int hwmsen_msensor_remove(struct platform_device *pdev)
- {
- int err = 0;
- int i = 0;
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (0 == strcmp(msensor_name, msensor_init_list[i]->name)) {
- if (NULL == msensor_init_list[i]->uninit) {
- HWM_LOG(" hwmsen_msensor_remove null pointer.\n");
- return -1;
- }
- msensor_init_list[i]->uninit();
- }
- }
- return 0;
- }
- static int msensor_probe(struct platform_device *pdev)
- {
- int i = 0;
- int err = 0;
- HWM_LOG(" msensor_probe +\n");
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (NULL != msensor_init_list[i]) {
- err = msensor_init_list[i]->init();
- if (0 == err) {
- strcpy(msensor_name, msensor_init_list[i]->name);
- HWM_LOG(" msensor %s probe ok\n", msensor_name);
- break;
- }
- }
- }
- return 0;
- }
- static struct platform_driver msensor_driver = {
- .probe = msensor_probe,
- .remove = hwmsen_msensor_remove,
- .driver = {
- .name = "msensor",
- /* .owner = THIS_MODULE,*/
- }
- };
- int hwmsen_msensor_add(struct sensor_init_info *obj)
- {
- int err = 0;
- int i = 0;
- HWM_FUN(f);
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (NULL == msensor_init_list[i]) {
- msensor_init_list[i] = kzalloc(sizeof(struct sensor_init_info), GFP_KERNEL);
- if (NULL == msensor_init_list[i]) {
- HWM_ERR("kzalloc error");
- return -1;
- }
- obj->platform_diver_addr = &msensor_driver;
- msensor_init_list[i] = obj;
- break;
- }
- }
- return err;
- }
- EXPORT_SYMBOL_GPL(hwmsen_msensor_add);
- #endif
- #if defined(CONFIG_MTK_AUTO_DETECT_ACCELEROMETER)
- int hwmsen_gsensor_remove(struct platform_device *pdev)
- {
- int i = 0;
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (0 == strcmp(gsensor_name, gsensor_init_list[i]->name)) {
- if (NULL == gsensor_init_list[i]->uninit) {
- HWM_LOG(" hwmsen_gsensor_remove null pointer +\n");
- return -1;
- }
- gsensor_init_list[i]->uninit();
- }
- }
- return 0;
- }
- static int gsensor_probe(struct platform_device *pdev)
- {
- int i = 0;
- int err = 0;
- HWM_LOG(" gsensor_probe +\n");
- /* */
- /*
- for(i = 0; i < MAX_CHOOSE_G_NUM; i++)
- {
- HWM_LOG(" gsensor_init_list[i]=%d\n",gsensor_init_list[i]);
- }
- */
- /* */
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- HWM_LOG(" i=%d\n", i);
- if (0 != gsensor_init_list[i]) {
- HWM_LOG(" !!!!!!!!\n");
- err = gsensor_init_list[i]->init();
- if (0 == err) {
- strcpy(gsensor_name, gsensor_init_list[i]->name);
- HWM_LOG(" gsensor %s probe ok\n", gsensor_name);
- break;
- }
- }
- }
- if (i == MAX_CHOOSE_G_NUM)
- HWM_LOG(" gsensor probe fail\n");
- return 0;
- }
- static struct platform_driver gsensor_driver = {
- .probe = gsensor_probe,
- .remove = hwmsen_gsensor_remove,
- .driver = {
- .name = "gsensor",
- /* .owner = THIS_MODULE,*/
- }
- };
- int hwmsen_gsensor_add(struct sensor_init_info *obj)
- {
- int err = 0;
- int i = 0;
- HWM_FUN(f);
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (NULL == gsensor_init_list[i]) {
- gsensor_init_list[i] = kzalloc(sizeof(struct sensor_init_info), GFP_KERNEL);
- if (NULL == gsensor_init_list[i]) {
- HWM_ERR("kzalloc error");
- return -1;
- }
- obj->platform_diver_addr = &gsensor_driver;
- gsensor_init_list[i] = obj;
- break;
- }
- }
- return err;
- }
- EXPORT_SYMBOL_GPL(hwmsen_gsensor_add);
- #endif
- #if defined(CONFIG_MTK_AUTO_DETECT_ALSPS)
- int hwmsen_alsps_sensor_remove(struct platform_device *pdev)
- {
- int err = 0;
- int i = 0;
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (0 == strcmp(alsps_name, alsps_init_list[i]->name)) {
- if (NULL == alsps_init_list[i]->uninit) {
- HWM_LOG(" hwmsen_alsps_sensor_remove null pointer.\n");
- return -1;
- }
- alsps_init_list[i]->uninit();
- }
- }
- return 0;
- }
- static int alsps_sensor_probe(struct platform_device *pdev)
- {
- int i = 0;
- int err = 0;
- HWM_LOG(" als_ps sensor_probe +\n");
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (NULL != alsps_init_list[i]) {
- err = alsps_init_list[i]->init();
- if (0 == err) {
- strcpy(alsps_name, alsps_init_list[i]->name);
- HWM_LOG(" alsps sensor %s probe ok\n", alsps_name);
- break;
- }
- }
- }
- return 0;
- }
- static struct platform_driver alsps_sensor_driver = {
- .probe = alsps_sensor_probe,
- .remove = hwmsen_alsps_sensor_remove,
- .driver = {
- .name = "als_ps",
- }
- };
- int hwmsen_alsps_sensor_add(struct sensor_init_info *obj)
- {
- int err = 0;
- int i = 0;
- HWM_FUN(f);
- for (i = 0; i < MAX_CHOOSE_G_NUM; i++) {
- if (NULL == alsps_init_list[i]) {
- alsps_init_list[i] = kzalloc(sizeof(struct sensor_init_info), GFP_KERNEL);
- if (NULL == alsps_init_list[i]) {
- HWM_ERR("kzalloc error");
- return -1;
- }
- obj->platform_diver_addr = &alsps_sensor_driver;
- alsps_init_list[i] = obj;
- break;
- }
- }
- return err;
- }
- EXPORT_SYMBOL_GPL(hwmsen_alsps_sensor_add);
- #endif
- /*----------------------------------------------------------------------------*/
- static int __init hwmsen_init(void)
- {
- HWM_FUN(f);
- if (0 != hwmsen_probe()) {
- HWM_ERR("failed to register sensor driver");
- return -ENODEV;
- }
- #if defined(CONFIG_MTK_AUTO_DETECT_ACCELEROMETER)
- if (platform_driver_register(&gsensor_driver)) {
- HWM_ERR("failed to register gensor driver");
- return -ENODEV;
- }
- #endif
- #if defined(CONFIG_MTK_AUTO_DETECT_MAGNETOMETER)
- if (platform_driver_register(&msensor_driver)) {
- HWM_ERR("failed to register mensor driver");
- return -ENODEV;
- }
- #endif
- #if defined(CONFIG_MTK_AUTO_DETECT_ALSPS)
- if (platform_driver_register(&alsps_sensor_driver)) {
- HWM_ERR("failed to register alsps_sensor_driver driver");
- return -ENODEV;
- }
- #endif
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- static void __exit hwmsen_exit(void)
- {
- hwmsen_remove();
- }
- /*----------------------------------------------------------------------------*/
- late_initcall(hwmsen_init);
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("sensor device driver");
- MODULE_AUTHOR("MTK");
|