batch.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. #include <batch.h>
  2. #include <linux/time.h>
  3. #include <linux/delay.h>
  4. #include <linux/uaccess.h>
  5. #ifdef CONFIG_PM_WAKELOCKS
  6. #include <linux/pm_wakeup.h>
  7. #else
  8. #include <linux/wakelock.h>
  9. #endif
  10. static DEFINE_MUTEX(batch_data_mutex);
  11. static DEFINE_MUTEX(batch_hw_mutex);
  12. static struct batch_context *batch_context_obj;
  13. static struct batch_init_info *batch_init_list[MAX_CHOOSE_BATCH_NUM] = {0};
  14. static int IDToSensorType(int id)
  15. {
  16. int sensorType;
  17. switch (id) {
  18. case ID_ACCELEROMETER:
  19. sensorType = SENSOR_TYPE_ACCELEROMETER;
  20. break;
  21. case ID_MAGNETIC:
  22. sensorType = SENSOR_TYPE_MAGNETIC_FIELD;
  23. break;
  24. case ID_ORIENTATION:
  25. sensorType = SENSOR_TYPE_ORIENTATION;
  26. break;
  27. case ID_GYROSCOPE:
  28. sensorType = SENSOR_TYPE_GYROSCOPE;
  29. break;
  30. case ID_LIGHT:
  31. sensorType = SENSOR_TYPE_LIGHT;
  32. break;
  33. case ID_PROXIMITY:
  34. sensorType = SENSOR_TYPE_PROXIMITY;
  35. break;
  36. case ID_PRESSURE:
  37. sensorType = SENSOR_TYPE_PRESSURE;
  38. break;
  39. case ID_TEMPRERATURE:
  40. sensorType = SENSOR_TYPE_TEMPERATURE;
  41. break;
  42. case ID_SIGNIFICANT_MOTION:
  43. sensorType = SENSOR_TYPE_SIGNIFICANT_MOTION;
  44. break;
  45. case ID_STEP_DETECTOR:
  46. sensorType = SENSOR_TYPE_STEP_DETECTOR;
  47. break;
  48. case ID_STEP_COUNTER:
  49. sensorType = SENSOR_TYPE_STEP_COUNTER;
  50. break;
  51. default:
  52. sensorType = -1;
  53. }
  54. return sensorType;
  55. }
  56. static int batch_update_polling_rate(void)
  57. {
  58. struct batch_context *obj = batch_context_obj;
  59. int idx = 0;
  60. int mindelay = 0;
  61. for (idx = 0; idx < ID_SENSOR_MAX_HANDLE; idx++) {
  62. if ((obj->active_sensor & (0x01 << idx)) && (0 != obj->dev_list.data_dev[idx].maxBatchReportLatencyMs))
  63. mindelay = ((obj->dev_list.data_dev[idx].maxBatchReportLatencyMs < mindelay)
  64. || (mindelay == 0)) ? obj->dev_list.data_dev[idx].maxBatchReportLatencyMs:mindelay;
  65. }
  66. BATCH_LOG("get polling rate min value (%d) !\n", mindelay);
  67. return mindelay;
  68. }
  69. static int get_fifo_data(struct batch_context *obj)
  70. {
  71. struct hwm_sensor_data sensor_data = {0};
  72. int idx, err = 0;
  73. int fifo_len = -1;
  74. int fifo_status = -1;
  75. int i = 0;
  76. int64_t nt;
  77. struct timespec time;
  78. time.tv_sec = 0;
  79. time.tv_nsec = 0;
  80. get_monotonic_boottime(&time);
  81. nt = time.tv_sec*1000000000LL+time.tv_nsec;
  82. for (i = 0; i <= ID_SENSOR_MAX_HANDLE; i++) {
  83. obj->timestamp_info[i].num = 1;
  84. obj->timestamp_info[i].end_t = nt;
  85. }
  86. BATCH_LOG("fwq!! get_fifo_data +++++++++ !\n");
  87. if ((obj->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].flush != NULL)
  88. && (obj->dev_list.data_dev[ID_SENSOR_MAX_HANDLE].get_data != NULL)
  89. && (obj->dev_list.data_dev[ID_SENSOR_MAX_HANDLE].get_fifo_status) != NULL) {
  90. mutex_lock(&batch_data_mutex);
  91. err = obj->dev_list.data_dev[ID_SENSOR_MAX_HANDLE]
  92. .get_fifo_status(&fifo_len, &fifo_status, 0, obj->timestamp_info);
  93. if (-1 == fifo_len) {
  94. /* we use fifo_status */
  95. if (1 == fifo_status) {
  96. err = obj->dev_list.data_dev[ID_SENSOR_MAX_HANDLE].get_data(0, &sensor_data);
  97. if (err)
  98. BATCH_LOG("batch get fifoA data error\n");
  99. }
  100. } else if (fifo_len >= 0) {
  101. #ifdef CONFIG_PM_WAKELOCKS
  102. __pm_stay_awake(&(batch_context_obj->read_data_wake_lock));
  103. #else
  104. wake_lock(&(batch_context_obj->read_data_wake_lock));
  105. #endif
  106. obj->numOfDataLeft = fifo_len;
  107. input_report_rel(obj->idev, EVENT_TYPE_BATCH_READY, fifo_len);
  108. input_sync(obj->idev);
  109. } else
  110. BATCH_LOG("can not handle this fifo, err = %d, fifo_len = %d\n", err, fifo_len);
  111. mutex_unlock(&batch_data_mutex);
  112. }
  113. for (idx = 0; idx < ID_SENSOR_MAX_HANDLE; idx++) {
  114. /* BATCH_LOG("get data from sensor (%d) !\n", idx); */
  115. if ((obj->dev_list.ctl_dev[idx].flush == NULL) || (obj->dev_list.data_dev[idx].get_data == NULL))
  116. continue;
  117. if ((obj->active_sensor & (0x01 << idx))) {
  118. do {
  119. err = obj->dev_list.data_dev[idx].get_data(idx, &sensor_data);
  120. if (err == 0)
  121. report_batch_data(obj->idev, &sensor_data);
  122. } while (err == 0);
  123. }
  124. }
  125. return err;
  126. }
  127. int batch_notify(enum BATCH_NOTIFY_TYPE type)
  128. {
  129. int err = 0;
  130. if (type == TYPE_BATCHFULL) {
  131. BATCH_LOG("fwq batch full notify\n");
  132. err = get_fifo_data(batch_context_obj);
  133. if (err)
  134. BATCH_LOG("fwq!! get fifo data error !\n");
  135. }
  136. if (type == TYPE_BATCHTIMEOUT)
  137. BATCH_LOG("fwq batch timeout notify do nothing\n");
  138. if (batch_context_obj->is_polling_run)
  139. mod_timer(&batch_context_obj->timer, jiffies + atomic_read(&batch_context_obj->delay)/(1000/HZ));
  140. return err;
  141. }
  142. static void batch_work_func(struct work_struct *work)
  143. {
  144. struct batch_context *obj = batch_context_obj;
  145. int err;
  146. BATCH_LOG("fwq!! get data from sensor+++++++++ !\n");
  147. err = get_fifo_data(obj);
  148. if (err)
  149. BATCH_LOG("fwq!! get fifo data error !\n");
  150. if (obj->is_polling_run)
  151. mod_timer(&obj->timer, jiffies + atomic_read(&obj->delay)/(1000/HZ));
  152. BATCH_LOG("fwq!! get data from sensor obj->delay=%d --------- !\n", atomic_read(&obj->delay));
  153. }
  154. static void batch_poll(unsigned long data)
  155. {
  156. struct batch_context *obj = (struct batch_context *)data;
  157. if (obj != NULL)
  158. schedule_work(&obj->report);
  159. }
  160. static void report_data_once(int handle)
  161. {
  162. struct batch_context *obj = batch_context_obj;
  163. struct hwm_sensor_data sensor_data = {0};
  164. int err;
  165. obj->flush_result = 0;
  166. if ((obj->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].flush != NULL)
  167. && (obj->dev_list.data_dev[ID_SENSOR_MAX_HANDLE].get_data != NULL)) {
  168. obj->flush_result = obj->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].flush(handle);
  169. get_fifo_data(obj);
  170. report_batch_finish(obj->idev, handle);
  171. }
  172. if ((obj->dev_list.ctl_dev[handle].flush != NULL) && (obj->dev_list.data_dev[handle].get_data != NULL)) {
  173. do {
  174. err = obj->dev_list.data_dev[handle].get_data(handle, &sensor_data);
  175. /* sensor_data.value_divide = obj->dev_list.data_dev[sensor_data.sensor-1].div; */
  176. if (err == 0)
  177. report_batch_data(obj->idev, &sensor_data);
  178. } while (err == 0);
  179. report_batch_finish(obj->idev, handle);
  180. obj->flush_result = obj->dev_list.ctl_dev[handle].flush(handle);
  181. } else
  182. BATCH_LOG("batch mode is not support for this sensor!\n");
  183. }
  184. static struct batch_context *batch_context_alloc_object(void)
  185. {
  186. struct batch_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  187. BATCH_LOG("batch_context_alloc_object++++\n");
  188. if (!obj) {
  189. BATCH_ERR("Alloc batch object error!\n");
  190. return NULL;
  191. }
  192. atomic_set(&obj->delay, 200); /*5Hz, set work queue delay time 200ms */
  193. atomic_set(&obj->wake, 0);
  194. INIT_WORK(&obj->report, batch_work_func);
  195. init_timer(&obj->timer);
  196. obj->timer.expires = jiffies + atomic_read(&obj->delay)/(1000/HZ);
  197. obj->timer.function = batch_poll;
  198. obj->timer.data = (unsigned long)obj;
  199. obj->is_first_data_after_enable = false;
  200. obj->is_polling_run = false;
  201. obj->active_sensor = 0;
  202. obj->div_flag = 0;
  203. obj->force_wake_upon_fifo_full = SENSORS_BATCH_WAKE_UPON_FIFO_FULL;
  204. mutex_init(&obj->batch_op_mutex);
  205. BATCH_LOG("batch_context_alloc_object----\n");
  206. return obj;
  207. }
  208. static ssize_t batch_store_active(struct device *dev, struct device_attribute *attr,
  209. const char *buf, size_t count)
  210. {
  211. struct batch_context *cxt = NULL;
  212. int res = 0;
  213. int handle = 0;
  214. int en = 0;
  215. int delay = 0;
  216. int64_t nt;
  217. struct timespec time;
  218. cxt = batch_context_obj;
  219. res = sscanf(buf, "%d,%d", &handle, &en);
  220. if (res != 2)
  221. BATCH_ERR(" batch_store_active param error: res = %d\n", res);
  222. BATCH_LOG(" batch_store_active handle=%d ,en=%d\n", handle, en);
  223. if (handle < 0 || ID_SENSOR_MAX_HANDLE < handle) {
  224. cxt->batch_result = -1;
  225. return count;
  226. } else if (ID_SENSOR_MAX_HANDLE <= handle) {
  227. cxt->batch_result = 0;
  228. return count;
  229. }
  230. if (2 == en) {
  231. cxt->div_flag = handle;
  232. BATCH_LOG(" batch_hal want read %d div\n", handle);
  233. return count;
  234. }
  235. if (cxt->dev_list.data_dev[handle].is_batch_supported == 0) {
  236. cxt->batch_result = 0;
  237. return count;
  238. }
  239. mutex_lock(&batch_hw_mutex);
  240. if (0 == en) {
  241. cxt->active_sensor = cxt->active_sensor & (~(0x01 << handle));
  242. /* L would not do flush at first sensor enable batch mode.
  243. *So we need to flush sensor data when sensor disabled.
  244. * Do flush before call enable_hw_batch to make sure flush finish. */
  245. report_data_once(handle);
  246. } else if (1 == en) {
  247. cxt->active_sensor = cxt->active_sensor | (0x01 << handle);
  248. time.tv_sec = 0;
  249. time.tv_nsec = 0;
  250. get_monotonic_boottime(&time);
  251. nt = time.tv_sec*1000000000LL+time.tv_nsec;
  252. cxt->timestamp_info[handle].start_t = nt;
  253. }
  254. if (cxt->dev_list.ctl_dev[handle].enable_hw_batch != NULL) {
  255. /* BATCH_LOG("cxt->dev_list.ctl_dev[%d].enable_hw_batch, %d, %d, %d\n", handle,en,
  256. *cxt->dev_list.data_dev[handle].samplingPeriodMs, cxt->dev_list
  257. *.data_dev[handle].maxBatchReportLatencyMs); */
  258. res = cxt->dev_list.ctl_dev[handle].enable_hw_batch(handle, en, cxt->dev_list.data_dev[handle]
  259. .flags|cxt->force_wake_upon_fifo_full, (long long)cxt->dev_list
  260. .data_dev[handle].samplingPeriodMs*1000000,
  261. (long long)cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs*1000000);
  262. if (res < 0) {
  263. cxt->batch_result = -1;
  264. mutex_unlock(&batch_hw_mutex);
  265. return count;
  266. }
  267. } else if (cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch != NULL) {
  268. /* BATCH_LOG("cxt->dev_list.ctl_dev[%d].enable_hw_batch, %d, %d, %d\n",
  269. *ID_SENSOR_MAX_HANDLE,en,cxt->dev_list.data_dev[handle].samplingPeriodMs,
  270. *cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs); */
  271. res = cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch(handle, en,
  272. cxt->dev_list.data_dev[handle].flags|cxt->force_wake_upon_fifo_full,
  273. (long long)cxt->dev_list.data_dev[handle].samplingPeriodMs*1000000,
  274. (long long)cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs*1000000);
  275. if (res < 0) {
  276. cxt->batch_result = -1;
  277. mutex_unlock(&batch_hw_mutex);
  278. return count;
  279. }
  280. }
  281. mutex_unlock(&batch_hw_mutex);
  282. delay = batch_update_polling_rate();
  283. BATCH_LOG("batch_update_polling_rate = %d\n", delay);
  284. if (delay > 0) {
  285. cxt->is_polling_run = true;
  286. atomic_set(&cxt->delay, delay);
  287. mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
  288. } else {
  289. cxt->is_polling_run = false;
  290. del_timer_sync(&cxt->timer);
  291. cancel_work_sync(&cxt->report);
  292. }
  293. return count;
  294. }
  295. /*----------------------------------------------------------------------------*/
  296. static ssize_t batch_show_active(struct device *dev,
  297. struct device_attribute *attr, char *buf)
  298. {
  299. int div = 0;
  300. int count = 0;
  301. struct batch_context *cxt = NULL;
  302. cxt = batch_context_obj;
  303. /* display now enabling sensors of batch mode */
  304. div = cxt->dev_list.data_dev[cxt->div_flag].div;
  305. BATCH_LOG("batch %d_div value: %d\n", cxt->div_flag, div);
  306. count = snprintf(buf, PAGE_SIZE, "%d\n", div);
  307. BATCH_LOG("count=%d,buf=%s\n", count, buf);
  308. return count;
  309. }
  310. static ssize_t batch_store_delay(struct device *dev, struct device_attribute *attr,
  311. const char *buf, size_t count)
  312. {
  313. BATCH_LOG(" batch_store_delay not support now\n");
  314. return count;
  315. }
  316. static ssize_t batch_show_delay(struct device *dev,
  317. struct device_attribute *attr, char *buf)
  318. {
  319. int len = 0;
  320. BATCH_LOG("batch_show_delay not support now\n");
  321. return len;
  322. }
  323. static ssize_t batch_store_batch(struct device *dev, struct device_attribute *attr,
  324. const char *buf, size_t count)
  325. {
  326. int handle, flags = 0;
  327. long long samplingPeriodNs, maxBatchReportLatencyNs = 0;
  328. int res, delay = 0;
  329. struct batch_context *cxt = NULL;
  330. int64_t nt;
  331. struct timespec time;
  332. int en;
  333. int normalToBatch = 0;
  334. int delayChange = 0;
  335. cxt = batch_context_obj;
  336. BATCH_LOG("write value: buf = %s\n", buf);
  337. res = sscanf(buf, "%d,%d,%lld,%lld", &handle, &flags, &samplingPeriodNs, &maxBatchReportLatencyNs);
  338. if (res != 4)
  339. BATCH_ERR("batch_store_delay param error: res = %d\n", res);
  340. BATCH_LOG("batch_store_delay param: handle %d, flag:%d samplingPeriodNs:%lld, maxBatchReportLatencyNs: %lld\n",
  341. handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
  342. if (handle < 0 || ID_SENSOR_MAX_HANDLE < handle) {
  343. cxt->batch_result = -1;
  344. return count;
  345. } else if (ID_SENSOR_MAX_HANDLE <= handle) {
  346. cxt->batch_result = 0;
  347. return count;
  348. }
  349. if (cxt->dev_list.data_dev[handle].is_batch_supported == 0) {
  350. if (maxBatchReportLatencyNs == 0)
  351. cxt->batch_result = 0;
  352. else
  353. cxt->batch_result = -1;
  354. return count;
  355. } else if (flags & SENSORS_BATCH_DRY_RUN) {
  356. cxt->batch_result = 0;
  357. return count;
  358. }
  359. if ((cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch == NULL)
  360. && (cxt->dev_list.ctl_dev[handle].enable_hw_batch == NULL)) {
  361. cxt->batch_result = -1;
  362. return count;
  363. }
  364. mutex_lock(&batch_hw_mutex);
  365. do_div(maxBatchReportLatencyNs, 1000000);
  366. do_div(samplingPeriodNs, 1000000);
  367. /* Change from normal mode to batch mode, update start time. */
  368. if (cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs == 0 && maxBatchReportLatencyNs != 0)
  369. normalToBatch = 1;
  370. if (cxt->dev_list.data_dev[handle].samplingPeriodMs != samplingPeriodNs)
  371. delayChange = 1;
  372. cxt->dev_list.data_dev[handle].samplingPeriodMs = samplingPeriodNs;
  373. cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs = maxBatchReportLatencyNs;
  374. cxt->dev_list.data_dev[handle].flags = flags;
  375. if (maxBatchReportLatencyNs == 0) {
  376. /* flush batch data when change from batch mode to normal mode. */
  377. if (cxt->active_sensor & (0x01 << handle)) {
  378. BATCH_LOG("%d from batch to normal\n", handle);
  379. report_data_once(handle);
  380. }
  381. } else if (maxBatchReportLatencyNs != 0) {
  382. /* Update start time only when change from normal mode to batch mode. */
  383. if (normalToBatch) {
  384. time.tv_sec = 0;
  385. time.tv_nsec = 0;
  386. get_monotonic_boottime(&time);
  387. nt = time.tv_sec*1000000000LL+time.tv_nsec;
  388. cxt->timestamp_info[handle].start_t = nt;
  389. } else if (delayChange)
  390. get_fifo_data(cxt);
  391. }
  392. en = (cxt->active_sensor & (0x01 << handle))?1:0;
  393. /* BATCH_LOG("en = %d\n", en); */
  394. if (cxt->dev_list.ctl_dev[handle].enable_hw_batch != NULL) {
  395. res = cxt->dev_list.ctl_dev[handle].enable_hw_batch(handle, en, flags|cxt->force_wake_upon_fifo_full,
  396. (long long)samplingPeriodNs*1000000, (long long)maxBatchReportLatencyNs*1000000);
  397. if (res < 0) {
  398. cxt->batch_result = -1;
  399. mutex_unlock(&batch_hw_mutex);
  400. return count;
  401. }
  402. } else if (cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch != NULL) {
  403. res = cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch
  404. (handle, en, flags|cxt->force_wake_upon_fifo_full,
  405. (long long)samplingPeriodNs*1000000, (long long)maxBatchReportLatencyNs*1000000);
  406. if (res < 0) {
  407. cxt->batch_result = -1;
  408. mutex_unlock(&batch_hw_mutex);
  409. return count;
  410. }
  411. }
  412. mutex_unlock(&batch_hw_mutex);
  413. delay = batch_update_polling_rate();
  414. BATCH_LOG("delay = %d\n", delay);
  415. if (delay > 0) {
  416. cxt->is_polling_run = true;
  417. atomic_set(&cxt->delay, delay);
  418. mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay)/(1000/HZ));
  419. } else {
  420. cxt->is_polling_run = false;
  421. del_timer_sync(&cxt->timer);
  422. cancel_work_sync(&cxt->report);
  423. }
  424. cxt->batch_result = 0;
  425. return count;
  426. }
  427. static ssize_t batch_show_batch(struct device *dev,
  428. struct device_attribute *attr, char *buf)
  429. {
  430. struct batch_context *cxt = NULL;
  431. int res = 0;
  432. cxt = batch_context_obj;
  433. res = cxt->batch_result;
  434. BATCH_LOG(" batch_show_delay batch result: %d\n", res);
  435. return snprintf(buf, PAGE_SIZE, "%d\n", res);
  436. }
  437. static ssize_t batch_store_flush(struct device *dev, struct device_attribute *attr,
  438. const char *buf, size_t count)
  439. {
  440. struct batch_context *cxt = NULL;
  441. int handle;
  442. int ret;
  443. BATCH_LOG("fwq flush_store_delay +++\n");
  444. cxt = batch_context_obj;
  445. ret = kstrtoint(buf, 10, &handle);
  446. if (ret != 0) {
  447. BATCH_LOG("fwq flush_ err......\n");
  448. BATCH_ERR("invalid format!!\n");
  449. return count;
  450. }
  451. if (handle < 0 || ID_SENSOR_MAX_HANDLE < handle) {
  452. BATCH_ERR("invalid handle : %d\n", handle);
  453. cxt->flush_result = -1;
  454. return count;
  455. }
  456. report_data_once(handle);/* handle need to use of this function */
  457. BATCH_LOG("flush_store_delay success------\n");
  458. return count;
  459. }
  460. static ssize_t batch_show_flush(struct device *dev,
  461. struct device_attribute *attr, char *buf)
  462. {
  463. struct batch_context *cxt = NULL;
  464. int res = 0;
  465. cxt = batch_context_obj;
  466. res = cxt->flush_result;
  467. BATCH_LOG(" batch_show_flush flush result: %d\n", res);
  468. return snprintf(buf, PAGE_SIZE, "%d\n", res);
  469. }
  470. static ssize_t batch_show_devnum(struct device *dev,
  471. struct device_attribute *attr, char *buf)
  472. {
  473. struct batch_context *cxt = NULL;
  474. const char *devname = NULL;
  475. cxt = batch_context_obj;
  476. devname = dev_name(&cxt->idev->dev);
  477. return snprintf(buf, PAGE_SIZE, "%s\n", devname+5);
  478. }
  479. /*----------------------------------------------------------------*/
  480. static int batch_open(struct inode *node , struct file *fp)
  481. {
  482. BATCH_FUN(f);
  483. fp->private_data = NULL;
  484. return nonseekable_open(node, fp);
  485. }
  486. /*----------------------------------------------------------------------------*/
  487. static int batch_release(struct inode *node, struct file *fp)
  488. {
  489. BATCH_FUN(f);
  490. kfree(fp->private_data);
  491. fp->private_data = NULL;
  492. return 0;
  493. }
  494. /*----------------------------------------------------------------------------*/
  495. static long batch_unlocked_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
  496. {
  497. void __user *argp = (void __user *)arg;
  498. struct batch_trans_data batch_sensors_data;
  499. int i;
  500. int err;
  501. struct batch_timestamp_info *pt;
  502. int handle;
  503. if (batch_context_obj == NULL) {
  504. BATCH_ERR("null pointer!!\n");
  505. return -EINVAL;
  506. }
  507. switch (cmd) {
  508. case BATCH_IO_GET_SENSORS_DATA:
  509. if (copy_from_user(&batch_sensors_data, argp, sizeof(batch_sensors_data))) {
  510. BATCH_ERR("copy_from_user fail!!\n");
  511. return -EFAULT;
  512. }
  513. mutex_lock(&batch_data_mutex);
  514. /* BATCH_ERR("BATCH_IO_GET_SENSORS_DATA1, %d, %d, %d!!\n", batch_sensors_data.numOfDataReturn,
  515. *batch_sensors_data.numOfDataLeft, batch_context_obj->numOfDataLeft); */
  516. for (i = 0; i < batch_context_obj->numOfDataLeft && i < batch_sensors_data.numOfDataReturn; i++) {
  517. err = batch_context_obj->dev_list.data_dev[ID_SENSOR_MAX_HANDLE]
  518. .get_data(0, &batch_sensors_data.data[i]);
  519. if (err)
  520. BATCH_ERR("BATCH_IO_GET_SENSORS_DATA err = %d\n", err);
  521. else {
  522. handle = batch_sensors_data.data[i].sensor;
  523. if (batch_context_obj->dev_list.data_dev[handle].is_timestamp_supported == 0) {
  524. pt = &batch_context_obj->timestamp_info[handle];
  525. batch_sensors_data.data[i].time = pt->end_t - pt->start_t;
  526. if (pt->total_count == 0)
  527. BATCH_ERR("pt->total_count == 0\n");
  528. else
  529. do_div(batch_sensors_data.data[i].time, pt->total_count);
  530. if (batch_sensors_data.data[i].time > (int64_t)batch_context_obj->dev_list
  531. .data_dev[handle].samplingPeriodMs*1100000) {
  532. batch_sensors_data.data[i].time = pt->end_t - (int64_t)
  533. batch_context_obj->dev_list.data_dev[handle]
  534. .samplingPeriodMs*1100000*(pt->total_count-1);
  535. BATCH_LOG("FIFO wrapper around1, %lld, %lld, %lld\n",
  536. (int64_t)batch_context_obj->dev_list.data_dev[handle]
  537. .samplingPeriodMs, (int64_t)pt->total_count,
  538. (int64_t)batch_context_obj->dev_list.data_dev[handle]
  539. .samplingPeriodMs*1100000*(pt->total_count-1));
  540. BATCH_LOG("FIFO wrapper around2, %lld, %lld, %lld\n", pt->start_t,
  541. batch_sensors_data.data[i].time, pt->end_t);
  542. } else
  543. batch_sensors_data.data[i].time += pt->start_t;
  544. pt->start_t = batch_sensors_data.data[i].time;
  545. }
  546. batch_sensors_data.data[i].sensor = IDToSensorType(handle);
  547. }
  548. }
  549. batch_sensors_data.numOfDataReturn = i;
  550. batch_context_obj->numOfDataLeft -= i;
  551. batch_sensors_data.numOfDataLeft = batch_context_obj->numOfDataLeft;
  552. if (batch_context_obj->numOfDataLeft == 0) {
  553. #ifdef CONFIG_PM_WAKELOCKS
  554. __pm_relax(&(batch_context_obj->read_data_wake_lock));
  555. #else
  556. wake_unlock(&(batch_context_obj->read_data_wake_lock));
  557. #endif
  558. }
  559. /* BATCH_ERR("BATCH_IO_GET_SENSORS_DATA2, %d, %d, %d!!\n",
  560. *batch_sensors_data.numOfDataReturn, batch_sensors_data.numOfDataLeft,
  561. *batch_context_obj->numOfDataLeft); */
  562. mutex_unlock(&batch_data_mutex);
  563. if (copy_to_user(argp, &batch_sensors_data, sizeof(batch_sensors_data))) {
  564. BATCH_ERR("copy_to_user fail!!\n");
  565. return -EFAULT;
  566. }
  567. break;
  568. default:
  569. BATCH_ERR("have no this paramenter %d!!\n", cmd);
  570. return -ENOIOCTLCMD;
  571. }
  572. return 0;
  573. }
  574. /*----------------------------------------------------------------------------*/
  575. static const struct file_operations batch_fops = {
  576. .open = batch_open,
  577. .release = batch_release,
  578. .unlocked_ioctl = batch_unlocked_ioctl,
  579. };
  580. /*----------------------------------------------------------------------------*/
  581. static int batch_misc_init(struct batch_context *cxt)
  582. {
  583. int err = 0;
  584. cxt->mdev.minor = MISC_DYNAMIC_MINOR;
  585. cxt->mdev.name = BATCH_MISC_DEV_NAME;
  586. cxt->mdev.fops = &batch_fops;
  587. err = misc_register(&cxt->mdev);
  588. if (err)
  589. BATCH_ERR("unable to register batch misc device!!\n");
  590. return err;
  591. }
  592. static void batch_input_destroy(struct batch_context *cxt)
  593. {
  594. struct input_dev *dev = cxt->idev;
  595. input_unregister_device(dev);
  596. input_free_device(dev);
  597. }
  598. static int batch_input_init(struct batch_context *cxt)
  599. {
  600. struct input_dev *dev;
  601. int err = 0;
  602. dev = input_allocate_device();
  603. if (NULL == dev)
  604. return -ENOMEM;
  605. dev->name = BATCH_INPUTDEV_NAME;
  606. input_set_capability(dev, EV_ABS, EVENT_TYPE_BATCH_X);
  607. input_set_capability(dev, EV_ABS, EVENT_TYPE_BATCH_Y);
  608. input_set_capability(dev, EV_ABS, EVENT_TYPE_BATCH_Z);
  609. /* input_set_capability(dev, EV_ABS, EVENT_TYPE_SENSORTYPE); */
  610. input_set_capability(dev, EV_REL, EVENT_TYPE_SENSORTYPE);
  611. input_set_capability(dev, EV_ABS, EVENT_TYPE_BATCH_VALUE);
  612. input_set_capability(dev, EV_ABS, EVENT_TYPE_BATCH_STATUS);
  613. /* input_set_capability(dev, EV_ABS, EVENT_TYPE_END_FLAG); */
  614. input_set_capability(dev, EV_REL, EVENT_TYPE_END_FLAG);
  615. input_set_capability(dev, EV_REL, EVENT_TYPE_TIMESTAMP_HI);
  616. input_set_capability(dev, EV_REL, EVENT_TYPE_TIMESTAMP_LO);
  617. input_set_capability(dev, EV_REL, EVENT_TYPE_BATCH_READY);
  618. input_set_abs_params(dev, EVENT_TYPE_BATCH_X, BATCH_VALUE_MIN, BATCH_VALUE_MAX, 0, 0);
  619. input_set_abs_params(dev, EVENT_TYPE_BATCH_Y, BATCH_VALUE_MIN, BATCH_VALUE_MAX, 0, 0);
  620. input_set_abs_params(dev, EVENT_TYPE_BATCH_Z, BATCH_VALUE_MIN, BATCH_VALUE_MAX, 0, 0);
  621. input_set_abs_params(dev, EVENT_TYPE_BATCH_STATUS, BATCH_STATUS_MIN, BATCH_STATUS_MAX, 0, 0);
  622. input_set_abs_params(dev, EVENT_TYPE_BATCH_VALUE, BATCH_VALUE_MIN, BATCH_VALUE_MAX, 0, 0);
  623. /* input_set_abs_params(dev, EVENT_TYPE_SENSORTYPE, BATCH_TYPE_MIN, BATCH_TYPE_MAX, 0, 0); */
  624. /* input_set_abs_params(dev, EVENT_TYPE_END_FLAG, BATCH_STATUS_MIN, BATCH_STATUS_MAX, 0, 0); */
  625. set_bit(EV_REL, dev->evbit);
  626. input_set_drvdata(dev, cxt);
  627. err = input_register_device(dev);
  628. if (err < 0) {
  629. input_free_device(dev);
  630. return err;
  631. }
  632. cxt->idev = dev;
  633. return 0;
  634. }
  635. DEVICE_ATTR(batchactive, S_IWUSR | S_IRUGO, batch_show_active, batch_store_active);
  636. DEVICE_ATTR(batchdelay, S_IWUSR | S_IRUGO, batch_show_delay, batch_store_delay);
  637. DEVICE_ATTR(batchbatch, S_IWUSR | S_IRUGO, batch_show_batch, batch_store_batch);
  638. DEVICE_ATTR(batchflush, S_IWUSR | S_IRUGO, batch_show_flush, batch_store_flush);
  639. DEVICE_ATTR(batchdevnum, S_IWUSR | S_IRUGO, batch_show_devnum, NULL);
  640. static struct attribute *batch_attributes[] = {
  641. &dev_attr_batchactive.attr,
  642. &dev_attr_batchdelay.attr,
  643. &dev_attr_batchbatch.attr,
  644. &dev_attr_batchflush.attr,
  645. &dev_attr_batchdevnum.attr,
  646. NULL
  647. };
  648. static struct attribute_group batch_attribute_group = {
  649. .attrs = batch_attributes
  650. };
  651. int batch_register_data_path(int handle, struct batch_data_path *data)
  652. {
  653. struct batch_context *cxt = NULL;
  654. cxt = batch_context_obj;
  655. if (data == NULL) {
  656. BATCH_ERR("data pointer is null!\n");
  657. return -1;
  658. }
  659. if (handle >= 0 && handle <= (ID_SENSOR_MAX_HANDLE)) {
  660. cxt->dev_list.data_dev[handle].get_data = data->get_data;
  661. cxt->dev_list.data_dev[handle].flags = data->flags;
  662. cxt->dev_list.data_dev[handle].get_fifo_status = data->get_fifo_status;
  663. /* cxt ->dev_list.data_dev[handle].is_batch_supported = data->is_batch_supported; */
  664. return 0;
  665. }
  666. return -1;
  667. }
  668. int batch_register_control_path(int handle, struct batch_control_path *ctl)
  669. {
  670. struct batch_context *cxt = NULL;
  671. cxt = batch_context_obj;
  672. if (ctl == NULL) {
  673. BATCH_ERR("ctl pointer is null!\n");
  674. return -1;
  675. }
  676. if (handle >= 0 && handle <= (ID_SENSOR_MAX_HANDLE)) {
  677. cxt->dev_list.ctl_dev[handle].enable_hw_batch = ctl->enable_hw_batch;
  678. cxt->dev_list.ctl_dev[handle].flush = ctl->flush;
  679. return 0;
  680. }
  681. return -1;
  682. }
  683. int batch_register_support_info(int handle, int support, int div, int timestamp_supported)
  684. {
  685. struct batch_context *cxt = NULL;
  686. cxt = batch_context_obj;
  687. if (cxt == NULL) {
  688. if (0 == support)
  689. return 0;
  690. BATCH_ERR("cxt pointer is null!\n");
  691. return -1;
  692. }
  693. if (handle >= 0 && handle <= (ID_SENSOR_MAX_HANDLE)) {
  694. cxt->dev_list.data_dev[handle].is_batch_supported = support;
  695. cxt->dev_list.data_dev[handle].div = div;
  696. cxt->dev_list.data_dev[handle].is_timestamp_supported = timestamp_supported;
  697. cxt->dev_list.data_dev[handle].samplingPeriodMs = 200;
  698. cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs = 0;
  699. return 0;
  700. }
  701. return -1;
  702. }
  703. void report_batch_data(struct input_dev *dev, struct hwm_sensor_data *data)
  704. {
  705. struct hwm_sensor_data report_data;
  706. memcpy(&report_data, data, sizeof(struct hwm_sensor_data));
  707. if (report_data.sensor == ID_ACCELEROMETER || report_data.sensor == ID_MAGNETIC
  708. || report_data.sensor == ID_ORIENTATION || report_data.sensor == ID_GYROSCOPE){
  709. input_report_rel(dev, EVENT_TYPE_SENSORTYPE, IDToSensorType(report_data.sensor));
  710. input_report_abs(dev, EVENT_TYPE_BATCH_X, report_data.values[0]);
  711. input_report_abs(dev, EVENT_TYPE_BATCH_Y, report_data.values[1]);
  712. input_report_abs(dev, EVENT_TYPE_BATCH_Z, report_data.values[2]);
  713. input_report_abs(dev, EVENT_TYPE_BATCH_STATUS, report_data.status);
  714. input_report_rel(dev, EVENT_TYPE_TIMESTAMP_HI, (uint32_t) (report_data.time>>32)&0xFFFFFFFF);
  715. input_report_rel(dev, EVENT_TYPE_TIMESTAMP_LO, (uint32_t)(report_data.time&0xFFFFFFFF));
  716. input_sync(dev);
  717. } else {
  718. input_report_rel(dev, EVENT_TYPE_SENSORTYPE, IDToSensorType(report_data.sensor));
  719. input_report_abs(dev, EVENT_TYPE_BATCH_VALUE, report_data.values[0]);
  720. input_report_abs(dev, EVENT_TYPE_BATCH_STATUS, report_data.status);
  721. input_report_rel(dev, EVENT_TYPE_TIMESTAMP_HI, (uint32_t) (report_data.time>>32)&0xFFFFFFFF);
  722. input_report_rel(dev, EVENT_TYPE_TIMESTAMP_LO, (uint32_t)(report_data.time&0xFFFFFFFF));
  723. input_sync(dev);
  724. }
  725. }
  726. void report_batch_finish(struct input_dev *dev, int handle)
  727. {
  728. BATCH_LOG("fwq report_batch_finish rel+++++\n");
  729. input_report_rel(dev, EVENT_TYPE_END_FLAG, 1<<16|handle);
  730. input_sync(dev);
  731. BATCH_LOG("fwq report_batch_finish----\n");
  732. }
  733. static int sensorHub_remove(struct platform_device *pdev)
  734. {
  735. BATCH_LOG("sensorHub_remove\n");
  736. return 0;
  737. }
  738. static int sensorHub_probe(struct platform_device *pdev)
  739. {
  740. BATCH_LOG("sensorHub_probe\n");
  741. return 0;
  742. }
  743. static int sensorHub_suspend(struct platform_device *dev, pm_message_t state)
  744. {
  745. int handle;
  746. struct batch_context *cxt = NULL;
  747. int res;
  748. int en;
  749. BATCH_FUN();
  750. cxt = batch_context_obj;
  751. mutex_lock(&batch_hw_mutex);
  752. cxt->force_wake_upon_fifo_full = 0;
  753. for (handle = 0; handle <= ID_SENSOR_MAX_HANDLE; handle++) {
  754. if (cxt->dev_list.data_dev[handle].is_batch_supported) {
  755. en = (cxt->active_sensor & (0x01 << handle))?1:0;
  756. if (cxt->dev_list.ctl_dev[handle].enable_hw_batch != NULL) {
  757. res = cxt->dev_list.ctl_dev[handle].enable_hw_batch(handle,
  758. en, cxt->dev_list.data_dev[handle].flags|cxt->force_wake_upon_fifo_full,
  759. (long long)cxt->dev_list.data_dev[handle].samplingPeriodMs*1000000,
  760. (long long)cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs*1000000);
  761. if (res < 0)
  762. BATCH_ERR("enable_hw_batch fail, %d, %d\n", handle, res);
  763. } else if (cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch != NULL) {
  764. res = cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch(handle,
  765. en, cxt->dev_list.data_dev[handle].flags|cxt->force_wake_upon_fifo_full,
  766. (long long)cxt->dev_list.data_dev[handle].samplingPeriodMs*1000000,
  767. (long long)cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs*1000000);
  768. if (res < 0)
  769. BATCH_ERR("enable_hw_batch fail, %d, %d\n",
  770. ID_SENSOR_MAX_HANDLE, res);
  771. }
  772. }
  773. }
  774. mutex_unlock(&batch_hw_mutex);
  775. return 0;
  776. }
  777. /*----------------------------------------------------------------------------*/
  778. static int sensorHub_resume(struct platform_device *dev)
  779. {
  780. int handle;
  781. struct batch_context *cxt = NULL;
  782. int res;
  783. int en;
  784. BATCH_FUN();
  785. cxt = batch_context_obj;
  786. mutex_lock(&batch_hw_mutex);
  787. cxt->force_wake_upon_fifo_full = SENSORS_BATCH_WAKE_UPON_FIFO_FULL;
  788. for (handle = 0; handle <= ID_SENSOR_MAX_HANDLE; handle++) {
  789. if (cxt->dev_list.data_dev[handle].is_batch_supported) {
  790. en = (cxt->active_sensor & (0x01 << handle))?1:0;
  791. if (cxt->dev_list.ctl_dev[handle].enable_hw_batch != NULL) {
  792. res = cxt->dev_list.ctl_dev[handle].enable_hw_batch(handle,
  793. en, cxt->dev_list.data_dev[handle].flags|cxt->force_wake_upon_fifo_full,
  794. (long long)cxt->dev_list.data_dev[handle].samplingPeriodMs*1000000,
  795. (long long)cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs*1000000);
  796. if (res < 0)
  797. BATCH_ERR("enable_hw_batch fail, %d, %d\n", handle, res);
  798. } else if (cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch != NULL) {
  799. res = cxt->dev_list.ctl_dev[ID_SENSOR_MAX_HANDLE].enable_hw_batch(handle,
  800. en, cxt->dev_list.data_dev[handle].flags|cxt->force_wake_upon_fifo_full,
  801. (long long)cxt->dev_list.data_dev[handle].samplingPeriodMs*1000000,
  802. (long long)cxt->dev_list.data_dev[handle].maxBatchReportLatencyMs*1000000);
  803. if (res < 0)
  804. BATCH_ERR("enable_hw_batch fail, %d, %d\n",
  805. ID_SENSOR_MAX_HANDLE, res);
  806. }
  807. }
  808. }
  809. mutex_unlock(&batch_hw_mutex);
  810. return 0;
  811. }
  812. #ifdef CONFIG_OF
  813. static const struct of_device_id sensorHub_of_match[] = {
  814. { .compatible = "mediatek,sensorHub", },
  815. {},
  816. };
  817. #endif
  818. static struct platform_driver sensorHub_driver = {
  819. .probe = sensorHub_probe,
  820. .remove = sensorHub_remove,
  821. .suspend = sensorHub_suspend,
  822. .resume = sensorHub_resume,
  823. .driver = {
  824. .name = "sensorHub",
  825. #ifdef CONFIG_OF
  826. .of_match_table = sensorHub_of_match,
  827. #endif
  828. }
  829. };
  830. static int batch_real_driver_init(void)
  831. {
  832. int i = 0;
  833. int err = 0;
  834. BATCH_LOG(" batch_real_driver_init +\n");
  835. for (i = 0; i < MAX_CHOOSE_BATCH_NUM; i++) {
  836. BATCH_LOG(" i=%d\n", i);
  837. if (0 != batch_init_list[i]) {
  838. BATCH_LOG(" batch try to init driver %s\n", batch_init_list[i]->name);
  839. err = batch_init_list[i]->init();
  840. if (0 == err) {
  841. BATCH_LOG(" batch real driver %s probe ok\n", batch_init_list[i]->name);
  842. break;
  843. }
  844. }
  845. }
  846. if (i == MAX_CHOOSE_BATCH_NUM) {
  847. BATCH_LOG(" batch_real_driver_init fail\n");
  848. err = -1;
  849. }
  850. return err;
  851. }
  852. int batch_driver_add(struct batch_init_info *obj)
  853. {
  854. int err = 0;
  855. int i = 0;
  856. BATCH_FUN();
  857. if (!obj) {
  858. BATCH_ERR("batch driver add fail, batch_init_info is NULL\n");
  859. return -1;
  860. }
  861. for (i = 0; i < MAX_CHOOSE_BATCH_NUM; i++) {
  862. if (i == 0) {
  863. BATCH_LOG("register sensorHub driver for the first time\n");
  864. if (platform_driver_register(&sensorHub_driver))
  865. BATCH_ERR("failed to register sensorHub driver already exist\n");
  866. }
  867. if (NULL == batch_init_list[i]) {
  868. obj->platform_diver_addr = &sensorHub_driver;
  869. batch_init_list[i] = obj;
  870. break;
  871. }
  872. }
  873. if (i >= MAX_CHOOSE_BATCH_NUM) {
  874. BATCH_LOG("batch driver add err\n");
  875. err = -1;
  876. }
  877. return err;
  878. }
  879. EXPORT_SYMBOL_GPL(batch_driver_add);
  880. static int batch_probe(void)
  881. {
  882. int err;
  883. BATCH_LOG("+++++++++++++batch_probe!!\n");
  884. batch_context_obj = batch_context_alloc_object();
  885. if (!batch_context_obj) {
  886. err = -ENOMEM;
  887. BATCH_ERR("unable to allocate devobj!\n");
  888. goto exit_alloc_data_failed;
  889. }
  890. err = batch_real_driver_init();
  891. if (err) {
  892. BATCH_ERR("batch real driver init fail\n");
  893. goto real_driver_init_fail;
  894. }
  895. /* init input dev */
  896. err = batch_input_init(batch_context_obj);
  897. if (err) {
  898. BATCH_ERR("unable to register batch input device!\n");
  899. goto exit_alloc_input_dev_failed;
  900. }
  901. /* add misc dev for sensor hal control cmd */
  902. err = batch_misc_init(batch_context_obj);
  903. if (err) {
  904. BATCH_ERR("unable to register batch misc device!!\n");
  905. goto exit_err_sysfs;
  906. }
  907. err = sysfs_create_group(&batch_context_obj->mdev.this_device->kobj,
  908. &batch_attribute_group);
  909. if (err < 0) {
  910. BATCH_ERR("unable to create batch attribute file\n");
  911. goto exit_misc_register_failed;
  912. }
  913. kobject_uevent(&batch_context_obj->mdev.this_device->kobj, KOBJ_ADD);
  914. BATCH_LOG("----batch_probe OK !!\n");
  915. return 0;
  916. exit_misc_register_failed:
  917. err = misc_deregister(&batch_context_obj->mdev);
  918. if (err)
  919. BATCH_ERR("misc_deregister fail: %d\n", err);
  920. exit_err_sysfs:
  921. if (err) {
  922. BATCH_ERR("sysfs node creation error\n");
  923. batch_input_destroy(batch_context_obj);
  924. }
  925. real_driver_init_fail:
  926. exit_alloc_input_dev_failed:
  927. kfree(batch_context_obj);
  928. batch_context_obj = NULL;
  929. exit_alloc_data_failed:
  930. BATCH_LOG("----batch_probe fail !!!\n");
  931. return err;
  932. }
  933. static int batch_remove(void)
  934. {
  935. int err = 0;
  936. BATCH_FUN(f);
  937. input_unregister_device(batch_context_obj->idev);
  938. sysfs_remove_group(&batch_context_obj->idev->dev.kobj,
  939. &batch_attribute_group);
  940. err = misc_deregister(&batch_context_obj->mdev);
  941. if (err)
  942. BATCH_ERR("misc_deregister fail: %d\n", err);
  943. kfree(batch_context_obj);
  944. return 0;
  945. }
  946. static int __init batch_init(void)
  947. {
  948. BATCH_FUN();
  949. if (batch_probe()) {
  950. BATCH_ERR("failed to register batch driver\n");
  951. return -ENODEV;
  952. }
  953. return 0;
  954. }
  955. static void __exit batch_exit(void)
  956. {
  957. batch_remove();
  958. platform_driver_unregister(&sensorHub_driver);
  959. }
  960. late_initcall(batch_init);
  961. MODULE_LICENSE("GPL");
  962. MODULE_DESCRIPTION("batch device driver");
  963. MODULE_AUTHOR("Mediatek");