0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/device.h>
0012 #include <linux/export.h>
0013 #include <linux/gfp.h>
0014 #include <linux/input.h>
0015 #include <linux/input/matrix_keypad.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/property.h>
0019 #include <linux/slab.h>
0020 #include <linux/types.h>
0021
0022 static bool matrix_keypad_map_key(struct input_dev *input_dev,
0023 unsigned int rows, unsigned int cols,
0024 unsigned int row_shift, unsigned int key)
0025 {
0026 unsigned short *keymap = input_dev->keycode;
0027 unsigned int row = KEY_ROW(key);
0028 unsigned int col = KEY_COL(key);
0029 unsigned short code = KEY_VAL(key);
0030
0031 if (row >= rows || col >= cols) {
0032 dev_err(input_dev->dev.parent,
0033 "%s: invalid keymap entry 0x%x (row: %d, col: %d, rows: %d, cols: %d)\n",
0034 __func__, key, row, col, rows, cols);
0035 return false;
0036 }
0037
0038 keymap[MATRIX_SCAN_CODE(row, col, row_shift)] = code;
0039 __set_bit(code, input_dev->keybit);
0040
0041 return true;
0042 }
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 int matrix_keypad_parse_properties(struct device *dev,
0053 unsigned int *rows, unsigned int *cols)
0054 {
0055 *rows = *cols = 0;
0056
0057 device_property_read_u32(dev, "keypad,num-rows", rows);
0058 device_property_read_u32(dev, "keypad,num-columns", cols);
0059
0060 if (!*rows || !*cols) {
0061 dev_err(dev, "number of keypad rows/columns not specified\n");
0062 return -EINVAL;
0063 }
0064
0065 return 0;
0066 }
0067 EXPORT_SYMBOL_GPL(matrix_keypad_parse_properties);
0068
0069 static int matrix_keypad_parse_keymap(const char *propname,
0070 unsigned int rows, unsigned int cols,
0071 struct input_dev *input_dev)
0072 {
0073 struct device *dev = input_dev->dev.parent;
0074 unsigned int row_shift = get_count_order(cols);
0075 unsigned int max_keys = rows << row_shift;
0076 u32 *keys;
0077 int i;
0078 int size;
0079 int retval;
0080
0081 if (!propname)
0082 propname = "linux,keymap";
0083
0084 size = device_property_count_u32(dev, propname);
0085 if (size <= 0) {
0086 dev_err(dev, "missing or malformed property %s: %d\n",
0087 propname, size);
0088 return size < 0 ? size : -EINVAL;
0089 }
0090
0091 if (size > max_keys) {
0092 dev_err(dev, "%s size overflow (%d vs max %u)\n",
0093 propname, size, max_keys);
0094 return -EINVAL;
0095 }
0096
0097 keys = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
0098 if (!keys)
0099 return -ENOMEM;
0100
0101 retval = device_property_read_u32_array(dev, propname, keys, size);
0102 if (retval) {
0103 dev_err(dev, "failed to read %s property: %d\n",
0104 propname, retval);
0105 goto out;
0106 }
0107
0108 for (i = 0; i < size; i++) {
0109 if (!matrix_keypad_map_key(input_dev, rows, cols,
0110 row_shift, keys[i])) {
0111 retval = -EINVAL;
0112 goto out;
0113 }
0114 }
0115
0116 retval = 0;
0117
0118 out:
0119 kfree(keys);
0120 return retval;
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
0151 const char *keymap_name,
0152 unsigned int rows, unsigned int cols,
0153 unsigned short *keymap,
0154 struct input_dev *input_dev)
0155 {
0156 unsigned int row_shift = get_count_order(cols);
0157 size_t max_keys = rows << row_shift;
0158 int i;
0159 int error;
0160
0161 if (WARN_ON(!input_dev->dev.parent))
0162 return -EINVAL;
0163
0164 if (!keymap) {
0165 keymap = devm_kcalloc(input_dev->dev.parent,
0166 max_keys, sizeof(*keymap),
0167 GFP_KERNEL);
0168 if (!keymap) {
0169 dev_err(input_dev->dev.parent,
0170 "Unable to allocate memory for keymap");
0171 return -ENOMEM;
0172 }
0173 }
0174
0175 input_dev->keycode = keymap;
0176 input_dev->keycodesize = sizeof(*keymap);
0177 input_dev->keycodemax = max_keys;
0178
0179 __set_bit(EV_KEY, input_dev->evbit);
0180
0181 if (keymap_data) {
0182 for (i = 0; i < keymap_data->keymap_size; i++) {
0183 unsigned int key = keymap_data->keymap[i];
0184
0185 if (!matrix_keypad_map_key(input_dev, rows, cols,
0186 row_shift, key))
0187 return -EINVAL;
0188 }
0189 } else {
0190 error = matrix_keypad_parse_keymap(keymap_name, rows, cols,
0191 input_dev);
0192 if (error)
0193 return error;
0194 }
0195
0196 __clear_bit(KEY_RESERVED, input_dev->keybit);
0197
0198 return 0;
0199 }
0200 EXPORT_SYMBOL(matrix_keypad_build_keymap);
0201
0202 MODULE_LICENSE("GPL");