aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-12-10 09:19:18 -0500
committerJiri Kosina <jkosina@suse.cz>2010-12-10 09:19:18 -0500
commit2ade0c1d9d93b7642212657ef76f4a1e30233711 (patch)
tree63bc720c0ffe5f4760cac4ed617b9870b050175e /drivers/hid
parent504499f22c08a03e2e19dc88d31aa0ecd2ac815e (diff)
parent6313e3c21743cc88bb5bd8aa72948ee1e83937b6 (diff)
Merge branch 'master' into upstream
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-core.c6
-rw-r--r--drivers/hid/hid-egalax.c2
-rw-r--r--drivers/hid/hid-ids.h4
-rw-r--r--drivers/hid/hid-input.c127
-rw-r--r--drivers/hid/hid-tmff.c2
-rw-r--r--drivers/hid/hidraw.c1
-rw-r--r--drivers/hid/usbhid/hiddev.c1
7 files changed, 99 insertions, 44 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index d4c1906313d2..c4d47e635f95 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1414,6 +1414,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1414 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, 1414 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
1415 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) }, 1415 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
1416 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, 1416 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
1417 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
1417 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, 1418 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
1418 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, 1419 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
1419 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, 1420 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
@@ -1814,6 +1815,11 @@ static bool hid_ignore(struct hid_device *hdev)
1814 hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST) 1815 hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST)
1815 return true; 1816 return true;
1816 break; 1817 break;
1818 case USB_VENDOR_ID_HANWANG:
1819 if (hdev->product >= USB_DEVICE_ID_HANWANG_TABLET_FIRST &&
1820 hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST)
1821 return true;
1822 break;
1817 } 1823 }
1818 1824
1819 if (hdev->type == HID_TYPE_USBMOUSE && 1825 if (hdev->type == HID_TYPE_USBMOUSE &&
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
index bbab6cff3518..72b1dd8d16ce 100644
--- a/drivers/hid/hid-egalax.c
+++ b/drivers/hid/hid-egalax.c
@@ -221,7 +221,7 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
221 struct egalax_data *td; 221 struct egalax_data *td;
222 struct hid_report *report; 222 struct hid_report *report;
223 223
224 td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL); 224 td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
225 if (!td) { 225 if (!td) {
226 hid_err(hdev, "cannot allocate eGalax data\n"); 226 hid_err(hdev, "cannot allocate eGalax data\n");
227 return -ENOMEM; 227 return -ENOMEM;
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index d91bb12f9c54..5cd1a6a356a3 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -309,6 +309,10 @@
309#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 309#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
310#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 310#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
311 311
312#define USB_VENDOR_ID_HANWANG 0x0b57
313#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000
314#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff
315
312#define USB_VENDOR_ID_HAPP 0x078b 316#define USB_VENDOR_ID_HAPP 0x078b
313#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 317#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
314#define USB_DEVICE_ID_UGCI_FLYING 0x0020 318#define USB_DEVICE_ID_UGCI_FLYING 0x0020
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index a1a2206714fc..c0757821b1fc 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("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 }
@@ -161,8 +203,8 @@ static int hidinput_setkeycode(struct input_dev *dev,
161 * 203 *
162 * as seen in the HID specification v1.11 6.2.2.7 Global Items. 204 * as seen in the HID specification v1.11 6.2.2.7 Global Items.
163 * 205 *
164 * Only exponent 1 length units are processed. Centimeters are converted to 206 * Only exponent 1 length units are processed. Centimeters and inches are
165 * inches. Degrees are converted to radians. 207 * converted to millimeters. Degrees are converted to radians.
166 */ 208 */
167static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) 209static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
168{ 210{
@@ -183,13 +225,16 @@ static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code)
183 */ 225 */
184 if (code == ABS_X || code == ABS_Y || code == ABS_Z) { 226 if (code == ABS_X || code == ABS_Y || code == ABS_Z) {
185 if (field->unit == 0x11) { /* If centimeters */ 227 if (field->unit == 0x11) { /* If centimeters */
186 /* Convert to inches */ 228 /* Convert to millimeters */
187 prev = logical_extents; 229 unit_exponent += 1;
188 logical_extents *= 254; 230 } else if (field->unit == 0x13) { /* If inches */
189 if (logical_extents < prev) 231 /* Convert to millimeters */
232 prev = physical_extents;
233 physical_extents *= 254;
234 if (physical_extents < prev)
190 return 0; 235 return 0;
191 unit_exponent += 2; 236 unit_exponent -= 1;
192 } else if (field->unit != 0x13) { /* If not inches */ 237 } else {
193 return 0; 238 return 0;
194 } 239 }
195 } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) { 240 } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) {
@@ -835,8 +880,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
835 hid->ll_driver->hidinput_input_event; 880 hid->ll_driver->hidinput_input_event;
836 input_dev->open = hidinput_open; 881 input_dev->open = hidinput_open;
837 input_dev->close = hidinput_close; 882 input_dev->close = hidinput_close;
838 input_dev->setkeycode = hidinput_setkeycode; 883 input_dev->setkeycode_new = hidinput_setkeycode;
839 input_dev->getkeycode = hidinput_getkeycode; 884 input_dev->getkeycode_new = hidinput_getkeycode;
840 885
841 input_dev->name = hid->name; 886 input_dev->name = hid->name;
842 input_dev->phys = hid->phys; 887 input_dev->phys = hid->phys;
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 356a98fcb365..575862b0688e 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -249,6 +249,8 @@ static const struct hid_device_id tm_devices[] = {
249 .driver_data = (unsigned long)ff_joystick }, 249 .driver_data = (unsigned long)ff_joystick },
250 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ 250 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */
251 .driver_data = (unsigned long)ff_joystick }, 251 .driver_data = (unsigned long)ff_joystick },
252 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a), /* F430 Force Feedback Wheel */
253 .driver_data = (unsigned long)ff_joystick },
252 { } 254 { }
253}; 255};
254MODULE_DEVICE_TABLE(hid, tm_devices); 256MODULE_DEVICE_TABLE(hid, tm_devices);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index eb16cd143e2a..68d087f63c02 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -34,7 +34,6 @@
34#include <linux/hid.h> 34#include <linux/hid.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/smp_lock.h>
38 37
39#include <linux/hidraw.h> 38#include <linux/hidraw.h>
40 39
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index fb78f75d49a9..af0a7c1002af 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -29,7 +29,6 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/smp_lock.h>
33#include <linux/input.h> 32#include <linux/input.h>
34#include <linux/usb.h> 33#include <linux/usb.h>
35#include <linux/hid.h> 34#include <linux/hid.h>