keycombo.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /* drivers/input/keycombo.c
  2. *
  3. * Copyright (C) 2014 Google, Inc.
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <linux/input.h>
  16. #include <linux/keycombo.h>
  17. #include <linux/module.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/reboot.h>
  20. #include <linux/sched.h>
  21. #include <linux/slab.h>
  22. struct keycombo_state {
  23. struct input_handler input_handler;
  24. unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
  25. unsigned long upbit[BITS_TO_LONGS(KEY_CNT)];
  26. unsigned long key[BITS_TO_LONGS(KEY_CNT)];
  27. spinlock_t lock;
  28. struct workqueue_struct *wq;
  29. int key_down_target;
  30. int key_down;
  31. int key_up;
  32. struct delayed_work key_down_work;
  33. int delay;
  34. struct work_struct key_up_work;
  35. void (*key_up_fn)(void *);
  36. void (*key_down_fn)(void *);
  37. void *priv;
  38. int key_is_down;
  39. struct wakeup_source combo_held_wake_source;
  40. struct wakeup_source combo_up_wake_source;
  41. };
  42. static void do_key_down(struct work_struct *work)
  43. {
  44. struct delayed_work *dwork = container_of(work, struct delayed_work,
  45. work);
  46. struct keycombo_state *state = container_of(dwork,
  47. struct keycombo_state, key_down_work);
  48. if (state->key_down_fn)
  49. state->key_down_fn(state->priv);
  50. }
  51. static void do_key_up(struct work_struct *work)
  52. {
  53. struct keycombo_state *state = container_of(work, struct keycombo_state,
  54. key_up_work);
  55. if (state->key_up_fn)
  56. state->key_up_fn(state->priv);
  57. __pm_relax(&state->combo_up_wake_source);
  58. }
  59. static void keycombo_event(struct input_handle *handle, unsigned int type,
  60. unsigned int code, int value)
  61. {
  62. unsigned long flags;
  63. struct keycombo_state *state = handle->private;
  64. if (type != EV_KEY)
  65. return;
  66. if (code >= KEY_MAX)
  67. return;
  68. if (!test_bit(code, state->keybit))
  69. return;
  70. spin_lock_irqsave(&state->lock, flags);
  71. if (!test_bit(code, state->key) == !value)
  72. goto done;
  73. __change_bit(code, state->key);
  74. if (test_bit(code, state->upbit)) {
  75. if (value)
  76. state->key_up++;
  77. else
  78. state->key_up--;
  79. } else {
  80. if (value)
  81. state->key_down++;
  82. else
  83. state->key_down--;
  84. }
  85. if (state->key_down == state->key_down_target && state->key_up == 0) {
  86. __pm_stay_awake(&state->combo_held_wake_source);
  87. state->key_is_down = 1;
  88. if (queue_delayed_work(state->wq, &state->key_down_work,
  89. state->delay))
  90. pr_debug("Key down work already queued!");
  91. } else if (state->key_is_down) {
  92. if (!cancel_delayed_work(&state->key_down_work)) {
  93. __pm_stay_awake(&state->combo_up_wake_source);
  94. queue_work(state->wq, &state->key_up_work);
  95. }
  96. __pm_relax(&state->combo_held_wake_source);
  97. state->key_is_down = 0;
  98. }
  99. done:
  100. spin_unlock_irqrestore(&state->lock, flags);
  101. }
  102. static int keycombo_connect(struct input_handler *handler,
  103. struct input_dev *dev,
  104. const struct input_device_id *id)
  105. {
  106. int i;
  107. int ret;
  108. struct input_handle *handle;
  109. struct keycombo_state *state =
  110. container_of(handler, struct keycombo_state, input_handler);
  111. for (i = 0; i < KEY_MAX; i++) {
  112. if (test_bit(i, state->keybit) && test_bit(i, dev->keybit))
  113. break;
  114. }
  115. if (i == KEY_MAX)
  116. return -ENODEV;
  117. handle = kzalloc(sizeof(*handle), GFP_KERNEL);
  118. if (!handle)
  119. return -ENOMEM;
  120. handle->dev = dev;
  121. handle->handler = handler;
  122. handle->name = KEYCOMBO_NAME;
  123. handle->private = state;
  124. ret = input_register_handle(handle);
  125. if (ret)
  126. goto err_input_register_handle;
  127. ret = input_open_device(handle);
  128. if (ret)
  129. goto err_input_open_device;
  130. return 0;
  131. err_input_open_device:
  132. input_unregister_handle(handle);
  133. err_input_register_handle:
  134. kfree(handle);
  135. return ret;
  136. }
  137. static void keycombo_disconnect(struct input_handle *handle)
  138. {
  139. input_close_device(handle);
  140. input_unregister_handle(handle);
  141. kfree(handle);
  142. }
  143. static const struct input_device_id keycombo_ids[] = {
  144. {
  145. .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
  146. .evbit = { BIT_MASK(EV_KEY) },
  147. },
  148. { },
  149. };
  150. MODULE_DEVICE_TABLE(input, keycombo_ids);
  151. static int keycombo_probe(struct platform_device *pdev)
  152. {
  153. int ret;
  154. int key, *keyp;
  155. struct keycombo_state *state;
  156. struct keycombo_platform_data *pdata = pdev->dev.platform_data;
  157. if (!pdata)
  158. return -EINVAL;
  159. state = kzalloc(sizeof(*state), GFP_KERNEL);
  160. if (!state)
  161. return -ENOMEM;
  162. spin_lock_init(&state->lock);
  163. keyp = pdata->keys_down;
  164. while ((key = *keyp++)) {
  165. if (key >= KEY_MAX)
  166. continue;
  167. state->key_down_target++;
  168. __set_bit(key, state->keybit);
  169. }
  170. if (pdata->keys_up) {
  171. keyp = pdata->keys_up;
  172. while ((key = *keyp++)) {
  173. if (key >= KEY_MAX)
  174. continue;
  175. __set_bit(key, state->keybit);
  176. __set_bit(key, state->upbit);
  177. }
  178. }
  179. state->wq = alloc_ordered_workqueue("keycombo", 0);
  180. if (!state->wq)
  181. return -ENOMEM;
  182. state->priv = pdata->priv;
  183. if (pdata->key_down_fn)
  184. state->key_down_fn = pdata->key_down_fn;
  185. INIT_DELAYED_WORK(&state->key_down_work, do_key_down);
  186. if (pdata->key_up_fn)
  187. state->key_up_fn = pdata->key_up_fn;
  188. INIT_WORK(&state->key_up_work, do_key_up);
  189. wakeup_source_init(&state->combo_held_wake_source, "key combo");
  190. wakeup_source_init(&state->combo_up_wake_source, "key combo up");
  191. state->delay = msecs_to_jiffies(pdata->key_down_delay);
  192. state->input_handler.event = keycombo_event;
  193. state->input_handler.connect = keycombo_connect;
  194. state->input_handler.disconnect = keycombo_disconnect;
  195. state->input_handler.name = KEYCOMBO_NAME;
  196. state->input_handler.id_table = keycombo_ids;
  197. ret = input_register_handler(&state->input_handler);
  198. if (ret) {
  199. kfree(state);
  200. return ret;
  201. }
  202. platform_set_drvdata(pdev, state);
  203. return 0;
  204. }
  205. int keycombo_remove(struct platform_device *pdev)
  206. {
  207. struct keycombo_state *state = platform_get_drvdata(pdev);
  208. input_unregister_handler(&state->input_handler);
  209. destroy_workqueue(state->wq);
  210. kfree(state);
  211. return 0;
  212. }
  213. struct platform_driver keycombo_driver = {
  214. .driver.name = KEYCOMBO_NAME,
  215. .probe = keycombo_probe,
  216. .remove = keycombo_remove,
  217. };
  218. static int __init keycombo_init(void)
  219. {
  220. return platform_driver_register(&keycombo_driver);
  221. }
  222. static void __exit keycombo_exit(void)
  223. {
  224. return platform_driver_unregister(&keycombo_driver);
  225. }
  226. module_init(keycombo_init);
  227. module_exit(keycombo_exit);