diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-12-10 09:19:18 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-12-10 09:19:18 -0500 |
commit | 2ade0c1d9d93b7642212657ef76f4a1e30233711 (patch) | |
tree | 63bc720c0ffe5f4760cac4ed617b9870b050175e /drivers/hid | |
parent | 504499f22c08a03e2e19dc88d31aa0ecd2ac815e (diff) | |
parent | 6313e3c21743cc88bb5bd8aa72948ee1e83937b6 (diff) |
Merge branch 'master' into upstream
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-core.c | 6 | ||||
-rw-r--r-- | drivers/hid/hid-egalax.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 4 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 127 | ||||
-rw-r--r-- | drivers/hid/hid-tmff.c | 2 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 1 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 1 |
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 | ||
71 | static inline int match_scancode(unsigned int code, unsigned int scancode) | 71 | static 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 | ||
79 | static inline int match_keycode(unsigned int code, unsigned int keycode) | 77 | static 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; | 86 | static 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 | ||
92 | typedef bool (*hid_usage_cmp_t)(struct hid_usage *usage, | ||
93 | unsigned int cur_idx, unsigned int val); | ||
94 | |||
87 | static struct hid_usage *hidinput_find_key(struct hid_device *hid, | 95 | static 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 | ||
124 | static 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 | |||
111 | static int hidinput_getkeycode(struct input_dev *dev, | 141 | static 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 | ||
125 | static int hidinput_setkeycode(struct input_dev *dev, | 162 | static 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 | */ |
167 | static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | 209 | static __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 | }; |
254 | MODULE_DEVICE_TABLE(hid, tm_devices); | 256 | MODULE_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> |