sparse-keymap.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Generic support for sparse keymaps
  4. *
  5. * Copyright (c) 2009 Dmitry Torokhov
  6. *
  7. * Derived from wistron button driver:
  8. * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
  9. * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
  10. * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
  11. */
  12. #include <linux/input.h>
  13. #include <linux/input/sparse-keymap.h>
  14. #include <linux/module.h>
  15. #include <linux/slab.h>
  16. MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
  17. MODULE_DESCRIPTION("Generic support for sparse keymaps");
  18. MODULE_LICENSE("GPL v2");
  19. static unsigned int sparse_keymap_get_key_index(struct input_dev *dev,
  20. const struct key_entry *k)
  21. {
  22. struct key_entry *key;
  23. unsigned int idx = 0;
  24. for (key = dev->keycode; key->type != KE_END; key++) {
  25. if (key->type == KE_KEY) {
  26. if (key == k)
  27. break;
  28. idx++;
  29. }
  30. }
  31. return idx;
  32. }
  33. static struct key_entry *sparse_keymap_entry_by_index(struct input_dev *dev,
  34. unsigned int index)
  35. {
  36. struct key_entry *key;
  37. unsigned int key_cnt = 0;
  38. for (key = dev->keycode; key->type != KE_END; key++)
  39. if (key->type == KE_KEY)
  40. if (key_cnt++ == index)
  41. return key;
  42. return NULL;
  43. }
  44. /**
  45. * sparse_keymap_entry_from_scancode - perform sparse keymap lookup
  46. * @dev: Input device using sparse keymap
  47. * @code: Scan code
  48. *
  49. * This function is used to perform &struct key_entry lookup in an
  50. * input device using sparse keymap.
  51. */
  52. struct key_entry *sparse_keymap_entry_from_scancode(struct input_dev *dev,
  53. unsigned int code)
  54. {
  55. struct key_entry *key;
  56. for (key = dev->keycode; key->type != KE_END; key++)
  57. if (code == key->code)
  58. return key;
  59. return NULL;
  60. }
  61. EXPORT_SYMBOL(sparse_keymap_entry_from_scancode);
  62. /**
  63. * sparse_keymap_entry_from_keycode - perform sparse keymap lookup
  64. * @dev: Input device using sparse keymap
  65. * @keycode: Key code
  66. *
  67. * This function is used to perform &struct key_entry lookup in an
  68. * input device using sparse keymap.
  69. */
  70. struct key_entry *sparse_keymap_entry_from_keycode(struct input_dev *dev,
  71. unsigned int keycode)
  72. {
  73. struct key_entry *key;
  74. for (key = dev->keycode; key->type != KE_END; key++)
  75. if (key->type == KE_KEY && keycode == key->keycode)
  76. return key;
  77. return NULL;
  78. }
  79. EXPORT_SYMBOL(sparse_keymap_entry_from_keycode);
  80. static struct key_entry *sparse_keymap_locate(struct input_dev *dev,
  81. const struct input_keymap_entry *ke)
  82. {
  83. struct key_entry *key;
  84. unsigned int scancode;
  85. if (ke->flags & INPUT_KEYMAP_BY_INDEX)
  86. key = sparse_keymap_entry_by_index(dev, ke->index);
  87. else if (input_scancode_to_scalar(ke, &scancode) == 0)
  88. key = sparse_keymap_entry_from_scancode(dev, scancode);
  89. else
  90. key = NULL;
  91. return key;
  92. }
  93. static int sparse_keymap_getkeycode(struct input_dev *dev,
  94. struct input_keymap_entry *ke)
  95. {
  96. const struct key_entry *key;
  97. if (dev->keycode) {
  98. key = sparse_keymap_locate(dev, ke);
  99. if (key && key->type == KE_KEY) {
  100. ke->keycode = key->keycode;
  101. if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
  102. ke->index =
  103. sparse_keymap_get_key_index(dev, key);
  104. ke->len = sizeof(key->code);
  105. memcpy(ke->scancode, &key->code, sizeof(key->code));
  106. return 0;
  107. }
  108. }
  109. return -EINVAL;
  110. }
  111. static int sparse_keymap_setkeycode(struct input_dev *dev,
  112. const struct input_keymap_entry *ke,
  113. unsigned int *old_keycode)
  114. {
  115. struct key_entry *key;
  116. if (dev->keycode) {
  117. key = sparse_keymap_locate(dev, ke);
  118. if (key && key->type == KE_KEY) {
  119. *old_keycode = key->keycode;
  120. key->keycode = ke->keycode;
  121. set_bit(ke->keycode, dev->keybit);
  122. if (!sparse_keymap_entry_from_keycode(dev, *old_keycode))
  123. clear_bit(*old_keycode, dev->keybit);
  124. return 0;
  125. }
  126. }
  127. return -EINVAL;
  128. }
  129. /**
  130. * sparse_keymap_setup - set up sparse keymap for an input device
  131. * @dev: Input device
  132. * @keymap: Keymap in form of array of &key_entry structures ending
  133. * with %KE_END type entry
  134. * @setup: Function that can be used to adjust keymap entries
  135. * depending on device's needs, may be %NULL
  136. *
  137. * The function calculates size and allocates copy of the original
  138. * keymap after which sets up input device event bits appropriately.
  139. * The allocated copy of the keymap is automatically freed when it
  140. * is no longer needed.
  141. */
  142. int sparse_keymap_setup(struct input_dev *dev,
  143. const struct key_entry *keymap,
  144. int (*setup)(struct input_dev *, struct key_entry *))
  145. {
  146. size_t map_size = 1; /* to account for the last KE_END entry */
  147. const struct key_entry *e;
  148. struct key_entry *map, *entry;
  149. int i;
  150. int error;
  151. for (e = keymap; e->type != KE_END; e++)
  152. map_size++;
  153. map = devm_kmemdup(&dev->dev, keymap, map_size * sizeof(*map),
  154. GFP_KERNEL);
  155. if (!map)
  156. return -ENOMEM;
  157. for (i = 0; i < map_size; i++) {
  158. entry = &map[i];
  159. if (setup) {
  160. error = setup(dev, entry);
  161. if (error)
  162. return error;
  163. }
  164. switch (entry->type) {
  165. case KE_KEY:
  166. __set_bit(EV_KEY, dev->evbit);
  167. __set_bit(entry->keycode, dev->keybit);
  168. break;
  169. case KE_SW:
  170. case KE_VSW:
  171. __set_bit(EV_SW, dev->evbit);
  172. __set_bit(entry->sw.code, dev->swbit);
  173. break;
  174. }
  175. }
  176. if (test_bit(EV_KEY, dev->evbit)) {
  177. __set_bit(KEY_UNKNOWN, dev->keybit);
  178. __set_bit(EV_MSC, dev->evbit);
  179. __set_bit(MSC_SCAN, dev->mscbit);
  180. }
  181. dev->keycode = map;
  182. dev->keycodemax = map_size;
  183. dev->getkeycode = sparse_keymap_getkeycode;
  184. dev->setkeycode = sparse_keymap_setkeycode;
  185. return 0;
  186. }
  187. EXPORT_SYMBOL(sparse_keymap_setup);
  188. /**
  189. * sparse_keymap_report_entry - report event corresponding to given key entry
  190. * @dev: Input device for which event should be reported
  191. * @ke: key entry describing event
  192. * @value: Value that should be reported (ignored by %KE_SW entries)
  193. * @autorelease: Signals whether release event should be emitted for %KE_KEY
  194. * entries right after reporting press event, ignored by all other
  195. * entries
  196. *
  197. * This function is used to report input event described by given
  198. * &struct key_entry.
  199. */
  200. void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *ke,
  201. unsigned int value, bool autorelease)
  202. {
  203. switch (ke->type) {
  204. case KE_KEY:
  205. input_event(dev, EV_MSC, MSC_SCAN, ke->code);
  206. input_report_key(dev, ke->keycode, value);
  207. input_sync(dev);
  208. if (value && autorelease) {
  209. input_report_key(dev, ke->keycode, 0);
  210. input_sync(dev);
  211. }
  212. break;
  213. case KE_SW:
  214. value = ke->sw.value;
  215. fallthrough;
  216. case KE_VSW:
  217. input_report_switch(dev, ke->sw.code, value);
  218. input_sync(dev);
  219. break;
  220. }
  221. }
  222. EXPORT_SYMBOL(sparse_keymap_report_entry);
  223. /**
  224. * sparse_keymap_report_event - report event corresponding to given scancode
  225. * @dev: Input device using sparse keymap
  226. * @code: Scan code
  227. * @value: Value that should be reported (ignored by %KE_SW entries)
  228. * @autorelease: Signals whether release event should be emitted for %KE_KEY
  229. * entries right after reporting press event, ignored by all other
  230. * entries
  231. *
  232. * This function is used to perform lookup in an input device using sparse
  233. * keymap and report corresponding event. Returns %true if lookup was
  234. * successful and %false otherwise.
  235. */
  236. bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code,
  237. unsigned int value, bool autorelease)
  238. {
  239. const struct key_entry *ke =
  240. sparse_keymap_entry_from_scancode(dev, code);
  241. struct key_entry unknown_ke;
  242. if (ke) {
  243. sparse_keymap_report_entry(dev, ke, value, autorelease);
  244. return true;
  245. }
  246. /* Report an unknown key event as a debugging aid */
  247. unknown_ke.type = KE_KEY;
  248. unknown_ke.code = code;
  249. unknown_ke.keycode = KEY_UNKNOWN;
  250. sparse_keymap_report_entry(dev, &unknown_ke, value, true);
  251. return false;
  252. }
  253. EXPORT_SYMBOL(sparse_keymap_report_event);