aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-09-15 22:36:56 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-09-16 02:11:29 -0400
commitf5854fad395b93071292bff27c0121b6e32215e0 (patch)
tree4420ba8623a9bb0ecef05875adf7d2da7941e862 /drivers
parent1f7930c55e1c1a2b6d5793a1002b31590356558c (diff)
Input: hid-input - allow mapping unknown usages
Currently HID layer only allows to remap keycodes for known usages, and responds with -EINVAL when user tries to map new usage code. This precludes us form relying on udev/keymap for establishing correct mappings and forces us to write dummy HID drivers responsible only for setting up keymaps. Let's allow remapping not only usages that have been set up as keys (usage->type == EV_KEY) but also yet-unmapped usages (usage->type == 0). Acked-by: Jarod Wilson <jarod@redhat.com> Acked-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-input.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index b12c07e64fbd..04121beed358 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -77,7 +77,10 @@ static bool match_scancode(struct hid_usage *usage,
77static bool match_keycode(struct hid_usage *usage, 77static bool match_keycode(struct hid_usage *usage,
78 unsigned int cur_idx, unsigned int keycode) 78 unsigned int cur_idx, unsigned int keycode)
79{ 79{
80 return usage->code == keycode; 80 /*
81 * We should exclude unmapped usages when doing lookup by keycode.
82 */
83 return (usage->type == EV_KEY && usage->code == keycode);
81} 84}
82 85
83static bool match_index(struct hid_usage *usage, 86static bool match_index(struct hid_usage *usage,
@@ -103,7 +106,7 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid,
103 for (i = 0; i < report->maxfield; i++) { 106 for (i = 0; i < report->maxfield; i++) {
104 for (j = 0; j < report->field[i]->maxusage; j++) { 107 for (j = 0; j < report->field[i]->maxusage; j++) {
105 usage = report->field[i]->usage + j; 108 usage = report->field[i]->usage + j;
106 if (usage->type == EV_KEY) { 109 if (usage->type == EV_KEY || usage->type == 0) {
107 if (match(usage, cur_idx, value)) { 110 if (match(usage, cur_idx, value)) {
108 if (usage_idx) 111 if (usage_idx)
109 *usage_idx = cur_idx; 112 *usage_idx = cur_idx;
@@ -144,7 +147,8 @@ static int hidinput_getkeycode(struct input_dev *dev,
144 147
145 usage = hidinput_locate_usage(hid, ke, &index); 148 usage = hidinput_locate_usage(hid, ke, &index);
146 if (usage) { 149 if (usage) {
147 ke->keycode = usage->code; 150 ke->keycode = usage->type == EV_KEY ?
151 usage->code : KEY_RESERVED;
148 ke->index = index; 152 ke->index = index;
149 scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE); 153 scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE);
150 ke->len = sizeof(scancode); 154 ke->len = sizeof(scancode);
@@ -164,7 +168,8 @@ static int hidinput_setkeycode(struct input_dev *dev,
164 168
165 usage = hidinput_locate_usage(hid, ke, NULL); 169 usage = hidinput_locate_usage(hid, ke, NULL);
166 if (usage) { 170 if (usage) {
167 *old_keycode = usage->code; 171 *old_keycode = usage->type == EV_KEY ?
172 usage->code : KEY_RESERVED;
168 usage->code = ke->keycode; 173 usage->code = ke->keycode;
169 174
170 clear_bit(*old_keycode, dev->keybit); 175 clear_bit(*old_keycode, dev->keybit);