heart_rate.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. #include "heart_rate.h"
  2. struct hrm_context *hrm_context_obj = NULL;
  3. static struct hrm_init_info *heart_rate_init_list[MAX_CHOOSE_HRM_NUM] = { 0 }; /* modified */
  4. static void hrm_early_suspend(struct early_suspend *h);
  5. static void hrm_late_resume(struct early_suspend *h);
  6. static void hrm_work_func(struct work_struct *work)
  7. {
  8. struct hrm_context *cxt = NULL;
  9. /* int out_size; */
  10. /* hwm_sensor_data sensor_data; */
  11. /* u64 data64[6]; //for unify get_data parameter type */
  12. u32 data32[6]; /* for hwm_sensor_data.values as int */
  13. /* u64 data[4]; */
  14. int status;
  15. int64_t nt;
  16. struct timespec time;
  17. int err = 0;
  18. cxt = hrm_context_obj;
  19. if (NULL == cxt->hrm_data.get_data)
  20. HRM_ERR("hrm driver not register data path\n");
  21. time.tv_sec = time.tv_nsec = 0;
  22. time = get_monotonic_coarse();
  23. nt = time.tv_sec * 1000000000LL + time.tv_nsec;
  24. /* add wake lock to make sure data can be read before system suspend */
  25. /* initial data */
  26. /* data[0] = cxt->drv_data.hrm_data.values[0]; */
  27. /* data[1] = cxt->drv_data.hrm_data.values[1]; */
  28. /* data[2] = cxt->drv_data.hrm_data.values[2]; */
  29. /* data[3] = cxt->drv_data.hrm_data.values[3]; */
  30. err = cxt->hrm_data.get_data(data32, &status);
  31. HRM_LOG("hrm get_data %d,%d,%d %d\n", data32[0], data32[1], data32[2], data32[3]);
  32. if (err) {
  33. HRM_ERR("get hrm data fails!!\n");
  34. goto hrm_loop;
  35. } else {
  36. if ((data32[0] == cxt->drv_data.hrm_data.values[0])
  37. && (data32[1] == cxt->drv_data.hrm_data.values[1])
  38. && (data32[2] == cxt->drv_data.hrm_data.values[2])
  39. && (data32[3] == cxt->drv_data.hrm_data.values[3])) {
  40. goto hrm_loop;
  41. } else {
  42. cxt->drv_data.hrm_data.values[0] = data32[0];
  43. cxt->drv_data.hrm_data.values[1] = data32[1];
  44. cxt->drv_data.hrm_data.values[2] = data32[2];
  45. cxt->drv_data.hrm_data.values[3] = data32[3];
  46. HRM_LOG("hrm values %d,%d,%d,%d\n",
  47. cxt->drv_data.hrm_data.values[0],
  48. cxt->drv_data.hrm_data.values[1],
  49. cxt->drv_data.hrm_data.values[2], cxt->drv_data.hrm_data.values[3]);
  50. cxt->drv_data.hrm_data.status = status;
  51. cxt->drv_data.hrm_data.time = nt;
  52. }
  53. }
  54. if (true == cxt->is_first_data_after_enable) {
  55. cxt->is_first_data_after_enable = false;
  56. /* filter -1 value */
  57. if (HRM_INVALID_VALUE == cxt->drv_data.hrm_data.values[0] ||
  58. HRM_INVALID_VALUE == cxt->drv_data.hrm_data.values[1] ||
  59. HRM_INVALID_VALUE == cxt->drv_data.hrm_data.values[2] ||
  60. HRM_INVALID_VALUE == cxt->drv_data.hrm_data.values[3]) {
  61. HRM_LOG(" read invalid data\n");
  62. goto hrm_loop;
  63. }
  64. }
  65. /* report data to input device */
  66. /* printk("new hrm work run....\n"); */
  67. HRM_LOG("hrm data %d,%d,%d %d\n", cxt->drv_data.hrm_data.values[0],
  68. cxt->drv_data.hrm_data.values[1], cxt->drv_data.hrm_data.values[2],
  69. cxt->drv_data.hrm_data.values[3]);
  70. hrm_data_report(cxt->drv_data.hrm_data, cxt->drv_data.hrm_data.status);
  71. hrm_loop:
  72. if (true == cxt->is_polling_run)
  73. mod_timer(&cxt->timer, jiffies + atomic_read(&cxt->delay) / (1000 / HZ));
  74. }
  75. static void hrm_poll(unsigned long data)
  76. {
  77. struct hrm_context *obj = (struct hrm_context *)data;
  78. if (obj != NULL)
  79. schedule_work(&obj->report);
  80. }
  81. static struct hrm_context *hrm_context_alloc_object(void)
  82. {
  83. struct hrm_context *obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  84. HRM_LOG("hrm_context_alloc_object++++\n");
  85. if (!obj) {
  86. HRM_ERR("Alloc hrm object error!\n");
  87. return NULL;
  88. }
  89. atomic_set(&obj->delay, 200); /*5Hz set work queue delay time 200ms */
  90. atomic_set(&obj->wake, 0);
  91. INIT_WORK(&obj->report, hrm_work_func);
  92. init_timer(&obj->timer);
  93. obj->timer.expires = jiffies + atomic_read(&obj->delay) / (1000 / HZ);
  94. obj->timer.function = hrm_poll;
  95. obj->timer.data = (unsigned long)obj;
  96. obj->is_first_data_after_enable = false;
  97. obj->is_polling_run = false;
  98. obj->is_batch_enable = false;
  99. mutex_init(&obj->hrm_op_mutex);
  100. HRM_LOG("hrm_context_alloc_object----\n");
  101. return obj;
  102. }
  103. static int hrm_real_enable(int enable)
  104. {
  105. int err = 0;
  106. struct hrm_context *cxt = NULL;
  107. cxt = hrm_context_obj;
  108. if (1 == enable) {
  109. if (true == cxt->is_active_data || true == cxt->is_active_nodata) {
  110. err = cxt->hrm_ctl.enable_nodata(1);
  111. if (err) {
  112. err = cxt->hrm_ctl.enable_nodata(1);
  113. if (err) {
  114. err = cxt->hrm_ctl.enable_nodata(1);
  115. if (err)
  116. HRM_ERR("hrm enable(%d) err 3 timers = %d\n",
  117. enable, err);
  118. }
  119. }
  120. HRM_LOG("hrm real enable\n");
  121. }
  122. }
  123. if (0 == enable) {
  124. if (false == cxt->is_active_data && false == cxt->is_active_nodata) {
  125. err = cxt->hrm_ctl.enable_nodata(0);
  126. if (err)
  127. HRM_ERR("hrm enable(%d) err = %d\n", enable, err);
  128. HRM_LOG("hrm real disable\n");
  129. }
  130. }
  131. return err;
  132. }
  133. static int hrm_enable_data(int enable)
  134. {
  135. struct hrm_context *cxt = NULL;
  136. cxt = hrm_context_obj;
  137. if (NULL == cxt->hrm_ctl.open_report_data) {
  138. HRM_ERR("no hrm control path\n");
  139. return -1;
  140. }
  141. if (1 == enable) {
  142. HRM_LOG("hrm enable data\n");
  143. cxt->is_active_data = true;
  144. cxt->is_first_data_after_enable = true;
  145. cxt->hrm_ctl.open_report_data(1);
  146. if (false == cxt->is_polling_run && cxt->is_batch_enable == false) {
  147. if (false == cxt->hrm_ctl.is_report_input_direct) {
  148. mod_timer(&cxt->timer,
  149. jiffies + atomic_read(&cxt->delay) / (1000 / HZ));
  150. cxt->is_polling_run = true;
  151. }
  152. }
  153. }
  154. if (0 == enable) {
  155. HRM_LOG("hrm disable\n");
  156. cxt->is_active_data = false;
  157. cxt->hrm_ctl.open_report_data(0);
  158. if (true == cxt->is_polling_run) {
  159. if (false == cxt->hrm_ctl.is_report_input_direct) {
  160. cxt->is_polling_run = false;
  161. del_timer_sync(&cxt->timer);
  162. cancel_work_sync(&cxt->report);
  163. cxt->drv_data.hrm_data.values[0] = HRM_INVALID_VALUE;
  164. cxt->drv_data.hrm_data.values[1] = HRM_INVALID_VALUE;
  165. cxt->drv_data.hrm_data.values[2] = HRM_INVALID_VALUE;
  166. cxt->drv_data.hrm_data.values[3] = HRM_INVALID_VALUE;
  167. }
  168. }
  169. }
  170. hrm_real_enable(enable);
  171. return 0;
  172. }
  173. int hrm_enable_nodata(int enable)
  174. {
  175. struct hrm_context *cxt = NULL;
  176. cxt = hrm_context_obj;
  177. if (NULL == cxt->hrm_ctl.enable_nodata) {
  178. HRM_ERR("hrm_enable_nodata:hrm ctl path is NULL\n");
  179. return -1;
  180. }
  181. if (1 == enable)
  182. cxt->is_active_nodata = true;
  183. if (0 == enable)
  184. cxt->is_active_nodata = false;
  185. hrm_real_enable(enable);
  186. return 0;
  187. }
  188. static ssize_t hrm_show_enable_nodata(struct device *dev, struct device_attribute *attr, char *buf)
  189. {
  190. int len = 0;
  191. HRM_LOG(" not support now\n");
  192. return len;
  193. }
  194. static ssize_t hrm_store_enable_nodata(struct device *dev, struct device_attribute *attr,
  195. const char *buf, size_t count)
  196. {
  197. struct hrm_context *cxt = NULL;
  198. /* int err =0; */
  199. HRM_LOG("hrm_store_enable nodata buf=%s\n", buf);
  200. mutex_lock(&hrm_context_obj->hrm_op_mutex);
  201. cxt = hrm_context_obj;
  202. if (NULL == cxt->hrm_ctl.enable_nodata) {
  203. HRM_LOG("hrm_ctl enable nodata NULL\n");
  204. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  205. return count;
  206. }
  207. if (!strncmp(buf, "1", 1))
  208. hrm_enable_nodata(1);
  209. else if (!strncmp(buf, "0", 1))
  210. hrm_enable_nodata(0);
  211. else
  212. HRM_ERR(" hrm_store enable nodata cmd error !!\n");
  213. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  214. return count;
  215. }
  216. static ssize_t hrm_store_active(struct device *dev, struct device_attribute *attr,
  217. const char *buf, size_t count)
  218. {
  219. struct hrm_context *cxt = NULL;
  220. HRM_LOG("hrm_store_active buf=%s\n", buf);
  221. mutex_lock(&hrm_context_obj->hrm_op_mutex);
  222. cxt = hrm_context_obj;
  223. if (NULL == cxt->hrm_ctl.open_report_data) {
  224. HRM_LOG("hrm_ctl enable NULL\n");
  225. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  226. return count;
  227. }
  228. if (!strncmp(buf, "1", 1))
  229. hrm_enable_data(1);
  230. else if (!strncmp(buf, "0", 1))
  231. hrm_enable_data(0);
  232. else
  233. HRM_ERR(" hrm_store_active error !!\n");
  234. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  235. HRM_LOG(" hrm_store_active done\n");
  236. return count;
  237. }
  238. /*----------------------------------------------------------------------------*/
  239. static ssize_t hrm_show_active(struct device *dev, struct device_attribute *attr, char *buf)
  240. {
  241. struct hrm_context *cxt = NULL;
  242. int div = 0;
  243. cxt = hrm_context_obj;
  244. /* int len = 0; */
  245. HRM_LOG("hrm show active not support now\n");
  246. /* div=cxt->hrm_data.vender_div; */
  247. HRM_LOG("hrm vender_div value: %d\n", div);
  248. return snprintf(buf, PAGE_SIZE, "%d\n", div);
  249. /* return len; */
  250. }
  251. static ssize_t hrm_store_delay(struct device *dev, struct device_attribute *attr,
  252. const char *buf, size_t count)
  253. {
  254. /* struct hrm_context *devobj = (struct hrm_context*)dev_get_drvdata(dev); */
  255. int delay;
  256. int mdelay = 0;
  257. struct hrm_context *cxt = NULL;
  258. int err = 0;
  259. mutex_lock(&hrm_context_obj->hrm_op_mutex);
  260. cxt = hrm_context_obj;
  261. if (NULL == cxt->hrm_ctl.set_delay) {
  262. HRM_LOG("hrm_ctl set_delay NULL\n");
  263. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  264. return count;
  265. }
  266. err = kstrtoint(buf, 10, &delay);
  267. if (err != 0) {
  268. HRM_ERR("invalid format!!\n");
  269. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  270. return count;
  271. }
  272. if (false == cxt->hrm_ctl.is_report_input_direct) {
  273. mdelay = (int)delay / 1000 / 1000;
  274. atomic_set(&hrm_context_obj->delay, mdelay);
  275. }
  276. cxt->hrm_ctl.set_delay(delay);
  277. HRM_LOG(" hrm_delay %d ns\n", delay);
  278. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  279. return count;
  280. }
  281. static ssize_t hrm_show_delay(struct device *dev, struct device_attribute *attr, char *buf)
  282. {
  283. int len = 0;
  284. HRM_LOG(" not support now\n");
  285. return len;
  286. }
  287. static ssize_t hrm_store_batch(struct device *dev, struct device_attribute *attr,
  288. const char *buf, size_t count)
  289. {
  290. struct hrm_context *cxt = NULL;
  291. /* int err =0; */
  292. HRM_LOG("hrm_store_batch buf=%s\n", buf);
  293. mutex_lock(&hrm_context_obj->hrm_op_mutex);
  294. cxt = hrm_context_obj;
  295. if (cxt->hrm_ctl.is_support_batch) {
  296. if (!strncmp(buf, "1", 1))
  297. cxt->is_batch_enable = true;
  298. else if (!strncmp(buf, "0", 1))
  299. cxt->is_batch_enable = false;
  300. else
  301. HRM_ERR(" hrm_store_batch error !!\n");
  302. } else {
  303. HRM_LOG(" hrm_store_batch not support\n");
  304. }
  305. mutex_unlock(&hrm_context_obj->hrm_op_mutex);
  306. HRM_LOG(" hrm_store_batch done: %d\n", cxt->is_batch_enable);
  307. return count;
  308. }
  309. static ssize_t hrm_show_batch(struct device *dev, struct device_attribute *attr, char *buf)
  310. {
  311. return snprintf(buf, PAGE_SIZE, "%d\n", 0);
  312. }
  313. static ssize_t hrm_store_flush(struct device *dev, struct device_attribute *attr,
  314. const char *buf, size_t count)
  315. {
  316. /* mutex_lock(&hrm_context_obj->hrm_op_mutex); */
  317. /* struct hrm_context *devobj = (struct hrm_context*)dev_get_drvdata(dev); */
  318. /* do read FIFO data function and report data immediately */
  319. /* mutex_unlock(&hrm_context_obj->hrm_op_mutex); */
  320. return count;
  321. }
  322. static ssize_t hrm_show_flush(struct device *dev, struct device_attribute *attr, char *buf)
  323. {
  324. return snprintf(buf, PAGE_SIZE, "%d\n", 0);
  325. }
  326. static ssize_t hrm_show_devnum(struct device *dev, struct device_attribute *attr, char *buf)
  327. {
  328. const char *devname = NULL;
  329. devname = dev_name(&hrm_context_obj->idev->dev);
  330. return snprintf(buf, PAGE_SIZE, "%s\n", devname + 5);
  331. }
  332. static int heart_rate_remove(struct platform_device *pdev)
  333. {
  334. HRM_LOG("heart_rate_remove\n");
  335. return 0;
  336. }
  337. static int heart_rate_probe(struct platform_device *pdev)
  338. {
  339. HRM_LOG("heart_rate_probe\n");
  340. return 0;
  341. }
  342. #ifdef CONFIG_OF
  343. static const struct of_device_id heart_rate_of_match[] = {
  344. {.compatible = "mediatek,heart_rate",},
  345. {},
  346. };
  347. #endif
  348. static struct platform_driver heart_rate_driver = {
  349. .probe = heart_rate_probe,
  350. .remove = heart_rate_remove,
  351. .driver = {
  352. .name = "heart_rate",
  353. #ifdef CONFIG_OF
  354. .of_match_table = heart_rate_of_match,
  355. #endif
  356. }
  357. };
  358. static int hrm_real_driver_init(void)
  359. {
  360. int i = 0;
  361. int err = 0;
  362. HRM_LOG(" hrm_real_driver_init +\n");
  363. for (i = 0; i < MAX_CHOOSE_HRM_NUM; i++) {
  364. HRM_LOG(" i=%d\n", i);
  365. if (0 != heart_rate_init_list[i]) {
  366. HRM_LOG(" hrm try to init driver %s\n", heart_rate_init_list[i]->name);
  367. err = heart_rate_init_list[i]->init();
  368. if (0 == err) {
  369. HRM_LOG(" hrm real driver %s probe ok\n",
  370. heart_rate_init_list[i]->name);
  371. break;
  372. }
  373. }
  374. }
  375. if (i == MAX_CHOOSE_HRM_NUM) {
  376. HRM_LOG(" hrm_real_driver_init fail\n");
  377. err = -1;
  378. }
  379. return err;
  380. }
  381. int hrm_driver_add(struct hrm_init_info *obj)
  382. {
  383. int err = 0;
  384. int i = 0;
  385. HRM_FUN(f);
  386. for (i = 0; i < MAX_CHOOSE_HRM_NUM; i++) {
  387. if (i == 0) {
  388. HRM_LOG("register hrm driver for the first time\n");
  389. if (platform_driver_register(&heart_rate_driver))
  390. HRM_ERR("failed to register hrm driver already exist\n");
  391. }
  392. if (NULL == heart_rate_init_list[i]) {
  393. obj->platform_diver_addr = &heart_rate_driver;
  394. heart_rate_init_list[i] = obj;
  395. break;
  396. }
  397. }
  398. if (NULL == heart_rate_init_list[i]) {
  399. HRM_ERR("hrm driver add err\n");
  400. err = -1;
  401. }
  402. return err;
  403. } EXPORT_SYMBOL_GPL(hrm_driver_add);
  404. static int hrm_misc_init(struct hrm_context *cxt)
  405. {
  406. int err = 0;
  407. /* kernel-3.10\include\linux\Miscdevice.h */
  408. /* use MISC_DYNAMIC_MINOR exceed 64 */
  409. cxt->mdev.minor = M_HRM_MISC_MINOR;
  410. cxt->mdev.name = HRM_MISC_DEV_NAME;
  411. err = misc_register(&cxt->mdev);
  412. if (err)
  413. HRM_ERR("unable to register hrm misc device!!\n");
  414. return err;
  415. }
  416. static void hrm_input_destroy(struct hrm_context *cxt)
  417. {
  418. struct input_dev *dev = cxt->idev;
  419. input_unregister_device(dev);
  420. input_free_device(dev);
  421. }
  422. static int hrm_input_init(struct hrm_context *cxt)
  423. {
  424. struct input_dev *dev;
  425. int err = 0;
  426. dev = input_allocate_device();
  427. if (NULL == dev)
  428. return -ENOMEM;
  429. dev->name = HRM_INPUTDEV_NAME;
  430. input_set_capability(dev, EV_ABS, EVENT_TYPE_HRM_BPM);
  431. input_set_capability(dev, EV_ABS, EVENT_TYPE_HRM_STATUS);
  432. input_set_abs_params(dev, EVENT_TYPE_HRM_BPM, HRM_VALUE_MIN, HRM_VALUE_MAX, 0, 0);
  433. input_set_abs_params(dev, EVENT_TYPE_HRM_STATUS, HRM_VALUE_MIN, HRM_VALUE_MAX, 0, 0);
  434. input_set_drvdata(dev, cxt);
  435. err = input_register_device(dev);
  436. if (err < 0) {
  437. input_free_device(dev);
  438. return err;
  439. }
  440. cxt->idev = dev;
  441. return 0;
  442. }
  443. DEVICE_ATTR(hrmenablenodata, S_IWUSR | S_IRUGO, hrm_show_enable_nodata, hrm_store_enable_nodata);
  444. DEVICE_ATTR(hrmactive, S_IWUSR | S_IRUGO, hrm_show_active, hrm_store_active);
  445. DEVICE_ATTR(hrmdelay, S_IWUSR | S_IRUGO, hrm_show_delay, hrm_store_delay);
  446. DEVICE_ATTR(hrmbatch, S_IWUSR | S_IRUGO, hrm_show_batch, hrm_store_batch);
  447. DEVICE_ATTR(hrmflush, S_IWUSR | S_IRUGO, hrm_show_flush, hrm_store_flush);
  448. DEVICE_ATTR(hrmdevnum, S_IWUSR | S_IRUGO, hrm_show_devnum, NULL);
  449. static struct attribute *hrm_attributes[] = {
  450. &dev_attr_hrmenablenodata.attr,
  451. &dev_attr_hrmactive.attr,
  452. &dev_attr_hrmdelay.attr,
  453. &dev_attr_hrmbatch.attr,
  454. &dev_attr_hrmflush.attr,
  455. &dev_attr_hrmdevnum.attr,
  456. NULL
  457. };
  458. static struct attribute_group hrm_attribute_group = {
  459. .attrs = hrm_attributes
  460. };
  461. int hrm_register_data_path(struct hrm_data_path *data)
  462. {
  463. struct hrm_context *cxt = NULL;
  464. /* int err =0; */
  465. cxt = hrm_context_obj;
  466. cxt->hrm_data.get_data = data->get_data;
  467. /* cxt->hrm_data.vender_div = data->vender_div; */
  468. /* cxt->hrm_data.get_raw_data = data->get_raw_data; */
  469. /* HRM_LOG("hrm register data path vender_div: %d\n", cxt->hrm_data.vender_div); */
  470. if (NULL == cxt->hrm_data.get_data) {
  471. HRM_LOG("hrm register data path fail\n");
  472. return -1;
  473. }
  474. return 0;
  475. }
  476. int hrm_register_control_path(struct hrm_control_path *ctl)
  477. {
  478. struct hrm_context *cxt = NULL;
  479. int err = 0;
  480. cxt = hrm_context_obj;
  481. cxt->hrm_ctl.set_delay = ctl->set_delay;
  482. cxt->hrm_ctl.open_report_data = ctl->open_report_data;
  483. cxt->hrm_ctl.enable_nodata = ctl->enable_nodata;
  484. cxt->hrm_ctl.is_support_batch = ctl->is_support_batch;
  485. if (NULL == cxt->hrm_ctl.set_delay || NULL == cxt->hrm_ctl.open_report_data
  486. || NULL == cxt->hrm_ctl.enable_nodata) {
  487. HRM_LOG("hrm register control path fail\n");
  488. return -1;
  489. }
  490. /* add misc dev for sensor hal control cmd */
  491. err = hrm_misc_init(hrm_context_obj);
  492. if (err) {
  493. HRM_ERR("unable to register hrm misc device!!\n");
  494. return -2;
  495. }
  496. err = sysfs_create_group(&hrm_context_obj->mdev.this_device->kobj, &hrm_attribute_group);
  497. if (err < 0) {
  498. HRM_ERR("unable to create hrm attribute file\n");
  499. return -3;
  500. }
  501. kobject_uevent(&hrm_context_obj->mdev.this_device->kobj, KOBJ_ADD);
  502. return 0;
  503. }
  504. int hrm_data_report(hwm_sensor_data data, int status)
  505. {
  506. struct hrm_context *cxt = NULL;
  507. int err = 0;
  508. HRM_LOG("+hrm_data_report! %d, %d, %d, %d\n", data.values[0], data.values[1],
  509. data.values[2], data.values[3]);
  510. cxt = hrm_context_obj;
  511. input_report_abs(cxt->idev, EVENT_TYPE_HRM_BPM, data.values[0]);
  512. input_report_abs(cxt->idev, EVENT_TYPE_HRM_STATUS, data.values[1]);
  513. input_sync(cxt->idev);
  514. return err;
  515. }
  516. static int hrm_probe(struct platform_device *pdev)
  517. {
  518. int err;
  519. HRM_LOG("+++++++++++++hrm_probe!!\n");
  520. hrm_context_obj = hrm_context_alloc_object();
  521. if (!hrm_context_obj) {
  522. err = -ENOMEM;
  523. HRM_ERR("unable to allocate devobj!\n");
  524. goto exit_alloc_data_failed;
  525. }
  526. /* init real hrmeleration driver */
  527. err = hrm_real_driver_init();
  528. if (err) {
  529. HRM_ERR("hrm real driver init fail\n");
  530. goto real_driver_init_fail;
  531. }
  532. /* err = hrm_factory_device_init(); */
  533. /* if(err) */
  534. /* { */
  535. /* HRM_ERR("hrm_factory_device_init fail\n"); */
  536. /* } */
  537. /* init input dev */
  538. err = hrm_input_init(hrm_context_obj);
  539. if (err) {
  540. HRM_ERR("unable to register hrm input device!\n");
  541. goto exit_alloc_input_dev_failed;
  542. }
  543. #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_EARLYSUSPEND)
  544. atomic_set(&(hrm_context_obj->early_suspend), 0);
  545. hrm_context_obj->early_drv.level = EARLY_SUSPEND_LEVEL_STOP_DRAWING - 1,
  546. hrm_context_obj->early_drv.suspend = hrm_early_suspend,
  547. hrm_context_obj->early_drv.resume = hrm_late_resume,
  548. register_early_suspend(&hrm_context_obj->early_drv);
  549. #endif /* #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_EARLYSUSPEND) */
  550. HRM_LOG("----hrm_probe OK !!\n");
  551. return 0;
  552. /* exit_hwmsen_create_attr_failed: */
  553. /* exit_misc_register_failed: */
  554. /* exit_err_sysfs: */
  555. if (err) {
  556. HRM_ERR("sysfs node creation error\n");
  557. hrm_input_destroy(hrm_context_obj);
  558. }
  559. real_driver_init_fail:
  560. exit_alloc_input_dev_failed:
  561. kfree(hrm_context_obj);
  562. exit_alloc_data_failed:
  563. HRM_LOG("----hrm_probe fail !!!\n");
  564. return err;
  565. }
  566. static int hrm_remove(struct platform_device *pdev)
  567. {
  568. int err = 0;
  569. HRM_FUN(f);
  570. input_unregister_device(hrm_context_obj->idev);
  571. sysfs_remove_group(&hrm_context_obj->idev->dev.kobj, &hrm_attribute_group);
  572. err = misc_deregister(&hrm_context_obj->mdev);
  573. if (err)
  574. HRM_ERR("misc_deregister fail: %d\n", err);
  575. kfree(hrm_context_obj);
  576. return 0;
  577. }
  578. static void hrm_early_suspend(struct early_suspend *h)
  579. {
  580. atomic_set(&(hrm_context_obj->early_suspend), 1);
  581. HRM_LOG(" hrm_early_suspend ok------->hwm_obj->early_suspend=%d\n",
  582. atomic_read(&(hrm_context_obj->early_suspend)));
  583. }
  584. /*----------------------------------------------------------------------------*/
  585. static void hrm_late_resume(struct early_suspend *h)
  586. {
  587. atomic_set(&(hrm_context_obj->early_suspend), 0);
  588. HRM_LOG(" hrm_late_resume ok------->hwm_obj->early_suspend=%d\n",
  589. atomic_read(&(hrm_context_obj->early_suspend)));
  590. }
  591. static int hrm_suspend(struct platform_device *dev, pm_message_t state)
  592. {
  593. return 0;
  594. }
  595. /*----------------------------------------------------------------------------*/
  596. static int hrm_resume(struct platform_device *dev)
  597. {
  598. return 0;
  599. }
  600. #ifdef CONFIG_OF
  601. static const struct of_device_id m_hrm_pl_of_match[] = {
  602. {.compatible = "mediatek,m_hrm_pl",},
  603. {},
  604. };
  605. #endif
  606. static struct platform_driver hrm_driver = {
  607. .probe = hrm_probe,
  608. .remove = hrm_remove,
  609. .suspend = hrm_suspend,
  610. .resume = hrm_resume,
  611. .driver = {
  612. .name = HRM_PL_DEV_NAME, /* mt_hrm_pl */
  613. #ifdef CONFIG_OF
  614. .of_match_table = m_hrm_pl_of_match,
  615. #endif
  616. }
  617. };
  618. static int __init hrm_init(void)
  619. {
  620. HRM_FUN(f);
  621. if (platform_driver_register(&hrm_driver)) {
  622. HRM_ERR("failed to register hrm driver\n");
  623. return -ENODEV;
  624. }
  625. return 0;
  626. }
  627. static void __exit hrm_exit(void)
  628. {
  629. platform_driver_unregister(&hrm_driver);
  630. platform_driver_unregister(&heart_rate_driver);
  631. }
  632. late_initcall(hrm_init);
  633. /* module_init(hrm_init); */
  634. /* module_exit(hrm_exit); */
  635. MODULE_LICENSE("GPL");
  636. MODULE_DESCRIPTION("HEART_RATE device driver");
  637. MODULE_AUTHOR("Mediatek");