ir-keytable.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /* ir-register.c - handle IR scancode->keycode tables
  2. *
  3. * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
  4. */
  5. #include <linux/usb/input.h>
  6. #include <media/ir-common.h>
  7. #define IR_TAB_MIN_SIZE 32
  8. /**
  9. * ir_roundup_tablesize() - gets an optimum value for the table size
  10. * @n_elems: minimum number of entries to store keycodes
  11. *
  12. * This routine is used to choose the keycode table size.
  13. *
  14. * In order to have some empty space for new keycodes,
  15. * and knowing in advance that kmalloc allocates only power of two
  16. * segments, it optimizes the allocated space to have some spare space
  17. * for those new keycodes by using the maximum number of entries that
  18. * will be effectively be allocated by kmalloc.
  19. * In order to reduce the quantity of table resizes, it has a minimum
  20. * table size of IR_TAB_MIN_SIZE.
  21. */
  22. int ir_roundup_tablesize(int n_elems)
  23. {
  24. size_t size;
  25. if (n_elems < IR_TAB_MIN_SIZE)
  26. n_elems = IR_TAB_MIN_SIZE;
  27. /*
  28. * As kmalloc only allocates sizes of power of two, get as
  29. * much entries as possible for the allocated memory segment
  30. */
  31. size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode));
  32. n_elems = size / sizeof(struct ir_scancode);
  33. return n_elems;
  34. }
  35. /**
  36. * ir_copy_table() - copies a keytable, discarding the unused entries
  37. * @destin: destin table
  38. * @origin: origin table
  39. *
  40. * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
  41. */
  42. int ir_copy_table(struct ir_scancode_table *destin,
  43. const struct ir_scancode_table *origin)
  44. {
  45. int i, j = 0;
  46. for (i = 0; i < origin->size; i++) {
  47. if (origin->scan[i].keycode != KEY_UNKNOWN &&
  48. origin->scan[i].keycode != KEY_RESERVED) {
  49. memcpy(&destin->scan[j], &origin->scan[i],
  50. sizeof(struct ir_scancode));
  51. j++;
  52. }
  53. }
  54. destin->size = j;
  55. IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", j);
  56. return 0;
  57. }
  58. /**
  59. * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
  60. * @dev: the struct input_dev device descriptor
  61. * @scancode: the desired scancode
  62. * @keycode: the keycode to be retorned.
  63. *
  64. * This routine is used to handle evdev EVIOCGKEY ioctl.
  65. * If the key is not found, returns -EINVAL, otherwise, returns 0.
  66. */
  67. static int ir_getkeycode(struct input_dev *dev,
  68. int scancode, int *keycode)
  69. {
  70. int i;
  71. struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
  72. struct ir_scancode *keymap = rc_tab->scan;
  73. /* See if we can match the raw key code. */
  74. for (i = 0; i < rc_tab->size; i++)
  75. if (keymap[i].scancode == scancode) {
  76. *keycode = keymap[i].keycode;
  77. return 0;
  78. }
  79. /*
  80. * If is there extra space, returns KEY_RESERVED,
  81. * otherwise, input core won't let ir_setkeycode
  82. * to work
  83. */
  84. for (i = 0; i < rc_tab->size; i++)
  85. if (keymap[i].keycode == KEY_RESERVED ||
  86. keymap[i].keycode == KEY_UNKNOWN) {
  87. *keycode = KEY_RESERVED;
  88. return 0;
  89. }
  90. return -EINVAL;
  91. }
  92. /**
  93. * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table
  94. * @dev: the struct input_dev device descriptor
  95. * @scancode: the desired scancode
  96. * @keycode: the keycode to be retorned.
  97. *
  98. * This routine is used to handle evdev EVIOCSKEY ioctl.
  99. * There's one caveat here: how can we increase the size of the table?
  100. * If the key is not found, returns -EINVAL, otherwise, returns 0.
  101. */
  102. static int ir_setkeycode(struct input_dev *dev,
  103. int scancode, int keycode)
  104. {
  105. int i;
  106. struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
  107. struct ir_scancode *keymap = rc_tab->scan;
  108. /* Search if it is replacing an existing keycode */
  109. for (i = 0; i < rc_tab->size; i++)
  110. if (keymap[i].scancode == scancode) {
  111. keymap[i].keycode = keycode;
  112. return 0;
  113. }
  114. /* Search if is there a clean entry. If so, use it */
  115. for (i = 0; i < rc_tab->size; i++)
  116. if (keymap[i].keycode == KEY_RESERVED ||
  117. keymap[i].keycode == KEY_UNKNOWN) {
  118. keymap[i].scancode = scancode;
  119. keymap[i].keycode = keycode;
  120. return 0;
  121. }
  122. /*
  123. * FIXME: Currently, it is not possible to increase the size of
  124. * scancode table. For it to happen, one possibility
  125. * would be to allocate a table with key_map_size + 1,
  126. * copying data, appending the new key on it, and freeing
  127. * the old one - or maybe just allocating some spare space
  128. */
  129. return -EINVAL;
  130. }
  131. /**
  132. * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
  133. * @rc_tab: the ir_scancode_table with the keymap to be used
  134. * @scancode: the scancode that we're seeking
  135. *
  136. * This routine is used by the input routines when a key is pressed at the
  137. * IR. The scancode is received and needs to be converted into a keycode.
  138. * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
  139. * corresponding keycode from the table.
  140. */
  141. u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
  142. {
  143. int i;
  144. struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
  145. struct ir_scancode *keymap = rc_tab->scan;
  146. for (i = 0; i < rc_tab->size; i++)
  147. if (keymap[i].scancode == scancode) {
  148. IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
  149. dev->name, scancode, keymap[i].keycode);
  150. return keymap[i].keycode;
  151. }
  152. printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n",
  153. dev->name, scancode);
  154. return KEY_UNKNOWN;
  155. }
  156. /**
  157. * ir_set_keycode_table() - sets the IR keycode table and add the handlers
  158. * for keymap table get/set
  159. * @input_dev: the struct input_dev descriptor of the device
  160. * @rc_tab: the struct ir_scancode_table table of scancode/keymap
  161. *
  162. * This routine is used to initialize the input infrastructure to work with
  163. * an IR. It requires that the caller initializes the input_dev struct with
  164. * some fields: name,
  165. */
  166. int ir_set_keycode_table(struct input_dev *input_dev,
  167. struct ir_scancode_table *rc_tab)
  168. {
  169. struct ir_scancode *keymap = rc_tab->scan;
  170. int i;
  171. if (rc_tab->scan == NULL || !rc_tab->size)
  172. return -EINVAL;
  173. /* set the bits for the keys */
  174. IR_dprintk(1, "key map size: %d\n", rc_tab->size);
  175. for (i = 0; i < rc_tab->size; i++) {
  176. IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
  177. i, keymap[i].keycode);
  178. set_bit(keymap[i].keycode, input_dev->keybit);
  179. }
  180. input_dev->getkeycode = ir_getkeycode;
  181. input_dev->setkeycode = ir_setkeycode;
  182. input_set_drvdata(input_dev, rc_tab);
  183. return 0;
  184. }
  185. void ir_input_free(struct input_dev *dev)
  186. {
  187. struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
  188. IR_dprintk(1, "Freed keycode table\n");
  189. rc_tab->size = 0;
  190. kfree(rc_tab->scan);
  191. rc_tab->scan = NULL;
  192. }
  193. EXPORT_SYMBOL_GPL(ir_input_free);