aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-10-25 01:11:17 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-10-25 01:11:17 -0400
commit49327ad2bbbaf1945d5ba431522201574219d150 (patch)
tree47beb374d0cfb77d401220f20e8cece4ce4469db /drivers/hid
parentf9ce6eb5b6fa8cbcf0a0fb7c5f4203f94730fc52 (diff)
parent6521d0bf984ab1cc25795d312e21c438aea8b5d5 (diff)
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c5
-rw-r--r--drivers/hid/hid-ids.h4
-rw-r--r--drivers/hid/hid-input.c108
3 files changed, 84 insertions, 33 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index e635199a0cd2..baa25ad8270a 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1766,6 +1766,11 @@ static bool hid_ignore(struct hid_device *hdev)
1766 hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST) 1766 hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
1767 return true; 1767 return true;
1768 break; 1768 break;
1769 case USB_VENDOR_ID_HANWANG:
1770 if (hdev->product >= USB_DEVICE_ID_HANWANG_TABLET_FIRST &&
1771 hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST)
1772 return true;
1773 break;
1769 } 1774 }
1770 1775
1771 if (hdev->type == HID_TYPE_USBMOUSE && 1776 if (hdev->type == HID_TYPE_USBMOUSE &&
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index d3fc13ae094d..11af537414b8 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -291,6 +291,10 @@
291#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 291#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
292#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 292#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
293 293
294#define USB_VENDOR_ID_HANWANG 0x0b57
295#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000
296#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff
297
294#define USB_VENDOR_ID_HAPP 0x078b 298#define USB_VENDOR_ID_HAPP 0x078b
295#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 299#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
296#define USB_DEVICE_ID_UGCI_FLYING 0x0020 300#define USB_DEVICE_ID_UGCI_FLYING 0x0020
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 6c03dcc5760a..04121beed358 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -68,39 +68,52 @@ 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 /*
82 return 1; 81 * We should exclude unmapped usages when doing lookup by keycode.
82 */
83 return (usage->type == EV_KEY && usage->code == keycode);
84}
83 85
84 return code == keycode; 86static bool match_index(struct hid_usage *usage,
87 unsigned int cur_idx, unsigned int idx)
88{
89 return cur_idx == idx;
85} 90}
86 91
92typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage,
93 unsigned int cur_idx, unsigned int val);
94
87static struct hid_usage *hidinput_find_key(struct hid_device *hid, 95static struct hid_usage *hidinput_find_key(struct hid_device *hid,
88 unsigned int scancode, 96 hid_usage_cmp_t match,
89 unsigned int keycode) 97 unsigned int value,
98 unsigned int *usage_idx)
90{ 99{
91 int i, j, k; 100 unsigned int i, j, k, cur_idx = 0;
92 struct hid_report *report; 101 struct hid_report *report;
93 struct hid_usage *usage; 102 struct hid_usage *usage;
94 103
95 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { 104 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
96 list_for_each_entry(report, &hid->report_enum[k].report_list, list) { 105 list_for_each_entry(report, &hid->report_enum[k].report_list, list) {
97 for (i = 0; i < report->maxfield; i++) { 106 for (i = 0; i < report->maxfield; i++) {
98 for ( j = 0; j < report->field[i]->maxusage; j++) { 107 for (j = 0; j < report->field[i]->maxusage; j++) {
99 usage = report->field[i]->usage + j; 108 usage = report->field[i]->usage + j;
100 if (usage->type == EV_KEY && 109 if (usage->type == EV_KEY || usage->type == 0) {
101 match_scancode(usage->hid, scancode) && 110 if (match(usage, cur_idx, value)) {
102 match_keycode(usage->code, keycode)) 111 if (usage_idx)
103 return usage; 112 *usage_idx = cur_idx;
113 return usage;
114 }
115 cur_idx++;
116 }
104 } 117 }
105 } 118 }
106 } 119 }
@@ -108,39 +121,68 @@ static struct hid_usage *hidinput_find_key(struct hid_device *hid,
108 return NULL; 121 return NULL;
109} 122}
110 123
124static struct hid_usage *hidinput_locate_usage(struct hid_device *hid,
125 const struct input_keymap_entry *ke,
126 unsigned int *index)
127{
128 struct hid_usage *usage;
129 unsigned int scancode;
130
131 if (ke->flags & INPUT_KEYMAP_BY_INDEX)
132 usage = hidinput_find_key(hid, match_index, ke->index, index);
133 else if (input_scancode_to_scalar(ke, &scancode) == 0)
134 usage = hidinput_find_key(hid, match_scancode, scancode, index);
135 else
136 usage = NULL;
137
138 return usage;
139}
140
111static int hidinput_getkeycode(struct input_dev *dev, 141static int hidinput_getkeycode(struct input_dev *dev,
112 unsigned int scancode, unsigned int *keycode) 142 struct input_keymap_entry *ke)
113{ 143{
114 struct hid_device *hid = input_get_drvdata(dev); 144 struct hid_device *hid = input_get_drvdata(dev);
115 struct hid_usage *usage; 145 struct hid_usage *usage;
146 unsigned int scancode, index;
116 147
117 usage = hidinput_find_key(hid, scancode, 0); 148 usage = hidinput_locate_usage(hid, ke, &index);
118 if (usage) { 149 if (usage) {
119 *keycode = usage->code; 150 ke->keycode = usage->type == EV_KEY ?
151 usage->code : KEY_RESERVED;
152 ke->index = index;
153 scancode = usage->hid & (HID_USAGE_PAGE | HID_USAGE);
154 ke->len = sizeof(scancode);
155 memcpy(ke->scancode, &scancode, sizeof(scancode));
120 return 0; 156 return 0;
121 } 157 }
158
122 return -EINVAL; 159 return -EINVAL;
123} 160}
124 161
125static int hidinput_setkeycode(struct input_dev *dev, 162static int hidinput_setkeycode(struct input_dev *dev,
126 unsigned int scancode, unsigned int keycode) 163 const struct input_keymap_entry *ke,
164 unsigned int *old_keycode)
127{ 165{
128 struct hid_device *hid = input_get_drvdata(dev); 166 struct hid_device *hid = input_get_drvdata(dev);
129 struct hid_usage *usage; 167 struct hid_usage *usage;
130 int old_keycode;
131 168
132 usage = hidinput_find_key(hid, scancode, 0); 169 usage = hidinput_locate_usage(hid, ke, NULL);
133 if (usage) { 170 if (usage) {
134 old_keycode = usage->code; 171 *old_keycode = usage->type == EV_KEY ?
135 usage->code = keycode; 172 usage->code : KEY_RESERVED;
173 usage->code = ke->keycode;
136 174
137 clear_bit(old_keycode, dev->keybit); 175 clear_bit(*old_keycode, dev->keybit);
138 set_bit(usage->code, dev->keybit); 176 set_bit(usage->code, dev->keybit);
139 dbg_hid(KERN_DEBUG "Assigned keycode %d to HID usage code %x\n", keycode, scancode); 177 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 178 usage->code, usage->hid);
141 * by another key */ 179
142 if (hidinput_find_key (hid, 0, old_keycode)) 180 /*
143 set_bit(old_keycode, dev->keybit); 181 * Set the keybit for the old keycode if the old keycode is used
182 * by another key
183 */
184 if (hidinput_find_key(hid, match_keycode, *old_keycode, NULL))
185 set_bit(*old_keycode, dev->keybit);
144 186
145 return 0; 187 return 0;
146 } 188 }
@@ -748,8 +790,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
748 hid->ll_driver->hidinput_input_event; 790 hid->ll_driver->hidinput_input_event;
749 input_dev->open = hidinput_open; 791 input_dev->open = hidinput_open;
750 input_dev->close = hidinput_close; 792 input_dev->close = hidinput_close;
751 input_dev->setkeycode = hidinput_setkeycode; 793 input_dev->setkeycode_new = hidinput_setkeycode;
752 input_dev->getkeycode = hidinput_getkeycode; 794 input_dev->getkeycode_new = hidinput_getkeycode;
753 795
754 input_dev->name = hid->name; 796 input_dev->name = hid->name;
755 input_dev->phys = hid->phys; 797 input_dev->phys = hid->phys;