aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:45:49 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-14 16:45:49 -0400
commitb322b7816908487c08b89b72f838174c37d8c836 (patch)
tree8fde3f20bf6fb97b91fd3f88e032251f0c569d00
parentf44c2c9e073a578b2946bcf4127ffb041ee765b8 (diff)
parent6341de0527c26ea1eaf7b7918e1df98f99e1a525 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: HID: fix inverted wheel for bluetooth version of apple mighty mouse HID: no more reinitializtion is needed in post_reset HID: hidraw -- fix comment about accepted devices HID: Multitouch support for the N-Trig touchscreen HID: add new multitouch and digitizer contants HID: autocentering support for Logitech Force 3D Pro HID: fix hid-ff drivers so that devices work even without ff support HID: force feedback support for SmartJoy PLUS PS2/USB adapter HID: Wacom Graphire Bluetooth driver HID: autocentering support for Logitech G25 Racing Wheel
-rw-r--r--drivers/hid/Kconfig92
-rw-r--r--drivers/hid/Makefile10
-rw-r--r--drivers/hid/hid-apple.c4
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-debug.c23
-rw-r--r--drivers/hid/hid-drff.c8
-rw-r--r--drivers/hid/hid-gaff.c8
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/hid/hid-lgff.c10
-rw-r--r--drivers/hid/hid-ntrig.c222
-rw-r--r--drivers/hid/hid-sjoy.c180
-rw-r--r--drivers/hid/hid-tmff.c17
-rw-r--r--drivers/hid/hid-wacom.c259
-rw-r--r--drivers/hid/hid-zpff.c7
-rw-r--r--drivers/hid/hidraw.c5
-rw-r--r--drivers/hid/usbhid/hid-core.c7
-rw-r--r--include/linux/hid.h36
17 files changed, 841 insertions, 51 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 7e67dcb3d4f6..7831a0318d3c 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -116,9 +116,16 @@ config HID_CYPRESS
116 ---help--- 116 ---help---
117 Support for cypress mouse and barcode readers. 117 Support for cypress mouse and barcode readers.
118 118
119config DRAGONRISE_FF 119config HID_DRAGONRISE
120 tristate "DragonRise Inc. force feedback support" 120 tristate "DragonRise Inc. support" if EMBEDDED
121 depends on USB_HID 121 depends on USB_HID
122 default !EMBEDDED
123 ---help---
124 Say Y here if you have DragonRise Inc.game controllers.
125
126config DRAGONRISE_FF
127 bool "DragonRise Inc. force feedback support"
128 depends on HID_DRAGONRISE
122 select INPUT_FF_MEMLESS 129 select INPUT_FF_MEMLESS
123 ---help--- 130 ---help---
124 Say Y here if you want to enable force feedback support for DragonRise Inc. 131 Say Y here if you want to enable force feedback support for DragonRise Inc.
@@ -160,7 +167,7 @@ config HID_LOGITECH
160 Support for Logitech devices that are not fully compliant with HID standard. 167 Support for Logitech devices that are not fully compliant with HID standard.
161 168
162config LOGITECH_FF 169config LOGITECH_FF
163 bool "Logitech force feedback" 170 bool "Logitech force feedback support"
164 depends on HID_LOGITECH 171 depends on HID_LOGITECH
165 select INPUT_FF_MEMLESS 172 select INPUT_FF_MEMLESS
166 help 173 help
@@ -176,7 +183,7 @@ config LOGITECH_FF
176 force feedback. 183 force feedback.
177 184
178config LOGIRUMBLEPAD2_FF 185config LOGIRUMBLEPAD2_FF
179 bool "Logitech Rumblepad 2 force feedback" 186 bool "Logitech Rumblepad 2 force feedback support"
180 depends on HID_LOGITECH 187 depends on HID_LOGITECH
181 select INPUT_FF_MEMLESS 188 select INPUT_FF_MEMLESS
182 help 189 help
@@ -211,11 +218,19 @@ config HID_PANTHERLORD
211 ---help--- 218 ---help---
212 Support for PantherLord/GreenAsia based device support. 219 Support for PantherLord/GreenAsia based device support.
213 220
221config HID_PANTHERLORD
222 tristate "Pantherlord support" if EMBEDDED
223 depends on USB_HID
224 default !EMBEDDED
225 ---help---
226 Say Y here if you have a PantherLord/GreenAsia based game controller
227 or adapter.
228
214config PANTHERLORD_FF 229config PANTHERLORD_FF
215 bool "Pantherlord force feedback support" 230 bool "Pantherlord force feedback support"
216 depends on HID_PANTHERLORD 231 depends on HID_PANTHERLORD
217 select INPUT_FF_MEMLESS 232 select INPUT_FF_MEMLESS
218 help 233 ---help---
219 Say Y here if you have a PantherLord/GreenAsia based game controller 234 Say Y here if you have a PantherLord/GreenAsia based game controller
220 or adapter and want to enable force feedback support for it. 235 or adapter and want to enable force feedback support for it.
221 236
@@ -247,15 +262,38 @@ config HID_SUNPLUS
247 ---help--- 262 ---help---
248 Support for Sunplus wireless desktop. 263 Support for Sunplus wireless desktop.
249 264
250config GREENASIA_FF 265config HID_GREENASIA
251 tristate "GreenAsia (Product ID 0x12) force feedback support" 266 tristate "GreenAsia (Product ID 0x12) support" if EMBEDDED
252 depends on USB_HID 267 depends on USB_HID
268 default !EMBEDDED
269 ---help---
270 Say Y here if you have a GreenAsia (Product ID 0x12) based game
271 controller or adapter.
272
273config GREENASIA_FF
274 bool "GreenAsia (Product ID 0x12) force feedback support"
275 depends on HID_GREENASIA
253 select INPUT_FF_MEMLESS 276 select INPUT_FF_MEMLESS
254 ---help--- 277 ---help---
255 Say Y here if you have a GreenAsia (Product ID 0x12) based game controller 278 Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
256 (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter 279 (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
257 and want to enable force feedback support for it. 280 and want to enable force feedback support for it.
258 281
282config HID_SMARTJOYPLUS
283 tristate "SmartJoy PLUS PS2/USB adapter support" if EMBEDDED
284 depends on USB_HID
285 default !EMBEDDED
286 ---help---
287 Support for SmartJoy PLUS PS2/USB adapter.
288
289config SMARTJOYPLUS_FF
290 bool "SmartJoy PLUS PS2/USB adapter force feedback support"
291 depends on HID_SMARTJOYPLUS
292 select INPUT_FF_MEMLESS
293 ---help---
294 Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to
295 enable force feedback support for it.
296
259config HID_TOPSEED 297config HID_TOPSEED
260 tristate "TopSeed Cyberlink remote control support" if EMBEDDED 298 tristate "TopSeed Cyberlink remote control support" if EMBEDDED
261 depends on USB_HID 299 depends on USB_HID
@@ -263,21 +301,45 @@ config HID_TOPSEED
263 ---help--- 301 ---help---
264 Say Y if you have a TopSeed Cyberlink remote control. 302 Say Y if you have a TopSeed Cyberlink remote control.
265 303
266config THRUSTMASTER_FF 304config HID_THRUSTMASTER
267 tristate "ThrustMaster devices support" 305 tristate "ThrustMaster devices support" if EMBEDDED
268 depends on USB_HID 306 depends on USB_HID
307 default !EMBEDDED
308 ---help---
309 Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
310 a THRUSTMASTER Ferrari GT Rumble Wheel.
311
312config THRUSTMASTER_FF
313 bool "ThrustMaster devices force feedback support"
314 depends on HID_THRUSTMASTER
269 select INPUT_FF_MEMLESS 315 select INPUT_FF_MEMLESS
270 help 316 ---help---
271 Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 317 Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
272 a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel. 318 a THRUSTMASTER Ferrari GT Rumble Force or Force Feedback Wheel and
319 want to enable force feedback support for it.
273 320
274config ZEROPLUS_FF 321config HID_WACOM
275 tristate "Zeroplus based game controller support" 322 tristate "Wacom Bluetooth devices support" if EMBEDDED
323 depends on BT_HIDP
324 default !EMBEDDED
325 ---help---
326 Support for Wacom Graphire Bluetooth tablet.
327
328config HID_ZEROPLUS
329 tristate "Zeroplus based game controller support" if EMBEDDED
276 depends on USB_HID 330 depends on USB_HID
277 select INPUT_FF_MEMLESS 331 default !EMBEDDED
278 help 332 ---help---
279 Say Y here if you have a Zeroplus based game controller. 333 Say Y here if you have a Zeroplus based game controller.
280 334
335config ZEROPLUS_FF
336 bool "Zeroplus based game controller force feedback support"
337 depends on HID_ZEROPLUS
338 select INPUT_FF_MEMLESS
339 ---help---
340 Say Y here if you have a Zeroplus based game controller and want
341 to have force feedback support for it.
342
281endmenu 343endmenu
282 344
283endif # HID_SUPPORT 345endif # HID_SUPPORT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 1f7cb0fd4505..db35151673b1 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
22obj-$(CONFIG_HID_CHERRY) += hid-cherry.o 22obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
23obj-$(CONFIG_HID_CHICONY) += hid-chicony.o 23obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
24obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 24obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
25obj-$(CONFIG_DRAGONRISE_FF) += hid-drff.o 25obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o
26obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o 26obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
27obj-$(CONFIG_HID_GYRATION) += hid-gyration.o 27obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
28obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 28obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
@@ -34,12 +34,14 @@ obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o
34obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o 34obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
35obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 35obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
36obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 36obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
37obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
37obj-$(CONFIG_HID_SONY) += hid-sony.o 38obj-$(CONFIG_HID_SONY) += hid-sony.o
38obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o 39obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
39obj-$(CONFIG_GREENASIA_FF) += hid-gaff.o 40obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
40obj-$(CONFIG_THRUSTMASTER_FF) += hid-tmff.o 41obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
41obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o 42obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
42obj-$(CONFIG_ZEROPLUS_FF) += hid-zpff.o 43obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
44obj-$(CONFIG_HID_WACOM) += hid-wacom.o
43 45
44obj-$(CONFIG_USB_HID) += usbhid/ 46obj-$(CONFIG_USB_HID) += usbhid/
45obj-$(CONFIG_USB_MOUSE) += usbhid/ 47obj-$(CONFIG_USB_MOUSE) += usbhid/
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index acbce5745b0c..303ccce05bb3 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -436,10 +436,6 @@ static const struct hid_device_id apple_devices[] = {
436 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), 436 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
437 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, 437 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
438 438
439 /* Apple wireless Mighty Mouse */
440 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c),
441 .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
442
443 { } 439 { }
444}; 440};
445MODULE_DEVICE_TABLE(hid, apple_devices); 441MODULE_DEVICE_TABLE(hid, apple_devices);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8551693d645f..f2c21d5d24e8 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1312,6 +1312,8 @@ static const struct hid_device_id hid_blacklist[] = {
1312 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, 1312 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) },
1313 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, 1313 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
1314 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, 1314 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
1315 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1316 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1315 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1317 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1316 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1318 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1317 1319
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 47ac1a7d66e1..04359ed64b87 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -137,6 +137,14 @@ static const struct hid_usage_entry hid_usage_table[] = {
137 {0, 0x44, "BarrelSwitch"}, 137 {0, 0x44, "BarrelSwitch"},
138 {0, 0x45, "Eraser"}, 138 {0, 0x45, "Eraser"},
139 {0, 0x46, "TabletPick"}, 139 {0, 0x46, "TabletPick"},
140 {0, 0x47, "Confidence"},
141 {0, 0x48, "Width"},
142 {0, 0x49, "Height"},
143 {0, 0x51, "ContactID"},
144 {0, 0x52, "InputMode"},
145 {0, 0x53, "DeviceIndex"},
146 {0, 0x54, "ContactCount"},
147 {0, 0x55, "ContactMaximumNumber"},
140 { 15, 0, "PhysicalInterfaceDevice" }, 148 { 15, 0, "PhysicalInterfaceDevice" },
141 {0, 0x00, "Undefined"}, 149 {0, 0x00, "Undefined"},
142 {0, 0x01, "Physical_Interface_Device"}, 150 {0, 0x01, "Physical_Interface_Device"},
@@ -514,9 +522,11 @@ static const char *events[EV_MAX + 1] = {
514 [EV_FF_STATUS] = "ForceFeedbackStatus", 522 [EV_FF_STATUS] = "ForceFeedbackStatus",
515}; 523};
516 524
517static const char *syncs[2] = { 525static const char *syncs[3] = {
518 [SYN_REPORT] = "Report", [SYN_CONFIG] = "Config", 526 [SYN_REPORT] = "Report", [SYN_CONFIG] = "Config",
527 [SYN_MT_REPORT] = "MT Report",
519}; 528};
529
520static const char *keys[KEY_MAX + 1] = { 530static const char *keys[KEY_MAX + 1] = {
521 [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc", 531 [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc",
522 [KEY_1] = "1", [KEY_2] = "2", 532 [KEY_1] = "1", [KEY_2] = "2",
@@ -734,8 +744,17 @@ static const char *absolutes[ABS_MAX + 1] = {
734 [ABS_HAT2Y] = "Hat2Y", [ABS_HAT3X] = "Hat3X", 744 [ABS_HAT2Y] = "Hat2Y", [ABS_HAT3X] = "Hat3X",
735 [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure", 745 [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure",
736 [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt", 746 [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt",
737 [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "Tool Width", 747 [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "ToolWidth",
738 [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc", 748 [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc",
749 [ABS_MT_TOUCH_MAJOR] = "MTMajor",
750 [ABS_MT_TOUCH_MINOR] = "MTMinor",
751 [ABS_MT_WIDTH_MAJOR] = "MTMajorW",
752 [ABS_MT_WIDTH_MINOR] = "MTMinorW",
753 [ABS_MT_ORIENTATION] = "MTOrientation",
754 [ABS_MT_POSITION_X] = "MTPositionX",
755 [ABS_MT_POSITION_Y] = "MTPositionY",
756 [ABS_MT_TOOL_TYPE] = "MTToolType",
757 [ABS_MT_BLOB_ID] = "MTBlobID",
739}; 758};
740 759
741static const char *misc[MSC_MAX + 1] = { 760static const char *misc[MSC_MAX + 1] = {
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c
index 34f3eb65100b..a239d20ad7a5 100644
--- a/drivers/hid/hid-drff.c
+++ b/drivers/hid/hid-drff.c
@@ -32,6 +32,8 @@
32#include <linux/hid.h> 32#include <linux/hid.h>
33 33
34#include "hid-ids.h" 34#include "hid-ids.h"
35
36#ifdef CONFIG_DRAGONRISE_FF
35#include "usbhid/usbhid.h" 37#include "usbhid/usbhid.h"
36 38
37struct drff_device { 39struct drff_device {
@@ -135,6 +137,12 @@ static int drff_init(struct hid_device *hid)
135 137
136 return 0; 138 return 0;
137} 139}
140#else
141static inline int drff_init(struct hid_device *hid)
142{
143 return 0;
144}
145#endif
138 146
139static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) 147static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
140{ 148{
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 510ad3ab8d33..8a11ccddaf2e 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -31,6 +31,8 @@
31#include <linux/usb.h> 31#include <linux/usb.h>
32#include <linux/hid.h> 32#include <linux/hid.h>
33#include "hid-ids.h" 33#include "hid-ids.h"
34
35#ifdef CONFIG_GREENASIA_FF
34#include "usbhid/usbhid.h" 36#include "usbhid/usbhid.h"
35 37
36struct gaff_device { 38struct gaff_device {
@@ -130,6 +132,12 @@ static int gaff_init(struct hid_device *hid)
130 132
131 return 0; 133 return 0;
132} 134}
135#else
136static inline int gaff_init(struct hid_device *hdev)
137{
138 return 0;
139}
140#endif
133 141
134static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id) 142static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id)
135{ 143{
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 4d5ee2bbc62b..630101037921 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -414,8 +414,10 @@
414#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 414#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
415 415
416#define USB_VENDOR_ID_WACOM 0x056a 416#define USB_VENDOR_ID_WACOM 0x056a
417#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
417 418
418#define USB_VENDOR_ID_WISEGROUP 0x0925 419#define USB_VENDOR_ID_WISEGROUP 0x0925
420#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
419#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 421#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
420#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 422#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
421#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201 423#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201
diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
index 51aff08e10ce..56099709581c 100644
--- a/drivers/hid/hid-lgff.c
+++ b/drivers/hid/hid-lgff.c
@@ -50,6 +50,12 @@ static const signed short ff_joystick[] = {
50 -1 50 -1
51}; 51};
52 52
53static const signed short ff_joystick_ac[] = {
54 FF_CONSTANT,
55 FF_AUTOCENTER,
56 -1
57};
58
53static const signed short ff_wheel[] = { 59static const signed short ff_wheel[] = {
54 FF_CONSTANT, 60 FF_CONSTANT,
55 FF_AUTOCENTER, 61 FF_AUTOCENTER,
@@ -60,8 +66,8 @@ static const struct dev_type devices[] = {
60 { 0x046d, 0xc211, ff_rumble }, 66 { 0x046d, 0xc211, ff_rumble },
61 { 0x046d, 0xc219, ff_rumble }, 67 { 0x046d, 0xc219, ff_rumble },
62 { 0x046d, 0xc283, ff_joystick }, 68 { 0x046d, 0xc283, ff_joystick },
63 { 0x046d, 0xc286, ff_joystick }, 69 { 0x046d, 0xc286, ff_joystick_ac },
64 { 0x046d, 0xc294, ff_joystick }, 70 { 0x046d, 0xc294, ff_wheel },
65 { 0x046d, 0xc295, ff_joystick }, 71 { 0x046d, 0xc295, ff_joystick },
66 { 0x046d, 0xca03, ff_wheel }, 72 { 0x046d, 0xca03, ff_wheel },
67}; 73};
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index c5b252be9c21..75ed9d2c1a36 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -1,13 +1,8 @@
1/* 1/*
2 * HID driver for some ntrig "special" devices 2 * HID driver for N-Trig touchscreens
3 * 3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby
10 * Copyright (c) 2008 Rafi Rubin 4 * Copyright (c) 2008 Rafi Rubin
5 * Copyright (c) 2009 Stephane Chatty
11 * 6 *
12 */ 7 */
13 8
@@ -29,15 +24,79 @@
29#define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 24#define nt_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
30 EV_KEY, (c)) 25 EV_KEY, (c))
31 26
27struct ntrig_data {
28 __s32 x, y, id, w, h;
29 char reading_a_point, found_contact_id;
30};
31
32/*
33 * this driver is aimed at two firmware versions in circulation:
34 * - dual pen/finger single touch
35 * - finger multitouch, pen not working
36 */
37
32static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, 38static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi,
33 struct hid_field *field, struct hid_usage *usage, 39 struct hid_field *field, struct hid_usage *usage,
34 unsigned long **bit, int *max) 40 unsigned long **bit, int *max)
35{ 41{
36 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_DIGITIZER && 42 switch (usage->hid & HID_USAGE_PAGE) {
37 (usage->hid & 0xff) == 0x47) { 43
38 nt_map_key_clear(BTN_TOOL_DOUBLETAP); 44 case HID_UP_GENDESK:
39 return 1; 45 switch (usage->hid) {
46 case HID_GD_X:
47 hid_map_usage(hi, usage, bit, max,
48 EV_ABS, ABS_MT_POSITION_X);
49 input_set_abs_params(hi->input, ABS_X,
50 field->logical_minimum,
51 field->logical_maximum, 0, 0);
52 return 1;
53 case HID_GD_Y:
54 hid_map_usage(hi, usage, bit, max,
55 EV_ABS, ABS_MT_POSITION_Y);
56 input_set_abs_params(hi->input, ABS_Y,
57 field->logical_minimum,
58 field->logical_maximum, 0, 0);
59 return 1;
60 }
61 return 0;
62
63 case HID_UP_DIGITIZER:
64 switch (usage->hid) {
65 /* we do not want to map these for now */
66 case HID_DG_INVERT: /* value is always 0 */
67 case HID_DG_ERASER: /* value is always 0 */
68 case HID_DG_CONTACTID: /* value is useless */
69 case HID_DG_BARRELSWITCH: /* doubtful */
70 case HID_DG_INPUTMODE:
71 case HID_DG_DEVICEINDEX:
72 case HID_DG_CONTACTCOUNT:
73 case HID_DG_CONTACTMAX:
74 return -1;
75
76 /* original mapping by Rafi Rubin */
77 case HID_DG_CONFIDENCE:
78 nt_map_key_clear(BTN_TOOL_DOUBLETAP);
79 return 1;
80
81 /* width/height mapped on TouchMajor/TouchMinor/Orientation */
82 case HID_DG_WIDTH:
83 hid_map_usage(hi, usage, bit, max,
84 EV_ABS, ABS_MT_TOUCH_MAJOR);
85 return 1;
86 case HID_DG_HEIGHT:
87 hid_map_usage(hi, usage, bit, max,
88 EV_ABS, ABS_MT_TOUCH_MINOR);
89 input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
90 0, 1, 0, 0);
91 return 1;
92 }
93 return 0;
94
95 case 0xff000000:
96 /* we do not want to map these: no input-oriented meaning */
97 return -1;
40 } 98 }
99
41 return 0; 100 return 0;
42} 101}
43 102
@@ -51,6 +110,138 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
51 110
52 return 0; 111 return 0;
53} 112}
113
114/*
115 * this function is called upon all reports
116 * so that we can filter contact point information,
117 * decide whether we are in multi or single touch mode
118 * and call input_mt_sync after each point if necessary
119 */
120static int ntrig_event (struct hid_device *hid, struct hid_field *field,
121 struct hid_usage *usage, __s32 value)
122{
123 struct input_dev *input = field->hidinput->input;
124 struct ntrig_data *nd = hid_get_drvdata(hid);
125
126 if (hid->claimed & HID_CLAIMED_INPUT) {
127 switch (usage->hid) {
128 case HID_GD_X:
129 nd->x = value;
130 nd->reading_a_point = 1;
131 break;
132 case HID_GD_Y:
133 nd->y = value;
134 break;
135 case HID_DG_CONTACTID:
136 nd->id = value;
137 /* we receive this only when in multitouch mode */
138 nd->found_contact_id = 1;
139 break;
140 case HID_DG_WIDTH:
141 nd->w = value;
142 break;
143 case HID_DG_HEIGHT:
144 nd->h = value;
145 /*
146 * when in single touch mode, this is the last
147 * report received in a finger event. We want
148 * to emit a normal (X, Y) position
149 */
150 if (! nd->found_contact_id) {
151 input_event(input, EV_ABS, ABS_X, nd->x);
152 input_event(input, EV_ABS, ABS_Y, nd->y);
153 }
154 break;
155 case HID_DG_TIPPRESSURE:
156 /*
157 * when in single touch mode, this is the last
158 * report received in a pen event. We want
159 * to emit a normal (X, Y) position
160 */
161 if (! nd->found_contact_id) {
162 input_event(input, EV_ABS, ABS_X, nd->x);
163 input_event(input, EV_ABS, ABS_Y, nd->y);
164 input_event(input, EV_ABS, ABS_PRESSURE, value);
165 }
166 break;
167 case 0xff000002:
168 /*
169 * we receive this when the device is in multitouch
170 * mode. The first of the three values tagged with
171 * this usage tells if the contact point is real
172 * or a placeholder
173 */
174 if (!nd->reading_a_point || value != 1)
175 break;
176 /* emit a normal (X, Y) for the first point only */
177 if (nd->id == 0) {
178 input_event(input, EV_ABS, ABS_X, nd->x);
179 input_event(input, EV_ABS, ABS_Y, nd->y);
180 }
181 input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x);
182 input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y);
183 if (nd->w > nd->h) {
184 input_event(input, EV_ABS,
185 ABS_MT_ORIENTATION, 1);
186 input_event(input, EV_ABS,
187 ABS_MT_TOUCH_MAJOR, nd->w);
188 input_event(input, EV_ABS,
189 ABS_MT_TOUCH_MINOR, nd->h);
190 } else {
191 input_event(input, EV_ABS,
192 ABS_MT_ORIENTATION, 0);
193 input_event(input, EV_ABS,
194 ABS_MT_TOUCH_MAJOR, nd->h);
195 input_event(input, EV_ABS,
196 ABS_MT_TOUCH_MINOR, nd->w);
197 }
198 input_mt_sync(field->hidinput->input);
199 nd->reading_a_point = 0;
200 nd->found_contact_id = 0;
201 break;
202
203 default:
204 /* fallback to the generic hidinput handling */
205 return 0;
206 }
207 }
208
209 /* we have handled the hidinput part, now remains hiddev */
210 if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
211 hid->hiddev_hid_event(hid, field, usage, value);
212
213 return 1;
214}
215
216static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
217{
218 int ret;
219 struct ntrig_data *nd;
220
221 nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL);
222 if (!nd) {
223 dev_err(&hdev->dev, "cannot allocate N-Trig data\n");
224 return -ENOMEM;
225 }
226 nd->reading_a_point = 0;
227 nd->found_contact_id = 0;
228 hid_set_drvdata(hdev, nd);
229
230 ret = hid_parse(hdev);
231 if (!ret)
232 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
233
234 if (ret)
235 kfree (nd);
236 return ret;
237}
238
239static void ntrig_remove(struct hid_device *hdev)
240{
241 hid_hw_stop(hdev);
242 kfree(hid_get_drvdata(hdev));
243}
244
54static const struct hid_device_id ntrig_devices[] = { 245static const struct hid_device_id ntrig_devices[] = {
55 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN), 246 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN),
56 .driver_data = NTRIG_DUPLICATE_USAGES }, 247 .driver_data = NTRIG_DUPLICATE_USAGES },
@@ -58,11 +249,20 @@ static const struct hid_device_id ntrig_devices[] = {
58}; 249};
59MODULE_DEVICE_TABLE(hid, ntrig_devices); 250MODULE_DEVICE_TABLE(hid, ntrig_devices);
60 251
252static const struct hid_usage_id ntrig_grabbed_usages[] = {
253 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
254 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
255};
256
61static struct hid_driver ntrig_driver = { 257static struct hid_driver ntrig_driver = {
62 .name = "ntrig", 258 .name = "ntrig",
63 .id_table = ntrig_devices, 259 .id_table = ntrig_devices,
260 .probe = ntrig_probe,
261 .remove = ntrig_remove,
64 .input_mapping = ntrig_input_mapping, 262 .input_mapping = ntrig_input_mapping,
65 .input_mapped = ntrig_input_mapped, 263 .input_mapped = ntrig_input_mapped,
264 .usage_table = ntrig_grabbed_usages,
265 .event = ntrig_event,
66}; 266};
67 267
68static int ntrig_init(void) 268static int ntrig_init(void)
diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c
new file mode 100644
index 000000000000..eab169e5c371
--- /dev/null
+++ b/drivers/hid/hid-sjoy.c
@@ -0,0 +1,180 @@
1/*
2 * Force feedback support for SmartJoy PLUS PS2->USB adapter
3 *
4 * Copyright (c) 2009 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
5 *
6 * Based of hid-pl.c and hid-gaff.c
7 * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
8 * Copyright (c) 2008 Lukasz Lubojanski <lukasz@lubojanski.info>
9 */
10
11/*
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27/* #define DEBUG */
28
29#include <linux/input.h>
30#include <linux/usb.h>
31#include <linux/hid.h>
32#include "hid-ids.h"
33
34#ifdef CONFIG_SMARTJOYPLUS_FF
35#include "usbhid/usbhid.h"
36
37struct sjoyff_device {
38 struct hid_report *report;
39};
40
41static int hid_sjoyff_play(struct input_dev *dev, void *data,
42 struct ff_effect *effect)
43{
44 struct hid_device *hid = input_get_drvdata(dev);
45 struct sjoyff_device *sjoyff = data;
46 u32 left, right;
47
48 left = effect->u.rumble.strong_magnitude;
49 right = effect->u.rumble.weak_magnitude;
50 dev_dbg(&dev->dev, "called with 0x%08x 0x%08x\n", left, right);
51
52 left = left * 0xff / 0xffff;
53 right = (right != 0); /* on/off only */
54
55 sjoyff->report->field[0]->value[1] = right;
56 sjoyff->report->field[0]->value[2] = left;
57 dev_dbg(&dev->dev, "running with 0x%02x 0x%02x\n", left, right);
58 usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
59
60 return 0;
61}
62
63static int sjoyff_init(struct hid_device *hid)
64{
65 struct sjoyff_device *sjoyff;
66 struct hid_report *report;
67 struct hid_input *hidinput = list_entry(hid->inputs.next,
68 struct hid_input, list);
69 struct list_head *report_list =
70 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
71 struct list_head *report_ptr = report_list;
72 struct input_dev *dev;
73 int error;
74
75 if (list_empty(report_list)) {
76 dev_err(&hid->dev, "no output reports found\n");
77 return -ENODEV;
78 }
79
80 report_ptr = report_ptr->next;
81
82 if (report_ptr == report_list) {
83 dev_err(&hid->dev, "required output report is "
84 "missing\n");
85 return -ENODEV;
86 }
87
88 report = list_entry(report_ptr, struct hid_report, list);
89 if (report->maxfield < 1) {
90 dev_err(&hid->dev, "no fields in the report\n");
91 return -ENODEV;
92 }
93
94 if (report->field[0]->report_count < 3) {
95 dev_err(&hid->dev, "not enough values in the field\n");
96 return -ENODEV;
97 }
98
99 sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL);
100 if (!sjoyff)
101 return -ENOMEM;
102
103 dev = hidinput->input;
104
105 set_bit(FF_RUMBLE, dev->ffbit);
106
107 error = input_ff_create_memless(dev, sjoyff, hid_sjoyff_play);
108 if (error) {
109 kfree(sjoyff);
110 return error;
111 }
112
113 sjoyff->report = report;
114 sjoyff->report->field[0]->value[0] = 0x01;
115 sjoyff->report->field[0]->value[1] = 0x00;
116 sjoyff->report->field[0]->value[2] = 0x00;
117 usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT);
118
119 dev_info(&hid->dev,
120 "Force feedback for SmartJoy PLUS PS2/USB adapter\n");
121
122 return 0;
123}
124#else
125static inline int sjoyff_init(struct hid_device *hid)
126{
127 return 0;
128}
129#endif
130
131static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id)
132{
133 int ret;
134
135 ret = hid_parse(hdev);
136 if (ret) {
137 dev_err(&hdev->dev, "parse failed\n");
138 goto err;
139 }
140
141 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
142 if (ret) {
143 dev_err(&hdev->dev, "hw start failed\n");
144 goto err;
145 }
146
147 sjoyff_init(hdev);
148
149 return 0;
150err:
151 return ret;
152}
153
154static const struct hid_device_id sjoy_devices[] = {
155 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
156 { }
157};
158MODULE_DEVICE_TABLE(hid, sjoy_devices);
159
160static struct hid_driver sjoy_driver = {
161 .name = "smartjoyplus",
162 .id_table = sjoy_devices,
163 .probe = sjoy_probe,
164};
165
166static int sjoy_init(void)
167{
168 return hid_register_driver(&sjoy_driver);
169}
170
171static void sjoy_exit(void)
172{
173 hid_unregister_driver(&sjoy_driver);
174}
175
176module_init(sjoy_init);
177module_exit(sjoy_exit);
178MODULE_LICENSE("GPL");
179MODULE_AUTHOR("Jussi Kivilinna");
180
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 7c1f7b50330c..fcd6ccd02fee 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -33,11 +33,6 @@
33 33
34#include "hid-ids.h" 34#include "hid-ids.h"
35 35
36#include "usbhid/usbhid.h"
37
38/* Usages for thrustmaster devices I know about */
39#define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb)
40
41static const signed short ff_rumble[] = { 36static const signed short ff_rumble[] = {
42 FF_RUMBLE, 37 FF_RUMBLE,
43 -1 38 -1
@@ -48,6 +43,12 @@ static const signed short ff_joystick[] = {
48 -1 43 -1
49}; 44};
50 45
46#ifdef CONFIG_THRUSTMASTER_FF
47#include "usbhid/usbhid.h"
48
49/* Usages for thrustmaster devices I know about */
50#define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb)
51
51struct tmff_device { 52struct tmff_device {
52 struct hid_report *report; 53 struct hid_report *report;
53 struct hid_field *ff_field; 54 struct hid_field *ff_field;
@@ -209,6 +210,12 @@ fail:
209 kfree(tmff); 210 kfree(tmff);
210 return error; 211 return error;
211} 212}
213#else
214static inline int tmff_init(struct hid_device *hid, const signed short *ff_bits)
215{
216 return 0;
217}
218#endif
212 219
213static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) 220static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id)
214{ 221{
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
new file mode 100644
index 000000000000..1f9237f511e3
--- /dev/null
+++ b/drivers/hid/hid-wacom.c
@@ -0,0 +1,259 @@
1/*
2 * Bluetooth Wacom Tablet support
3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
10 * Copyright (c) 2006 Andrew Zabolotny <zap@homelink.ru>
11 * Copyright (c) 2009 Bastien Nocera <hadess@hadess.net>
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at your option)
18 * any later version.
19 */
20
21#include <linux/device.h>
22#include <linux/hid.h>
23#include <linux/module.h>
24
25#include "hid-ids.h"
26
27struct wacom_data {
28 __u16 tool;
29 unsigned char butstate;
30};
31
32static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report,
33 u8 *raw_data, int size)
34{
35 struct wacom_data *wdata = hid_get_drvdata(hdev);
36 struct hid_input *hidinput;
37 struct input_dev *input;
38 unsigned char *data = (unsigned char *) raw_data;
39 int tool, x, y, rw;
40
41 if (!(hdev->claimed & HID_CLAIMED_INPUT))
42 return 0;
43
44 tool = 0;
45 hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
46 input = hidinput->input;
47
48 /* Check if this is a tablet report */
49 if (data[0] != 0x03)
50 return 0;
51
52 /* Get X & Y positions */
53 x = le16_to_cpu(*(__le16 *) &data[2]);
54 y = le16_to_cpu(*(__le16 *) &data[4]);
55
56 /* Get current tool identifier */
57 if (data[1] & 0x90) { /* If pen is in the in/active area */
58 switch ((data[1] >> 5) & 3) {
59 case 0: /* Pen */
60 tool = BTN_TOOL_PEN;
61 break;
62
63 case 1: /* Rubber */
64 tool = BTN_TOOL_RUBBER;
65 break;
66
67 case 2: /* Mouse with wheel */
68 case 3: /* Mouse without wheel */
69 tool = BTN_TOOL_MOUSE;
70 break;
71 }
72
73 /* Reset tool if out of active tablet area */
74 if (!(data[1] & 0x10))
75 tool = 0;
76 }
77
78 /* If tool changed, notify input subsystem */
79 if (wdata->tool != tool) {
80 if (wdata->tool) {
81 /* Completely reset old tool state */
82 if (wdata->tool == BTN_TOOL_MOUSE) {
83 input_report_key(input, BTN_LEFT, 0);
84 input_report_key(input, BTN_RIGHT, 0);
85 input_report_key(input, BTN_MIDDLE, 0);
86 input_report_abs(input, ABS_DISTANCE,
87 input->absmax[ABS_DISTANCE]);
88 } else {
89 input_report_key(input, BTN_TOUCH, 0);
90 input_report_key(input, BTN_STYLUS, 0);
91 input_report_key(input, BTN_STYLUS2, 0);
92 input_report_abs(input, ABS_PRESSURE, 0);
93 }
94 input_report_key(input, wdata->tool, 0);
95 input_sync(input);
96 }
97 wdata->tool = tool;
98 if (tool)
99 input_report_key(input, tool, 1);
100 }
101
102 if (tool) {
103 input_report_abs(input, ABS_X, x);
104 input_report_abs(input, ABS_Y, y);
105
106 switch ((data[1] >> 5) & 3) {
107 case 2: /* Mouse with wheel */
108 input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
109 rw = (data[6] & 0x01) ? -1 :
110 (data[6] & 0x02) ? 1 : 0;
111 input_report_rel(input, REL_WHEEL, rw);
112 /* fall through */
113
114 case 3: /* Mouse without wheel */
115 input_report_key(input, BTN_LEFT, data[1] & 0x01);
116 input_report_key(input, BTN_RIGHT, data[1] & 0x02);
117 /* Compute distance between mouse and tablet */
118 rw = 44 - (data[6] >> 2);
119 if (rw < 0)
120 rw = 0;
121 else if (rw > 31)
122 rw = 31;
123 input_report_abs(input, ABS_DISTANCE, rw);
124 break;
125
126 default:
127 input_report_abs(input, ABS_PRESSURE,
128 data[6] | (((__u16) (data[1] & 0x08)) << 5));
129 input_report_key(input, BTN_TOUCH, data[1] & 0x01);
130 input_report_key(input, BTN_STYLUS, data[1] & 0x02);
131 input_report_key(input, BTN_STYLUS2, (tool == BTN_TOOL_PEN) && data[1] & 0x04);
132 break;
133 }
134
135 input_sync(input);
136 }
137
138 /* Report the state of the two buttons at the top of the tablet
139 * as two extra fingerpad keys (buttons 4 & 5). */
140 rw = data[7] & 0x03;
141 if (rw != wdata->butstate) {
142 wdata->butstate = rw;
143 input_report_key(input, BTN_0, rw & 0x02);
144 input_report_key(input, BTN_1, rw & 0x01);
145 input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
146 input_sync(input);
147 }
148
149 return 1;
150}
151
152static int wacom_probe(struct hid_device *hdev,
153 const struct hid_device_id *id)
154{
155 struct hid_input *hidinput;
156 struct input_dev *input;
157 struct wacom_data *wdata;
158 int ret;
159
160 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
161 if (wdata == NULL) {
162 dev_err(&hdev->dev, "can't alloc wacom descriptor\n");
163 return -ENOMEM;
164 }
165
166 hid_set_drvdata(hdev, wdata);
167
168 ret = hid_parse(hdev);
169 if (ret) {
170 dev_err(&hdev->dev, "parse failed\n");
171 goto err_free;
172 }
173
174 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
175 if (ret) {
176 dev_err(&hdev->dev, "hw start failed\n");
177 goto err_free;
178 }
179
180 hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
181 input = hidinput->input;
182
183 /* Basics */
184 input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
185 input->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) |
186 BIT(ABS_PRESSURE) | BIT(ABS_DISTANCE);
187 input->relbit[0] |= BIT(REL_WHEEL);
188 set_bit(BTN_TOOL_PEN, input->keybit);
189 set_bit(BTN_TOUCH, input->keybit);
190 set_bit(BTN_STYLUS, input->keybit);
191 set_bit(BTN_STYLUS2, input->keybit);
192 set_bit(BTN_LEFT, input->keybit);
193 set_bit(BTN_RIGHT, input->keybit);
194 set_bit(BTN_MIDDLE, input->keybit);
195
196 /* Pad */
197 input->evbit[0] |= BIT(EV_MSC);
198 input->mscbit[0] |= BIT(MSC_SERIAL);
199
200 /* Distance, rubber and mouse */
201 input->absbit[0] |= BIT(ABS_DISTANCE);
202 set_bit(BTN_TOOL_RUBBER, input->keybit);
203 set_bit(BTN_TOOL_MOUSE, input->keybit);
204
205 input->absmax[ABS_PRESSURE] = 511;
206 input->absmax[ABS_DISTANCE] = 32;
207
208 input->absmax[ABS_X] = 16704;
209 input->absmax[ABS_Y] = 12064;
210 input->absfuzz[ABS_X] = 4;
211 input->absfuzz[ABS_Y] = 4;
212
213 return 0;
214err_free:
215 kfree(wdata);
216 return ret;
217}
218
219static void wacom_remove(struct hid_device *hdev)
220{
221 hid_hw_stop(hdev);
222 kfree(hid_get_drvdata(hdev));
223}
224
225static const struct hid_device_id wacom_devices[] = {
226 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
227
228 { }
229};
230MODULE_DEVICE_TABLE(hid, wacom_devices);
231
232static struct hid_driver wacom_driver = {
233 .name = "wacom",
234 .id_table = wacom_devices,
235 .probe = wacom_probe,
236 .remove = wacom_remove,
237 .raw_event = wacom_raw_event,
238};
239
240static int wacom_init(void)
241{
242 int ret;
243
244 ret = hid_register_driver(&wacom_driver);
245 if (ret)
246 printk(KERN_ERR "can't register wacom driver\n");
247 printk(KERN_ERR "wacom driver registered\n");
248 return ret;
249}
250
251static void wacom_exit(void)
252{
253 hid_unregister_driver(&wacom_driver);
254}
255
256module_init(wacom_init);
257module_exit(wacom_exit);
258MODULE_LICENSE("GPL");
259
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index 85a198a18537..57f710757bf4 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -27,6 +27,7 @@
27 27
28#include "hid-ids.h" 28#include "hid-ids.h"
29 29
30#ifdef CONFIG_ZEROPLUS_FF
30#include "usbhid/usbhid.h" 31#include "usbhid/usbhid.h"
31 32
32struct zpff_device { 33struct zpff_device {
@@ -108,6 +109,12 @@ static int zpff_init(struct hid_device *hid)
108 109
109 return 0; 110 return 0;
110} 111}
112#else
113static inline int zpff_init(struct hid_device *hid)
114{
115 return 0;
116}
117#endif
111 118
112static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id) 119static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id)
113{ 120{
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 00ccf4b1985d..0c6639ea03dd 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -349,10 +349,7 @@ int hidraw_connect(struct hid_device *hid)
349 int minor, result; 349 int minor, result;
350 struct hidraw *dev; 350 struct hidraw *dev;
351 351
352 /* TODO currently we accept any HID device. This should later 352 /* we accept any HID device, no matter the applications */
353 * probably be fixed to accept only those devices which provide
354 * non-input applications
355 */
356 353
357 dev = kzalloc(sizeof(struct hidraw), GFP_KERNEL); 354 dev = kzalloc(sizeof(struct hidraw), GFP_KERNEL);
358 if (!dev) 355 if (!dev)
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ac8049b5f1e9..76c4bbe9dccb 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1234,12 +1234,11 @@ static int hid_post_reset(struct usb_interface *intf)
1234 struct hid_device *hid = usb_get_intfdata(intf); 1234 struct hid_device *hid = usb_get_intfdata(intf);
1235 struct usbhid_device *usbhid = hid->driver_data; 1235 struct usbhid_device *usbhid = hid->driver_data;
1236 int status; 1236 int status;
1237 1237
1238 spin_lock_irq(&usbhid->lock); 1238 spin_lock_irq(&usbhid->lock);
1239 clear_bit(HID_RESET_PENDING, &usbhid->iofl); 1239 clear_bit(HID_RESET_PENDING, &usbhid->iofl);
1240 spin_unlock_irq(&usbhid->lock); 1240 spin_unlock_irq(&usbhid->lock);
1241 hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0); 1241 hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
1242 /* FIXME: Any more reinitialization needed? */
1243 status = hid_start_in(hid); 1242 status = hid_start_in(hid);
1244 if (status < 0) 1243 if (status < 0)
1245 hid_io_error(hid); 1244 hid_io_error(hid);
@@ -1251,14 +1250,14 @@ static int hid_post_reset(struct usb_interface *intf)
1251int usbhid_get_power(struct hid_device *hid) 1250int usbhid_get_power(struct hid_device *hid)
1252{ 1251{
1253 struct usbhid_device *usbhid = hid->driver_data; 1252 struct usbhid_device *usbhid = hid->driver_data;
1254 1253
1255 return usb_autopm_get_interface(usbhid->intf); 1254 return usb_autopm_get_interface(usbhid->intf);
1256} 1255}
1257 1256
1258void usbhid_put_power(struct hid_device *hid) 1257void usbhid_put_power(struct hid_device *hid)
1259{ 1258{
1260 struct usbhid_device *usbhid = hid->driver_data; 1259 struct usbhid_device *usbhid = hid->driver_data;
1261 1260
1262 usb_autopm_put_interface(usbhid->intf); 1261 usb_autopm_put_interface(usbhid->intf);
1263} 1262}
1264 1263
diff --git a/include/linux/hid.h b/include/linux/hid.h
index a72876e43589..53489fd4d700 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -238,6 +238,42 @@ struct hid_item {
238#define HID_GD_RIGHT 0x00010092 238#define HID_GD_RIGHT 0x00010092
239#define HID_GD_LEFT 0x00010093 239#define HID_GD_LEFT 0x00010093
240 240
241#define HID_DG_DIGITIZER 0x000d0001
242#define HID_DG_PEN 0x000d0002
243#define HID_DG_LIGHTPEN 0x000d0003
244#define HID_DG_TOUCHSCREEN 0x000d0004
245#define HID_DG_TOUCHPAD 0x000d0005
246#define HID_DG_STYLUS 0x000d0020
247#define HID_DG_PUCK 0x000d0021
248#define HID_DG_FINGER 0x000d0022
249#define HID_DG_TIPPRESSURE 0x000d0030
250#define HID_DG_BARRELPRESSURE 0x000d0031
251#define HID_DG_INRANGE 0x000d0032
252#define HID_DG_TOUCH 0x000d0033
253#define HID_DG_UNTOUCH 0x000d0034
254#define HID_DG_TAP 0x000d0035
255#define HID_DG_TABLETFUNCTIONKEY 0x000d0039
256#define HID_DG_PROGRAMCHANGEKEY 0x000d003a
257#define HID_DG_INVERT 0x000d003c
258#define HID_DG_TIPSWITCH 0x000d0042
259#define HID_DG_TIPSWITCH2 0x000d0043
260#define HID_DG_BARRELSWITCH 0x000d0044
261#define HID_DG_ERASER 0x000d0045
262#define HID_DG_TABLETPICK 0x000d0046
263/*
264 * as of May 20, 2009 the usages below are not yet in the official USB spec
265 * but are being pushed by Microsft as described in their paper "Digitizer
266 * Drivers for Windows Touch and Pen-Based Computers"
267 */
268#define HID_DG_CONFIDENCE 0x000d0047
269#define HID_DG_WIDTH 0x000d0048
270#define HID_DG_HEIGHT 0x000d0049
271#define HID_DG_CONTACTID 0x000d0051
272#define HID_DG_INPUTMODE 0x000d0052
273#define HID_DG_DEVICEINDEX 0x000d0053
274#define HID_DG_CONTACTCOUNT 0x000d0054
275#define HID_DG_CONTACTMAX 0x000d0055
276
241/* 277/*
242 * HID report types --- Ouch! HID spec says 1 2 3! 278 * HID report types --- Ouch! HID spec says 1 2 3!
243 */ 279 */