aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-input.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-09-10 00:57:17 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-09-10 01:02:11 -0400
commita0bf0ea809ba0a7621e191ec4cab5775d502ef7e (patch)
treef91841943ddb1091dd9ffa4197018c7a5f52d4a5 /drivers/hid/hid-input.c
parent9f470095068e415658ccc6977cf4b3f5be418526 (diff)
Input: hid-input - switch to using new keycode interface
Switch HID code to use new style of getkeycode and setkeycode methods to allow retrieving and setting keycodes not only by their scancodes but also by index. 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.c103
1 files changed, 70 insertions, 33 deletions
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 6c03dcc5760a..b12c07e64fbd 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -68,39 +68,49 @@ static const struct {
68#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ 68#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
69 &max, EV_KEY, (c)) 69 &max, EV_KEY, (c))
70 70
71static inline int match_scancode(unsigned int code, unsigned int scancode) 71static bool match_scancode(struct hid_usage *usage,
72 unsigned int cur_idx, unsigned int scancode)
72{ 73{
73 if (scancode == 0) 74 return (usage->hid & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
74 return 1;
75
76 return (code & (HID_USAGE_PAGE | HID_USAGE)) == scancode;
77} 75}
78 76
79static inline int match_keycode(unsigned int code, unsigned int keycode) 77static bool match_keycode(struct hid_usage *usage,
78 unsigned int cur_idx, unsigned int keycode)
80{ 79{
81 if (keycode == 0) 80 return usage->code == keycode;
82 return 1; 81}
83 82
84 return code == keycode; 83static bool match_index(struct hid_usage *usage,
84 unsigned int cur_idx, unsigned int idx)
85{
86 return cur_idx == idx;
85} 87}
86 88
89typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
90 unsigned int cur_idx, unsigned int val);
91
87static struct hid_usage *hidinput_find_key(struct hid_device *hid, 92static struct hid_usage *hidinput_find_key(struct hid_device *hid,
88 unsigned int scancode, 93 hid_usage_cmp_t match,
89 unsigned int keycode) 94 unsigned int value,
95 unsigned int *usage_idx)
90{ 96{
91 int i, j, k; 97 unsigned int i, j, k, cur_idx = 0;
92 struct hid_report *report; 98 struct hid_report *report;
93 struct hid_usage *usage; 99 struct hid_usage *usage;
94 100
95 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { 101 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
96 list_for_each_entry(report, &hid->report_enum[k].report_list, list) { 102 list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
97 for (i = 0; i < report->maxfield; i++) { 103 for (i = 0; i < report->maxfield; i++) {
98 for ( j = 0; j < report->field[i]->maxusage; j++) { 104 for (j = 0; j < report->field[i]->maxusage; j++) {
99 usage = report->field[i]->usage + j; 105 usage = report->field[i]->usage + j;
100 if (usage->type == EV_KEY && 106 if (usage->type == EV_KEY) {
101 match_scancode(usage->hid, scancode) && 107 if (match(usage, cur_idx, value)) {
102 match_keycode(usage->code, keycode)) 108 if (usage_idx)
103 return usage; 109 *usage_idx = cur_idx;
110 return usage;
111 }
112 cur_idx++;
113 }
104 } 114 }
105 } 115 }
106 } 116 }
@@ -108,39 +118,66 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid,
108 return NULL; 118 return NULL;
109} 119}
110 120
121static struct hid_usage *hidinput_locate_usage(struct hid_device *hid,
122 const struct input_keymap_entry *ke,
123 unsigned int *index)
124{
125 struct hid_usage *usage;
126 unsigned int scancode;
127
128 if (ke->flags & INPUT_KEYMAP_BY_INDEX)
129 usage = hidinput_find_key(hid, match_index, ke->index, index);
130 else if (input_scancode_to_scalar(ke, &scancode) == 0)
131 usage = hidinput_find_key(hid, match_scancode, scancode, index);
132 else
133 usage = NULL;
134
135 return usage;
136}
137
111static int hidinput_getkeycode(struct input_dev *dev, 138static int hidinput_getkeycode(struct input_dev *dev,
112 unsigned int scancode, unsigned int *keycode) 139 struct input_keymap_entry *ke)
113{ 140{
114 struct hid_device *hid = input_get_drvdata(dev); 141 struct hid_device *hid = input_get_drvdata(dev);
115 struct hid_usage *usage; 142 struct hid_usage *usage;
143 unsigned int scancode, index;
116 144
117 usage = hidinput_find_key(hid, scancode, 0); 145 usage = hidinput_locate_usage(hid, ke, &index);
118 if (usage) { 146 if (usage) {
119 *keycode = usage->code; 147 ke->keycode = usage->code;
148 ke->index = index;
149 scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE);
150 ke->len = sizeof(scancode);
151 memcpy(ke->scancode, &scancode, sizeof(scancode));
120 return 0; 152 return 0;
121 } 153 }
154
122 return -EINVAL; 155 return -EINVAL;
123} 156}
124 157
125static int hidinput_setkeycode(struct input_dev *dev, 158static int hidinput_setkeycode(struct input_dev *dev,
126 unsigned int scancode, unsigned int keycode) 159 const struct input_keymap_entry *ke,
160 unsigned int *old_keycode)
127{ 161{
128 struct hid_device *hid = input_get_drvdata(dev); 162 struct hid_device *hid = input_get_drvdata(dev);
129 struct hid_usage *usage; 163 struct hid_usage *usage;
130 int old_keycode;
131 164
132 usage = hidinput_find_key(hid, scancode, 0); 165 usage = hidinput_locate_usage(hid, ke, NULL);
133 if (usage) { 166 if (usage) {
134 old_keycode = usage->code; 167 *old_keycode = usage->code;
135 usage->code = keycode; 168 usage->code = ke->keycode;
136 169
137 clear_bit(old_keycode, dev->keybit); 170 clear_bit(*old_keycode, dev->keybit);
138 set_bit(usage->code, dev->keybit); 171 set_bit(usage->code, dev->keybit);
139 dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); 172 dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n",
140 /* Set the keybit for the old keycode if the old keycode is used 173 usage->code, usage->hid);
141 * by another key */ 174
142 if (hidinput_find_key (hid, 0, old_keycode)) 175 /*
143 set_bit(old_keycode, dev->keybit); 176 * Set the keybit for the old keycode if the old keycode is used
177 * by another key
178 */
179 if (hidinput_find_key(hid, match_keycode, *old_keycode, NULL))
180 set_bit(*old_keycode, dev->keybit);
144 181
145 return 0; 182 return 0;
146 } 183 }
@@ -748,8 +785,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
748 hid->ll_driver->hidinput_input_event; 785 hid->ll_driver->hidinput_input_event;
749 input_dev->open = hidinput_open; 786 input_dev->open = hidinput_open;
750 input_dev->close = hidinput_close; 787 input_dev->close = hidinput_close;
751 input_dev->setkeycode = hidinput_setkeycode; 788 input_dev->setkeycode_new = hidinput_setkeycode;
752 input_dev->getkeycode = hidinput_getkeycode; 789 input_dev->getkeycode_new = hidinput_getkeycode;
753 790
754 input_dev->name = hid->name; 791 input_dev->name = hid->name;
755 input_dev->phys = hid->phys; 792 input_dev->phys = hid->phys;