input_pointer.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file input manager interface
  8. */
  9. #include <os_common_api.h>
  10. #include <string.h>
  11. #include <key_hal.h>
  12. #include <app_manager.h>
  13. #include <mem_manager.h>
  14. #include <input_manager.h>
  15. #include <msg_manager.h>
  16. #include <sys_event.h>
  17. #include <property_manager.h>
  18. #include <input_manager_inner.h>
  19. #include <sys_wakelock.h>
  20. #define CONFIG_READ_DIRCT 1
  21. /* Drag threshold in pixels */
  22. #define POINTER_SCROLL_LIMIT 10
  23. /* Gesture threshold in pixels */
  24. #define POINTER_GESTURE_LIMIT 50
  25. /* Gesture min velocity at release before swipe (pixels) */
  26. #define POINTER_GESTURE_MIN_VELOCITY 3
  27. #ifndef ABS
  28. # define ABS(x) (((x) >= 0) ? (x) : -(x))
  29. #endif
  30. #ifdef CONFIG_INPUT_DEV_ACTS_TP_KEY
  31. #ifndef CONFIG_READ_DIRCT
  32. K_MSGQ_DEFINE(pointer_scan_msgq, sizeof(input_dev_data_t), 10, 4);
  33. #endif
  34. static uint32_t s_supported_gestures;
  35. static void pointer_gesture_detect(input_drv_t *drv, input_dev_data_t *data)
  36. {
  37. static point_t scroll_sum;
  38. static point_t gesture_sum;
  39. static input_dev_data_t prev = {
  40. .point.x = 0,
  41. .point.y = 0,
  42. .state = INPUT_DEV_STATE_REL,
  43. .gesture_dir = 0,
  44. .scroll_dir = 0,
  45. };
  46. point_t vec;
  47. uint8_t gesture_dir = 0;
  48. uint8_t scroll_dir = 0;
  49. if (prev.state == INPUT_DEV_STATE_REL)
  50. goto out_exit;
  51. if (data->state == INPUT_DEV_STATE_PR) {
  52. vec.x = data->point.x - prev.point.x;
  53. vec.y = data->point.y - prev.point.y;
  54. scroll_sum.x += vec.x;
  55. scroll_sum.y += vec.y;
  56. if (ABS(scroll_sum.x) > drv->scroll_limit ||
  57. ABS(scroll_sum.y) > drv->scroll_limit) {
  58. if (ABS(scroll_sum.x) >= ABS(scroll_sum.y)) {
  59. scroll_dir = (scroll_sum.x > 0) ? GESTURE_DROP_RIGHT : GESTURE_DROP_LEFT;
  60. } else {
  61. scroll_dir = (scroll_sum.y > 0) ? GESTURE_DROP_DOWN : GESTURE_DROP_UP;
  62. }
  63. }
  64. if (ABS(vec.x) < drv->gesture_min_velocity &&
  65. ABS(vec.y) < drv->gesture_min_velocity) {
  66. gesture_sum.x = 0;
  67. gesture_sum.y = 0;
  68. }
  69. gesture_sum.x += vec.x;
  70. gesture_sum.y += vec.y;
  71. if (ABS(gesture_sum.x) > drv->gesture_limit ||
  72. ABS(gesture_sum.y) > drv->gesture_limit) {
  73. if (ABS(gesture_sum.x) >= ABS(gesture_sum.y)) {
  74. gesture_dir = (gesture_sum.x > 0) ? GESTURE_DROP_RIGHT : GESTURE_DROP_LEFT;
  75. } else {
  76. gesture_dir = (gesture_sum.y > 0) ? GESTURE_DROP_DOWN : GESTURE_DROP_UP;
  77. }
  78. }
  79. } else if (data->state == INPUT_DEV_STATE_REL) {
  80. gesture_sum.x = 0;
  81. gesture_sum.y = 0;
  82. scroll_sum.x = 0;
  83. scroll_sum.y = 0;
  84. }
  85. out_exit:
  86. data->gesture_dir = gesture_dir;
  87. data->scroll_dir = scroll_dir;
  88. prev = *data;
  89. }
  90. static void pointer_scan_callback(struct device *dev, struct input_value *val)
  91. {
  92. #ifndef CONFIG_READ_DIRCT
  93. input_dev_data_t data = {
  94. .point.x = val->point.loc_x,
  95. .point.y = val->point.loc_y,
  96. .state = (val->point.pessure_value == 1)? INPUT_DEV_STATE_PR : INPUT_DEV_STATE_REL,
  97. .gesture = val->point.gesture,
  98. };
  99. if (k_msgq_put(&pointer_scan_msgq, &data, K_NO_WAIT) != 0) {
  100. SYS_LOG_ERR("Could put input data into queue");
  101. }
  102. #endif
  103. }
  104. static bool pointer_scan_read(input_drv_t *drv, input_dev_data_t *data)
  105. {
  106. #if CONFIG_READ_DIRCT
  107. static input_dev_state_t last_state = INPUT_DEV_STATE_REL;
  108. struct input_value val;
  109. memset(&val, 0, sizeof(struct input_value));
  110. input_dev_inquiry(drv->input_dev, &val);
  111. data->point.x = val.point.loc_x;
  112. data->point.y = val.point.loc_y;
  113. data->state = (val.point.pessure_value == 1)? INPUT_DEV_STATE_PR : INPUT_DEV_STATE_REL;
  114. if (s_supported_gestures == 0) {
  115. pointer_gesture_detect(drv, data);
  116. } else {
  117. data->gesture_dir = val.point.gesture;
  118. data->scroll_dir = val.point.gesture;
  119. }
  120. if (last_state != data->state) {
  121. input_manager_boost(data->state == INPUT_DEV_STATE_PR);
  122. last_state = data->state;
  123. #ifdef CONFIG_SYS_WAKELOCK
  124. if (data->state == INPUT_DEV_STATE_PR) {
  125. sys_wake_lock(FULL_WAKE_LOCK);
  126. } else {
  127. sys_wake_unlock(FULL_WAKE_LOCK);
  128. }
  129. #endif /* CONFIG_SYS_WAKELOCK */
  130. }
  131. return false;
  132. #else
  133. static input_dev_data_t prev = {
  134. .point.x = 0,
  135. .point.y = 0,
  136. .state = INPUT_DEV_STATE_REL,
  137. .gesture = 0,
  138. };
  139. input_dev_data_t curr;
  140. if (k_msgq_get(&pointer_scan_msgq, &curr, K_NO_WAIT) == 0) {
  141. prev = curr;
  142. }
  143. *data = prev;
  144. if (s_supported_gestures == 0) {
  145. pointer_gesture_detect(data);
  146. }
  147. return k_msgq_num_used_get(&pointer_scan_msgq) > 0;
  148. #endif
  149. }
  150. static void pointer_scan_enable(input_drv_t *drv, bool enable)
  151. {
  152. struct device *input_dev = (struct device *)device_get_binding("tpkey");
  153. if (input_dev) {
  154. if (enable)
  155. input_dev_enable(input_dev);
  156. else
  157. input_dev_disable(input_dev);
  158. }
  159. }
  160. #endif /* CONFIG_INPUT_DEV_ACTS_TP_KEY */
  161. static bool pointer_scan_read_fake(input_drv_t *drv, input_dev_data_t *data)
  162. {
  163. *data = (input_dev_data_t) {
  164. .point.x = 0,
  165. .point.y = 0,
  166. .state = INPUT_DEV_STATE_REL,
  167. .gesture_dir = 0,
  168. .scroll_dir = 0,
  169. };
  170. return false;
  171. }
  172. int input_pointer_device_init(void)
  173. {
  174. input_drv_t input_drv;
  175. memset(&input_drv, 0, sizeof(input_drv));
  176. input_drv.type = INPUT_DEV_TYPE_POINTER;
  177. input_drv.scroll_limit = POINTER_SCROLL_LIMIT;
  178. input_drv.gesture_limit = POINTER_GESTURE_LIMIT;
  179. input_drv.gesture_min_velocity = POINTER_GESTURE_MIN_VELOCITY;
  180. #ifdef CONFIG_INPUT_DEV_ACTS_TP_KEY
  181. input_drv.input_dev = (struct device *)device_get_binding("tpkey");
  182. if (input_drv.input_dev) {
  183. struct input_capabilities cap;
  184. memset(&cap, 0, sizeof(cap));
  185. input_dev_get_capabilities(input_drv.input_dev, &cap);
  186. s_supported_gestures = cap.pointer.supported_gestures;
  187. input_dev_register_notify(input_drv.input_dev, pointer_scan_callback);
  188. input_drv.read_cb = pointer_scan_read;
  189. input_drv.enable = pointer_scan_enable;
  190. }
  191. #endif /*CONFIG_INPUT_DEV_ACTS_TP_KEY*/
  192. if (input_drv.input_dev == NULL) {
  193. os_printk("cannot found tpkey dev, fake one\n");
  194. input_drv.read_cb = pointer_scan_read_fake;
  195. }
  196. input_driver_register(&input_drv);
  197. SYS_LOG_INF("init ok");
  198. return 0;
  199. }