matrix-keymap.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Helpers for matrix keyboard bindings
  3. *
  4. * Copyright (C) 2012 Google, Inc
  5. *
  6. * Author:
  7. * Olof Johansson <olof@lixom.net>
  8. *
  9. * This software is licensed under the terms of the GNU General Public
  10. * License version 2, as published by the Free Software Foundation, and
  11. * may be copied, distributed, and modified under those terms.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. */
  18. #include <linux/device.h>
  19. #include <linux/export.h>
  20. #include <linux/gfp.h>
  21. #include <linux/input.h>
  22. #include <linux/input/matrix_keypad.h>
  23. #include <linux/kernel.h>
  24. #include <linux/module.h>
  25. #include <linux/property.h>
  26. #include <linux/slab.h>
  27. #include <linux/types.h>
  28. static bool matrix_keypad_map_key(struct input_dev *input_dev,
  29. unsigned int rows, unsigned int cols,
  30. unsigned int row_shift, unsigned int key)
  31. {
  32. unsigned short *keymap = input_dev->keycode;
  33. unsigned int row = KEY_ROW(key);
  34. unsigned int col = KEY_COL(key);
  35. unsigned short code = KEY_VAL(key);
  36. if (row >= rows || col >= cols) {
  37. dev_err(input_dev->dev.parent,
  38. "%s: invalid keymap entry 0x%x (row: %d, col: %d, rows: %d, cols: %d)\n",
  39. __func__, key, row, col, rows, cols);
  40. return false;
  41. }
  42. keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code;
  43. __set_bit(code, input_dev->keybit);
  44. return true;
  45. }
  46. /**
  47. * matrix_keypad_parse_properties() - Read properties of matrix keypad
  48. *
  49. * @dev: Device containing properties
  50. * @rows: Returns number of matrix rows
  51. * @cols: Returns number of matrix columns
  52. * @return 0 if OK, <0 on error
  53. */
  54. int matrix_keypad_parse_properties(struct device *dev,
  55. unsigned int *rows, unsigned int *cols)
  56. {
  57. *rows = *cols = 0;
  58. device_property_read_u32(dev, "keypad,num-rows", rows);
  59. device_property_read_u32(dev, "keypad,num-columns", cols);
  60. if (!*rows || !*cols) {
  61. dev_err(dev, "number of keypad rows/columns not specified\n");
  62. return -EINVAL;
  63. }
  64. return 0;
  65. }
  66. EXPORT_SYMBOL_GPL(matrix_keypad_parse_properties);
  67. static int matrix_keypad_parse_keymap(const char *propname,
  68. unsigned int rows, unsigned int cols,
  69. struct input_dev *input_dev)
  70. {
  71. struct device *dev = input_dev->dev.parent;
  72. unsigned int row_shift = get_count_order(cols);
  73. unsigned int max_keys = rows << row_shift;
  74. u32 *keys;
  75. int i;
  76. int size;
  77. int retval;
  78. if (!propname)
  79. propname = "linux,keymap";
  80. size = device_property_read_u32_array(dev, propname, NULL, 0);
  81. if (size <= 0) {
  82. dev_err(dev, "missing or malformed property %s: %d\n",
  83. propname, size);
  84. return size < 0 ? size : -EINVAL;
  85. }
  86. if (size > max_keys) {
  87. dev_err(dev, "%s size overflow (%d vs max %u)\n",
  88. propname, size, max_keys);
  89. return -EINVAL;
  90. }
  91. keys = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
  92. if (!keys)
  93. return -ENOMEM;
  94. retval = device_property_read_u32_array(dev, propname, keys, size);
  95. if (retval) {
  96. dev_err(dev, "failed to read %s property: %d\n",
  97. propname, retval);
  98. goto out;
  99. }
  100. for (i = 0; i < size; i++) {
  101. if (!matrix_keypad_map_key(input_dev, rows, cols,
  102. row_shift, keys[i])) {
  103. retval = -EINVAL;
  104. goto out;
  105. }
  106. }
  107. retval = 0;
  108. out:
  109. kfree(keys);
  110. return retval;
  111. }
  112. /**
  113. * matrix_keypad_build_keymap - convert platform keymap into matrix keymap
  114. * @keymap_data: keymap supplied by the platform code
  115. * @keymap_name: name of device tree property containing keymap (if device
  116. * tree support is enabled).
  117. * @rows: number of rows in target keymap array
  118. * @cols: number of cols in target keymap array
  119. * @keymap: expanded version of keymap that is suitable for use by
  120. * matrix keyboard driver
  121. * @input_dev: input devices for which we are setting up the keymap
  122. *
  123. * This function converts platform keymap (encoded with KEY() macro) into
  124. * an array of keycodes that is suitable for using in a standard matrix
  125. * keyboard driver that uses row and col as indices.
  126. *
  127. * If @keymap_data is not supplied and device tree support is enabled
  128. * it will attempt load the keymap from property specified by @keymap_name
  129. * argument (or "linux,keymap" if @keymap_name is %NULL).
  130. *
  131. * If @keymap is %NULL the function will automatically allocate managed
  132. * block of memory to store the keymap. This memory will be associated with
  133. * the parent device and automatically freed when device unbinds from the
  134. * driver.
  135. *
  136. * Callers are expected to set up input_dev->dev.parent before calling this
  137. * function.
  138. */
  139. int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
  140. const char *keymap_name,
  141. unsigned int rows, unsigned int cols,
  142. unsigned short *keymap,
  143. struct input_dev *input_dev)
  144. {
  145. unsigned int row_shift = get_count_order(cols);
  146. size_t max_keys = rows << row_shift;
  147. int i;
  148. int error;
  149. if (WARN_ON(!input_dev->dev.parent))
  150. return -EINVAL;
  151. if (!keymap) {
  152. keymap = devm_kcalloc(input_dev->dev.parent,
  153. max_keys, sizeof(*keymap),
  154. GFP_KERNEL);
  155. if (!keymap) {
  156. dev_err(input_dev->dev.parent,
  157. "Unable to allocate memory for keymap");
  158. return -ENOMEM;
  159. }
  160. }
  161. input_dev->keycode = keymap;
  162. input_dev->keycodesize = sizeof(*keymap);
  163. input_dev->keycodemax = max_keys;
  164. __set_bit(EV_KEY, input_dev->evbit);
  165. if (keymap_data) {
  166. for (i = 0; i < keymap_data->keymap_size; i++) {
  167. unsigned int key = keymap_data->keymap[i];
  168. if (!matrix_keypad_map_key(input_dev, rows, cols,
  169. row_shift, key))
  170. return -EINVAL;
  171. }
  172. } else {
  173. error = matrix_keypad_parse_keymap(keymap_name, rows, cols,
  174. input_dev);
  175. if (error)
  176. return error;
  177. }
  178. __clear_bit(KEY_RESERVED, input_dev->keybit);
  179. return 0;
  180. }
  181. EXPORT_SYMBOL(matrix_keypad_build_keymap);
  182. MODULE_LICENSE("GPL");