common_timer.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*
  2. * common_timer.c - Linux kernel modules for sensortek stk6d2x
  3. * ambient light sensor (Common function)
  4. *
  5. * Copyright (C) 2019 Bk, sensortek Inc.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <linux/input.h>
  22. #include <linux/module.h>
  23. #include <linux/of.h>
  24. #include <linux/types.h>
  25. #include <linux/pm.h>
  26. #include <linux/delay.h>
  27. #include <linux/pm_wakeup.h>
  28. #include <common_define.h>
  29. typedef struct timer_manager timer_manager;
  30. struct timer_manager
  31. {
  32. struct work_struct stk_work;
  33. struct hrtimer stk_hrtimer;
  34. struct workqueue_struct *stk_wq;
  35. ktime_t timer_interval;
  36. stk_timer_info *timer_info;
  37. } timer_mgr_default = {.timer_info = 0};
  38. #define MAX_LINUX_TIMER_MANAGER_NUM 5
  39. timer_manager linux_timer_mgr[MAX_LINUX_TIMER_MANAGER_NUM];
  40. static timer_manager* parser_timer(struct hrtimer *timer)
  41. {
  42. int timer_idx = 0;
  43. if (timer == NULL)
  44. {
  45. return NULL;
  46. }
  47. for (timer_idx = 0; timer_idx < MAX_LINUX_TIMER_MANAGER_NUM; timer_idx ++)
  48. {
  49. if (&linux_timer_mgr[timer_idx].stk_hrtimer == timer)
  50. {
  51. return &linux_timer_mgr[timer_idx];
  52. }
  53. }
  54. return NULL;
  55. }
  56. static enum hrtimer_restart timer_func(struct hrtimer *timer)
  57. {
  58. timer_manager *timer_mgr = parser_timer(timer);
  59. if (timer_mgr == NULL)
  60. {
  61. printk(KERN_ERR "%s: timer_mgr is NULL\n", __func__);
  62. return HRTIMER_NORESTART;
  63. }
  64. if (timer_mgr->stk_wq == NULL)
  65. {
  66. printk(KERN_ERR "%s: timer_mgr->stk_wq is NULL\n", __func__);
  67. return HRTIMER_NORESTART;
  68. }
  69. if (timer_mgr->timer_info == NULL)
  70. {
  71. printk(KERN_ERR "%s: timer_mgr->timer_info is NULL\n", __func__);
  72. return HRTIMER_NORESTART;
  73. }
  74. queue_work(timer_mgr->stk_wq, &timer_mgr->stk_work);
  75. hrtimer_forward_now(&timer_mgr->stk_hrtimer, timer_mgr->timer_interval);
  76. return HRTIMER_RESTART;
  77. }
  78. static timer_manager* parser_work(struct work_struct *work)
  79. {
  80. int timer_idx = 0;
  81. if (work == NULL)
  82. {
  83. return NULL;
  84. }
  85. for (timer_idx = 0; timer_idx < MAX_LINUX_TIMER_MANAGER_NUM; timer_idx ++)
  86. {
  87. if (&linux_timer_mgr[timer_idx].stk_work == work)
  88. {
  89. return &linux_timer_mgr[timer_idx];
  90. }
  91. }
  92. return NULL;
  93. }
  94. static void timer_callback(struct work_struct *work)
  95. {
  96. timer_manager *timer_mgr = parser_work(work);
  97. if (timer_mgr == NULL)
  98. {
  99. return;
  100. }
  101. timer_mgr->timer_info->timer_cb(timer_mgr->timer_info);
  102. }
  103. int register_timer(stk_timer_info *t_info)
  104. {
  105. int timer_idx = 0;
  106. if (t_info == NULL)
  107. {
  108. return -1;
  109. }
  110. for (timer_idx = 0; timer_idx < MAX_LINUX_TIMER_MANAGER_NUM; timer_idx ++)
  111. {
  112. if (!linux_timer_mgr[timer_idx].timer_info)
  113. {
  114. linux_timer_mgr[timer_idx].timer_info = t_info;
  115. break;
  116. }
  117. else
  118. {
  119. if (linux_timer_mgr[timer_idx].timer_info == t_info)
  120. {
  121. //already register
  122. if (linux_timer_mgr[timer_idx].timer_info->change_interval_time)
  123. {
  124. linux_timer_mgr[timer_idx].timer_info->change_interval_time = 0;
  125. printk(KERN_ERR "%s: chang interval time\n", __func__);
  126. switch (linux_timer_mgr[timer_idx].timer_info->timer_unit)
  127. {
  128. case N_SECOND:
  129. linux_timer_mgr[timer_idx].timer_interval = ns_to_ktime(linux_timer_mgr[timer_idx].timer_info->interval_time);
  130. break;
  131. case U_SECOND:
  132. linux_timer_mgr[timer_idx].timer_interval = ns_to_ktime(linux_timer_mgr[timer_idx].timer_info->interval_time * NSEC_PER_USEC);
  133. break;
  134. case M_SECOND:
  135. linux_timer_mgr[timer_idx].timer_interval = ns_to_ktime(linux_timer_mgr[timer_idx].timer_info->interval_time * NSEC_PER_MSEC);
  136. break;
  137. case SECOND:
  138. break;
  139. }
  140. return 0;
  141. }
  142. printk(KERN_ERR "%s: this timer is registered\n", __func__);
  143. return -1;
  144. }
  145. }
  146. }
  147. // if search/register timer manager not successfully
  148. if (timer_idx == MAX_LINUX_TIMER_MANAGER_NUM)
  149. {
  150. printk(KERN_ERR "%s: timer_idx out of range %d\n", __func__, timer_idx);
  151. return -1;
  152. }
  153. printk(KERN_ERR "%s: register timer name %s\n", __func__, linux_timer_mgr[timer_idx].timer_info->wq_name);
  154. linux_timer_mgr[timer_idx].stk_wq = create_singlethread_workqueue(linux_timer_mgr[timer_idx].timer_info->wq_name);
  155. if (linux_timer_mgr[timer_idx].stk_wq == NULL)
  156. {
  157. printk(KERN_ERR "%s: create single thread workqueue fail\n", __func__);
  158. linux_timer_mgr[timer_idx].timer_info = 0;
  159. return -1;
  160. }
  161. INIT_WORK(&linux_timer_mgr[timer_idx].stk_work, timer_callback);
  162. hrtimer_init(&linux_timer_mgr[timer_idx].stk_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  163. switch (linux_timer_mgr[timer_idx].timer_info->timer_unit)
  164. {
  165. case N_SECOND:
  166. linux_timer_mgr[timer_idx].timer_interval = ns_to_ktime(linux_timer_mgr[timer_idx].timer_info->interval_time);
  167. break;
  168. case U_SECOND:
  169. linux_timer_mgr[timer_idx].timer_interval = ns_to_ktime(linux_timer_mgr[timer_idx].timer_info->interval_time * NSEC_PER_USEC);
  170. break;
  171. case M_SECOND:
  172. linux_timer_mgr[timer_idx].timer_interval = ns_to_ktime(linux_timer_mgr[timer_idx].timer_info->interval_time * NSEC_PER_MSEC);
  173. break;
  174. case SECOND:
  175. break;
  176. }
  177. linux_timer_mgr[timer_idx].stk_hrtimer.function = timer_func;
  178. linux_timer_mgr[timer_idx].timer_info->is_exist = true;
  179. return 0;
  180. }
  181. int start_timer(stk_timer_info *t_info)
  182. {
  183. int timer_idx = 0;
  184. for (timer_idx = 0; timer_idx < MAX_LINUX_TIMER_MANAGER_NUM; timer_idx ++)
  185. {
  186. if (linux_timer_mgr[timer_idx].timer_info == t_info)
  187. {
  188. if (linux_timer_mgr[timer_idx].timer_info->is_exist)
  189. {
  190. if (!linux_timer_mgr[timer_idx].timer_info->is_active)
  191. {
  192. hrtimer_start(&linux_timer_mgr[timer_idx].stk_hrtimer, linux_timer_mgr[timer_idx].timer_interval, HRTIMER_MODE_REL);
  193. linux_timer_mgr[timer_idx].timer_info->is_active = true;
  194. printk(KERN_ERR "%s: start timer name %s\n", __func__, linux_timer_mgr[timer_idx].timer_info->wq_name);
  195. }
  196. else
  197. {
  198. printk(KERN_INFO "%s: %s was already running\n", __func__, linux_timer_mgr[timer_idx].timer_info->wq_name);
  199. }
  200. }
  201. return 0;
  202. }
  203. }
  204. return -1;
  205. }
  206. int stop_timer(stk_timer_info *t_info)
  207. {
  208. int timer_idx = 0;
  209. for (timer_idx = 0; timer_idx < MAX_LINUX_TIMER_MANAGER_NUM; timer_idx ++)
  210. {
  211. if (linux_timer_mgr[timer_idx].timer_info == t_info)
  212. {
  213. if (linux_timer_mgr[timer_idx].timer_info->is_exist)
  214. {
  215. if (linux_timer_mgr[timer_idx].timer_info->is_active)
  216. {
  217. hrtimer_cancel(&linux_timer_mgr[timer_idx].stk_hrtimer);
  218. drain_workqueue(linux_timer_mgr[timer_idx].stk_wq);
  219. linux_timer_mgr[timer_idx].timer_info->is_active = false;
  220. printk(KERN_ERR "%s: stop timer name %s\n", __func__, linux_timer_mgr[timer_idx].timer_info->wq_name);
  221. }
  222. else
  223. {
  224. printk(KERN_ERR "%s: %s stop already stop\n", __func__, linux_timer_mgr[timer_idx].timer_info->wq_name);
  225. }
  226. }
  227. return 0;
  228. }
  229. }
  230. return -1;
  231. }
  232. int remove_timer(stk_timer_info *t_info)
  233. {
  234. int timer_idx = 0;
  235. for (timer_idx = 0; timer_idx < MAX_LINUX_TIMER_MANAGER_NUM; timer_idx ++)
  236. {
  237. if (linux_timer_mgr[timer_idx].timer_info == t_info)
  238. {
  239. if (linux_timer_mgr[timer_idx].timer_info->is_exist)
  240. {
  241. if (linux_timer_mgr[timer_idx].timer_info->is_active)
  242. {
  243. hrtimer_try_to_cancel(&linux_timer_mgr[timer_idx].stk_hrtimer);
  244. destroy_workqueue(linux_timer_mgr[timer_idx].stk_wq);
  245. cancel_work_sync(&linux_timer_mgr[timer_idx].stk_work);
  246. linux_timer_mgr[timer_idx].timer_info->is_active = false;
  247. linux_timer_mgr[timer_idx].timer_info->is_exist = false;
  248. linux_timer_mgr[timer_idx].timer_info = 0;
  249. }
  250. }
  251. return 0;
  252. }
  253. }
  254. return -1;
  255. }
  256. void busy_wait(unsigned long min, unsigned long max, BUSY_WAIT_TYPE mode)
  257. {
  258. if ((!min) || (!max) || (max < min))
  259. {
  260. return;
  261. }
  262. if (mode == US_RANGE_DELAY)
  263. {
  264. usleep_range(min, max);
  265. }
  266. if (mode == MS_DELAY)
  267. {
  268. msleep(max);
  269. }
  270. }
  271. const struct stk_timer_ops stk_t_ops =
  272. {
  273. .register_timer = register_timer,
  274. .start_timer = start_timer,
  275. .stop_timer = stop_timer,
  276. .remove = remove_timer,
  277. .busy_wait = busy_wait,
  278. };