keychord.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. /*
  2. * drivers/input/misc/keychord.c
  3. *
  4. * Copyright (C) 2008 Google, Inc.
  5. * Author: Mike Lockwood <lockwood@android.com>
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. #include <linux/poll.h>
  18. #include <linux/slab.h>
  19. #include <linux/module.h>
  20. #include <linux/init.h>
  21. #include <linux/spinlock.h>
  22. #include <linux/fs.h>
  23. #include <linux/miscdevice.h>
  24. #include <linux/keychord.h>
  25. #include <linux/sched.h>
  26. #define KEYCHORD_NAME "keychord"
  27. #define BUFFER_SIZE 16
  28. MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
  29. MODULE_DESCRIPTION("Key chord input driver");
  30. MODULE_SUPPORTED_DEVICE("keychord");
  31. MODULE_LICENSE("GPL");
  32. #define NEXT_KEYCHORD(kc) ((struct input_keychord *) \
  33. ((char *)kc + sizeof(struct input_keychord) + \
  34. kc->count * sizeof(kc->keycodes[0])))
  35. struct keychord_device {
  36. struct input_handler input_handler;
  37. int registered;
  38. /* list of keychords to monitor */
  39. struct input_keychord *keychords;
  40. int keychord_count;
  41. /* bitmask of keys contained in our keychords */
  42. unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
  43. /* current state of the keys */
  44. unsigned long keystate[BITS_TO_LONGS(KEY_CNT)];
  45. /* number of keys that are currently pressed */
  46. int key_down;
  47. /* second input_device_id is needed for null termination */
  48. struct input_device_id device_ids[2];
  49. spinlock_t lock;
  50. wait_queue_head_t waitq;
  51. unsigned char head;
  52. unsigned char tail;
  53. __u16 buff[BUFFER_SIZE];
  54. /* Bit to serialize writes to this device */
  55. #define KEYCHORD_BUSY 0x01
  56. unsigned long flags;
  57. wait_queue_head_t write_waitq;
  58. };
  59. static int check_keychord(struct keychord_device *kdev,
  60. struct input_keychord *keychord)
  61. {
  62. int i;
  63. if (keychord->count != kdev->key_down)
  64. return 0;
  65. for (i = 0; i < keychord->count; i++) {
  66. if (!test_bit(keychord->keycodes[i], kdev->keystate))
  67. return 0;
  68. }
  69. /* we have a match */
  70. return 1;
  71. }
  72. static void keychord_event(struct input_handle *handle, unsigned int type,
  73. unsigned int code, int value)
  74. {
  75. struct keychord_device *kdev = handle->private;
  76. struct input_keychord *keychord;
  77. unsigned long flags;
  78. int i, got_chord = 0;
  79. if (type != EV_KEY || code >= KEY_MAX)
  80. return;
  81. spin_lock_irqsave(&kdev->lock, flags);
  82. /* do nothing if key state did not change */
  83. if (!test_bit(code, kdev->keystate) == !value)
  84. goto done;
  85. __change_bit(code, kdev->keystate);
  86. if (value)
  87. kdev->key_down++;
  88. else
  89. kdev->key_down--;
  90. /* don't notify on key up */
  91. if (!value)
  92. goto done;
  93. /* ignore this event if it is not one of the keys we are monitoring */
  94. if (!test_bit(code, kdev->keybit))
  95. goto done;
  96. keychord = kdev->keychords;
  97. if (!keychord)
  98. goto done;
  99. /* check to see if the keyboard state matches any keychords */
  100. for (i = 0; i < kdev->keychord_count; i++) {
  101. if (check_keychord(kdev, keychord)) {
  102. kdev->buff[kdev->head] = keychord->id;
  103. kdev->head = (kdev->head + 1) % BUFFER_SIZE;
  104. got_chord = 1;
  105. break;
  106. }
  107. /* skip to next keychord */
  108. keychord = NEXT_KEYCHORD(keychord);
  109. }
  110. done:
  111. spin_unlock_irqrestore(&kdev->lock, flags);
  112. if (got_chord) {
  113. pr_info("keychord: got keychord id %d. Any tasks: %d\n",
  114. keychord->id,
  115. !list_empty_careful(&kdev->waitq.task_list));
  116. wake_up_interruptible(&kdev->waitq);
  117. }
  118. }
  119. static int keychord_connect(struct input_handler *handler,
  120. struct input_dev *dev,
  121. const struct input_device_id *id)
  122. {
  123. int i, ret;
  124. struct input_handle *handle;
  125. struct keychord_device *kdev =
  126. container_of(handler, struct keychord_device, input_handler);
  127. /*
  128. * ignore this input device if it does not contain any keycodes
  129. * that we are monitoring
  130. */
  131. for (i = 0; i < KEY_MAX; i++) {
  132. if (test_bit(i, kdev->keybit) && test_bit(i, dev->keybit))
  133. break;
  134. }
  135. if (i == KEY_MAX)
  136. return -ENODEV;
  137. handle = kzalloc(sizeof(*handle), GFP_KERNEL);
  138. if (!handle)
  139. return -ENOMEM;
  140. handle->dev = dev;
  141. handle->handler = handler;
  142. handle->name = KEYCHORD_NAME;
  143. handle->private = kdev;
  144. ret = input_register_handle(handle);
  145. if (ret)
  146. goto err_input_register_handle;
  147. ret = input_open_device(handle);
  148. if (ret)
  149. goto err_input_open_device;
  150. pr_info("keychord: using input dev %s for fevent\n", dev->name);
  151. return 0;
  152. err_input_open_device:
  153. input_unregister_handle(handle);
  154. err_input_register_handle:
  155. kfree(handle);
  156. return ret;
  157. }
  158. static void keychord_disconnect(struct input_handle *handle)
  159. {
  160. input_close_device(handle);
  161. input_unregister_handle(handle);
  162. kfree(handle);
  163. }
  164. /*
  165. * keychord_read is used to read keychord events from the driver
  166. */
  167. static ssize_t keychord_read(struct file *file, char __user *buffer,
  168. size_t count, loff_t *ppos)
  169. {
  170. struct keychord_device *kdev = file->private_data;
  171. __u16 id;
  172. int retval;
  173. unsigned long flags;
  174. if (count < sizeof(id))
  175. return -EINVAL;
  176. count = sizeof(id);
  177. if (kdev->head == kdev->tail && (file->f_flags & O_NONBLOCK))
  178. return -EAGAIN;
  179. retval = wait_event_interruptible(kdev->waitq,
  180. kdev->head != kdev->tail);
  181. if (retval)
  182. return retval;
  183. spin_lock_irqsave(&kdev->lock, flags);
  184. /* pop a keychord ID off the queue */
  185. id = kdev->buff[kdev->tail];
  186. kdev->tail = (kdev->tail + 1) % BUFFER_SIZE;
  187. spin_unlock_irqrestore(&kdev->lock, flags);
  188. if (copy_to_user(buffer, &id, count))
  189. return -EFAULT;
  190. return count;
  191. }
  192. /*
  193. * serializes writes on a device. can use mutex_lock_interruptible()
  194. * for this particular use case as well - a matter of preference.
  195. */
  196. static int
  197. keychord_write_lock(struct keychord_device *kdev)
  198. {
  199. int ret;
  200. unsigned long flags;
  201. spin_lock_irqsave(&kdev->lock, flags);
  202. while (kdev->flags & KEYCHORD_BUSY) {
  203. spin_unlock_irqrestore(&kdev->lock, flags);
  204. ret = wait_event_interruptible(kdev->write_waitq,
  205. ((kdev->flags & KEYCHORD_BUSY) == 0));
  206. if (ret)
  207. return ret;
  208. spin_lock_irqsave(&kdev->lock, flags);
  209. }
  210. kdev->flags |= KEYCHORD_BUSY;
  211. spin_unlock_irqrestore(&kdev->lock, flags);
  212. return 0;
  213. }
  214. static void
  215. keychord_write_unlock(struct keychord_device *kdev)
  216. {
  217. unsigned long flags;
  218. spin_lock_irqsave(&kdev->lock, flags);
  219. kdev->flags &= ~KEYCHORD_BUSY;
  220. spin_unlock_irqrestore(&kdev->lock, flags);
  221. wake_up_interruptible(&kdev->write_waitq);
  222. }
  223. /*
  224. * keychord_write is used to configure the driver
  225. */
  226. static ssize_t keychord_write(struct file *file, const char __user *buffer,
  227. size_t count, loff_t *ppos)
  228. {
  229. struct keychord_device *kdev = file->private_data;
  230. struct input_keychord *keychords = 0;
  231. struct input_keychord *keychord;
  232. int ret, i, key;
  233. unsigned long flags;
  234. size_t resid = count;
  235. size_t key_bytes;
  236. if (count < sizeof(struct input_keychord))
  237. return -EINVAL;
  238. keychords = kzalloc(count, GFP_KERNEL);
  239. if (!keychords)
  240. return -ENOMEM;
  241. /* read list of keychords from userspace */
  242. if (copy_from_user(keychords, buffer, count)) {
  243. kfree(keychords);
  244. return -EFAULT;
  245. }
  246. /*
  247. * Serialize writes to this device to prevent various races.
  248. * 1) writers racing here could do duplicate input_unregister_handler()
  249. * calls, resulting in attempting to unlink a node from a list that
  250. * does not exist.
  251. * 2) writers racing here could do duplicate input_register_handler() calls
  252. * below, resulting in a duplicate insertion of a node into the list.
  253. * 3) a double kfree of keychords can occur (in the event that
  254. * input_register_handler() fails below.
  255. */
  256. ret = keychord_write_lock(kdev);
  257. if (ret) {
  258. kfree(keychords);
  259. return ret;
  260. }
  261. /* unregister handler before changing configuration */
  262. if (kdev->registered) {
  263. input_unregister_handler(&kdev->input_handler);
  264. kdev->registered = 0;
  265. }
  266. spin_lock_irqsave(&kdev->lock, flags);
  267. /* clear any existing configuration */
  268. kfree(kdev->keychords);
  269. kdev->keychords = 0;
  270. kdev->keychord_count = 0;
  271. kdev->key_down = 0;
  272. memset(kdev->keybit, 0, sizeof(kdev->keybit));
  273. memset(kdev->keystate, 0, sizeof(kdev->keystate));
  274. kdev->head = kdev->tail = 0;
  275. keychord = keychords;
  276. while (resid > 0) {
  277. /* Is the entire keychord entry header present ? */
  278. if (resid < sizeof(struct input_keychord)) {
  279. pr_err("keychord: Insufficient bytes present for header %zu\n",
  280. resid);
  281. goto err_unlock_return;
  282. }
  283. resid -= sizeof(struct input_keychord);
  284. if (keychord->count <= 0) {
  285. pr_err("keychord: invalid keycode count %d\n",
  286. keychord->count);
  287. goto err_unlock_return;
  288. }
  289. key_bytes = keychord->count * sizeof(keychord->keycodes[0]);
  290. /* Do we have all the expected keycodes ? */
  291. if (resid < key_bytes) {
  292. pr_err("keychord: Insufficient bytes present for keycount %zu\n",
  293. resid);
  294. goto err_unlock_return;
  295. }
  296. resid -= key_bytes;
  297. if (keychord->version != KEYCHORD_VERSION) {
  298. pr_err("keychord: unsupported version %d\n",
  299. keychord->version);
  300. goto err_unlock_return;
  301. }
  302. /* keep track of the keys we are monitoring in keybit */
  303. for (i = 0; i < keychord->count; i++) {
  304. key = keychord->keycodes[i];
  305. if (key < 0 || key >= KEY_CNT) {
  306. pr_err("keychord: keycode %d out of range\n",
  307. key);
  308. goto err_unlock_return;
  309. }
  310. __set_bit(key, kdev->keybit);
  311. }
  312. kdev->keychord_count++;
  313. keychord = NEXT_KEYCHORD(keychord);
  314. }
  315. kdev->keychords = keychords;
  316. spin_unlock_irqrestore(&kdev->lock, flags);
  317. ret = input_register_handler(&kdev->input_handler);
  318. if (ret) {
  319. spin_lock_irqsave(&kdev->lock, flags);
  320. kfree(kdev->keychords);
  321. kdev->keychords = 0;
  322. spin_unlock_irqrestore(&kdev->lock, flags);
  323. keychord_write_unlock(kdev);
  324. return ret;
  325. }
  326. kdev->registered = 1;
  327. keychord_write_unlock(kdev);
  328. return count;
  329. err_unlock_return:
  330. spin_unlock_irqrestore(&kdev->lock, flags);
  331. kfree(keychords);
  332. keychord_write_unlock(kdev);
  333. return -EINVAL;
  334. }
  335. static unsigned int keychord_poll(struct file *file, poll_table *wait)
  336. {
  337. struct keychord_device *kdev = file->private_data;
  338. poll_wait(file, &kdev->waitq, wait);
  339. if (kdev->head != kdev->tail)
  340. return POLLIN | POLLRDNORM;
  341. return 0;
  342. }
  343. static int keychord_open(struct inode *inode, struct file *file)
  344. {
  345. struct keychord_device *kdev;
  346. kdev = kzalloc(sizeof(struct keychord_device), GFP_KERNEL);
  347. if (!kdev)
  348. return -ENOMEM;
  349. spin_lock_init(&kdev->lock);
  350. init_waitqueue_head(&kdev->waitq);
  351. init_waitqueue_head(&kdev->write_waitq);
  352. kdev->input_handler.event = keychord_event;
  353. kdev->input_handler.connect = keychord_connect;
  354. kdev->input_handler.disconnect = keychord_disconnect;
  355. kdev->input_handler.name = KEYCHORD_NAME;
  356. kdev->input_handler.id_table = kdev->device_ids;
  357. kdev->device_ids[0].flags = INPUT_DEVICE_ID_MATCH_EVBIT;
  358. __set_bit(EV_KEY, kdev->device_ids[0].evbit);
  359. file->private_data = kdev;
  360. return 0;
  361. }
  362. static int keychord_release(struct inode *inode, struct file *file)
  363. {
  364. struct keychord_device *kdev = file->private_data;
  365. if (kdev->registered)
  366. input_unregister_handler(&kdev->input_handler);
  367. kfree(kdev->keychords);
  368. kfree(kdev);
  369. return 0;
  370. }
  371. static const struct file_operations keychord_fops = {
  372. .owner = THIS_MODULE,
  373. .open = keychord_open,
  374. .release = keychord_release,
  375. .read = keychord_read,
  376. .write = keychord_write,
  377. .poll = keychord_poll,
  378. };
  379. static struct miscdevice keychord_misc = {
  380. .fops = &keychord_fops,
  381. .name = KEYCHORD_NAME,
  382. .minor = MISC_DYNAMIC_MINOR,
  383. };
  384. static int __init keychord_init(void)
  385. {
  386. return misc_register(&keychord_misc);
  387. }
  388. static void __exit keychord_exit(void)
  389. {
  390. misc_deregister(&keychord_misc);
  391. }
  392. module_init(keychord_init);
  393. module_exit(keychord_exit);