diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-09-15 22:36:56 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-09-16 02:11:29 -0400 |
commit | f5854fad395b93071292bff27c0121b6e32215e0 (patch) | |
tree | 4420ba8623a9bb0ecef05875adf7d2da7941e862 /drivers/hid/hid-input.c | |
parent | 1f7930c55e1c1a2b6d5793a1002b31590356558c (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/hid/hid-input.c')
-rw-r--r-- | drivers/hid/hid-input.c | 13 |
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, | |||
77 | static bool match_keycode(struct hid_usage *usage, | 77 | static 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 | ||
83 | static bool match_index(struct hid_usage *usage, | 86 | static 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); |