aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid10
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-arvo53
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-kone8
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus11
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus100
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra9
-rw-r--r--Documentation/ioctl/ioctl-number.txt1
-rw-r--r--drivers/hid/Kconfig60
-rw-r--r--drivers/hid/Makefile8
-rw-r--r--drivers/hid/hid-axff.c31
-rw-r--r--drivers/hid/hid-core.c42
-rw-r--r--drivers/hid/hid-egalax.c279
-rw-r--r--drivers/hid/hid-gyration.c5
-rw-r--r--drivers/hid/hid-ids.h13
-rw-r--r--drivers/hid/hid-input.c31
-rw-r--r--drivers/hid/hid-keytouch.c66
-rw-r--r--drivers/hid/hid-lcpower.c70
-rw-r--r--drivers/hid/hid-lg.c2
-rw-r--r--drivers/hid/hid-magicmouse.c4
-rw-r--r--drivers/hid/hid-multitouch.c76
-rw-r--r--drivers/hid/hid-ntrig.c519
-rw-r--r--drivers/hid/hid-ortek.c6
-rw-r--r--drivers/hid/hid-roccat-arvo.c450
-rw-r--r--drivers/hid/hid-roccat-arvo.h98
-rw-r--r--drivers/hid/hid-roccat-common.c62
-rw-r--r--drivers/hid/hid-roccat-common.h23
-rw-r--r--drivers/hid/hid-roccat-kone.c156
-rw-r--r--drivers/hid/hid-roccat-koneplus.c167
-rw-r--r--drivers/hid/hid-roccat-kovaplus.c715
-rw-r--r--drivers/hid/hid-roccat-kovaplus.h157
-rw-r--r--drivers/hid/hid-roccat-pyra.c174
-rw-r--r--drivers/hid/hid-roccat.c53
-rw-r--r--drivers/hid/hid-sony.c20
-rw-r--r--drivers/hid/hidraw.c112
-rw-r--r--drivers/hid/usbhid/hid-core.c35
-rw-r--r--include/linux/hid-roccat.h (renamed from drivers/hid/hid-roccat.h)19
-rw-r--r--include/linux/hid.h5
-rw-r--r--include/linux/hidraw.h3
-rw-r--r--net/bluetooth/hidp/core.c197
-rw-r--r--net/bluetooth/hidp/hidp.h15
40 files changed, 2915 insertions, 950 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid b/Documentation/ABI/testing/sysfs-driver-hid
new file mode 100644
index 000000000000..b6490e14fe83
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid
@@ -0,0 +1,10 @@
1What: For USB devices : /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/report_descriptor
2 For BT devices : /sys/class/bluetooth/hci<addr>/<hid-bus>:<vendor-id>:<product-id>.<num>/report_descriptor
3 Symlink : /sys/class/hidraw/hidraw<num>/device/report_descriptor
4Date: Jan 2011
5KernelVersion: 2.0.39
6Contact: Alan Ott <alan@signal11.us>
7Description: When read, this file returns the device's raw binary HID
8 report descriptor.
9 This file cannot be written.
10Users: HIDAPI library (http://www.signal11.us/oss/hidapi)
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-arvo b/Documentation/ABI/testing/sysfs-driver-hid-roccat-arvo
new file mode 100644
index 000000000000..55e281b0071a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-arvo
@@ -0,0 +1,53 @@
1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/arvo/roccatarvo<minor>/actual_profile
2Date: Januar 2011
3Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: The integer value of this attribute ranges from 1-5.
5 When read, this attribute returns the number of the actual
6 profile which is also the profile that's active on device startup.
7 When written this attribute activates the selected profile
8 immediately.
9Users: http://roccat.sourceforge.net
10
11What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/arvo/roccatarvo<minor>/button
12Date: Januar 2011
13Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
14Description: The keyboard can store short macros with consist of 1 button with
15 several modifier keys internally.
16 When written, this file lets one set the sequence for a specific
17 button for a specific profile. Button and profile numbers are
18 included in written data. The data has to be 24 bytes long.
19 This file is writeonly.
20Users: http://roccat.sourceforge.net
21
22What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/arvo/roccatarvo<minor>/info
23Date: Januar 2011
24Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
25Description: When read, this file returns some info about the device like the
26 installed firmware version.
27 The size of the data is 8 bytes in size.
28 This file is readonly.
29Users: http://roccat.sourceforge.net
30
31What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/arvo/roccatarvo<minor>/key_mask
32Date: Januar 2011
33Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
34Description: The keyboard lets the user deactivate 5 certain keys like the
35 windows and application keys, to protect the user from the outcome
36 of accidentally pressing them.
37 The integer value of this attribute has bits 0-4 set depending
38 on the state of the corresponding key.
39 When read, this file returns the current state of the buttons.
40 When written, the given buttons are activated/deactivated
41 immediately.
42Users: http://roccat.sourceforge.net
43
44What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/arvo/roccatarvo<minor>/mode_key
45Date: Januar 2011
46Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
47Description: The keyboard has a condensed layout without num-lock key.
48 Instead it uses a mode-key which activates a gaming mode where
49 the assignment of the number block changes.
50 The integer value of this attribute ranges from 0 (OFF) to 1 (ON).
51 When read, this file returns the actual state of the key.
52 When written, the key is activated/deactivated immediately.
53Users: http://roccat.sourceforge.net
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
index 698b8081c473..b4c4f158ab9c 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
@@ -16,12 +16,14 @@ Description: It is possible to switch the dpi setting of the mouse with the
16 6 3200 16 6 3200
17 17
18 This file is readonly. 18 This file is readonly.
19Users: http://roccat.sourceforge.net
19 20
20What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/actual_profile 21What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/actual_profile
21Date: March 2010 22Date: March 2010
22Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 23Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
23Description: When read, this file returns the number of the actual profile. 24Description: When read, this file returns the number of the actual profile.
24 This file is readonly. 25 This file is readonly.
26Users: http://roccat.sourceforge.net
25 27
26What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/firmware_version 28What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/firmware_version
27Date: March 2010 29Date: March 2010
@@ -32,6 +34,7 @@ Description: When read, this file returns the raw integer version number of the
32 number the decimal point has to be shifted 2 positions to the 34 number the decimal point has to be shifted 2 positions to the
33 left. E.g. a returned value of 138 means 1.38 35 left. E.g. a returned value of 138 means 1.38
34 This file is readonly. 36 This file is readonly.
37Users: http://roccat.sourceforge.net
35 38
36What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/profile[1-5] 39What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/profile[1-5]
37Date: March 2010 40Date: March 2010
@@ -47,6 +50,7 @@ Description: The mouse can store 5 profiles which can be switched by the
47 The mouse will reject invalid data, whereas the profile number 50 The mouse will reject invalid data, whereas the profile number
48 stored in the profile doesn't need to fit the number of the 51 stored in the profile doesn't need to fit the number of the
49 store. 52 store.
53Users: http://roccat.sourceforge.net
50 54
51What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/settings 55What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/settings
52Date: March 2010 56Date: March 2010
@@ -57,6 +61,7 @@ Description: When read, this file returns the settings stored in the mouse.
57 When written, this file lets write settings back to the mouse. 61 When written, this file lets write settings back to the mouse.
58 The data has to be 36 bytes long. The mouse will reject invalid 62 The data has to be 36 bytes long. The mouse will reject invalid
59 data. 63 data.
64Users: http://roccat.sourceforge.net
60 65
61What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/startup_profile 66What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/startup_profile
62Date: March 2010 67Date: March 2010
@@ -66,6 +71,7 @@ Description: The integer value of this attribute ranges from 1 to 5.
66 that's active when the mouse is powered on. 71 that's active when the mouse is powered on.
67 When written, this file sets the number of the startup profile 72 When written, this file sets the number of the startup profile
68 and the mouse activates this profile immediately. 73 and the mouse activates this profile immediately.
74Users: http://roccat.sourceforge.net
69 75
70What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/tcu 76What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/tcu
71Date: March 2010 77Date: March 2010
@@ -77,6 +83,7 @@ Description: The mouse has a "Tracking Control Unit" which lets the user
77 Writing 0 in this file will switch the TCU off. 83 Writing 0 in this file will switch the TCU off.
78 Writing 1 in this file will start the calibration which takes 84 Writing 1 in this file will start the calibration which takes
79 around 6 seconds to complete and activates the TCU. 85 around 6 seconds to complete and activates the TCU.
86Users: http://roccat.sourceforge.net
80 87
81What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/weight 88What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kone/roccatkone<minor>/weight
82Date: March 2010 89Date: March 2010
@@ -96,3 +103,4 @@ Description: The mouse can be equipped with one of four supplied weights
96 4 20g 103 4 20g
97 104
98 This file is readonly. 105 This file is readonly.
106Users: http://roccat.sourceforge.net
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
index 0f9f30eb1742..00efced73969 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
@@ -4,6 +4,7 @@ Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: When read, this file returns the number of the actual profile in 4Description: When read, this file returns the number of the actual profile in
5 range 0-4. 5 range 0-4.
6 This file is readonly. 6 This file is readonly.
7Users: http://roccat.sourceforge.net
7 8
8What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version 9What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version
9Date: October 2010 10Date: October 2010
@@ -14,6 +15,7 @@ Description: When read, this file returns the raw integer version number of the
14 number the decimal point has to be shifted 2 positions to the 15 number the decimal point has to be shifted 2 positions to the
15 left. E.g. a returned value of 121 means 1.21 16 left. E.g. a returned value of 121 means 1.21
16 This file is readonly. 17 This file is readonly.
18Users: http://roccat.sourceforge.net
17 19
18What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro 20What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro
19Date: October 2010 21Date: October 2010
@@ -24,6 +26,7 @@ Description: The mouse can store a macro with max 500 key/button strokes
24 button for a specific profile. Button and profile numbers are 26 button for a specific profile. Button and profile numbers are
25 included in written data. The data has to be 2082 bytes long. 27 included in written data. The data has to be 2082 bytes long.
26 This file is writeonly. 28 This file is writeonly.
29Users: http://roccat.sourceforge.net
27 30
28What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_buttons 31What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_buttons
29Date: August 2010 32Date: August 2010
@@ -37,6 +40,7 @@ Description: The mouse can store 5 profiles which can be switched by the
37 Which profile to write is determined by the profile number 40 Which profile to write is determined by the profile number
38 contained in the data. 41 contained in the data.
39 This file is writeonly. 42 This file is writeonly.
43Users: http://roccat.sourceforge.net
40 44
41What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons 45What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons
42Date: August 2010 46Date: August 2010
@@ -47,6 +51,7 @@ Description: The mouse can store 5 profiles which can be switched by the
47 When read, these files return the respective profile buttons. 51 When read, these files return the respective profile buttons.
48 The returned data is 77 bytes in size. 52 The returned data is 77 bytes in size.
49 This file is readonly. 53 This file is readonly.
54Users: http://roccat.sourceforge.net
50 55
51What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings 56What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings
52Date: October 2010 57Date: October 2010
@@ -61,6 +66,7 @@ Description: The mouse can store 5 profiles which can be switched by the
61 Which profile to write is determined by the profile number 66 Which profile to write is determined by the profile number
62 contained in the data. 67 contained in the data.
63 This file is writeonly. 68 This file is writeonly.
69Users: http://roccat.sourceforge.net
64 70
65What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings 71What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings
66Date: August 2010 72Date: August 2010
@@ -72,6 +78,7 @@ Description: The mouse can store 5 profiles which can be switched by the
72 When read, these files return the respective profile settings. 78 When read, these files return the respective profile settings.
73 The returned data is 43 bytes in size. 79 The returned data is 43 bytes in size.
74 This file is readonly. 80 This file is readonly.
81Users: http://roccat.sourceforge.net
75 82
76What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor 83What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor
77Date: October 2010 84Date: October 2010
@@ -80,6 +87,7 @@ Description: The mouse has a tracking- and a distance-control-unit. These
80 can be activated/deactivated and the lift-off distance can be 87 can be activated/deactivated and the lift-off distance can be
81 set. The data has to be 6 bytes long. 88 set. The data has to be 6 bytes long.
82 This file is writeonly. 89 This file is writeonly.
90Users: http://roccat.sourceforge.net
83 91
84What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile 92What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile
85Date: October 2010 93Date: October 2010
@@ -89,6 +97,7 @@ Description: The integer value of this attribute ranges from 0-4.
89 that's active when the mouse is powered on. 97 that's active when the mouse is powered on.
90 When written, this file sets the number of the startup profile 98 When written, this file sets the number of the startup profile
91 and the mouse activates this profile immediately. 99 and the mouse activates this profile immediately.
100Users: http://roccat.sourceforge.net
92 101
93What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu 102What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu
94Date: October 2010 103Date: October 2010
@@ -97,6 +106,7 @@ Description: When written a calibration process for the tracking control unit
97 can be initiated/cancelled. 106 can be initiated/cancelled.
98 The data has to be 3 bytes long. 107 The data has to be 3 bytes long.
99 This file is writeonly. 108 This file is writeonly.
109Users: http://roccat.sourceforge.net
100 110
101What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image 111What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image
102Date: October 2010 112Date: October 2010
@@ -106,3 +116,4 @@ Description: When read the mouse returns a 30x30 pixel image of the
106 calibration process initiated with tcu. 116 calibration process initiated with tcu.
107 The returned data is 1028 bytes in size. 117 The returned data is 1028 bytes in size.
108 This file is readonly. 118 This file is readonly.
119Users: http://roccat.sourceforge.net
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus
new file mode 100644
index 000000000000..fdfa16f8189b
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus
@@ -0,0 +1,100 @@
1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_cpi
2Date: January 2011
3Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: The integer value of this attribute ranges from 1-4.
5 When read, this attribute returns the number of the active
6 cpi level.
7 This file is readonly.
8Users: http://roccat.sourceforge.net
9
10What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile
11Date: January 2011
12Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
13Description: The integer value of this attribute ranges from 0-4.
14 When read, this attribute returns the number of the active
15 profile.
16 When written, the mouse activates this profile immediately.
17 The profile that's active when powered down is the same that's
18 active when the mouse is powered on.
19Users: http://roccat.sourceforge.net
20
21What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x
22Date: January 2011
23Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
24Description: The integer value of this attribute ranges from 1-10.
25 When read, this attribute returns the number of the actual
26 sensitivity in x direction.
27 This file is readonly.
28Users: http://roccat.sourceforge.net
29
30What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_y
31Date: January 2011
32Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
33Description: The integer value of this attribute ranges from 1-10.
34 When read, this attribute returns the number of the actual
35 sensitivity in y direction.
36 This file is readonly.
37Users: http://roccat.sourceforge.net
38
39What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/firmware_version
40Date: January 2011
41Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
42Description: When read, this file returns the raw integer version number of the
43 firmware reported by the mouse. Using the integer value eases
44 further usage in other programs. To receive the real version
45 number the decimal point has to be shifted 2 positions to the
46 left. E.g. a returned value of 121 means 1.21
47 This file is readonly.
48Users: http://roccat.sourceforge.net
49
50What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_buttons
51Date: January 2011
52Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
53Description: The mouse can store 5 profiles which can be switched by the
54 press of a button. A profile is split in settings and buttons.
55 profile_buttons holds informations about button layout.
56 When written, this file lets one write the respective profile
57 buttons back to the mouse. The data has to be 23 bytes long.
58 The mouse will reject invalid data.
59 Which profile to write is determined by the profile number
60 contained in the data.
61 This file is writeonly.
62Users: http://roccat.sourceforge.net
63
64What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_buttons
65Date: January 2011
66Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
67Description: The mouse can store 5 profiles which can be switched by the
68 press of a button. A profile is split in settings and buttons.
69 profile_buttons holds informations about button layout.
70 When read, these files return the respective profile buttons.
71 The returned data is 23 bytes in size.
72 This file is readonly.
73Users: http://roccat.sourceforge.net
74
75What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_settings
76Date: January 2011
77Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
78Description: The mouse can store 5 profiles which can be switched by the
79 press of a button. A profile is split in settings and buttons.
80 profile_settings holds informations like resolution, sensitivity
81 and light effects.
82 When written, this file lets one write the respective profile
83 settings back to the mouse. The data has to be 16 bytes long.
84 The mouse will reject invalid data.
85 Which profile to write is determined by the profile number
86 contained in the data.
87 This file is writeonly.
88Users: http://roccat.sourceforge.net
89
90What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_settings
91Date: January 2011
92Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
93Description: The mouse can store 5 profiles which can be switched by the
94 press of a button. A profile is split in settings and buttons.
95 profile_settings holds informations like resolution, sensitivity
96 and light effects.
97 When read, these files return the respective profile settings.
98 The returned data is 16 bytes in size.
99 This file is readonly.
100Users: http://roccat.sourceforge.net
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
index 1c37b823f142..5fab71af3c46 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
@@ -13,6 +13,7 @@ Description: It is possible to switch the cpi setting of the mouse with the
13 4 1600 13 4 1600
14 14
15 This file is readonly. 15 This file is readonly.
16Users: http://roccat.sourceforge.net
16 17
17What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile 18What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/actual_profile
18Date: August 2010 19Date: August 2010
@@ -20,6 +21,7 @@ Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
20Description: When read, this file returns the number of the actual profile in 21Description: When read, this file returns the number of the actual profile in
21 range 0-4. 22 range 0-4.
22 This file is readonly. 23 This file is readonly.
24Users: http://roccat.sourceforge.net
23 25
24What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version 26What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/firmware_version
25Date: August 2010 27Date: August 2010
@@ -30,6 +32,7 @@ Description: When read, this file returns the raw integer version number of the
30 number the decimal point has to be shifted 2 positions to the 32 number the decimal point has to be shifted 2 positions to the
31 left. E.g. a returned value of 138 means 1.38 33 left. E.g. a returned value of 138 means 1.38
32 This file is readonly. 34 This file is readonly.
35Users: http://roccat.sourceforge.net
33 36
34What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings 37What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings
35Date: August 2010 38Date: August 2010
@@ -44,6 +47,7 @@ Description: The mouse can store 5 profiles which can be switched by the
44 Which profile to write is determined by the profile number 47 Which profile to write is determined by the profile number
45 contained in the data. 48 contained in the data.
46 This file is writeonly. 49 This file is writeonly.
50Users: http://roccat.sourceforge.net
47 51
48What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings 52What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings
49Date: August 2010 53Date: August 2010
@@ -55,6 +59,7 @@ Description: The mouse can store 5 profiles which can be switched by the
55 When read, these files return the respective profile settings. 59 When read, these files return the respective profile settings.
56 The returned data is 13 bytes in size. 60 The returned data is 13 bytes in size.
57 This file is readonly. 61 This file is readonly.
62Users: http://roccat.sourceforge.net
58 63
59What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons 64What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons
60Date: August 2010 65Date: August 2010
@@ -68,6 +73,7 @@ Description: The mouse can store 5 profiles which can be switched by the
68 Which profile to write is determined by the profile number 73 Which profile to write is determined by the profile number
69 contained in the data. 74 contained in the data.
70 This file is writeonly. 75 This file is writeonly.
76Users: http://roccat.sourceforge.net
71 77
72What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons 78What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons
73Date: August 2010 79Date: August 2010
@@ -78,6 +84,7 @@ Description: The mouse can store 5 profiles which can be switched by the
78 When read, these files return the respective profile buttons. 84 When read, these files return the respective profile buttons.
79 The returned data is 19 bytes in size. 85 The returned data is 19 bytes in size.
80 This file is readonly. 86 This file is readonly.
87Users: http://roccat.sourceforge.net
81 88
82What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile 89What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile
83Date: August 2010 90Date: August 2010
@@ -86,6 +93,7 @@ Description: The integer value of this attribute ranges from 0-4.
86 When read, this attribute returns the number of the profile 93 When read, this attribute returns the number of the profile
87 that's active when the mouse is powered on. 94 that's active when the mouse is powered on.
88 This file is readonly. 95 This file is readonly.
96Users: http://roccat.sourceforge.net
89 97
90What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings 98What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings
91Date: August 2010 99Date: August 2010
@@ -96,3 +104,4 @@ Description: When read, this file returns the settings stored in the mouse.
96 When written, this file lets write settings back to the mouse. 104 When written, this file lets write settings back to the mouse.
97 The data has to be 3 bytes long. The mouse will reject invalid 105 The data has to be 3 bytes long. The mouse will reject invalid
98 data. 106 data.
107Users: http://roccat.sourceforge.net
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index ac293e955308..e68543f767d5 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -133,6 +133,7 @@ Code Seq#(hex) Include File Comments
133'H' C0-DF net/bluetooth/hidp/hidp.h conflict! 133'H' C0-DF net/bluetooth/hidp/hidp.h conflict!
134'H' C0-DF net/bluetooth/cmtp/cmtp.h conflict! 134'H' C0-DF net/bluetooth/cmtp/cmtp.h conflict!
135'H' C0-DF net/bluetooth/bnep/bnep.h conflict! 135'H' C0-DF net/bluetooth/bnep/bnep.h conflict!
136'H' F1 linux/hid-roccat.h <mailto:erazor_de@users.sourceforge.net>
136'I' all linux/isdn.h conflict! 137'I' all linux/isdn.h conflict!
137'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict! 138'I' 00-0F drivers/isdn/divert/isdn_divert.h conflict!
138'I' 40-4F linux/mISDNif.h conflict! 139'I' 40-4F linux/mISDNif.h conflict!
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 98600e594b54..d8123920f79c 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -68,9 +68,15 @@ config HID_A4TECH
68 ---help--- 68 ---help---
69 Support for A4 tech X5 and WOP-35 / Trust 450L mice. 69 Support for A4 tech X5 and WOP-35 / Trust 450L mice.
70 70
71config HID_ACRUX_FF 71config HID_ACRUX
72 tristate "ACRUX force feedback" 72 tristate "ACRUX game controller support"
73 depends on USB_HID 73 depends on USB_HID
74 ---help---
75 Say Y here if you want to enable support for ACRUX game controllers.
76
77config HID_ACRUX_FF
78 tristate "ACRUX force feedback support"
79 depends on HID_ACRUX
74 select INPUT_FF_MEMLESS 80 select INPUT_FF_MEMLESS
75 ---help--- 81 ---help---
76 Say Y here if you want to enable force feedback support for ACRUX 82 Say Y here if you want to enable force feedback support for ACRUX
@@ -165,13 +171,6 @@ config HID_EMS_FF
165 Currently the following devices are known to be supported: 171 Currently the following devices are known to be supported:
166 - Trio Linker Plus II 172 - Trio Linker Plus II
167 173
168config HID_EGALAX
169 tristate "eGalax multi-touch panel"
170 depends on USB_HID
171 ---help---
172 Support for the eGalax dual-touch panels, including the
173 Joojoo and Wetab tablets.
174
175config HID_ELECOM 174config HID_ELECOM
176 tristate "ELECOM BM084 bluetooth mouse" 175 tristate "ELECOM BM084 bluetooth mouse"
177 depends on BT_HIDP 176 depends on BT_HIDP
@@ -185,6 +184,14 @@ config HID_EZKEY
185 ---help--- 184 ---help---
186 Support for Ezkey BTC 8193 keyboard. 185 Support for Ezkey BTC 8193 keyboard.
187 186
187config HID_KEYTOUCH
188 tristate "Keyoutch HID devices"
189 depends on USB_HID
190 ---help---
191 Support for Keytouch HID devices not fully compliant with
192 the specification. Currently supported:
193 - Keytouch IEC 60945
194
188config HID_KYE 195config HID_KYE
189 tristate "Kye/Genius Ergo Mouse" if EMBEDDED 196 tristate "Kye/Genius Ergo Mouse" if EMBEDDED
190 depends on USB_HID 197 depends on USB_HID
@@ -223,6 +230,12 @@ config HID_KENSINGTON
223 ---help--- 230 ---help---
224 Support for Kensington Slimblade Trackball. 231 Support for Kensington Slimblade Trackball.
225 232
233config HID_LCPOWER
234 tristate "LC-Power"
235 depends on USB_HID
236 ---help---
237 Support for LC-Power RC1000MCE RF remote control.
238
226config HID_LOGITECH 239config HID_LOGITECH
227 tristate "Logitech devices" if EMBEDDED 240 tristate "Logitech devices" if EMBEDDED
228 depends on USB_HID 241 depends on USB_HID
@@ -309,8 +322,11 @@ config HID_MULTITOUCH
309 Say Y here if you have one of the following devices: 322 Say Y here if you have one of the following devices:
310 - Cypress TrueTouch panels 323 - Cypress TrueTouch panels
311 - Hanvon dual touch panels 324 - Hanvon dual touch panels
325 - IrTouch Infrared USB panels
312 - Pixcir dual touch panels 326 - Pixcir dual touch panels
313 - 'Sensing Win7-TwoFinger' panel by GeneralTouch 327 - 'Sensing Win7-TwoFinger' panel by GeneralTouch
328 - eGalax dual-touch panels, including the
329 Joojoo and Wetab tablets
314 330
315 If unsure, say N. 331 If unsure, say N.
316 332
@@ -324,10 +340,10 @@ config HID_NTRIG
324 Support for N-Trig touch screen. 340 Support for N-Trig touch screen.
325 341
326config HID_ORTEK 342config HID_ORTEK
327 tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad" 343 tristate "Ortek PKB-1700/WKB-2000 wireless keyboard and mouse trackpad"
328 depends on USB_HID 344 depends on USB_HID
329 ---help--- 345 ---help---
330 Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. 346 Support for Ortek PKB-1700/WKB-2000 wireless keyboard + mouse trackpad.
331 347
332config HID_PANTHERLORD 348config HID_PANTHERLORD
333 tristate "Pantherlord/GreenAsia game controller" 349 tristate "Pantherlord/GreenAsia game controller"
@@ -422,10 +438,22 @@ config HID_ROCCAT
422 Say Y here if you have a Roccat mouse or keyboard and want OSD or 438 Say Y here if you have a Roccat mouse or keyboard and want OSD or
423 macro execution support. 439 macro execution support.
424 440
441config HID_ROCCAT_COMMON
442 tristate
443
444config HID_ROCCAT_ARVO
445 tristate "Roccat Arvo keyboard support"
446 depends on USB_HID
447 select HID_ROCCAT
448 select HID_ROCCAT_COMMON
449 ---help---
450 Support for Roccat Arvo keyboard.
451
425config HID_ROCCAT_KONE 452config HID_ROCCAT_KONE
426 tristate "Roccat Kone Mouse support" 453 tristate "Roccat Kone Mouse support"
427 depends on USB_HID 454 depends on USB_HID
428 select HID_ROCCAT 455 select HID_ROCCAT
456 select HID_ROCCAT_COMMON
429 ---help--- 457 ---help---
430 Support for Roccat Kone mouse. 458 Support for Roccat Kone mouse.
431 459
@@ -433,13 +461,23 @@ config HID_ROCCAT_KONEPLUS
433 tristate "Roccat Kone[+] mouse support" 461 tristate "Roccat Kone[+] mouse support"
434 depends on USB_HID 462 depends on USB_HID
435 select HID_ROCCAT 463 select HID_ROCCAT
464 select HID_ROCCAT_COMMON
436 ---help--- 465 ---help---
437 Support for Roccat Kone[+] mouse. 466 Support for Roccat Kone[+] mouse.
438 467
468config HID_ROCCAT_KOVAPLUS
469 tristate "Roccat Kova[+] mouse support"
470 depends on USB_HID
471 select HID_ROCCAT
472 select HID_ROCCAT_COMMON
473 ---help---
474 Support for Roccat Kova[+] mouse.
475
439config HID_ROCCAT_PYRA 476config HID_ROCCAT_PYRA
440 tristate "Roccat Pyra mouse support" 477 tristate "Roccat Pyra mouse support"
441 depends on USB_HID 478 depends on USB_HID
442 select HID_ROCCAT 479 select HID_ROCCAT
480 select HID_ROCCAT_COMMON
443 ---help--- 481 ---help---
444 Support for Roccat Pyra mouse. 482 Support for Roccat Pyra mouse.
445 483
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index bb744e6f75e6..06c68ae3abee 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -27,7 +27,7 @@ endif
27 27
28obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o 28obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
29obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o 29obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
30obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o 30obj-$(CONFIG_HID_ACRUX) += hid-axff.o
31obj-$(CONFIG_HID_APPLE) += hid-apple.o 31obj-$(CONFIG_HID_APPLE) += hid-apple.o
32obj-$(CONFIG_HID_BELKIN) += hid-belkin.o 32obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
33obj-$(CONFIG_HID_CANDO) += hid-cando.o 33obj-$(CONFIG_HID_CANDO) += hid-cando.o
@@ -36,12 +36,13 @@ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
36obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 36obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
37obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o 37obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o
38obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o 38obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
39obj-$(CONFIG_HID_EGALAX) += hid-egalax.o
40obj-$(CONFIG_HID_ELECOM) += hid-elecom.o 39obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
41obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o 40obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
42obj-$(CONFIG_HID_GYRATION) += hid-gyration.o 41obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
43obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 42obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
43obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
44obj-$(CONFIG_HID_KYE) += hid-kye.o 44obj-$(CONFIG_HID_KYE) += hid-kye.o
45obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
45obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 46obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
46obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o 47obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
47obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o 48obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
@@ -56,8 +57,11 @@ obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
56obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o 57obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
57obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 58obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
58obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o 59obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
60obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o
61obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o
59obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o 62obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
60obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o 63obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o
64obj-$(CONFIG_HID_ROCCAT_KOVAPLUS) += hid-roccat-kovaplus.o
61obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o 65obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
62obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 66obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
63obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 67obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c
index e5b961d6ff22..b4554288de00 100644
--- a/drivers/hid/hid-axff.c
+++ b/drivers/hid/hid-axff.c
@@ -33,6 +33,8 @@
33#include <linux/hid.h> 33#include <linux/hid.h>
34 34
35#include "hid-ids.h" 35#include "hid-ids.h"
36
37#ifdef CONFIG_HID_ACRUX_FF
36#include "usbhid/usbhid.h" 38#include "usbhid/usbhid.h"
37 39
38struct axff_device { 40struct axff_device {
@@ -109,6 +111,12 @@ err_free_mem:
109 kfree(axff); 111 kfree(axff);
110 return error; 112 return error;
111} 113}
114#else
115static inline int axff_init(struct hid_device *hid)
116{
117 return 0;
118}
119#endif
112 120
113static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id) 121static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
114{ 122{
@@ -139,9 +147,25 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
139 error); 147 error);
140 } 148 }
141 149
150 /*
151 * We need to start polling device right away, otherwise
152 * it will go into a coma.
153 */
154 error = hid_hw_open(hdev);
155 if (error) {
156 dev_err(&hdev->dev, "hw open failed\n");
157 return error;
158 }
159
142 return 0; 160 return 0;
143} 161}
144 162
163static void ax_remove(struct hid_device *hdev)
164{
165 hid_hw_close(hdev);
166 hid_hw_stop(hdev);
167}
168
145static const struct hid_device_id ax_devices[] = { 169static const struct hid_device_id ax_devices[] = {
146 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), }, 170 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), },
147 { } 171 { }
@@ -149,9 +173,10 @@ static const struct hid_device_id ax_devices[] = {
149MODULE_DEVICE_TABLE(hid, ax_devices); 173MODULE_DEVICE_TABLE(hid, ax_devices);
150 174
151static struct hid_driver ax_driver = { 175static struct hid_driver ax_driver = {
152 .name = "acrux", 176 .name = "acrux",
153 .id_table = ax_devices, 177 .id_table = ax_devices,
154 .probe = ax_probe, 178 .probe = ax_probe,
179 .remove = ax_remove,
155}; 180};
156 181
157static int __init ax_init(void) 182static int __init ax_init(void)
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 75af1f835320..c3d66269ed7d 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1159,6 +1159,32 @@ static bool hid_hiddev(struct hid_device *hdev)
1159 return !!hid_match_id(hdev, hid_hiddev_list); 1159 return !!hid_match_id(hdev, hid_hiddev_list);
1160} 1160}
1161 1161
1162
1163static ssize_t
1164read_report_descriptor(struct file *filp, struct kobject *kobj,
1165 struct bin_attribute *attr,
1166 char *buf, loff_t off, size_t count)
1167{
1168 struct device *dev = container_of(kobj, struct device, kobj);
1169 struct hid_device *hdev = container_of(dev, struct hid_device, dev);
1170
1171 if (off >= hdev->rsize)
1172 return 0;
1173
1174 if (off + count > hdev->rsize)
1175 count = hdev->rsize - off;
1176
1177 memcpy(buf, hdev->rdesc + off, count);
1178
1179 return count;
1180}
1181
1182static struct bin_attribute dev_bin_attr_report_desc = {
1183 .attr = { .name = "report_descriptor", .mode = 0444 },
1184 .read = read_report_descriptor,
1185 .size = HID_MAX_DESCRIPTOR_SIZE,
1186};
1187
1162int hid_connect(struct hid_device *hdev, unsigned int connect_mask) 1188int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1163{ 1189{
1164 static const char *types[] = { "Device", "Pointer", "Mouse", "Device", 1190 static const char *types[] = { "Device", "Pointer", "Mouse", "Device",
@@ -1169,6 +1195,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1169 char buf[64]; 1195 char buf[64];
1170 unsigned int i; 1196 unsigned int i;
1171 int len; 1197 int len;
1198 int ret;
1172 1199
1173 if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE) 1200 if (hdev->quirks & HID_QUIRK_HIDDEV_FORCE)
1174 connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV); 1201 connect_mask |= (HID_CONNECT_HIDDEV_FORCE | HID_CONNECT_HIDDEV);
@@ -1230,6 +1257,11 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1230 bus = "<UNKNOWN>"; 1257 bus = "<UNKNOWN>";
1231 } 1258 }
1232 1259
1260 ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
1261 if (ret)
1262 hid_warn(hdev,
1263 "can't create sysfs report descriptor attribute err: %d\n", ret);
1264
1233 hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n", 1265 hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
1234 buf, bus, hdev->version >> 8, hdev->version & 0xff, 1266 buf, bus, hdev->version >> 8, hdev->version & 0xff,
1235 type, hdev->name, hdev->phys); 1267 type, hdev->name, hdev->phys);
@@ -1240,6 +1272,7 @@ EXPORT_SYMBOL_GPL(hid_connect);
1240 1272
1241void hid_disconnect(struct hid_device *hdev) 1273void hid_disconnect(struct hid_device *hdev)
1242{ 1274{
1275 device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
1243 if (hdev->claimed & HID_CLAIMED_INPUT) 1276 if (hdev->claimed & HID_CLAIMED_INPUT)
1244 hidinput_disconnect(hdev); 1277 hidinput_disconnect(hdev);
1245 if (hdev->claimed & HID_CLAIMED_HIDDEV) 1278 if (hdev->claimed & HID_CLAIMED_HIDDEV)
@@ -1256,9 +1289,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1256 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1289 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
1257 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, 1290 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
1258 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, 1291 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
1259#if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE)
1260 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, 1292 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
1261#endif
1262 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, 1293 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
1263 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, 1294 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
1264 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, 1295 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
@@ -1346,9 +1377,12 @@ static const struct hid_device_id hid_have_special_driver[] = {
1346 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, 1377 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
1347 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, 1378 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
1348 { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, 1379 { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
1380 { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
1349 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, 1381 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
1382 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
1350 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, 1383 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
1351 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, 1384 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
1385 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
1352 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, 1386 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
1353 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, 1387 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
1354 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, 1388 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
@@ -1369,6 +1403,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1369 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) }, 1403 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
1370 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, 1404 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
1371 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, 1405 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
1406 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
1372 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, 1407 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
1373 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) }, 1408 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
1374 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, 1409 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
@@ -1401,12 +1436,15 @@ static const struct hid_device_id hid_have_special_driver[] = {
1401 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) }, 1436 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16) },
1402 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) }, 1437 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17) },
1403 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) }, 1438 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
1439 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
1404 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, 1440 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
1405 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, 1441 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
1406 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1442 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1407 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1443 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1408 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, 1444 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
1445 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
1409 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, 1446 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
1447 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
1410 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, 1448 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1411 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1449 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1412 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1450 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c
deleted file mode 100644
index 03bee1970d70..000000000000
--- a/drivers/hid/hid-egalax.c
+++ /dev/null
@@ -1,279 +0,0 @@
1/*
2 * HID driver for eGalax dual-touch panels
3 *
4 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
5 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
6 * Copyright (c) 2010 Canonical, Ltd.
7 *
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 */
16
17#include <linux/device.h>
18#include <linux/hid.h>
19#include <linux/module.h>
20#include <linux/usb.h>
21#include <linux/input/mt.h>
22#include <linux/slab.h>
23#include "usbhid/usbhid.h"
24
25MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
26MODULE_DESCRIPTION("eGalax dual-touch panel");
27MODULE_LICENSE("GPL");
28
29#include "hid-ids.h"
30
31#define MAX_SLOTS 2
32
33/* estimated signal-to-noise ratios */
34#define SN_MOVE 4096
35#define SN_PRESSURE 32
36
37struct egalax_data {
38 int valid;
39 int slot;
40 int touch;
41 int x, y, z;
42};
43
44static void set_abs(struct input_dev *input, unsigned int code,
45 struct hid_field *field, int snratio)
46{
47 int fmin = field->logical_minimum;
48 int fmax = field->logical_maximum;
49 int fuzz = snratio ? (fmax - fmin) / snratio : 0;
50 input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
51}
52
53static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi,
54 struct hid_field *field, struct hid_usage *usage,
55 unsigned long **bit, int *max)
56{
57 struct input_dev *input = hi->input;
58
59 switch (usage->hid & HID_USAGE_PAGE) {
60
61 case HID_UP_GENDESK:
62 switch (usage->hid) {
63 case HID_GD_X:
64 field->logical_maximum = 32760;
65 hid_map_usage(hi, usage, bit, max,
66 EV_ABS, ABS_MT_POSITION_X);
67 set_abs(input, ABS_MT_POSITION_X, field, SN_MOVE);
68 /* touchscreen emulation */
69 set_abs(input, ABS_X, field, SN_MOVE);
70 return 1;
71 case HID_GD_Y:
72 field->logical_maximum = 32760;
73 hid_map_usage(hi, usage, bit, max,
74 EV_ABS, ABS_MT_POSITION_Y);
75 set_abs(input, ABS_MT_POSITION_Y, field, SN_MOVE);
76 /* touchscreen emulation */
77 set_abs(input, ABS_Y, field, SN_MOVE);
78 return 1;
79 }
80 return 0;
81
82 case HID_UP_DIGITIZER:
83 switch (usage->hid) {
84 case HID_DG_TIPSWITCH:
85 /* touchscreen emulation */
86 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
87 input_set_capability(input, EV_KEY, BTN_TOUCH);
88 return 1;
89 case HID_DG_INRANGE:
90 case HID_DG_CONFIDENCE:
91 case HID_DG_CONTACTCOUNT:
92 case HID_DG_CONTACTMAX:
93 return -1;
94 case HID_DG_CONTACTID:
95 input_mt_init_slots(input, MAX_SLOTS);
96 return 1;
97 case HID_DG_TIPPRESSURE:
98 field->logical_minimum = 0;
99 hid_map_usage(hi, usage, bit, max,
100 EV_ABS, ABS_MT_PRESSURE);
101 set_abs(input, ABS_MT_PRESSURE, field, SN_PRESSURE);
102 /* touchscreen emulation */
103 set_abs(input, ABS_PRESSURE, field, SN_PRESSURE);
104 return 1;
105 }
106 return 0;
107 }
108
109 /* ignore others (from other reports we won't get anyway) */
110 return -1;
111}
112
113static int egalax_input_mapped(struct hid_device *hdev, struct hid_input *hi,
114 struct hid_field *field, struct hid_usage *usage,
115 unsigned long **bit, int *max)
116{
117 /* tell hid-input to skip setup of these event types */
118 if (usage->type == EV_KEY || usage->type == EV_ABS)
119 set_bit(usage->type, hi->input->evbit);
120 return -1;
121}
122
123/*
124 * this function is called when a whole finger has been parsed,
125 * so that it can decide what to send to the input layer.
126 */
127static void egalax_filter_event(struct egalax_data *td, struct input_dev *input)
128{
129 input_mt_slot(input, td->slot);
130 input_mt_report_slot_state(input, MT_TOOL_FINGER, td->touch);
131 if (td->touch) {
132 input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x);
133 input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y);
134 input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z);
135 }
136 input_mt_report_pointer_emulation(input, true);
137}
138
139static int egalax_event(struct hid_device *hid, struct hid_field *field,
140 struct hid_usage *usage, __s32 value)
141{
142 struct egalax_data *td = hid_get_drvdata(hid);
143
144 /* Note, eGalax has two product lines: the first is resistive and
145 * uses a standard parallel multitouch protocol (product ID ==
146 * 48xx). The second is capacitive and uses an unusual "serial"
147 * protocol with a different message for each multitouch finger
148 * (product ID == 72xx).
149 */
150 if (hid->claimed & HID_CLAIMED_INPUT) {
151 struct input_dev *input = field->hidinput->input;
152
153 switch (usage->hid) {
154 case HID_DG_INRANGE:
155 td->valid = value;
156 break;
157 case HID_DG_CONFIDENCE:
158 /* avoid interference from generic hidinput handling */
159 break;
160 case HID_DG_TIPSWITCH:
161 td->touch = value;
162 break;
163 case HID_DG_TIPPRESSURE:
164 td->z = value;
165 break;
166 case HID_DG_CONTACTID:
167 td->slot = clamp_val(value, 0, MAX_SLOTS - 1);
168 break;
169 case HID_GD_X:
170 td->x = value;
171 break;
172 case HID_GD_Y:
173 td->y = value;
174 /* this is the last field in a finger */
175 if (td->valid)
176 egalax_filter_event(td, input);
177 break;
178 case HID_DG_CONTACTCOUNT:
179 /* touch emulation: this is the last field in a frame */
180 break;
181
182 default:
183 /* fallback to the generic hidinput handling */
184 return 0;
185 }
186 }
187
188 /* we have handled the hidinput part, now remains hiddev */
189 if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
190 hid->hiddev_hid_event(hid, field, usage, value);
191
192 return 1;
193}
194
195static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id)
196{
197 int ret;
198 struct egalax_data *td;
199 struct hid_report *report;
200
201 td = kzalloc(sizeof(struct egalax_data), GFP_KERNEL);
202 if (!td) {
203 hid_err(hdev, "cannot allocate eGalax data\n");
204 return -ENOMEM;
205 }
206 hid_set_drvdata(hdev, td);
207
208 ret = hid_parse(hdev);
209 if (ret)
210 goto end;
211
212 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
213 if (ret)
214 goto end;
215
216 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[5];
217 if (report) {
218 report->field[0]->value[0] = 2;
219 usbhid_submit_report(hdev, report, USB_DIR_OUT);
220 }
221
222end:
223 if (ret)
224 kfree(td);
225
226 return ret;
227}
228
229static void egalax_remove(struct hid_device *hdev)
230{
231 hid_hw_stop(hdev);
232 kfree(hid_get_drvdata(hdev));
233 hid_set_drvdata(hdev, NULL);
234}
235
236static const struct hid_device_id egalax_devices[] = {
237 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
238 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
239 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
240 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
241 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
242 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
243 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
244 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
245 { HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
246 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
247 { }
248};
249MODULE_DEVICE_TABLE(hid, egalax_devices);
250
251static const struct hid_usage_id egalax_grabbed_usages[] = {
252 { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
253 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
254};
255
256static struct hid_driver egalax_driver = {
257 .name = "egalax-touch",
258 .id_table = egalax_devices,
259 .probe = egalax_probe,
260 .remove = egalax_remove,
261 .input_mapping = egalax_input_mapping,
262 .input_mapped = egalax_input_mapped,
263 .usage_table = egalax_grabbed_usages,
264 .event = egalax_event,
265};
266
267static int __init egalax_init(void)
268{
269 return hid_register_driver(&egalax_driver);
270}
271
272static void __exit egalax_exit(void)
273{
274 hid_unregister_driver(&egalax_driver);
275}
276
277module_init(egalax_init);
278module_exit(egalax_exit);
279
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index 3975e039c3dd..e88b951cd10d 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -43,6 +43,11 @@ static int gyration_input_mapping(struct hid_device *hdev, struct hid_input *hi,
43 case 0x048: gy_map_key_clear(KEY_MEDIA); break; 43 case 0x048: gy_map_key_clear(KEY_MEDIA); break;
44 case 0x049: gy_map_key_clear(KEY_CAMERA); break; 44 case 0x049: gy_map_key_clear(KEY_CAMERA); break;
45 case 0x04a: gy_map_key_clear(KEY_VIDEO); break; 45 case 0x04a: gy_map_key_clear(KEY_VIDEO); break;
46 case 0x05a: gy_map_key_clear(KEY_TEXT); break;
47 case 0x05b: gy_map_key_clear(KEY_RED); break;
48 case 0x05c: gy_map_key_clear(KEY_GREEN); break;
49 case 0x05d: gy_map_key_clear(KEY_YELLOW); break;
50 case 0x05e: gy_map_key_clear(KEY_BLUE); break;
46 51
47 default: 52 default:
48 return 0; 53 return 0;
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 92a0d61a7379..d485894ff4db 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -333,6 +333,9 @@
333#define USB_VENDOR_ID_IMATION 0x0718 333#define USB_VENDOR_ID_IMATION 0x0718
334#define USB_DEVICE_ID_DISC_STAKKA 0xd000 334#define USB_DEVICE_ID_DISC_STAKKA 0xd000
335 335
336#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615
337#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070
338
336#define USB_VENDOR_ID_JESS 0x0c45 339#define USB_VENDOR_ID_JESS 0x0c45
337#define USB_DEVICE_ID_JESS_YUREX 0x1010 340#define USB_DEVICE_ID_JESS_YUREX 0x1010
338 341
@@ -345,6 +348,9 @@
345#define USB_VENDOR_ID_KWORLD 0x1b80 348#define USB_VENDOR_ID_KWORLD 0x1b80
346#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 349#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
347 350
351#define USB_VENDOR_ID_KEYTOUCH 0x0926
352#define USB_DEVICE_ID_KEYTOUCH_IEC 0x3333
353
348#define USB_VENDOR_ID_KYE 0x0458 354#define USB_VENDOR_ID_KYE 0x0458
349#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 355#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
350#define USB_DEVICE_ID_KYE_GPEN_560 0x5003 356#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
@@ -352,6 +358,9 @@
352#define USB_VENDOR_ID_LABTEC 0x1020 358#define USB_VENDOR_ID_LABTEC 0x1020
353#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 359#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
354 360
361#define USB_VENDOR_ID_LCPOWER 0x1241
362#define USB_DEVICE_ID_LCPOWER_LC1000 0xf767
363
355#define USB_VENDOR_ID_LD 0x0f11 364#define USB_VENDOR_ID_LD 0x0f11
356#define USB_DEVICE_ID_LD_CASSY 0x1000 365#define USB_DEVICE_ID_LD_CASSY 0x1000
357#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 366#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010
@@ -383,6 +392,7 @@
383#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 392#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
384#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 393#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
385#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 394#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
395#define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298
386#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 396#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299
387#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c 397#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c
388#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a 398#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
@@ -466,6 +476,7 @@
466#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 476#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
467 477
468#define USB_VENDOR_ID_ORTEK 0x05a4 478#define USB_VENDOR_ID_ORTEK 0x05a4
479#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700
469#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 480#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000
470 481
471#define USB_VENDOR_ID_PANJIT 0x134c 482#define USB_VENDOR_ID_PANJIT 0x134c
@@ -496,8 +507,10 @@
496#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001 507#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
497 508
498#define USB_VENDOR_ID_ROCCAT 0x1e7d 509#define USB_VENDOR_ID_ROCCAT 0x1e7d
510#define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4
499#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 511#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
500#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 512#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51
513#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50
501#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 514#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
502#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 515#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
503 516
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7f552bfad32c..cd74203c8178 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -290,14 +290,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
290 goto ignore; 290 goto ignore;
291 } 291 }
292 292
293 if (field->report_type == HID_FEATURE_REPORT) {
294 if (device->driver->feature_mapping) {
295 device->driver->feature_mapping(device, hidinput, field,
296 usage);
297 }
298 goto ignore;
299 }
300
301 if (device->driver->input_mapping) { 293 if (device->driver->input_mapping) {
302 int ret = device->driver->input_mapping(device, hidinput, field, 294 int ret = device->driver->input_mapping(device, hidinput, field,
303 usage, &bit, &max); 295 usage, &bit, &max);
@@ -835,6 +827,24 @@ static void hidinput_close(struct input_dev *dev)
835 hid_hw_close(hid); 827 hid_hw_close(hid);
836} 828}
837 829
830static void report_features(struct hid_device *hid)
831{
832 struct hid_driver *drv = hid->driver;
833 struct hid_report_enum *rep_enum;
834 struct hid_report *rep;
835 int i, j;
836
837 if (!drv->feature_mapping)
838 return;
839
840 rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
841 list_for_each_entry(rep, &rep_enum->report_list, list)
842 for (i = 0; i < rep->maxfield; i++)
843 for (j = 0; j < rep->field[i]->maxusage; j++)
844 drv->feature_mapping(hid, rep->field[i],
845 rep->field[i]->usage + j);
846}
847
838/* 848/*
839 * Register the input device; print a message. 849 * Register the input device; print a message.
840 * Configure the input layer interface 850 * Configure the input layer interface
@@ -863,7 +873,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
863 return -1; 873 return -1;
864 } 874 }
865 875
866 for (k = HID_INPUT_REPORT; k <= HID_FEATURE_REPORT; k++) { 876 report_features(hid);
877
878 for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
867 if (k == HID_OUTPUT_REPORT && 879 if (k == HID_OUTPUT_REPORT &&
868 hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) 880 hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS)
869 continue; 881 continue;
@@ -928,6 +940,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
928 return 0; 940 return 0;
929 941
930out_cleanup: 942out_cleanup:
943 list_del(&hidinput->list);
931 input_free_device(hidinput->input); 944 input_free_device(hidinput->input);
932 kfree(hidinput); 945 kfree(hidinput);
933out_unwind: 946out_unwind:
diff --git a/drivers/hid/hid-keytouch.c b/drivers/hid/hid-keytouch.c
new file mode 100644
index 000000000000..07cd825f6f01
--- /dev/null
+++ b/drivers/hid/hid-keytouch.c
@@ -0,0 +1,66 @@
1/*
2 * HID driver for Keytouch devices not fully compliant with HID standard
3 *
4 * Copyright (c) 2011 Jiri Kosina
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/hid.h>
16#include <linux/module.h>
17
18#include "hid-ids.h"
19
20/* Replace the broken report descriptor of this device with rather
21 * a default one */
22static __u8 keytouch_fixed_rdesc[] = {
230x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15,
240x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08,
250x81, 0x01, 0x95, 0x03, 0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91,
260x02, 0x95, 0x05, 0x75, 0x01, 0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00,
270x26, 0xff, 0x00, 0x05, 0x07, 0x19, 0x00, 0x2a, 0xff, 0x00, 0x81, 0x00, 0xc0
28};
29
30static __u8 *keytouch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
31 unsigned int *rsize)
32{
33 hid_info(hdev, "fixing up Keytouch IEC report descriptor\n");
34
35 rdesc = keytouch_fixed_rdesc;
36 *rsize = sizeof(keytouch_fixed_rdesc);
37
38 return rdesc;
39}
40
41static const struct hid_device_id keytouch_devices[] = {
42 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
43 { }
44};
45MODULE_DEVICE_TABLE(hid, keytouch_devices);
46
47static struct hid_driver keytouch_driver = {
48 .name = "keytouch",
49 .id_table = keytouch_devices,
50 .report_fixup = keytouch_report_fixup,
51};
52
53static int __init keytouch_init(void)
54{
55 return hid_register_driver(&keytouch_driver);
56}
57
58static void __exit keytouch_exit(void)
59{
60 hid_unregister_driver(&keytouch_driver);
61}
62
63module_init(keytouch_init);
64module_exit(keytouch_exit);
65MODULE_LICENSE("GPL");
66MODULE_AUTHOR("Jiri Kosina");
diff --git a/drivers/hid/hid-lcpower.c b/drivers/hid/hid-lcpower.c
new file mode 100644
index 000000000000..c4fe9bd095b7
--- /dev/null
+++ b/drivers/hid/hid-lcpower.c
@@ -0,0 +1,70 @@
1/*
2 * HID driver for LC Power Model RC1000MCE
3 *
4 * Copyright (c) 2011 Chris Schlund
5 * based on hid-topseed module
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/device.h>
16#include <linux/hid.h>
17#include <linux/module.h>
18
19#include "hid-ids.h"
20
21#define ts_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
22 EV_KEY, (c))
23static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
24 struct hid_field *field, struct hid_usage *usage,
25 unsigned long **bit, int *max)
26{
27 if ((usage->hid & HID_USAGE_PAGE) != 0x0ffbc0000)
28 return 0;
29
30 switch (usage->hid & HID_USAGE) {
31 case 0x046: ts_map_key_clear(KEY_YELLOW); break;
32 case 0x047: ts_map_key_clear(KEY_GREEN); break;
33 case 0x049: ts_map_key_clear(KEY_BLUE); break;
34 case 0x04a: ts_map_key_clear(KEY_RED); break;
35 case 0x00d: ts_map_key_clear(KEY_HOME); break;
36 case 0x025: ts_map_key_clear(KEY_TV); break;
37 case 0x048: ts_map_key_clear(KEY_VCR); break;
38 case 0x024: ts_map_key_clear(KEY_MENU); break;
39 default:
40 return 0;
41 }
42
43 return 1;
44}
45
46static const struct hid_device_id ts_devices[] = {
47 { HID_USB_DEVICE( USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000) },
48 { }
49};
50MODULE_DEVICE_TABLE(hid, ts_devices);
51
52static struct hid_driver ts_driver = {
53 .name = "LC RC1000MCE",
54 .id_table = ts_devices,
55 .input_mapping = ts_input_mapping,
56};
57
58static int __init ts_init(void)
59{
60 return hid_register_driver(&ts_driver);
61}
62
63static void __exit ts_exit(void)
64{
65 hid_unregister_driver(&ts_driver);
66}
67
68module_init(ts_init);
69module_exit(ts_exit);
70MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index aef4104da141..3da90402ee81 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -377,6 +377,8 @@ static const struct hid_device_id lg_devices[] = {
377 .driver_data = LG_FF }, 377 .driver_data = LG_FF },
378 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), 378 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
379 .driver_data = LG_FF }, 379 .driver_data = LG_FF },
380 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
381 .driver_data = LG_FF },
380 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), 382 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
381 .driver_data = LG_FF4 }, 383 .driver_data = LG_FF4 },
382 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), 384 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 698e6459fd0b..318cc40df92d 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -258,7 +258,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
258 input_report_abs(input, ABS_MT_TRACKING_ID, id); 258 input_report_abs(input, ABS_MT_TRACKING_ID, id);
259 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); 259 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
260 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); 260 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
261 input_report_abs(input, ABS_MT_ORIENTATION, orientation); 261 input_report_abs(input, ABS_MT_ORIENTATION, -orientation);
262 input_report_abs(input, ABS_MT_POSITION_X, x); 262 input_report_abs(input, ABS_MT_POSITION_X, x);
263 input_report_abs(input, ABS_MT_POSITION_Y, y); 263 input_report_abs(input, ABS_MT_POSITION_Y, y);
264 264
@@ -397,7 +397,7 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
397 input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); 397 input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0);
398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); 398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0);
399 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); 399 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0);
400 input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); 400 input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
401 401
402 /* Note: Touch Y position from the device is inverted relative 402 /* Note: Touch Y position from the device is inverted relative
403 * to how pointer motion is reported (and relative to how USB 403 * to how pointer motion is reported (and relative to how USB
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 07d3183fdde5..ee01e65e22d6 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -5,6 +5,12 @@
5 * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com> 5 * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6 * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France 6 * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
7 * 7 *
8 * This code is partly based on hid-egalax.c:
9 *
10 * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
11 * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
12 * Copyright (c) 2010 Canonical, Ltd.
13 *
8 */ 14 */
9 15
10/* 16/*
@@ -24,6 +30,7 @@
24 30
25 31
26MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); 32MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
33MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
27MODULE_DESCRIPTION("HID multitouch panels"); 34MODULE_DESCRIPTION("HID multitouch panels");
28MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
29 36
@@ -36,6 +43,7 @@ MODULE_LICENSE("GPL");
36#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3) 43#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3)
37#define MT_QUIRK_VALID_IS_INRANGE (1 << 4) 44#define MT_QUIRK_VALID_IS_INRANGE (1 << 4)
38#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5) 45#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 5)
46#define MT_QUIRK_EGALAX_XYZ_FIXUP (1 << 6)
39 47
40struct mt_slot { 48struct mt_slot {
41 __s32 x, y, p, w, h; 49 __s32 x, y, p, w, h;
@@ -65,10 +73,11 @@ struct mt_class {
65}; 73};
66 74
67/* classes of device behavior */ 75/* classes of device behavior */
68#define MT_CLS_DEFAULT 1 76#define MT_CLS_DEFAULT 1
69#define MT_CLS_DUAL1 2 77#define MT_CLS_DUAL_INRANGE_CONTACTID 2
70#define MT_CLS_DUAL2 3 78#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 3
71#define MT_CLS_CYPRESS 4 79#define MT_CLS_CYPRESS 4
80#define MT_CLS_EGALAX 5
72 81
73/* 82/*
74 * these device-dependent functions determine what slot corresponds 83 * these device-dependent functions determine what slot corresponds
@@ -104,13 +113,13 @@ static int find_slot_from_contactid(struct mt_device *td)
104 113
105struct mt_class mt_classes[] = { 114struct mt_class mt_classes[] = {
106 { .name = MT_CLS_DEFAULT, 115 { .name = MT_CLS_DEFAULT,
107 .quirks = MT_QUIRK_VALID_IS_INRANGE, 116 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
108 .maxcontacts = 10 }, 117 .maxcontacts = 10 },
109 { .name = MT_CLS_DUAL1, 118 { .name = MT_CLS_DUAL_INRANGE_CONTACTID,
110 .quirks = MT_QUIRK_VALID_IS_INRANGE | 119 .quirks = MT_QUIRK_VALID_IS_INRANGE |
111 MT_QUIRK_SLOT_IS_CONTACTID, 120 MT_QUIRK_SLOT_IS_CONTACTID,
112 .maxcontacts = 2 }, 121 .maxcontacts = 2 },
113 { .name = MT_CLS_DUAL2, 122 { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
114 .quirks = MT_QUIRK_VALID_IS_INRANGE | 123 .quirks = MT_QUIRK_VALID_IS_INRANGE |
115 MT_QUIRK_SLOT_IS_CONTACTNUMBER, 124 MT_QUIRK_SLOT_IS_CONTACTNUMBER,
116 .maxcontacts = 2 }, 125 .maxcontacts = 2 },
@@ -119,10 +128,18 @@ struct mt_class mt_classes[] = {
119 MT_QUIRK_CYPRESS, 128 MT_QUIRK_CYPRESS,
120 .maxcontacts = 10 }, 129 .maxcontacts = 10 },
121 130
131 { .name = MT_CLS_EGALAX,
132 .quirks = MT_QUIRK_SLOT_IS_CONTACTID |
133 MT_QUIRK_VALID_IS_INRANGE |
134 MT_QUIRK_EGALAX_XYZ_FIXUP,
135 .maxcontacts = 2,
136 .sn_move = 4096,
137 .sn_pressure = 32,
138 },
122 { } 139 { }
123}; 140};
124 141
125static void mt_feature_mapping(struct hid_device *hdev, struct hid_input *hi, 142static void mt_feature_mapping(struct hid_device *hdev,
126 struct hid_field *field, struct hid_usage *usage) 143 struct hid_field *field, struct hid_usage *usage)
127{ 144{
128 if (usage->hid == HID_DG_INPUTMODE) { 145 if (usage->hid == HID_DG_INPUTMODE) {
@@ -146,11 +163,15 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
146{ 163{
147 struct mt_device *td = hid_get_drvdata(hdev); 164 struct mt_device *td = hid_get_drvdata(hdev);
148 struct mt_class *cls = td->mtclass; 165 struct mt_class *cls = td->mtclass;
166 __s32 quirks = cls->quirks;
167
149 switch (usage->hid & HID_USAGE_PAGE) { 168 switch (usage->hid & HID_USAGE_PAGE) {
150 169
151 case HID_UP_GENDESK: 170 case HID_UP_GENDESK:
152 switch (usage->hid) { 171 switch (usage->hid) {
153 case HID_GD_X: 172 case HID_GD_X:
173 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
174 field->logical_maximum = 32760;
154 hid_map_usage(hi, usage, bit, max, 175 hid_map_usage(hi, usage, bit, max,
155 EV_ABS, ABS_MT_POSITION_X); 176 EV_ABS, ABS_MT_POSITION_X);
156 set_abs(hi->input, ABS_MT_POSITION_X, field, 177 set_abs(hi->input, ABS_MT_POSITION_X, field,
@@ -160,6 +181,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
160 td->last_slot_field = usage->hid; 181 td->last_slot_field = usage->hid;
161 return 1; 182 return 1;
162 case HID_GD_Y: 183 case HID_GD_Y:
184 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
185 field->logical_maximum = 32760;
163 hid_map_usage(hi, usage, bit, max, 186 hid_map_usage(hi, usage, bit, max,
164 EV_ABS, ABS_MT_POSITION_Y); 187 EV_ABS, ABS_MT_POSITION_Y);
165 set_abs(hi->input, ABS_MT_POSITION_Y, field, 188 set_abs(hi->input, ABS_MT_POSITION_Y, field,
@@ -203,6 +226,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
203 td->last_slot_field = usage->hid; 226 td->last_slot_field = usage->hid;
204 return 1; 227 return 1;
205 case HID_DG_TIPPRESSURE: 228 case HID_DG_TIPPRESSURE:
229 if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
230 field->logical_minimum = 0;
206 hid_map_usage(hi, usage, bit, max, 231 hid_map_usage(hi, usage, bit, max,
207 EV_ABS, ABS_MT_PRESSURE); 232 EV_ABS, ABS_MT_PRESSURE);
208 set_abs(hi->input, ABS_MT_PRESSURE, field, 233 set_abs(hi->input, ABS_MT_PRESSURE, field,
@@ -363,8 +388,11 @@ static int mt_event(struct hid_device *hid, struct hid_field *field,
363 return 0; 388 return 0;
364 } 389 }
365 390
366 if (usage->hid == td->last_slot_field) 391 if (usage->hid == td->last_slot_field) {
367 mt_complete_slot(td); 392 mt_complete_slot(td);
393 if (!td->last_field_index)
394 mt_emit_event(td, field->hidinput->input);
395 }
368 396
369 if (field->index == td->last_field_index 397 if (field->index == td->last_field_index
370 && td->num_received >= td->num_expected) 398 && td->num_received >= td->num_expected)
@@ -466,18 +494,42 @@ static const struct hid_device_id mt_devices[] = {
466 USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, 494 USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
467 495
468 /* GeneralTouch panel */ 496 /* GeneralTouch panel */
469 { .driver_data = MT_CLS_DUAL2, 497 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
470 HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 498 HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
471 USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, 499 USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
472 500
501 /* IRTOUCH panels */
502 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
503 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
504 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
505
473 /* PixCir-based panels */ 506 /* PixCir-based panels */
474 { .driver_data = MT_CLS_DUAL1, 507 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
475 HID_USB_DEVICE(USB_VENDOR_ID_HANVON, 508 HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
476 USB_DEVICE_ID_HANVON_MULTITOUCH) }, 509 USB_DEVICE_ID_HANVON_MULTITOUCH) },
477 { .driver_data = MT_CLS_DUAL1, 510 { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
478 HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 511 HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
479 USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, 512 USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
480 513
514 /* Resistive eGalax devices */
515 { .driver_data = MT_CLS_EGALAX,
516 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
517 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
518 { .driver_data = MT_CLS_EGALAX,
519 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
520 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
521
522 /* Capacitive eGalax devices */
523 { .driver_data = MT_CLS_EGALAX,
524 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
525 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
526 { .driver_data = MT_CLS_EGALAX,
527 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
528 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
529 { .driver_data = MT_CLS_EGALAX,
530 HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
531 USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
532
481 { } 533 { }
482}; 534};
483MODULE_DEVICE_TABLE(hid, mt_devices); 535MODULE_DEVICE_TABLE(hid, mt_devices);
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index beb403421e72..9fae2ebdd758 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -110,6 +110,36 @@ static int ntrig_version_string(unsigned char *raw, char *buf)
110 return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e); 110 return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e);
111} 111}
112 112
113static inline int ntrig_get_mode(struct hid_device *hdev)
114{
115 struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT].
116 report_id_hash[0x0d];
117
118 if (!report)
119 return -EINVAL;
120
121 usbhid_submit_report(hdev, report, USB_DIR_IN);
122 usbhid_wait_io(hdev);
123 return (int)report->field[0]->value[0];
124}
125
126static inline void ntrig_set_mode(struct hid_device *hdev, const int mode)
127{
128 struct hid_report *report;
129 __u8 mode_commands[4] = { 0xe, 0xf, 0x1b, 0x10 };
130
131 if (mode < 0 || mode > 3)
132 return;
133
134 report = hdev->report_enum[HID_FEATURE_REPORT].
135 report_id_hash[mode_commands[mode]];
136
137 if (!report)
138 return;
139
140 usbhid_submit_report(hdev, report, USB_DIR_IN);
141}
142
113static void ntrig_report_version(struct hid_device *hdev) 143static void ntrig_report_version(struct hid_device *hdev)
114{ 144{
115 int ret; 145 int ret;
@@ -539,277 +569,288 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi,
539static int ntrig_event (struct hid_device *hid, struct hid_field *field, 569static int ntrig_event (struct hid_device *hid, struct hid_field *field,
540 struct hid_usage *usage, __s32 value) 570 struct hid_usage *usage, __s32 value)
541{ 571{
542 struct input_dev *input = field->hidinput->input;
543 struct ntrig_data *nd = hid_get_drvdata(hid); 572 struct ntrig_data *nd = hid_get_drvdata(hid);
573 struct input_dev *input;
574
575 /* Skip processing if not a claimed input */
576 if (!(hid->claimed & HID_CLAIMED_INPUT))
577 goto not_claimed_input;
578
579 /* This function is being called before the structures are fully
580 * initialized */
581 if(!(field->hidinput && field->hidinput->input))
582 return -EINVAL;
583
584 input = field->hidinput->input;
544 585
545 /* No special handling needed for the pen */ 586 /* No special handling needed for the pen */
546 if (field->application == HID_DG_PEN) 587 if (field->application == HID_DG_PEN)
547 return 0; 588 return 0;
548 589
549 if (hid->claimed & HID_CLAIMED_INPUT) { 590 switch (usage->hid) {
550 switch (usage->hid) { 591 case 0xff000001:
551 case 0xff000001: 592 /* Tag indicating the start of a multitouch group */
552 /* Tag indicating the start of a multitouch group */ 593 nd->reading_mt = 1;
553 nd->reading_mt = 1; 594 nd->first_contact_touch = 0;
554 nd->first_contact_touch = 0; 595 break;
555 break; 596 case HID_DG_TIPSWITCH:
556 case HID_DG_TIPSWITCH: 597 nd->tipswitch = value;
557 nd->tipswitch = value; 598 /* Prevent emission of touch until validated */
558 /* Prevent emission of touch until validated */ 599 return 1;
559 return 1; 600 case HID_DG_CONFIDENCE:
560 case HID_DG_CONFIDENCE: 601 nd->confidence = value;
561 nd->confidence = value; 602 break;
562 break; 603 case HID_GD_X:
563 case HID_GD_X: 604 nd->x = value;
564 nd->x = value; 605 /* Clear the contact footer */
565 /* Clear the contact footer */ 606 nd->mt_foot_count = 0;
566 nd->mt_foot_count = 0; 607 break;
567 break; 608 case HID_GD_Y:
568 case HID_GD_Y: 609 nd->y = value;
569 nd->y = value; 610 break;
570 break; 611 case HID_DG_CONTACTID:
571 case HID_DG_CONTACTID: 612 nd->id = value;
572 nd->id = value; 613 break;
573 break; 614 case HID_DG_WIDTH:
574 case HID_DG_WIDTH: 615 nd->w = value;
575 nd->w = value; 616 break;
576 break; 617 case HID_DG_HEIGHT:
577 case HID_DG_HEIGHT: 618 nd->h = value;
578 nd->h = value; 619 /*
620 * when in single touch mode, this is the last
621 * report received in a finger event. We want
622 * to emit a normal (X, Y) position
623 */
624 if (!nd->reading_mt) {
579 /* 625 /*
580 * when in single touch mode, this is the last 626 * TipSwitch indicates the presence of a
581 * report received in a finger event. We want 627 * finger in single touch mode.
582 * to emit a normal (X, Y) position
583 */ 628 */
584 if (!nd->reading_mt) { 629 input_report_key(input, BTN_TOUCH,
585 /* 630 nd->tipswitch);
586 * TipSwitch indicates the presence of a 631 input_report_key(input, BTN_TOOL_DOUBLETAP,
587 * finger in single touch mode. 632 nd->tipswitch);
588 */ 633 input_event(input, EV_ABS, ABS_X, nd->x);
589 input_report_key(input, BTN_TOUCH, 634 input_event(input, EV_ABS, ABS_Y, nd->y);
590 nd->tipswitch); 635 }
591 input_report_key(input, BTN_TOOL_DOUBLETAP, 636 break;
592 nd->tipswitch); 637 case 0xff000002:
593 input_event(input, EV_ABS, ABS_X, nd->x); 638 /*
594 input_event(input, EV_ABS, ABS_Y, nd->y); 639 * we receive this when the device is in multitouch
595 } 640 * mode. The first of the three values tagged with
641 * this usage tells if the contact point is real
642 * or a placeholder
643 */
644
645 /* Shouldn't get more than 4 footer packets, so skip */
646 if (nd->mt_foot_count >= 4)
596 break; 647 break;
597 case 0xff000002:
598 /*
599 * we receive this when the device is in multitouch
600 * mode. The first of the three values tagged with
601 * this usage tells if the contact point is real
602 * or a placeholder
603 */
604 648
605 /* Shouldn't get more than 4 footer packets, so skip */ 649 nd->mt_footer[nd->mt_foot_count++] = value;
606 if (nd->mt_foot_count >= 4)
607 break;
608 650
609 nd->mt_footer[nd->mt_foot_count++] = value; 651 /* if the footer isn't complete break */
652 if (nd->mt_foot_count != 4)
653 break;
610 654
611 /* if the footer isn't complete break */ 655 /* Pen activity signal. */
612 if (nd->mt_foot_count != 4) 656 if (nd->mt_footer[2]) {
613 break; 657 /*
658 * When the pen deactivates touch, we see a
659 * bogus frame with ContactCount > 0.
660 * We can
661 * save a bit of work by ensuring act_state < 0
662 * even if deactivation slack is turned off.
663 */
664 nd->act_state = deactivate_slack - 1;
665 nd->confidence = 0;
666 break;
667 }
614 668
615 /* Pen activity signal. */ 669 /*
616 if (nd->mt_footer[2]) { 670 * The first footer value indicates the presence of a
617 /* 671 * finger.
618 * When the pen deactivates touch, we see a 672 */
619 * bogus frame with ContactCount > 0. 673 if (nd->mt_footer[0]) {
620 * We can 674 /*
621 * save a bit of work by ensuring act_state < 0 675 * We do not want to process contacts under
622 * even if deactivation slack is turned off. 676 * the size threshold, but do not want to
623 */ 677 * ignore them for activation state
624 nd->act_state = deactivate_slack - 1; 678 */
679 if (nd->w < nd->min_width ||
680 nd->h < nd->min_height)
625 nd->confidence = 0; 681 nd->confidence = 0;
626 break; 682 } else
627 } 683 break;
628 684
685 if (nd->act_state > 0) {
629 /* 686 /*
630 * The first footer value indicates the presence of a 687 * Contact meets the activation size threshold
631 * finger.
632 */ 688 */
633 if (nd->mt_footer[0]) { 689 if (nd->w >= nd->activation_width &&
634 /* 690 nd->h >= nd->activation_height) {
635 * We do not want to process contacts under 691 if (nd->id)
636 * the size threshold, but do not want to
637 * ignore them for activation state
638 */
639 if (nd->w < nd->min_width ||
640 nd->h < nd->min_height)
641 nd->confidence = 0;
642 } else
643 break;
644
645 if (nd->act_state > 0) {
646 /*
647 * Contact meets the activation size threshold
648 */
649 if (nd->w >= nd->activation_width &&
650 nd->h >= nd->activation_height) {
651 if (nd->id)
652 /*
653 * first contact, activate now
654 */
655 nd->act_state = 0;
656 else {
657 /*
658 * avoid corrupting this frame
659 * but ensure next frame will
660 * be active
661 */
662 nd->act_state = 1;
663 break;
664 }
665 } else
666 /* 692 /*
667 * Defer adjusting the activation state 693 * first contact, activate now
668 * until the end of the frame.
669 */ 694 */
695 nd->act_state = 0;
696 else {
697 /*
698 * avoid corrupting this frame
699 * but ensure next frame will
700 * be active
701 */
702 nd->act_state = 1;
670 break; 703 break;
671 } 704 }
672 705 } else
673 /* Discarding this contact */
674 if (!nd->confidence)
675 break;
676
677 /* emit a normal (X, Y) for the first point only */
678 if (nd->id == 0) {
679 /* 706 /*
680 * TipSwitch is superfluous in multitouch 707 * Defer adjusting the activation state
681 * mode. The footer events tell us 708 * until the end of the frame.
682 * if there is a finger on the screen or
683 * not.
684 */ 709 */
685 nd->first_contact_touch = nd->confidence; 710 break;
686 input_event(input, EV_ABS, ABS_X, nd->x); 711 }
687 input_event(input, EV_ABS, ABS_Y, nd->y);
688 }
689 712
690 /* Emit MT events */ 713 /* Discarding this contact */
691 input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x); 714 if (!nd->confidence)
692 input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y); 715 break;
693 716
717 /* emit a normal (X, Y) for the first point only */
718 if (nd->id == 0) {
694 /* 719 /*
695 * Translate from height and width to size 720 * TipSwitch is superfluous in multitouch
696 * and orientation. 721 * mode. The footer events tell us
722 * if there is a finger on the screen or
723 * not.
697 */ 724 */
698 if (nd->w > nd->h) { 725 nd->first_contact_touch = nd->confidence;
699 input_event(input, EV_ABS, 726 input_event(input, EV_ABS, ABS_X, nd->x);
700 ABS_MT_ORIENTATION, 1); 727 input_event(input, EV_ABS, ABS_Y, nd->y);
701 input_event(input, EV_ABS, 728 }
702 ABS_MT_TOUCH_MAJOR, nd->w);
703 input_event(input, EV_ABS,
704 ABS_MT_TOUCH_MINOR, nd->h);
705 } else {
706 input_event(input, EV_ABS,
707 ABS_MT_ORIENTATION, 0);
708 input_event(input, EV_ABS,
709 ABS_MT_TOUCH_MAJOR, nd->h);
710 input_event(input, EV_ABS,
711 ABS_MT_TOUCH_MINOR, nd->w);
712 }
713 input_mt_sync(field->hidinput->input);
714 break;
715 729
716 case HID_DG_CONTACTCOUNT: /* End of a multitouch group */ 730 /* Emit MT events */
717 if (!nd->reading_mt) /* Just to be sure */ 731 input_event(input, EV_ABS, ABS_MT_POSITION_X, nd->x);
718 break; 732 input_event(input, EV_ABS, ABS_MT_POSITION_Y, nd->y);
733
734 /*
735 * Translate from height and width to size
736 * and orientation.
737 */
738 if (nd->w > nd->h) {
739 input_event(input, EV_ABS,
740 ABS_MT_ORIENTATION, 1);
741 input_event(input, EV_ABS,
742 ABS_MT_TOUCH_MAJOR, nd->w);
743 input_event(input, EV_ABS,
744 ABS_MT_TOUCH_MINOR, nd->h);
745 } else {
746 input_event(input, EV_ABS,
747 ABS_MT_ORIENTATION, 0);
748 input_event(input, EV_ABS,
749 ABS_MT_TOUCH_MAJOR, nd->h);
750 input_event(input, EV_ABS,
751 ABS_MT_TOUCH_MINOR, nd->w);
752 }
753 input_mt_sync(field->hidinput->input);
754 break;
719 755
720 nd->reading_mt = 0; 756 case HID_DG_CONTACTCOUNT: /* End of a multitouch group */
757 if (!nd->reading_mt) /* Just to be sure */
758 break;
721 759
760 nd->reading_mt = 0;
761
762
763 /*
764 * Activation state machine logic:
765 *
766 * Fundamental states:
767 * state > 0: Inactive
768 * state <= 0: Active
769 * state < -deactivate_slack:
770 * Pen termination of touch
771 *
772 * Specific values of interest
773 * state == activate_slack
774 * no valid input since the last reset
775 *
776 * state == 0
777 * general operational state
778 *
779 * state == -deactivate_slack
780 * read sufficient empty frames to accept
781 * the end of input and reset
782 */
783
784 if (nd->act_state > 0) { /* Currently inactive */
785 if (value)
786 /*
787 * Consider each live contact as
788 * evidence of intentional activity.
789 */
790 nd->act_state = (nd->act_state > value)
791 ? nd->act_state - value
792 : 0;
793 else
794 /*
795 * Empty frame before we hit the
796 * activity threshold, reset.
797 */
798 nd->act_state = nd->activate_slack;
722 799
723 /* 800 /*
724 * Activation state machine logic: 801 * Entered this block inactive and no
725 * 802 * coordinates sent this frame, so hold off
726 * Fundamental states: 803 * on button state.
727 * state > 0: Inactive
728 * state <= 0: Active
729 * state < -deactivate_slack:
730 * Pen termination of touch
731 *
732 * Specific values of interest
733 * state == activate_slack
734 * no valid input since the last reset
735 *
736 * state == 0
737 * general operational state
738 *
739 * state == -deactivate_slack
740 * read sufficient empty frames to accept
741 * the end of input and reset
742 */ 804 */
743 805 break;
744 if (nd->act_state > 0) { /* Currently inactive */ 806 } else { /* Currently active */
745 if (value) 807 if (value && nd->act_state >=
746 /* 808 nd->deactivate_slack)
747 * Consider each live contact as
748 * evidence of intentional activity.
749 */
750 nd->act_state = (nd->act_state > value)
751 ? nd->act_state - value
752 : 0;
753 else
754 /*
755 * Empty frame before we hit the
756 * activity threshold, reset.
757 */
758 nd->act_state = nd->activate_slack;
759
760 /* 809 /*
761 * Entered this block inactive and no 810 * Live point: clear accumulated
762 * coordinates sent this frame, so hold off 811 * deactivation count.
763 * on button state.
764 */ 812 */
765 break; 813 nd->act_state = 0;
766 } else { /* Currently active */ 814 else if (nd->act_state <= nd->deactivate_slack)
767 if (value && nd->act_state >=
768 nd->deactivate_slack)
769 /*
770 * Live point: clear accumulated
771 * deactivation count.
772 */
773 nd->act_state = 0;
774 else if (nd->act_state <= nd->deactivate_slack)
775 /*
776 * We've consumed the deactivation
777 * slack, time to deactivate and reset.
778 */
779 nd->act_state =
780 nd->activate_slack;
781 else { /* Move towards deactivation */
782 nd->act_state--;
783 break;
784 }
785 }
786
787 if (nd->first_contact_touch && nd->act_state <= 0) {
788 /* 815 /*
789 * Check to see if we're ready to start 816 * We've consumed the deactivation
790 * emitting touch events. 817 * slack, time to deactivate and reset.
791 *
792 * Note: activation slack will decrease over
793 * the course of the frame, and it will be
794 * inconsistent from the start to the end of
795 * the frame. However if the frame starts
796 * with slack, first_contact_touch will still
797 * be 0 and we will not get to this point.
798 */ 818 */
799 input_report_key(input, BTN_TOOL_DOUBLETAP, 1); 819 nd->act_state =
800 input_report_key(input, BTN_TOUCH, 1); 820 nd->activate_slack;
801 } else { 821 else { /* Move towards deactivation */
802 input_report_key(input, BTN_TOOL_DOUBLETAP, 0); 822 nd->act_state--;
803 input_report_key(input, BTN_TOUCH, 0); 823 break;
804 } 824 }
805 break; 825 }
806 826
807 default: 827 if (nd->first_contact_touch && nd->act_state <= 0) {
808 /* fall-back to the generic hidinput handling */ 828 /*
809 return 0; 829 * Check to see if we're ready to start
830 * emitting touch events.
831 *
832 * Note: activation slack will decrease over
833 * the course of the frame, and it will be
834 * inconsistent from the start to the end of
835 * the frame. However if the frame starts
836 * with slack, first_contact_touch will still
837 * be 0 and we will not get to this point.
838 */
839 input_report_key(input, BTN_TOOL_DOUBLETAP, 1);
840 input_report_key(input, BTN_TOUCH, 1);
841 } else {
842 input_report_key(input, BTN_TOOL_DOUBLETAP, 0);
843 input_report_key(input, BTN_TOUCH, 0);
810 } 844 }
845 break;
846
847 default:
848 /* fall-back to the generic hidinput handling */
849 return 0;
811 } 850 }
812 851
852not_claimed_input:
853
813 /* we have handled the hidinput part, now remains hiddev */ 854 /* we have handled the hidinput part, now remains hiddev */
814 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event) 855 if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_hid_event)
815 hid->hiddev_hid_event(hid, field, usage, value); 856 hid->hiddev_hid_event(hid, field, usage, value);
@@ -826,7 +867,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
826 struct hid_report *report; 867 struct hid_report *report;
827 868
828 if (id->driver_data) 869 if (id->driver_data)
829 hdev->quirks |= HID_QUIRK_MULTI_INPUT; 870 hdev->quirks |= HID_QUIRK_MULTI_INPUT
871 | HID_QUIRK_NO_INIT_REPORTS;
830 872
831 nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); 873 nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL);
832 if (!nd) { 874 if (!nd) {
@@ -893,8 +935,19 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id)
893 935
894 /* This is needed for devices with more recent firmware versions */ 936 /* This is needed for devices with more recent firmware versions */
895 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a]; 937 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0x0a];
896 if (report) 938 if (report) {
897 usbhid_submit_report(hdev, report, USB_DIR_OUT); 939 /* Let the device settle to ensure the wakeup message gets
940 * through */
941 usbhid_wait_io(hdev);
942 usbhid_submit_report(hdev, report, USB_DIR_IN);
943
944 /*
945 * Sanity check: if the current mode is invalid reset it to
946 * something reasonable.
947 */
948 if (ntrig_get_mode(hdev) >= 4)
949 ntrig_set_mode(hdev, 3);
950 }
898 951
899 ntrig_report_version(hdev); 952 ntrig_report_version(hdev);
900 953
diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c
index e90edfc63051..f9b7dd4f607f 100644
--- a/drivers/hid/hid-ortek.c
+++ b/drivers/hid/hid-ortek.c
@@ -1,7 +1,6 @@
1/* 1/*
2 * HID driver for Ortek WKB-2000 (wireless keyboard + mouse trackpad). 2 * HID driver for Ortek PKB-1700/WKB-2000 (wireless keyboard + mouse trackpad).
3 * Fixes LogicalMaximum error in USB report description, see 3 * Fixes LogicalMaximum error in HID report description.
4 * http://bugzilla.kernel.org/show_bug.cgi?id=14787
5 * 4 *
6 * Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com> 5 * Copyright (c) 2010 Johnathon Harris <jmharris@gmail.com>
7 */ 6 */
@@ -30,6 +29,7 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
30} 29}
31 30
32static const struct hid_device_id ortek_devices[] = { 31static const struct hid_device_id ortek_devices[] = {
32 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
33 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) }, 33 { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
34 { } 34 { }
35}; 35};
diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c
new file mode 100644
index 000000000000..2307471d96dc
--- /dev/null
+++ b/drivers/hid/hid-roccat-arvo.c
@@ -0,0 +1,450 @@
1/*
2 * Roccat Arvo driver for Linux
3 *
4 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14/*
15 * Roccat Arvo is a gamer keyboard with 5 macro keys that can be configured in
16 * 5 profiles.
17 */
18
19#include <linux/device.h>
20#include <linux/input.h>
21#include <linux/hid.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/hid-roccat.h>
25#include "hid-ids.h"
26#include "hid-roccat-common.h"
27#include "hid-roccat-arvo.h"
28
29static struct class *arvo_class;
30
31static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
32 struct device_attribute *attr, char *buf)
33{
34 struct arvo_device *arvo =
35 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
36 struct usb_device *usb_dev =
37 interface_to_usbdev(to_usb_interface(dev->parent->parent));
38 struct arvo_mode_key temp_buf;
39 int retval;
40
41 mutex_lock(&arvo->arvo_lock);
42 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
43 &temp_buf, sizeof(struct arvo_mode_key));
44 mutex_unlock(&arvo->arvo_lock);
45 if (retval)
46 return retval;
47
48 return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.state);
49}
50
51static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
52 struct device_attribute *attr, char const *buf, size_t size)
53{
54 struct arvo_device *arvo =
55 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
56 struct usb_device *usb_dev =
57 interface_to_usbdev(to_usb_interface(dev->parent->parent));
58 struct arvo_mode_key temp_buf;
59 unsigned long state;
60 int retval;
61
62 retval = strict_strtoul(buf, 10, &state);
63 if (retval)
64 return retval;
65
66 temp_buf.command = ARVO_COMMAND_MODE_KEY;
67 temp_buf.state = state;
68
69 mutex_lock(&arvo->arvo_lock);
70 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY,
71 &temp_buf, sizeof(struct arvo_mode_key));
72 mutex_unlock(&arvo->arvo_lock);
73 if (retval)
74 return retval;
75
76 return size;
77}
78
79static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
80 struct device_attribute *attr, char *buf)
81{
82 struct arvo_device *arvo =
83 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
84 struct usb_device *usb_dev =
85 interface_to_usbdev(to_usb_interface(dev->parent->parent));
86 struct arvo_key_mask temp_buf;
87 int retval;
88
89 mutex_lock(&arvo->arvo_lock);
90 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
91 &temp_buf, sizeof(struct arvo_key_mask));
92 mutex_unlock(&arvo->arvo_lock);
93 if (retval)
94 return retval;
95
96 return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.key_mask);
97}
98
99static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
100 struct device_attribute *attr, char const *buf, size_t size)
101{
102 struct arvo_device *arvo =
103 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
104 struct usb_device *usb_dev =
105 interface_to_usbdev(to_usb_interface(dev->parent->parent));
106 struct arvo_key_mask temp_buf;
107 unsigned long key_mask;
108 int retval;
109
110 retval = strict_strtoul(buf, 10, &key_mask);
111 if (retval)
112 return retval;
113
114 temp_buf.command = ARVO_COMMAND_KEY_MASK;
115 temp_buf.key_mask = key_mask;
116
117 mutex_lock(&arvo->arvo_lock);
118 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK,
119 &temp_buf, sizeof(struct arvo_key_mask));
120 mutex_unlock(&arvo->arvo_lock);
121 if (retval)
122 return retval;
123
124 return size;
125}
126
127/* retval is 1-5 on success, < 0 on error */
128static int arvo_get_actual_profile(struct usb_device *usb_dev)
129{
130 struct arvo_actual_profile temp_buf;
131 int retval;
132
133 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
134 &temp_buf, sizeof(struct arvo_actual_profile));
135
136 if (retval)
137 return retval;
138
139 return temp_buf.actual_profile;
140}
141
142static ssize_t arvo_sysfs_show_actual_profile(struct device *dev,
143 struct device_attribute *attr, char *buf)
144{
145 struct arvo_device *arvo =
146 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
147
148 return snprintf(buf, PAGE_SIZE, "%d\n", arvo->actual_profile);
149}
150
151static ssize_t arvo_sysfs_set_actual_profile(struct device *dev,
152 struct device_attribute *attr, char const *buf, size_t size)
153{
154 struct arvo_device *arvo =
155 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
156 struct usb_device *usb_dev =
157 interface_to_usbdev(to_usb_interface(dev->parent->parent));
158 struct arvo_actual_profile temp_buf;
159 unsigned long profile;
160 int retval;
161
162 retval = strict_strtoul(buf, 10, &profile);
163 if (retval)
164 return retval;
165
166 temp_buf.command = ARVO_COMMAND_ACTUAL_PROFILE;
167 temp_buf.actual_profile = profile;
168
169 mutex_lock(&arvo->arvo_lock);
170 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE,
171 &temp_buf, sizeof(struct arvo_actual_profile));
172 if (!retval) {
173 arvo->actual_profile = profile;
174 retval = size;
175 }
176 mutex_unlock(&arvo->arvo_lock);
177 return retval;
178}
179
180static ssize_t arvo_sysfs_write(struct file *fp,
181 struct kobject *kobj, void const *buf,
182 loff_t off, size_t count, size_t real_size, uint command)
183{
184 struct device *dev =
185 container_of(kobj, struct device, kobj)->parent->parent;
186 struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev));
187 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
188 int retval;
189
190 if (off != 0 || count != real_size)
191 return -EINVAL;
192
193 mutex_lock(&arvo->arvo_lock);
194 retval = roccat_common_send(usb_dev, command, buf, real_size);
195 mutex_unlock(&arvo->arvo_lock);
196
197 return (retval ? retval : real_size);
198}
199
200static ssize_t arvo_sysfs_read(struct file *fp,
201 struct kobject *kobj, void *buf, loff_t off,
202 size_t count, size_t real_size, uint command)
203{
204 struct device *dev =
205 container_of(kobj, struct device, kobj)->parent->parent;
206 struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev));
207 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
208 int retval;
209
210 if (off >= real_size)
211 return 0;
212
213 if (off != 0 || count != real_size)
214 return -EINVAL;
215
216 mutex_lock(&arvo->arvo_lock);
217 retval = roccat_common_receive(usb_dev, command, buf, real_size);
218 mutex_unlock(&arvo->arvo_lock);
219
220 return (retval ? retval : real_size);
221}
222
223static ssize_t arvo_sysfs_write_button(struct file *fp,
224 struct kobject *kobj, struct bin_attribute *attr, char *buf,
225 loff_t off, size_t count)
226{
227 return arvo_sysfs_write(fp, kobj, buf, off, count,
228 sizeof(struct arvo_button), ARVO_USB_COMMAND_BUTTON);
229}
230
231static ssize_t arvo_sysfs_read_info(struct file *fp,
232 struct kobject *kobj, struct bin_attribute *attr, char *buf,
233 loff_t off, size_t count)
234{
235 return arvo_sysfs_read(fp, kobj, buf, off, count,
236 sizeof(struct arvo_info), ARVO_USB_COMMAND_INFO);
237}
238
239
240static struct device_attribute arvo_attributes[] = {
241 __ATTR(mode_key, 0660,
242 arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key),
243 __ATTR(key_mask, 0660,
244 arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask),
245 __ATTR(actual_profile, 0660,
246 arvo_sysfs_show_actual_profile,
247 arvo_sysfs_set_actual_profile),
248 __ATTR_NULL
249};
250
251static struct bin_attribute arvo_bin_attributes[] = {
252 {
253 .attr = { .name = "button", .mode = 0220 },
254 .size = sizeof(struct arvo_button),
255 .write = arvo_sysfs_write_button
256 },
257 {
258 .attr = { .name = "info", .mode = 0440 },
259 .size = sizeof(struct arvo_info),
260 .read = arvo_sysfs_read_info
261 },
262 __ATTR_NULL
263};
264
265static int arvo_init_arvo_device_struct(struct usb_device *usb_dev,
266 struct arvo_device *arvo)
267{
268 int retval;
269
270 mutex_init(&arvo->arvo_lock);
271
272 retval = arvo_get_actual_profile(usb_dev);
273 if (retval < 0)
274 return retval;
275 arvo->actual_profile = retval;
276
277 return 0;
278}
279
280static int arvo_init_specials(struct hid_device *hdev)
281{
282 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
283 struct usb_device *usb_dev = interface_to_usbdev(intf);
284 struct arvo_device *arvo;
285 int retval;
286
287 if (intf->cur_altsetting->desc.bInterfaceProtocol
288 == USB_INTERFACE_PROTOCOL_KEYBOARD) {
289 hid_set_drvdata(hdev, NULL);
290 return 0;
291 }
292
293 arvo = kzalloc(sizeof(*arvo), GFP_KERNEL);
294 if (!arvo) {
295 hid_err(hdev, "can't alloc device descriptor\n");
296 return -ENOMEM;
297 }
298 hid_set_drvdata(hdev, arvo);
299
300 retval = arvo_init_arvo_device_struct(usb_dev, arvo);
301 if (retval) {
302 hid_err(hdev, "couldn't init struct arvo_device\n");
303 goto exit_free;
304 }
305
306 retval = roccat_connect(arvo_class, hdev,
307 sizeof(struct arvo_roccat_report));
308 if (retval < 0) {
309 hid_err(hdev, "couldn't init char dev\n");
310 } else {
311 arvo->chrdev_minor = retval;
312 arvo->roccat_claimed = 1;
313 }
314
315 return 0;
316exit_free:
317 kfree(arvo);
318 return retval;
319}
320
321static void arvo_remove_specials(struct hid_device *hdev)
322{
323 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
324 struct arvo_device *arvo;
325
326 if (intf->cur_altsetting->desc.bInterfaceProtocol
327 == USB_INTERFACE_PROTOCOL_KEYBOARD)
328 return;
329
330 arvo = hid_get_drvdata(hdev);
331 if (arvo->roccat_claimed)
332 roccat_disconnect(arvo->chrdev_minor);
333 kfree(arvo);
334}
335
336static int arvo_probe(struct hid_device *hdev,
337 const struct hid_device_id *id)
338{
339 int retval;
340
341 retval = hid_parse(hdev);
342 if (retval) {
343 hid_err(hdev, "parse failed\n");
344 goto exit;
345 }
346
347 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
348 if (retval) {
349 hid_err(hdev, "hw start failed\n");
350 goto exit;
351 }
352
353 retval = arvo_init_specials(hdev);
354 if (retval) {
355 hid_err(hdev, "couldn't install keyboard\n");
356 goto exit_stop;
357 }
358
359 return 0;
360
361exit_stop:
362 hid_hw_stop(hdev);
363exit:
364 return retval;
365}
366
367static void arvo_remove(struct hid_device *hdev)
368{
369 arvo_remove_specials(hdev);
370 hid_hw_stop(hdev);
371}
372
373static void arvo_report_to_chrdev(struct arvo_device const *arvo,
374 u8 const *data)
375{
376 struct arvo_special_report const *special_report;
377 struct arvo_roccat_report roccat_report;
378
379 special_report = (struct arvo_special_report const *)data;
380
381 roccat_report.profile = arvo->actual_profile;
382 roccat_report.button = special_report->event &
383 ARVO_SPECIAL_REPORT_EVENT_MASK_BUTTON;
384 if ((special_report->event & ARVO_SPECIAL_REPORT_EVENT_MASK_ACTION) ==
385 ARVO_SPECIAL_REPORT_EVENT_ACTION_PRESS)
386 roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_PRESS;
387 else
388 roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_RELEASE;
389
390 roccat_report_event(arvo->chrdev_minor,
391 (uint8_t const *)&roccat_report);
392}
393
394static int arvo_raw_event(struct hid_device *hdev,
395 struct hid_report *report, u8 *data, int size)
396{
397 struct arvo_device *arvo = hid_get_drvdata(hdev);
398
399 if (size != 3)
400 return 0;
401
402 if (arvo->roccat_claimed)
403 arvo_report_to_chrdev(arvo, data);
404
405 return 0;
406}
407
408static const struct hid_device_id arvo_devices[] = {
409 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
410 { }
411};
412
413MODULE_DEVICE_TABLE(hid, arvo_devices);
414
415static struct hid_driver arvo_driver = {
416 .name = "arvo",
417 .id_table = arvo_devices,
418 .probe = arvo_probe,
419 .remove = arvo_remove,
420 .raw_event = arvo_raw_event
421};
422
423static int __init arvo_init(void)
424{
425 int retval;
426
427 arvo_class = class_create(THIS_MODULE, "arvo");
428 if (IS_ERR(arvo_class))
429 return PTR_ERR(arvo_class);
430 arvo_class->dev_attrs = arvo_attributes;
431 arvo_class->dev_bin_attrs = arvo_bin_attributes;
432
433 retval = hid_register_driver(&arvo_driver);
434 if (retval)
435 class_destroy(arvo_class);
436 return retval;
437}
438
439static void __exit arvo_exit(void)
440{
441 hid_unregister_driver(&arvo_driver);
442 class_destroy(arvo_class);
443}
444
445module_init(arvo_init);
446module_exit(arvo_exit);
447
448MODULE_AUTHOR("Stefan Achatz");
449MODULE_DESCRIPTION("USB Roccat Arvo driver");
450MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-arvo.h b/drivers/hid/hid-roccat-arvo.h
new file mode 100644
index 000000000000..d284a781c99e
--- /dev/null
+++ b/drivers/hid/hid-roccat-arvo.h
@@ -0,0 +1,98 @@
1#ifndef __HID_ROCCAT_ARVO_H
2#define __HID_ROCCAT_ARVO_H
3
4/*
5 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/types.h>
16
17struct arvo_mode_key { /* 2 bytes */
18 uint8_t command; /* ARVO_COMMAND_MODE_KEY */
19 uint8_t state;
20} __packed;
21
22struct arvo_button {
23 uint8_t unknown[24];
24} __packed;
25
26struct arvo_info {
27 uint8_t unknown[8];
28} __packed;
29
30struct arvo_key_mask { /* 2 bytes */
31 uint8_t command; /* ARVO_COMMAND_KEY_MASK */
32 uint8_t key_mask;
33} __packed;
34
35/* selected profile is persistent */
36struct arvo_actual_profile { /* 2 bytes */
37 uint8_t command; /* ARVO_COMMAND_ACTUAL_PROFILE */
38 uint8_t actual_profile;
39} __packed;
40
41enum arvo_commands {
42 ARVO_COMMAND_MODE_KEY = 0x3,
43 ARVO_COMMAND_BUTTON = 0x4,
44 ARVO_COMMAND_INFO = 0x5,
45 ARVO_COMMAND_KEY_MASK = 0x6,
46 ARVO_COMMAND_ACTUAL_PROFILE = 0x7,
47};
48
49enum arvo_usb_commands {
50 ARVO_USB_COMMAND_MODE_KEY = 0x303,
51 /*
52 * read/write
53 * Read uses both index bytes as profile/key indexes
54 * Write has index 0, profile/key is determined by payload
55 */
56 ARVO_USB_COMMAND_BUTTON = 0x304,
57 ARVO_USB_COMMAND_INFO = 0x305,
58 ARVO_USB_COMMAND_KEY_MASK = 0x306,
59 ARVO_USB_COMMAND_ACTUAL_PROFILE = 0x307,
60};
61
62struct arvo_special_report {
63 uint8_t unknown1; /* always 0x01 */
64 uint8_t event;
65 uint8_t unknown2; /* always 0x70 */
66} __packed;
67
68enum arvo_special_report_events {
69 ARVO_SPECIAL_REPORT_EVENT_ACTION_PRESS = 0x10,
70 ARVO_SPECIAL_REPORT_EVENT_ACTION_RELEASE = 0x0,
71};
72
73enum arvo_special_report_event_masks {
74 ARVO_SPECIAL_REPORT_EVENT_MASK_ACTION = 0xf0,
75 ARVO_SPECIAL_REPORT_EVENT_MASK_BUTTON = 0x0f,
76};
77
78struct arvo_roccat_report {
79 uint8_t profile;
80 uint8_t button;
81 uint8_t action;
82} __packed;
83
84enum arvo_roccat_report_action {
85 ARVO_ROCCAT_REPORT_ACTION_RELEASE = 0,
86 ARVO_ROCCAT_REPORT_ACTION_PRESS = 1,
87};
88
89struct arvo_device {
90 int roccat_claimed;
91 int chrdev_minor;
92
93 struct mutex arvo_lock;
94
95 int actual_profile;
96};
97
98#endif
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c
new file mode 100644
index 000000000000..13b1eb0c8c65
--- /dev/null
+++ b/drivers/hid/hid-roccat-common.c
@@ -0,0 +1,62 @@
1/*
2 * Roccat common functions for device specific drivers
3 *
4 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/slab.h>
15#include "hid-roccat-common.h"
16
17int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
18 void *data, uint size)
19{
20 char *buf;
21 int len;
22
23 buf = kmalloc(size, GFP_KERNEL);
24 if (buf == NULL)
25 return -ENOMEM;
26
27 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
28 USB_REQ_CLEAR_FEATURE,
29 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
30 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
31
32 memcpy(data, buf, size);
33 kfree(buf);
34 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
35}
36EXPORT_SYMBOL_GPL(roccat_common_receive);
37
38int roccat_common_send(struct usb_device *usb_dev, uint usb_command,
39 void const *data, uint size)
40{
41 char *buf;
42 int len;
43
44 buf = kmalloc(size, GFP_KERNEL);
45 if (buf == NULL)
46 return -ENOMEM;
47
48 memcpy(buf, data, size);
49
50 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
51 USB_REQ_SET_CONFIGURATION,
52 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
53 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
54
55 kfree(buf);
56 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
57}
58EXPORT_SYMBOL_GPL(roccat_common_send);
59
60MODULE_AUTHOR("Stefan Achatz");
61MODULE_DESCRIPTION("USB Roccat common driver");
62MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h
new file mode 100644
index 000000000000..fe45fae05bb9
--- /dev/null
+++ b/drivers/hid/hid-roccat-common.h
@@ -0,0 +1,23 @@
1#ifndef __HID_ROCCAT_COMMON_H
2#define __HID_ROCCAT_COMMON_H
3
4/*
5 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/usb.h>
16#include <linux/types.h>
17
18int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
19 void *data, uint size);
20int roccat_common_send(struct usb_device *usb_dev, uint usb_command,
21 void const *data, uint size);
22
23#endif
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index cbd8cc42e75a..a57838d15267 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
@@ -28,11 +28,11 @@
28#include <linux/device.h> 28#include <linux/device.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/hid.h> 30#include <linux/hid.h>
31#include <linux/usb.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/hid-roccat.h>
34#include "hid-ids.h" 34#include "hid-ids.h"
35#include "hid-roccat.h" 35#include "hid-roccat-common.h"
36#include "hid-roccat-kone.h" 36#include "hid-roccat-kone.h"
37 37
38static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 38static uint profile_numbers[5] = {0, 1, 2, 3, 4};
@@ -58,12 +58,8 @@ static void kone_set_settings_checksum(struct kone_settings *settings)
58 */ 58 */
59static int kone_check_write(struct usb_device *usb_dev) 59static int kone_check_write(struct usb_device *usb_dev)
60{ 60{
61 int len; 61 int retval;
62 unsigned char *data; 62 uint8_t data;
63
64 data = kmalloc(1, GFP_KERNEL);
65 if (!data)
66 return -ENOMEM;
67 63
68 do { 64 do {
69 /* 65 /*
@@ -72,56 +68,36 @@ static int kone_check_write(struct usb_device *usb_dev)
72 */ 68 */
73 msleep(80); 69 msleep(80);
74 70
75 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 71 retval = roccat_common_receive(usb_dev,
76 USB_REQ_CLEAR_FEATURE, 72 kone_command_confirm_write, &data, 1);
77 USB_TYPE_CLASS | USB_RECIP_INTERFACE | 73 if (retval)
78 USB_DIR_IN, 74 return retval;
79 kone_command_confirm_write, 0, data, 1,
80 USB_CTRL_SET_TIMEOUT);
81
82 if (len != 1) {
83 kfree(data);
84 return -EIO;
85 }
86 75
87 /* 76 /*
88 * value of 3 seems to mean something like 77 * value of 3 seems to mean something like
89 * "not finished yet, but it looks good" 78 * "not finished yet, but it looks good"
90 * So check again after a moment. 79 * So check again after a moment.
91 */ 80 */
92 } while (*data == 3); 81 } while (data == 3);
93 82
94 if (*data == 1) { /* everything alright */ 83 if (data == 1) /* everything alright */
95 kfree(data);
96 return 0; 84 return 0;
97 } else { /* unknown answer */ 85
98 hid_err(usb_dev, "got retval %d when checking write\n", *data); 86 /* unknown answer */
99 kfree(data); 87 hid_err(usb_dev, "got retval %d when checking write\n", data);
100 return -EIO; 88 return -EIO;
101 }
102} 89}
103 90
104/* 91/*
105 * Reads settings from mouse and stores it in @buf 92 * Reads settings from mouse and stores it in @buf
106 * @buf has to be alloced with GFP_KERNEL
107 * On success returns 0 93 * On success returns 0
108 * On failure returns errno 94 * On failure returns errno
109 */ 95 */
110static int kone_get_settings(struct usb_device *usb_dev, 96static int kone_get_settings(struct usb_device *usb_dev,
111 struct kone_settings *buf) 97 struct kone_settings *buf)
112{ 98{
113 int len; 99 return roccat_common_receive(usb_dev, kone_command_settings, buf,
114 100 sizeof(struct kone_settings));
115 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
116 USB_REQ_CLEAR_FEATURE,
117 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
118 kone_command_settings, 0, buf,
119 sizeof(struct kone_settings), USB_CTRL_SET_TIMEOUT);
120
121 if (len != sizeof(struct kone_settings))
122 return -EIO;
123
124 return 0;
125} 101}
126 102
127/* 103/*
@@ -132,22 +108,12 @@ static int kone_get_settings(struct usb_device *usb_dev,
132static int kone_set_settings(struct usb_device *usb_dev, 108static int kone_set_settings(struct usb_device *usb_dev,
133 struct kone_settings const *settings) 109 struct kone_settings const *settings)
134{ 110{
135 int len; 111 int retval;
136 112 retval = roccat_common_send(usb_dev, kone_command_settings,
137 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 113 settings, sizeof(struct kone_settings));
138 USB_REQ_SET_CONFIGURATION, 114 if (retval)
139 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 115 return retval;
140 kone_command_settings, 0, (char *)settings, 116 return kone_check_write(usb_dev);
141 sizeof(struct kone_settings),
142 USB_CTRL_SET_TIMEOUT);
143
144 if (len != sizeof(struct kone_settings))
145 return -EIO;
146
147 if (kone_check_write(usb_dev))
148 return -EIO;
149
150 return 0;
151} 117}
152 118
153/* 119/*
@@ -193,7 +159,7 @@ static int kone_set_profile(struct usb_device *usb_dev,
193 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 159 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
194 USB_REQ_SET_CONFIGURATION, 160 USB_REQ_SET_CONFIGURATION,
195 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 161 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
196 kone_command_profile, number, (char *)profile, 162 kone_command_profile, number, (void *)profile,
197 sizeof(struct kone_profile), 163 sizeof(struct kone_profile),
198 USB_CTRL_SET_TIMEOUT); 164 USB_CTRL_SET_TIMEOUT);
199 165
@@ -213,24 +179,15 @@ static int kone_set_profile(struct usb_device *usb_dev,
213 */ 179 */
214static int kone_get_weight(struct usb_device *usb_dev, int *result) 180static int kone_get_weight(struct usb_device *usb_dev, int *result)
215{ 181{
216 int len; 182 int retval;
217 uint8_t *data; 183 uint8_t data;
218 184
219 data = kmalloc(1, GFP_KERNEL); 185 retval = roccat_common_receive(usb_dev, kone_command_weight, &data, 1);
220 if (!data)
221 return -ENOMEM;
222 186
223 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 187 if (retval)
224 USB_REQ_CLEAR_FEATURE, 188 return retval;
225 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
226 kone_command_weight, 0, data, 1, USB_CTRL_SET_TIMEOUT);
227 189
228 if (len != 1) { 190 *result = (int)data;
229 kfree(data);
230 return -EIO;
231 }
232 *result = (int)*data;
233 kfree(data);
234 return 0; 191 return 0;
235} 192}
236 193
@@ -241,25 +198,15 @@ static int kone_get_weight(struct usb_device *usb_dev, int *result)
241 */ 198 */
242static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) 199static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
243{ 200{
244 int len; 201 int retval;
245 unsigned char *data; 202 uint16_t data;
246
247 data = kmalloc(2, GFP_KERNEL);
248 if (!data)
249 return -ENOMEM;
250 203
251 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 204 retval = roccat_common_receive(usb_dev, kone_command_firmware_version,
252 USB_REQ_CLEAR_FEATURE, 205 &data, 2);
253 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 206 if (retval)
254 kone_command_firmware_version, 0, data, 2, 207 return retval;
255 USB_CTRL_SET_TIMEOUT);
256 208
257 if (len != 2) { 209 *result = le16_to_cpu(data);
258 kfree(data);
259 return -EIO;
260 }
261 *result = le16_to_cpu(*data);
262 kfree(data);
263 return 0; 210 return 0;
264} 211}
265 212
@@ -435,23 +382,9 @@ static ssize_t kone_sysfs_show_tcu(struct device *dev,
435 382
436static int kone_tcu_command(struct usb_device *usb_dev, int number) 383static int kone_tcu_command(struct usb_device *usb_dev, int number)
437{ 384{
438 int len; 385 unsigned char value;
439 char *value; 386 value = number;
440 387 return roccat_common_send(usb_dev, kone_command_calibrate, &value, 1);
441 value = kmalloc(1, GFP_KERNEL);
442 if (!value)
443 return -ENOMEM;
444
445 *value = number;
446
447 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
448 USB_REQ_SET_CONFIGURATION,
449 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
450 kone_command_calibrate, 0, value, 1,
451 USB_CTRL_SET_TIMEOUT);
452
453 kfree(value);
454 return ((len != 1) ? -EIO : 0);
455} 388}
456 389
457/* 390/*
@@ -727,7 +660,8 @@ static int kone_init_specials(struct hid_device *hdev)
727 goto exit_free; 660 goto exit_free;
728 } 661 }
729 662
730 retval = roccat_connect(kone_class, hdev); 663 retval = roccat_connect(kone_class, hdev,
664 sizeof(struct kone_roccat_report));
731 if (retval < 0) { 665 if (retval < 0) {
732 hid_err(hdev, "couldn't init char dev\n"); 666 hid_err(hdev, "couldn't init char dev\n");
733 /* be tolerant about not getting chrdev */ 667 /* be tolerant about not getting chrdev */
@@ -827,8 +761,7 @@ static void kone_report_to_chrdev(struct kone_device const *kone,
827 roccat_report.value = event->value; 761 roccat_report.value = event->value;
828 roccat_report.key = 0; 762 roccat_report.key = 0;
829 roccat_report_event(kone->chrdev_minor, 763 roccat_report_event(kone->chrdev_minor,
830 (uint8_t *)&roccat_report, 764 (uint8_t *)&roccat_report);
831 sizeof(struct kone_roccat_report));
832 break; 765 break;
833 case kone_mouse_event_call_overlong_macro: 766 case kone_mouse_event_call_overlong_macro:
834 if (event->value == kone_keystroke_action_press) { 767 if (event->value == kone_keystroke_action_press) {
@@ -836,8 +769,7 @@ static void kone_report_to_chrdev(struct kone_device const *kone,
836 roccat_report.value = kone->actual_profile; 769 roccat_report.value = kone->actual_profile;
837 roccat_report.key = event->macro_key; 770 roccat_report.key = event->macro_key;
838 roccat_report_event(kone->chrdev_minor, 771 roccat_report_event(kone->chrdev_minor,
839 (uint8_t *)&roccat_report, 772 (uint8_t *)&roccat_report);
840 sizeof(struct kone_roccat_report));
841 } 773 }
842 break; 774 break;
843 } 775 }
@@ -912,8 +844,8 @@ static int __init kone_init(void)
912 844
913static void __exit kone_exit(void) 845static void __exit kone_exit(void)
914{ 846{
915 class_destroy(kone_class);
916 hid_unregister_driver(&kone_driver); 847 hid_unregister_driver(&kone_driver);
848 class_destroy(kone_class);
917} 849}
918 850
919module_init(kone_init); 851module_init(kone_init);
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
index 1608c8d1efd6..33eec74e0615 100644
--- a/drivers/hid/hid-roccat-koneplus.c
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -19,11 +19,11 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/input.h> 20#include <linux/input.h>
21#include <linux/hid.h> 21#include <linux/hid.h>
22#include <linux/usb.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/hid-roccat.h>
25#include "hid-ids.h" 25#include "hid-ids.h"
26#include "hid-roccat.h" 26#include "hid-roccat-common.h"
27#include "hid-roccat-koneplus.h" 27#include "hid-roccat-koneplus.h"
28 28
29static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 29static uint profile_numbers[5] = {0, 1, 2, 3, 4};
@@ -39,110 +39,63 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus,
39static int koneplus_send_control(struct usb_device *usb_dev, uint value, 39static int koneplus_send_control(struct usb_device *usb_dev, uint value,
40 enum koneplus_control_requests request) 40 enum koneplus_control_requests request)
41{ 41{
42 int len; 42 struct koneplus_control control;
43 struct koneplus_control *control;
44 43
45 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || 44 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
46 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && 45 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
47 value > 4) 46 value > 4)
48 return -EINVAL; 47 return -EINVAL;
49 48
50 control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL); 49 control.command = KONEPLUS_COMMAND_CONTROL;
51 if (!control) 50 control.value = value;
52 return -ENOMEM; 51 control.request = request;
53 52
54 control->command = KONEPLUS_COMMAND_CONTROL; 53 return roccat_common_send(usb_dev, KONEPLUS_USB_COMMAND_CONTROL,
55 control->value = value; 54 &control, sizeof(struct koneplus_control));
56 control->request = request;
57
58 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
59 USB_REQ_SET_CONFIGURATION,
60 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
61 KONEPLUS_USB_COMMAND_CONTROL, 0, control,
62 sizeof(struct koneplus_control),
63 USB_CTRL_SET_TIMEOUT);
64
65 kfree(control);
66
67 if (len != sizeof(struct koneplus_control))
68 return len;
69
70 return 0;
71}
72
73static int koneplus_receive(struct usb_device *usb_dev, uint usb_command,
74 void *buf, uint size) {
75 int len;
76
77 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
78 USB_REQ_CLEAR_FEATURE,
79 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
80 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
81
82 return (len != size) ? -EIO : 0;
83} 55}
84 56
85static int koneplus_receive_control_status(struct usb_device *usb_dev) 57static int koneplus_receive_control_status(struct usb_device *usb_dev)
86{ 58{
87 int retval; 59 int retval;
88 struct koneplus_control *control; 60 struct koneplus_control control;
89
90 control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL);
91 if (!control)
92 return -ENOMEM;
93 61
94 do { 62 do {
95 retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL, 63 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL,
96 control, sizeof(struct koneplus_control)); 64 &control, sizeof(struct koneplus_control));
97 65
98 /* check if we get a completely wrong answer */ 66 /* check if we get a completely wrong answer */
99 if (retval) 67 if (retval)
100 goto out; 68 return retval;
101 69
102 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OK) { 70 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK)
103 retval = 0; 71 return 0;
104 goto out;
105 }
106 72
107 /* indicates that hardware needs some more time to complete action */ 73 /* indicates that hardware needs some more time to complete action */
108 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) { 74 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) {
109 msleep(500); /* windows driver uses 1000 */ 75 msleep(500); /* windows driver uses 1000 */
110 continue; 76 continue;
111 } 77 }
112 78
113 /* seems to be critical - replug necessary */ 79 /* seems to be critical - replug necessary */
114 if (control->value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) { 80 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
115 retval = -EINVAL; 81 return -EINVAL;
116 goto out;
117 }
118
119 dev_err(&usb_dev->dev, "koneplus_receive_control_status: "
120 "unknown response value 0x%x\n", control->value);
121 retval = -EINVAL;
122 goto out;
123 82
83 hid_err(usb_dev, "koneplus_receive_control_status: "
84 "unknown response value 0x%x\n", control.value);
85 return -EINVAL;
124 } while (1); 86 } while (1);
125out:
126 kfree(control);
127 return retval;
128} 87}
129 88
130static int koneplus_send(struct usb_device *usb_dev, uint command, 89static int koneplus_send(struct usb_device *usb_dev, uint command,
131 void *buf, uint size) { 90 void const *buf, uint size)
132 int len; 91{
133 92 int retval;
134 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
135 USB_REQ_SET_CONFIGURATION,
136 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
137 command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
138
139 if (len != size)
140 return -EIO;
141 93
142 if (koneplus_receive_control_status(usb_dev)) 94 retval = roccat_common_send(usb_dev, command, buf, size);
143 return -EIO; 95 if (retval)
96 return retval;
144 97
145 return 0; 98 return koneplus_receive_control_status(usb_dev);
146} 99}
147 100
148static int koneplus_select_profile(struct usb_device *usb_dev, uint number, 101static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
@@ -167,7 +120,7 @@ static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
167static int koneplus_get_info(struct usb_device *usb_dev, 120static int koneplus_get_info(struct usb_device *usb_dev,
168 struct koneplus_info *buf) 121 struct koneplus_info *buf)
169{ 122{
170 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO, 123 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO,
171 buf, sizeof(struct koneplus_info)); 124 buf, sizeof(struct koneplus_info));
172} 125}
173 126
@@ -181,7 +134,7 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
181 if (retval) 134 if (retval)
182 return retval; 135 return retval;
183 136
184 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 137 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
185 buf, sizeof(struct koneplus_profile_settings)); 138 buf, sizeof(struct koneplus_profile_settings));
186} 139}
187 140
@@ -189,7 +142,7 @@ static int koneplus_set_profile_settings(struct usb_device *usb_dev,
189 struct koneplus_profile_settings const *settings) 142 struct koneplus_profile_settings const *settings)
190{ 143{
191 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 144 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS,
192 (void *)settings, sizeof(struct koneplus_profile_settings)); 145 settings, sizeof(struct koneplus_profile_settings));
193} 146}
194 147
195static int koneplus_get_profile_buttons(struct usb_device *usb_dev, 148static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
@@ -202,7 +155,7 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
202 if (retval) 155 if (retval)
203 return retval; 156 return retval;
204 157
205 return koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 158 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
206 buf, sizeof(struct koneplus_profile_buttons)); 159 buf, sizeof(struct koneplus_profile_buttons));
207} 160}
208 161
@@ -210,27 +163,19 @@ static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
210 struct koneplus_profile_buttons const *buttons) 163 struct koneplus_profile_buttons const *buttons)
211{ 164{
212 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 165 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS,
213 (void *)buttons, sizeof(struct koneplus_profile_buttons)); 166 buttons, sizeof(struct koneplus_profile_buttons));
214} 167}
215 168
216/* retval is 0-4 on success, < 0 on error */ 169/* retval is 0-4 on success, < 0 on error */
217static int koneplus_get_startup_profile(struct usb_device *usb_dev) 170static int koneplus_get_startup_profile(struct usb_device *usb_dev)
218{ 171{
219 struct koneplus_startup_profile *buf; 172 struct koneplus_startup_profile buf;
220 int retval; 173 int retval;
221 174
222 buf = kmalloc(sizeof(struct koneplus_startup_profile), GFP_KERNEL); 175 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
176 &buf, sizeof(struct koneplus_startup_profile));
223 177
224 retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, 178 return retval ? retval : buf.startup_profile;
225 buf, sizeof(struct koneplus_startup_profile));
226
227 if (retval)
228 goto out;
229
230 retval = buf->startup_profile;
231out:
232 kfree(buf);
233 return retval;
234} 179}
235 180
236static int koneplus_set_startup_profile(struct usb_device *usb_dev, 181static int koneplus_set_startup_profile(struct usb_device *usb_dev,
@@ -243,7 +188,7 @@ static int koneplus_set_startup_profile(struct usb_device *usb_dev,
243 buf.startup_profile = startup_profile; 188 buf.startup_profile = startup_profile;
244 189
245 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, 190 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
246 (char *)&buf, sizeof(struct koneplus_profile_buttons)); 191 &buf, sizeof(struct koneplus_profile_buttons));
247} 192}
248 193
249static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, 194static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
@@ -256,11 +201,14 @@ static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
256 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 201 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
257 int retval; 202 int retval;
258 203
204 if (off >= real_size)
205 return 0;
206
259 if (off != 0 || count != real_size) 207 if (off != 0 || count != real_size)
260 return -EINVAL; 208 return -EINVAL;
261 209
262 mutex_lock(&koneplus->koneplus_lock); 210 mutex_lock(&koneplus->koneplus_lock);
263 retval = koneplus_receive(usb_dev, command, buf, real_size); 211 retval = roccat_common_receive(usb_dev, command, buf, real_size);
264 mutex_unlock(&koneplus->koneplus_lock); 212 mutex_unlock(&koneplus->koneplus_lock);
265 213
266 if (retval) 214 if (retval)
@@ -283,7 +231,7 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
283 return -EINVAL; 231 return -EINVAL;
284 232
285 mutex_lock(&koneplus->koneplus_lock); 233 mutex_lock(&koneplus->koneplus_lock);
286 retval = koneplus_send(usb_dev, command, (void *)buf, real_size); 234 retval = koneplus_send(usb_dev, command, buf, real_size);
287 mutex_unlock(&koneplus->koneplus_lock); 235 mutex_unlock(&koneplus->koneplus_lock);
288 236
289 if (retval) 237 if (retval)
@@ -347,7 +295,7 @@ static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
347 count = sizeof(struct koneplus_profile_settings) - off; 295 count = sizeof(struct koneplus_profile_settings) - off;
348 296
349 mutex_lock(&koneplus->koneplus_lock); 297 mutex_lock(&koneplus->koneplus_lock);
350 memcpy(buf, ((void const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, 298 memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off,
351 count); 299 count);
352 mutex_unlock(&koneplus->koneplus_lock); 300 mutex_unlock(&koneplus->koneplus_lock);
353 301
@@ -406,7 +354,7 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp,
406 count = sizeof(struct koneplus_profile_buttons) - off; 354 count = sizeof(struct koneplus_profile_buttons) - off;
407 355
408 mutex_lock(&koneplus->koneplus_lock); 356 mutex_lock(&koneplus->koneplus_lock);
409 memcpy(buf, ((void const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, 357 memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off,
410 count); 358 count);
411 mutex_unlock(&koneplus->koneplus_lock); 359 mutex_unlock(&koneplus->koneplus_lock);
412 360
@@ -512,7 +460,7 @@ static struct device_attribute koneplus_attributes[] = {
512 460
513static struct bin_attribute koneplus_bin_attributes[] = { 461static struct bin_attribute koneplus_bin_attributes[] = {
514 { 462 {
515 .attr = { .name = "sensor", .mode = 0220 }, 463 .attr = { .name = "sensor", .mode = 0660 },
516 .size = sizeof(struct koneplus_sensor), 464 .size = sizeof(struct koneplus_sensor),
517 .read = koneplus_sysfs_read_sensor, 465 .read = koneplus_sysfs_read_sensor,
518 .write = koneplus_sysfs_write_sensor 466 .write = koneplus_sysfs_write_sensor
@@ -609,11 +557,13 @@ static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev,
609 struct koneplus_device *koneplus) 557 struct koneplus_device *koneplus)
610{ 558{
611 int retval, i; 559 int retval, i;
612 static uint wait = 70; /* device will freeze with just 60 */ 560 static uint wait = 100; /* device will freeze with just 60 */
613 561
614 mutex_init(&koneplus->koneplus_lock); 562 mutex_init(&koneplus->koneplus_lock);
615 563
616 koneplus->startup_profile = koneplus_get_startup_profile(usb_dev); 564 koneplus->startup_profile = koneplus_get_startup_profile(usb_dev);
565 if (koneplus->startup_profile < 0)
566 return koneplus->startup_profile;
617 567
618 msleep(wait); 568 msleep(wait);
619 retval = koneplus_get_info(usb_dev, &koneplus->info); 569 retval = koneplus_get_info(usb_dev, &koneplus->info);
@@ -651,21 +601,21 @@ static int koneplus_init_specials(struct hid_device *hdev)
651 601
652 koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL); 602 koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL);
653 if (!koneplus) { 603 if (!koneplus) {
654 dev_err(&hdev->dev, "can't alloc device descriptor\n"); 604 hid_err(hdev, "can't alloc device descriptor\n");
655 return -ENOMEM; 605 return -ENOMEM;
656 } 606 }
657 hid_set_drvdata(hdev, koneplus); 607 hid_set_drvdata(hdev, koneplus);
658 608
659 retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus); 609 retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus);
660 if (retval) { 610 if (retval) {
661 dev_err(&hdev->dev, 611 hid_err(hdev, "couldn't init struct koneplus_device\n");
662 "couldn't init struct koneplus_device\n");
663 goto exit_free; 612 goto exit_free;
664 } 613 }
665 614
666 retval = roccat_connect(koneplus_class, hdev); 615 retval = roccat_connect(koneplus_class, hdev,
616 sizeof(struct koneplus_roccat_report));
667 if (retval < 0) { 617 if (retval < 0) {
668 dev_err(&hdev->dev, "couldn't init char dev\n"); 618 hid_err(hdev, "couldn't init char dev\n");
669 } else { 619 } else {
670 koneplus->chrdev_minor = retval; 620 koneplus->chrdev_minor = retval;
671 koneplus->roccat_claimed = 1; 621 koneplus->roccat_claimed = 1;
@@ -701,19 +651,19 @@ static int koneplus_probe(struct hid_device *hdev,
701 651
702 retval = hid_parse(hdev); 652 retval = hid_parse(hdev);
703 if (retval) { 653 if (retval) {
704 dev_err(&hdev->dev, "parse failed\n"); 654 hid_err(hdev, "parse failed\n");
705 goto exit; 655 goto exit;
706 } 656 }
707 657
708 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 658 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
709 if (retval) { 659 if (retval) {
710 dev_err(&hdev->dev, "hw start failed\n"); 660 hid_err(hdev, "hw start failed\n");
711 goto exit; 661 goto exit;
712 } 662 }
713 663
714 retval = koneplus_init_specials(hdev); 664 retval = koneplus_init_specials(hdev);
715 if (retval) { 665 if (retval) {
716 dev_err(&hdev->dev, "couldn't install mouse\n"); 666 hid_err(hdev, "couldn't install mouse\n");
717 goto exit_stop; 667 goto exit_stop;
718 } 668 }
719 669
@@ -769,8 +719,7 @@ static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus,
769 roccat_report.data2 = button_report->data2; 719 roccat_report.data2 = button_report->data2;
770 roccat_report.profile = koneplus->actual_profile + 1; 720 roccat_report.profile = koneplus->actual_profile + 1;
771 roccat_report_event(koneplus->chrdev_minor, 721 roccat_report_event(koneplus->chrdev_minor,
772 (uint8_t const *)&roccat_report, 722 (uint8_t const *)&roccat_report);
773 sizeof(struct koneplus_roccat_report));
774} 723}
775 724
776static int koneplus_raw_event(struct hid_device *hdev, 725static int koneplus_raw_event(struct hid_device *hdev,
@@ -825,8 +774,8 @@ static int __init koneplus_init(void)
825 774
826static void __exit koneplus_exit(void) 775static void __exit koneplus_exit(void)
827{ 776{
828 class_destroy(koneplus_class);
829 hid_unregister_driver(&koneplus_driver); 777 hid_unregister_driver(&koneplus_driver);
778 class_destroy(koneplus_class);
830} 779}
831 780
832module_init(koneplus_init); 781module_init(koneplus_init);
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
new file mode 100644
index 000000000000..984be2f8967e
--- /dev/null
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -0,0 +1,715 @@
1/*
2 * Roccat Kova[+] driver for Linux
3 *
4 * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14/*
15 * Roccat Kova[+] is a bigger version of the Pyra with two more side buttons.
16 */
17
18#include <linux/device.h>
19#include <linux/input.h>
20#include <linux/hid.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/hid-roccat.h>
24#include "hid-ids.h"
25#include "hid-roccat-common.h"
26#include "hid-roccat-kovaplus.h"
27
28static uint profile_numbers[5] = {0, 1, 2, 3, 4};
29
30static struct class *kovaplus_class;
31
32static uint kovaplus_convert_event_cpi(uint value)
33{
34 return (value == 7 ? 4 : (value == 4 ? 3 : value));
35}
36
37static void kovaplus_profile_activated(struct kovaplus_device *kovaplus,
38 uint new_profile_index)
39{
40 kovaplus->actual_profile = new_profile_index;
41 kovaplus->actual_cpi = kovaplus->profile_settings[new_profile_index].cpi_startup_level;
42 kovaplus->actual_x_sensitivity = kovaplus->profile_settings[new_profile_index].sensitivity_x;
43 kovaplus->actual_y_sensitivity = kovaplus->profile_settings[new_profile_index].sensitivity_y;
44}
45
46static int kovaplus_send_control(struct usb_device *usb_dev, uint value,
47 enum kovaplus_control_requests request)
48{
49 int retval;
50 struct kovaplus_control control;
51
52 if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
53 request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
54 value > 4)
55 return -EINVAL;
56
57 control.command = KOVAPLUS_COMMAND_CONTROL;
58 control.value = value;
59 control.request = request;
60
61 retval = roccat_common_send(usb_dev, KOVAPLUS_USB_COMMAND_CONTROL,
62 &control, sizeof(struct kovaplus_control));
63
64 return retval;
65}
66
67static int kovaplus_receive_control_status(struct usb_device *usb_dev)
68{
69 int retval;
70 struct kovaplus_control control;
71
72 do {
73 retval = roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_CONTROL,
74 &control, sizeof(struct kovaplus_control));
75
76 /* check if we get a completely wrong answer */
77 if (retval)
78 return retval;
79
80 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OK)
81 return 0;
82
83 /* indicates that hardware needs some more time to complete action */
84 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT) {
85 msleep(500); /* windows driver uses 1000 */
86 continue;
87 }
88
89 /* seems to be critical - replug necessary */
90 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
91 return -EINVAL;
92
93 hid_err(usb_dev, "kovaplus_receive_control_status: "
94 "unknown response value 0x%x\n", control.value);
95 return -EINVAL;
96 } while (1);
97}
98
99static int kovaplus_send(struct usb_device *usb_dev, uint command,
100 void const *buf, uint size)
101{
102 int retval;
103
104 retval = roccat_common_send(usb_dev, command, buf, size);
105 if (retval)
106 return retval;
107
108 msleep(100);
109
110 return kovaplus_receive_control_status(usb_dev);
111}
112
113static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
114 enum kovaplus_control_requests request)
115{
116 return kovaplus_send_control(usb_dev, number, request);
117}
118
119static int kovaplus_get_info(struct usb_device *usb_dev,
120 struct kovaplus_info *buf)
121{
122 return roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_INFO,
123 buf, sizeof(struct kovaplus_info));
124}
125
126static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
127 struct kovaplus_profile_settings *buf, uint number)
128{
129 int retval;
130
131 retval = kovaplus_select_profile(usb_dev, number,
132 KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
133 if (retval)
134 return retval;
135
136 return roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_SETTINGS,
137 buf, sizeof(struct kovaplus_profile_settings));
138}
139
140static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
141 struct kovaplus_profile_settings const *settings)
142{
143 return kovaplus_send(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_SETTINGS,
144 settings, sizeof(struct kovaplus_profile_settings));
145}
146
147static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
148 struct kovaplus_profile_buttons *buf, int number)
149{
150 int retval;
151
152 retval = kovaplus_select_profile(usb_dev, number,
153 KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
154 if (retval)
155 return retval;
156
157 return roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_BUTTONS,
158 buf, sizeof(struct kovaplus_profile_buttons));
159}
160
161static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
162 struct kovaplus_profile_buttons const *buttons)
163{
164 return kovaplus_send(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_BUTTONS,
165 buttons, sizeof(struct kovaplus_profile_buttons));
166}
167
168/* retval is 0-4 on success, < 0 on error */
169static int kovaplus_get_actual_profile(struct usb_device *usb_dev)
170{
171 struct kovaplus_actual_profile buf;
172 int retval;
173
174 retval = roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_ACTUAL_PROFILE,
175 &buf, sizeof(struct kovaplus_actual_profile));
176
177 return retval ? retval : buf.actual_profile;
178}
179
180static int kovaplus_set_actual_profile(struct usb_device *usb_dev,
181 int new_profile)
182{
183 struct kovaplus_actual_profile buf;
184
185 buf.command = KOVAPLUS_COMMAND_ACTUAL_PROFILE;
186 buf.size = sizeof(struct kovaplus_actual_profile);
187 buf.actual_profile = new_profile;
188
189 return kovaplus_send(usb_dev, KOVAPLUS_USB_COMMAND_ACTUAL_PROFILE,
190 &buf, sizeof(struct kovaplus_actual_profile));
191}
192
193static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp,
194 struct kobject *kobj, struct bin_attribute *attr, char *buf,
195 loff_t off, size_t count)
196{
197 struct device *dev =
198 container_of(kobj, struct device, kobj)->parent->parent;
199 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
200
201 if (off >= sizeof(struct kovaplus_profile_settings))
202 return 0;
203
204 if (off + count > sizeof(struct kovaplus_profile_settings))
205 count = sizeof(struct kovaplus_profile_settings) - off;
206
207 mutex_lock(&kovaplus->kovaplus_lock);
208 memcpy(buf, ((char const *)&kovaplus->profile_settings[*(uint *)(attr->private)]) + off,
209 count);
210 mutex_unlock(&kovaplus->kovaplus_lock);
211
212 return count;
213}
214
215static ssize_t kovaplus_sysfs_write_profile_settings(struct file *fp,
216 struct kobject *kobj, struct bin_attribute *attr, char *buf,
217 loff_t off, size_t count)
218{
219 struct device *dev =
220 container_of(kobj, struct device, kobj)->parent->parent;
221 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
222 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
223 int retval = 0;
224 int difference;
225 int profile_index;
226 struct kovaplus_profile_settings *profile_settings;
227
228 if (off != 0 || count != sizeof(struct kovaplus_profile_settings))
229 return -EINVAL;
230
231 profile_index = ((struct kovaplus_profile_settings const *)buf)->profile_index;
232 profile_settings = &kovaplus->profile_settings[profile_index];
233
234 mutex_lock(&kovaplus->kovaplus_lock);
235 difference = memcmp(buf, profile_settings,
236 sizeof(struct kovaplus_profile_settings));
237 if (difference) {
238 retval = kovaplus_set_profile_settings(usb_dev,
239 (struct kovaplus_profile_settings const *)buf);
240 if (!retval)
241 memcpy(profile_settings, buf,
242 sizeof(struct kovaplus_profile_settings));
243 }
244 mutex_unlock(&kovaplus->kovaplus_lock);
245
246 if (retval)
247 return retval;
248
249 return sizeof(struct kovaplus_profile_settings);
250}
251
252static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp,
253 struct kobject *kobj, struct bin_attribute *attr, char *buf,
254 loff_t off, size_t count)
255{
256 struct device *dev =
257 container_of(kobj, struct device, kobj)->parent->parent;
258 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
259
260 if (off >= sizeof(struct kovaplus_profile_buttons))
261 return 0;
262
263 if (off + count > sizeof(struct kovaplus_profile_buttons))
264 count = sizeof(struct kovaplus_profile_buttons) - off;
265
266 mutex_lock(&kovaplus->kovaplus_lock);
267 memcpy(buf, ((char const *)&kovaplus->profile_buttons[*(uint *)(attr->private)]) + off,
268 count);
269 mutex_unlock(&kovaplus->kovaplus_lock);
270
271 return count;
272}
273
274static ssize_t kovaplus_sysfs_write_profile_buttons(struct file *fp,
275 struct kobject *kobj, struct bin_attribute *attr, char *buf,
276 loff_t off, size_t count)
277{
278 struct device *dev =
279 container_of(kobj, struct device, kobj)->parent->parent;
280 struct kovaplus_device *kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
281 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
282 int retval = 0;
283 int difference;
284 uint profile_index;
285 struct kovaplus_profile_buttons *profile_buttons;
286
287 if (off != 0 || count != sizeof(struct kovaplus_profile_buttons))
288 return -EINVAL;
289
290 profile_index = ((struct kovaplus_profile_buttons const *)buf)->profile_index;
291 profile_buttons = &kovaplus->profile_buttons[profile_index];
292
293 mutex_lock(&kovaplus->kovaplus_lock);
294 difference = memcmp(buf, profile_buttons,
295 sizeof(struct kovaplus_profile_buttons));
296 if (difference) {
297 retval = kovaplus_set_profile_buttons(usb_dev,
298 (struct kovaplus_profile_buttons const *)buf);
299 if (!retval)
300 memcpy(profile_buttons, buf,
301 sizeof(struct kovaplus_profile_buttons));
302 }
303 mutex_unlock(&kovaplus->kovaplus_lock);
304
305 if (retval)
306 return retval;
307
308 return sizeof(struct kovaplus_profile_buttons);
309}
310
311static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev,
312 struct device_attribute *attr, char *buf)
313{
314 struct kovaplus_device *kovaplus =
315 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
316 return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_profile);
317}
318
319static ssize_t kovaplus_sysfs_set_actual_profile(struct device *dev,
320 struct device_attribute *attr, char const *buf, size_t size)
321{
322 struct kovaplus_device *kovaplus;
323 struct usb_device *usb_dev;
324 unsigned long profile;
325 int retval;
326
327 dev = dev->parent->parent;
328 kovaplus = hid_get_drvdata(dev_get_drvdata(dev));
329 usb_dev = interface_to_usbdev(to_usb_interface(dev));
330
331 retval = strict_strtoul(buf, 10, &profile);
332 if (retval)
333 return retval;
334
335 if (profile >= 5)
336 return -EINVAL;
337
338 mutex_lock(&kovaplus->kovaplus_lock);
339 retval = kovaplus_set_actual_profile(usb_dev, profile);
340 kovaplus->actual_profile = profile;
341 mutex_unlock(&kovaplus->kovaplus_lock);
342 if (retval)
343 return retval;
344
345 return size;
346}
347
348static ssize_t kovaplus_sysfs_show_actual_cpi(struct device *dev,
349 struct device_attribute *attr, char *buf)
350{
351 struct kovaplus_device *kovaplus =
352 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
353 return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_cpi);
354}
355
356static ssize_t kovaplus_sysfs_show_actual_sensitivity_x(struct device *dev,
357 struct device_attribute *attr, char *buf)
358{
359 struct kovaplus_device *kovaplus =
360 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
361 return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_x_sensitivity);
362}
363
364static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev,
365 struct device_attribute *attr, char *buf)
366{
367 struct kovaplus_device *kovaplus =
368 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
369 return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_y_sensitivity);
370}
371
372static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev,
373 struct device_attribute *attr, char *buf)
374{
375 struct kovaplus_device *kovaplus =
376 hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
377 return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->info.firmware_version);
378}
379
380static struct device_attribute kovaplus_attributes[] = {
381 __ATTR(actual_cpi, 0440,
382 kovaplus_sysfs_show_actual_cpi, NULL),
383 __ATTR(firmware_version, 0440,
384 kovaplus_sysfs_show_firmware_version, NULL),
385 __ATTR(actual_profile, 0660,
386 kovaplus_sysfs_show_actual_profile,
387 kovaplus_sysfs_set_actual_profile),
388 __ATTR(actual_sensitivity_x, 0440,
389 kovaplus_sysfs_show_actual_sensitivity_x, NULL),
390 __ATTR(actual_sensitivity_y, 0440,
391 kovaplus_sysfs_show_actual_sensitivity_y, NULL),
392 __ATTR_NULL
393};
394
395static struct bin_attribute kovaplus_bin_attributes[] = {
396 {
397 .attr = { .name = "profile_settings", .mode = 0220 },
398 .size = sizeof(struct kovaplus_profile_settings),
399 .write = kovaplus_sysfs_write_profile_settings
400 },
401 {
402 .attr = { .name = "profile1_settings", .mode = 0440 },
403 .size = sizeof(struct kovaplus_profile_settings),
404 .read = kovaplus_sysfs_read_profilex_settings,
405 .private = &profile_numbers[0]
406 },
407 {
408 .attr = { .name = "profile2_settings", .mode = 0440 },
409 .size = sizeof(struct kovaplus_profile_settings),
410 .read = kovaplus_sysfs_read_profilex_settings,
411 .private = &profile_numbers[1]
412 },
413 {
414 .attr = { .name = "profile3_settings", .mode = 0440 },
415 .size = sizeof(struct kovaplus_profile_settings),
416 .read = kovaplus_sysfs_read_profilex_settings,
417 .private = &profile_numbers[2]
418 },
419 {
420 .attr = { .name = "profile4_settings", .mode = 0440 },
421 .size = sizeof(struct kovaplus_profile_settings),
422 .read = kovaplus_sysfs_read_profilex_settings,
423 .private = &profile_numbers[3]
424 },
425 {
426 .attr = { .name = "profile5_settings", .mode = 0440 },
427 .size = sizeof(struct kovaplus_profile_settings),
428 .read = kovaplus_sysfs_read_profilex_settings,
429 .private = &profile_numbers[4]
430 },
431 {
432 .attr = { .name = "profile_buttons", .mode = 0220 },
433 .size = sizeof(struct kovaplus_profile_buttons),
434 .write = kovaplus_sysfs_write_profile_buttons
435 },
436 {
437 .attr = { .name = "profile1_buttons", .mode = 0440 },
438 .size = sizeof(struct kovaplus_profile_buttons),
439 .read = kovaplus_sysfs_read_profilex_buttons,
440 .private = &profile_numbers[0]
441 },
442 {
443 .attr = { .name = "profile2_buttons", .mode = 0440 },
444 .size = sizeof(struct kovaplus_profile_buttons),
445 .read = kovaplus_sysfs_read_profilex_buttons,
446 .private = &profile_numbers[1]
447 },
448 {
449 .attr = { .name = "profile3_buttons", .mode = 0440 },
450 .size = sizeof(struct kovaplus_profile_buttons),
451 .read = kovaplus_sysfs_read_profilex_buttons,
452 .private = &profile_numbers[2]
453 },
454 {
455 .attr = { .name = "profile4_buttons", .mode = 0440 },
456 .size = sizeof(struct kovaplus_profile_buttons),
457 .read = kovaplus_sysfs_read_profilex_buttons,
458 .private = &profile_numbers[3]
459 },
460 {
461 .attr = { .name = "profile5_buttons", .mode = 0440 },
462 .size = sizeof(struct kovaplus_profile_buttons),
463 .read = kovaplus_sysfs_read_profilex_buttons,
464 .private = &profile_numbers[4]
465 },
466 __ATTR_NULL
467};
468
469static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev,
470 struct kovaplus_device *kovaplus)
471{
472 int retval, i;
473 static uint wait = 70; /* device will freeze with just 60 */
474
475 mutex_init(&kovaplus->kovaplus_lock);
476
477 retval = kovaplus_get_info(usb_dev, &kovaplus->info);
478 if (retval)
479 return retval;
480
481 for (i = 0; i < 5; ++i) {
482 msleep(wait);
483 retval = kovaplus_get_profile_settings(usb_dev,
484 &kovaplus->profile_settings[i], i);
485 if (retval)
486 return retval;
487
488 msleep(wait);
489 retval = kovaplus_get_profile_buttons(usb_dev,
490 &kovaplus->profile_buttons[i], i);
491 if (retval)
492 return retval;
493 }
494
495 msleep(wait);
496 retval = kovaplus_get_actual_profile(usb_dev);
497 if (retval < 0)
498 return retval;
499 kovaplus_profile_activated(kovaplus, retval);
500
501 return 0;
502}
503
504static int kovaplus_init_specials(struct hid_device *hdev)
505{
506 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
507 struct usb_device *usb_dev = interface_to_usbdev(intf);
508 struct kovaplus_device *kovaplus;
509 int retval;
510
511 if (intf->cur_altsetting->desc.bInterfaceProtocol
512 == USB_INTERFACE_PROTOCOL_MOUSE) {
513
514 kovaplus = kzalloc(sizeof(*kovaplus), GFP_KERNEL);
515 if (!kovaplus) {
516 hid_err(hdev, "can't alloc device descriptor\n");
517 return -ENOMEM;
518 }
519 hid_set_drvdata(hdev, kovaplus);
520
521 retval = kovaplus_init_kovaplus_device_struct(usb_dev, kovaplus);
522 if (retval) {
523 hid_err(hdev, "couldn't init struct kovaplus_device\n");
524 goto exit_free;
525 }
526
527 retval = roccat_connect(kovaplus_class, hdev,
528 sizeof(struct kovaplus_roccat_report));
529 if (retval < 0) {
530 hid_err(hdev, "couldn't init char dev\n");
531 } else {
532 kovaplus->chrdev_minor = retval;
533 kovaplus->roccat_claimed = 1;
534 }
535
536 } else {
537 hid_set_drvdata(hdev, NULL);
538 }
539
540 return 0;
541exit_free:
542 kfree(kovaplus);
543 return retval;
544}
545
546static void kovaplus_remove_specials(struct hid_device *hdev)
547{
548 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
549 struct kovaplus_device *kovaplus;
550
551 if (intf->cur_altsetting->desc.bInterfaceProtocol
552 == USB_INTERFACE_PROTOCOL_MOUSE) {
553 kovaplus = hid_get_drvdata(hdev);
554 if (kovaplus->roccat_claimed)
555 roccat_disconnect(kovaplus->chrdev_minor);
556 kfree(kovaplus);
557 }
558}
559
560static int kovaplus_probe(struct hid_device *hdev,
561 const struct hid_device_id *id)
562{
563 int retval;
564
565 retval = hid_parse(hdev);
566 if (retval) {
567 hid_err(hdev, "parse failed\n");
568 goto exit;
569 }
570
571 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
572 if (retval) {
573 hid_err(hdev, "hw start failed\n");
574 goto exit;
575 }
576
577 retval = kovaplus_init_specials(hdev);
578 if (retval) {
579 hid_err(hdev, "couldn't install mouse\n");
580 goto exit_stop;
581 }
582
583 return 0;
584
585exit_stop:
586 hid_hw_stop(hdev);
587exit:
588 return retval;
589}
590
591static void kovaplus_remove(struct hid_device *hdev)
592{
593 kovaplus_remove_specials(hdev);
594 hid_hw_stop(hdev);
595}
596
597static void kovaplus_keep_values_up_to_date(struct kovaplus_device *kovaplus,
598 u8 const *data)
599{
600 struct kovaplus_mouse_report_button const *button_report;
601
602 if (data[0] != KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON)
603 return;
604
605 button_report = (struct kovaplus_mouse_report_button const *)data;
606
607 switch (button_report->type) {
608 case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_1:
609 kovaplus_profile_activated(kovaplus, button_report->data1 - 1);
610 break;
611 case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI:
612 kovaplus->actual_cpi = kovaplus_convert_event_cpi(button_report->data1);
613 case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY:
614 kovaplus->actual_x_sensitivity = button_report->data1;
615 kovaplus->actual_y_sensitivity = button_report->data2;
616 }
617}
618
619static void kovaplus_report_to_chrdev(struct kovaplus_device const *kovaplus,
620 u8 const *data)
621{
622 struct kovaplus_roccat_report roccat_report;
623 struct kovaplus_mouse_report_button const *button_report;
624
625 if (data[0] != KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON)
626 return;
627
628 button_report = (struct kovaplus_mouse_report_button const *)data;
629
630 if (button_report->type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_2)
631 return;
632
633 roccat_report.type = button_report->type;
634 roccat_report.profile = kovaplus->actual_profile + 1;
635
636 if (roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_MACRO ||
637 roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SHORTCUT ||
638 roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH ||
639 roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER)
640 roccat_report.button = button_report->data1;
641 else
642 roccat_report.button = 0;
643
644 if (roccat_report.type == KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI)
645 roccat_report.data1 = kovaplus_convert_event_cpi(button_report->data1);
646 else
647 roccat_report.data1 = button_report->data1;
648
649 roccat_report.data2 = button_report->data2;
650
651 roccat_report_event(kovaplus->chrdev_minor,
652 (uint8_t const *)&roccat_report);
653}
654
655static int kovaplus_raw_event(struct hid_device *hdev,
656 struct hid_report *report, u8 *data, int size)
657{
658 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
659 struct kovaplus_device *kovaplus = hid_get_drvdata(hdev);
660
661 if (intf->cur_altsetting->desc.bInterfaceProtocol
662 != USB_INTERFACE_PROTOCOL_MOUSE)
663 return 0;
664
665 kovaplus_keep_values_up_to_date(kovaplus, data);
666
667 if (kovaplus->roccat_claimed)
668 kovaplus_report_to_chrdev(kovaplus, data);
669
670 return 0;
671}
672
673static const struct hid_device_id kovaplus_devices[] = {
674 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
675 { }
676};
677
678MODULE_DEVICE_TABLE(hid, kovaplus_devices);
679
680static struct hid_driver kovaplus_driver = {
681 .name = "kovaplus",
682 .id_table = kovaplus_devices,
683 .probe = kovaplus_probe,
684 .remove = kovaplus_remove,
685 .raw_event = kovaplus_raw_event
686};
687
688static int __init kovaplus_init(void)
689{
690 int retval;
691
692 kovaplus_class = class_create(THIS_MODULE, "kovaplus");
693 if (IS_ERR(kovaplus_class))
694 return PTR_ERR(kovaplus_class);
695 kovaplus_class->dev_attrs = kovaplus_attributes;
696 kovaplus_class->dev_bin_attrs = kovaplus_bin_attributes;
697
698 retval = hid_register_driver(&kovaplus_driver);
699 if (retval)
700 class_destroy(kovaplus_class);
701 return retval;
702}
703
704static void __exit kovaplus_exit(void)
705{
706 hid_unregister_driver(&kovaplus_driver);
707 class_destroy(kovaplus_class);
708}
709
710module_init(kovaplus_init);
711module_exit(kovaplus_exit);
712
713MODULE_AUTHOR("Stefan Achatz");
714MODULE_DESCRIPTION("USB Roccat Kova[+] driver");
715MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h
new file mode 100644
index 000000000000..ce40607d21c7
--- /dev/null
+++ b/drivers/hid/hid-roccat-kovaplus.h
@@ -0,0 +1,157 @@
1#ifndef __HID_ROCCAT_KOVAPLUS_H
2#define __HID_ROCCAT_KOVAPLUS_H
3
4/*
5 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/types.h>
16
17struct kovaplus_control {
18 uint8_t command; /* KOVAPLUS_COMMAND_CONTROL */
19 uint8_t value;
20 uint8_t request;
21} __packed;
22
23enum kovaplus_control_requests {
24 /* read after write; value = 1 */
25 KOVAPLUS_CONTROL_REQUEST_STATUS = 0x0,
26 /* write; value = profile number range 0-4 */
27 KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
28 /* write; value = profile number range 0-4 */
29 KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20,
30};
31
32enum kovaplus_control_values {
33 KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, /* supposed */
34 KOVAPLUS_CONTROL_REQUEST_STATUS_OK = 1,
35 KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, /* supposed */
36};
37
38struct kovaplus_actual_profile {
39 uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */
40 uint8_t size; /* always 3 */
41 uint8_t actual_profile; /* Range 0-4! */
42} __packed;
43
44struct kovaplus_profile_settings {
45 uint8_t command; /* KOVAPLUS_COMMAND_PROFILE_SETTINGS */
46 uint8_t size; /* 16 */
47 uint8_t profile_index; /* range 0-4 */
48 uint8_t unknown1;
49 uint8_t sensitivity_x; /* range 1-10 */
50 uint8_t sensitivity_y; /* range 1-10 */
51 uint8_t cpi_levels_enabled;
52 uint8_t cpi_startup_level; /* range 1-4 */
53 uint8_t data[8];
54} __packed;
55
56struct kovaplus_profile_buttons {
57 uint8_t command; /* KOVAPLUS_COMMAND_PROFILE_BUTTONS */
58 uint8_t size; /* 23 */
59 uint8_t profile_index; /* range 0-4 */
60 uint8_t data[20];
61} __packed;
62
63struct kovaplus_info {
64 uint8_t command; /* KOVAPLUS_COMMAND_INFO */
65 uint8_t size; /* 6 */
66 uint8_t firmware_version;
67 uint8_t unknown[3];
68} __packed;
69
70/* writes 1 on plugin */
71struct kovaplus_a {
72 uint8_t command; /* KOVAPLUS_COMMAND_A */
73 uint8_t size; /* 3 */
74 uint8_t unknown;
75} __packed;
76
77enum kovaplus_commands {
78 KOVAPLUS_COMMAND_CONTROL = 0x4,
79 KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
80 KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
81 KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
82 KOVAPLUS_COMMAND_INFO = 0x9,
83 KOVAPLUS_COMMAND_A = 0xa,
84};
85
86enum kovaplus_usb_commands {
87 KOVAPLUS_USB_COMMAND_CONTROL = 0x304,
88 KOVAPLUS_USB_COMMAND_ACTUAL_PROFILE = 0x305,
89 KOVAPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306,
90 KOVAPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307,
91 KOVAPLUS_USB_COMMAND_INFO = 0x309,
92 KOVAPLUS_USB_COMMAND_A = 0x30a,
93};
94
95enum kovaplus_mouse_report_numbers {
96 KOVAPLUS_MOUSE_REPORT_NUMBER_MOUSE = 1,
97 KOVAPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2,
98 KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON = 3,
99 KOVAPLUS_MOUSE_REPORT_NUMBER_KBD = 4,
100};
101
102struct kovaplus_mouse_report_button {
103 uint8_t report_number; /* KOVAPLUS_MOUSE_REPORT_NUMBER_BUTTON */
104 uint8_t unknown1;
105 uint8_t type;
106 uint8_t data1;
107 uint8_t data2;
108} __packed;
109
110enum kovaplus_mouse_report_button_types {
111 /* data1 = profile_number range 1-5; no release event */
112 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_1 = 0x20,
113 /* data1 = profile_number range 1-5; no release event */
114 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE_2 = 0x30,
115 /* data1 = button_number range 1-18; data2 = action */
116 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_MACRO = 0x40,
117 /* data1 = button_number range 1-18; data2 = action */
118 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SHORTCUT = 0x50,
119 /* data1 = button_number range 1-18; data2 = action */
120 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
121 /* data1 = button_number range 1-18; data2 = action */
122 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80,
123 /* data1 = 1 = 400, 2 = 800, 4 = 1600, 7 = 3200; no release event */
124 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0,
125 /* data1 + data2 = sense range 1-10; no release event */
126 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0,
127 /* data1 = type as in profile_buttons; data2 = action */
128 KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
129};
130
131enum kovaplus_mouse_report_button_actions {
132 KOVAPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS = 0,
133 KOVAPLUS_MOUSE_REPORT_BUTTON_ACTION_RELEASE = 1,
134};
135
136struct kovaplus_roccat_report {
137 uint8_t type;
138 uint8_t profile;
139 uint8_t button;
140 uint8_t data1;
141 uint8_t data2;
142} __packed;
143
144struct kovaplus_device {
145 int actual_profile;
146 int actual_cpi;
147 int actual_x_sensitivity;
148 int actual_y_sensitivity;
149 int roccat_claimed;
150 int chrdev_minor;
151 struct mutex kovaplus_lock;
152 struct kovaplus_info info;
153 struct kovaplus_profile_settings profile_settings[5];
154 struct kovaplus_profile_buttons profile_buttons[5];
155};
156
157#endif
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
index 02c58e015bee..160f481344f6 100644
--- a/drivers/hid/hid-roccat-pyra.c
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -20,11 +20,11 @@
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/input.h> 21#include <linux/input.h>
22#include <linux/hid.h> 22#include <linux/hid.h>
23#include <linux/usb.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/hid-roccat.h>
26#include "hid-ids.h" 26#include "hid-ids.h"
27#include "hid-roccat.h" 27#include "hid-roccat-common.h"
28#include "hid-roccat-pyra.h" 28#include "hid-roccat-pyra.h"
29 29
30static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 30static uint profile_numbers[5] = {0, 1, 2, 3, 4};
@@ -42,7 +42,6 @@ static void profile_activated(struct pyra_device *pyra,
42static int pyra_send_control(struct usb_device *usb_dev, int value, 42static int pyra_send_control(struct usb_device *usb_dev, int value,
43 enum pyra_control_requests request) 43 enum pyra_control_requests request)
44{ 44{
45 int len;
46 struct pyra_control control; 45 struct pyra_control control;
47 46
48 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || 47 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
@@ -54,47 +53,31 @@ static int pyra_send_control(struct usb_device *usb_dev, int value,
54 control.value = value; 53 control.value = value;
55 control.request = request; 54 control.request = request;
56 55
57 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 56 return roccat_common_send(usb_dev, PYRA_USB_COMMAND_CONTROL,
58 USB_REQ_SET_CONFIGURATION, 57 &control, sizeof(struct pyra_control));
59 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
60 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
61 sizeof(struct pyra_control),
62 USB_CTRL_SET_TIMEOUT);
63
64 if (len != sizeof(struct pyra_control))
65 return len;
66
67 return 0;
68} 58}
69 59
70static int pyra_receive_control_status(struct usb_device *usb_dev) 60static int pyra_receive_control_status(struct usb_device *usb_dev)
71{ 61{
72 int len; 62 int retval;
73 struct pyra_control control; 63 struct pyra_control control;
74 64
75 do { 65 do {
76 msleep(10); 66 msleep(10);
77 67 retval = roccat_common_receive(usb_dev, PYRA_USB_COMMAND_CONTROL,
78 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 68 &control, sizeof(struct pyra_control));
79 USB_REQ_CLEAR_FEATURE,
80 USB_TYPE_CLASS | USB_RECIP_INTERFACE |
81 USB_DIR_IN,
82 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
83 sizeof(struct pyra_control),
84 USB_CTRL_SET_TIMEOUT);
85 69
86 /* requested too early, try again */ 70 /* requested too early, try again */
87 } while (len == -EPROTO); 71 } while (retval == -EPROTO);
88 72
89 if (len == sizeof(struct pyra_control) && 73 if (!retval && control.command == PYRA_COMMAND_CONTROL &&
90 control.command == PYRA_COMMAND_CONTROL &&
91 control.request == PYRA_CONTROL_REQUEST_STATUS && 74 control.request == PYRA_CONTROL_REQUEST_STATUS &&
92 control.value == 1) 75 control.value == 1)
93 return 0; 76 return 0;
94 else { 77 else {
95 hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n", 78 hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n",
96 control.request, control.value); 79 control.request, control.value);
97 return -EINVAL; 80 return retval ? retval : -EINVAL;
98 } 81 }
99} 82}
100 83
@@ -102,125 +85,72 @@ static int pyra_get_profile_settings(struct usb_device *usb_dev,
102 struct pyra_profile_settings *buf, int number) 85 struct pyra_profile_settings *buf, int number)
103{ 86{
104 int retval; 87 int retval;
105
106 retval = pyra_send_control(usb_dev, number, 88 retval = pyra_send_control(usb_dev, number,
107 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); 89 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
108
109 if (retval) 90 if (retval)
110 return retval; 91 return retval;
111 92 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_PROFILE_SETTINGS,
112 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 93 buf, sizeof(struct pyra_profile_settings));
113 USB_REQ_CLEAR_FEATURE,
114 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
115 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)buf,
116 sizeof(struct pyra_profile_settings),
117 USB_CTRL_SET_TIMEOUT);
118
119 if (retval != sizeof(struct pyra_profile_settings))
120 return retval;
121
122 return 0;
123} 94}
124 95
125static int pyra_get_profile_buttons(struct usb_device *usb_dev, 96static int pyra_get_profile_buttons(struct usb_device *usb_dev,
126 struct pyra_profile_buttons *buf, int number) 97 struct pyra_profile_buttons *buf, int number)
127{ 98{
128 int retval; 99 int retval;
129
130 retval = pyra_send_control(usb_dev, number, 100 retval = pyra_send_control(usb_dev, number,
131 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); 101 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
132
133 if (retval) 102 if (retval)
134 return retval; 103 return retval;
135 104 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_PROFILE_BUTTONS,
136 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 105 buf, sizeof(struct pyra_profile_buttons));
137 USB_REQ_CLEAR_FEATURE,
138 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
139 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buf,
140 sizeof(struct pyra_profile_buttons),
141 USB_CTRL_SET_TIMEOUT);
142
143 if (retval != sizeof(struct pyra_profile_buttons))
144 return retval;
145
146 return 0;
147} 106}
148 107
149static int pyra_get_settings(struct usb_device *usb_dev, 108static int pyra_get_settings(struct usb_device *usb_dev,
150 struct pyra_settings *buf) 109 struct pyra_settings *buf)
151{ 110{
152 int len; 111 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_SETTINGS,
153 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 112 buf, sizeof(struct pyra_settings));
154 USB_REQ_CLEAR_FEATURE,
155 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
156 PYRA_USB_COMMAND_SETTINGS, 0, buf,
157 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
158 if (len != sizeof(struct pyra_settings))
159 return -EIO;
160 return 0;
161} 113}
162 114
163static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) 115static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
164{ 116{
165 int len; 117 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_INFO,
166 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 118 buf, sizeof(struct pyra_info));
167 USB_REQ_CLEAR_FEATURE, 119}
168 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 120
169 PYRA_USB_COMMAND_INFO, 0, buf, 121static int pyra_send(struct usb_device *usb_dev, uint command,
170 sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT); 122 void const *buf, uint size)
171 if (len != sizeof(struct pyra_info)) 123{
172 return -EIO; 124 int retval;
173 return 0; 125 retval = roccat_common_send(usb_dev, command, buf, size);
126 if (retval)
127 return retval;
128 return pyra_receive_control_status(usb_dev);
174} 129}
175 130
176static int pyra_set_profile_settings(struct usb_device *usb_dev, 131static int pyra_set_profile_settings(struct usb_device *usb_dev,
177 struct pyra_profile_settings const *settings) 132 struct pyra_profile_settings const *settings)
178{ 133{
179 int len; 134 return pyra_send(usb_dev, PYRA_USB_COMMAND_PROFILE_SETTINGS, settings,
180 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 135 sizeof(struct pyra_profile_settings));
181 USB_REQ_SET_CONFIGURATION,
182 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
183 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)settings,
184 sizeof(struct pyra_profile_settings),
185 USB_CTRL_SET_TIMEOUT);
186 if (len != sizeof(struct pyra_profile_settings))
187 return -EIO;
188 if (pyra_receive_control_status(usb_dev))
189 return -EIO;
190 return 0;
191} 136}
192 137
193static int pyra_set_profile_buttons(struct usb_device *usb_dev, 138static int pyra_set_profile_buttons(struct usb_device *usb_dev,
194 struct pyra_profile_buttons const *buttons) 139 struct pyra_profile_buttons const *buttons)
195{ 140{
196 int len; 141 return pyra_send(usb_dev, PYRA_USB_COMMAND_PROFILE_BUTTONS, buttons,
197 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 142 sizeof(struct pyra_profile_buttons));
198 USB_REQ_SET_CONFIGURATION,
199 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
200 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buttons,
201 sizeof(struct pyra_profile_buttons),
202 USB_CTRL_SET_TIMEOUT);
203 if (len != sizeof(struct pyra_profile_buttons))
204 return -EIO;
205 if (pyra_receive_control_status(usb_dev))
206 return -EIO;
207 return 0;
208} 143}
209 144
210static int pyra_set_settings(struct usb_device *usb_dev, 145static int pyra_set_settings(struct usb_device *usb_dev,
211 struct pyra_settings const *settings) 146 struct pyra_settings const *settings)
212{ 147{
213 int len; 148 int retval;
214 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 149 retval = roccat_common_send(usb_dev, PYRA_USB_COMMAND_SETTINGS, settings,
215 USB_REQ_SET_CONFIGURATION, 150 sizeof(struct pyra_settings));
216 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 151 if (retval)
217 PYRA_USB_COMMAND_SETTINGS, 0, (char *)settings, 152 return retval;
218 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT); 153 return pyra_receive_control_status(usb_dev);
219 if (len != sizeof(struct pyra_settings))
220 return -EIO;
221 if (pyra_receive_control_status(usb_dev))
222 return -EIO;
223 return 0;
224} 154}
225 155
226static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, 156static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
@@ -521,21 +451,16 @@ static struct bin_attribute pyra_bin_attributes[] = {
521static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, 451static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
522 struct pyra_device *pyra) 452 struct pyra_device *pyra)
523{ 453{
524 struct pyra_info *info; 454 struct pyra_info info;
525 int retval, i; 455 int retval, i;
526 456
527 mutex_init(&pyra->pyra_lock); 457 mutex_init(&pyra->pyra_lock);
528 458
529 info = kmalloc(sizeof(struct pyra_info), GFP_KERNEL); 459 retval = pyra_get_info(usb_dev, &info);
530 if (!info) 460 if (retval)
531 return -ENOMEM;
532 retval = pyra_get_info(usb_dev, info);
533 if (retval) {
534 kfree(info);
535 return retval; 461 return retval;
536 } 462
537 pyra->firmware_version = info->firmware_version; 463 pyra->firmware_version = info.firmware_version;
538 kfree(info);
539 464
540 retval = pyra_get_settings(usb_dev, &pyra->settings); 465 retval = pyra_get_settings(usb_dev, &pyra->settings);
541 if (retval) 466 if (retval)
@@ -581,7 +506,8 @@ static int pyra_init_specials(struct hid_device *hdev)
581 goto exit_free; 506 goto exit_free;
582 } 507 }
583 508
584 retval = roccat_connect(pyra_class, hdev); 509 retval = roccat_connect(pyra_class, hdev,
510 sizeof(struct pyra_roccat_report));
585 if (retval < 0) { 511 if (retval < 0) {
586 hid_err(hdev, "couldn't init char dev\n"); 512 hid_err(hdev, "couldn't init char dev\n");
587 } else { 513 } else {
@@ -685,8 +611,7 @@ static void pyra_report_to_chrdev(struct pyra_device const *pyra,
685 roccat_report.value = button_event->data1; 611 roccat_report.value = button_event->data1;
686 roccat_report.key = 0; 612 roccat_report.key = 0;
687 roccat_report_event(pyra->chrdev_minor, 613 roccat_report_event(pyra->chrdev_minor,
688 (uint8_t const *)&roccat_report, 614 (uint8_t const *)&roccat_report);
689 sizeof(struct pyra_roccat_report));
690 break; 615 break;
691 case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO: 616 case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
692 case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT: 617 case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
@@ -700,8 +625,7 @@ static void pyra_report_to_chrdev(struct pyra_device const *pyra,
700 */ 625 */
701 roccat_report.value = pyra->actual_profile + 1; 626 roccat_report.value = pyra->actual_profile + 1;
702 roccat_report_event(pyra->chrdev_minor, 627 roccat_report_event(pyra->chrdev_minor,
703 (uint8_t const *)&roccat_report, 628 (uint8_t const *)&roccat_report);
704 sizeof(struct pyra_roccat_report));
705 } 629 }
706 break; 630 break;
707 } 631 }
@@ -761,8 +685,8 @@ static int __init pyra_init(void)
761 685
762static void __exit pyra_exit(void) 686static void __exit pyra_exit(void)
763{ 687{
764 class_destroy(pyra_class);
765 hid_unregister_driver(&pyra_driver); 688 hid_unregister_driver(&pyra_driver);
689 class_destroy(pyra_class);
766} 690}
767 691
768module_init(pyra_init); 692module_init(pyra_init);
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
index a14c579ea781..5666e7587b18 100644
--- a/drivers/hid/hid-roccat.c
+++ b/drivers/hid/hid-roccat.c
@@ -26,8 +26,7 @@
26#include <linux/cdev.h> 26#include <linux/cdev.h>
27#include <linux/poll.h> 27#include <linux/poll.h>
28#include <linux/sched.h> 28#include <linux/sched.h>
29 29#include <linux/hid-roccat.h>
30#include "hid-roccat.h"
31 30
32#define ROCCAT_FIRST_MINOR 0 31#define ROCCAT_FIRST_MINOR 0
33#define ROCCAT_MAX_DEVICES 8 32#define ROCCAT_MAX_DEVICES 8
@@ -37,11 +36,11 @@
37 36
38struct roccat_report { 37struct roccat_report {
39 uint8_t *value; 38 uint8_t *value;
40 int len;
41}; 39};
42 40
43struct roccat_device { 41struct roccat_device {
44 unsigned int minor; 42 unsigned int minor;
43 int report_size;
45 int open; 44 int open;
46 int exist; 45 int exist;
47 wait_queue_head_t wait; 46 wait_queue_head_t wait;
@@ -123,7 +122,7 @@ static ssize_t roccat_read(struct file *file, char __user *buffer,
123 * If report is larger than requested amount of data, rest of report 122 * If report is larger than requested amount of data, rest of report
124 * is lost! 123 * is lost!
125 */ 124 */
126 len = report->len > count ? count : report->len; 125 len = device->report_size > count ? count : device->report_size;
127 126
128 if (copy_to_user(buffer, report->value, len)) { 127 if (copy_to_user(buffer, report->value, len)) {
129 retval = -EFAULT; 128 retval = -EFAULT;
@@ -248,26 +247,25 @@ static int roccat_release(struct inode *inode, struct file *file)
248 * 247 *
249 * This is called from interrupt handler. 248 * This is called from interrupt handler.
250 */ 249 */
251int roccat_report_event(int minor, u8 const *data, int len) 250int roccat_report_event(int minor, u8 const *data)
252{ 251{
253 struct roccat_device *device; 252 struct roccat_device *device;
254 struct roccat_reader *reader; 253 struct roccat_reader *reader;
255 struct roccat_report *report; 254 struct roccat_report *report;
256 uint8_t *new_value; 255 uint8_t *new_value;
257 256
258 new_value = kmemdup(data, len, GFP_ATOMIC); 257 device = devices[minor];
258
259 new_value = kmemdup(data, device->report_size, GFP_ATOMIC);
259 if (!new_value) 260 if (!new_value)
260 return -ENOMEM; 261 return -ENOMEM;
261 262
262 device = devices[minor];
263
264 report = &device->cbuf[device->cbuf_end]; 263 report = &device->cbuf[device->cbuf_end];
265 264
266 /* passing NULL is safe */ 265 /* passing NULL is safe */
267 kfree(report->value); 266 kfree(report->value);
268 267
269 report->value = new_value; 268 report->value = new_value;
270 report->len = len;
271 device->cbuf_end = (device->cbuf_end + 1) % ROCCAT_CBUF_SIZE; 269 device->cbuf_end = (device->cbuf_end + 1) % ROCCAT_CBUF_SIZE;
272 270
273 list_for_each_entry(reader, &device->readers, node) { 271 list_for_each_entry(reader, &device->readers, node) {
@@ -295,7 +293,7 @@ EXPORT_SYMBOL_GPL(roccat_report_event);
295 * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on 293 * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on
296 * success, a negative error code on failure. 294 * success, a negative error code on failure.
297 */ 295 */
298int roccat_connect(struct class *klass, struct hid_device *hid) 296int roccat_connect(struct class *klass, struct hid_device *hid, int report_size)
299{ 297{
300 unsigned int minor; 298 unsigned int minor;
301 struct roccat_device *device; 299 struct roccat_device *device;
@@ -343,6 +341,7 @@ int roccat_connect(struct class *klass, struct hid_device *hid)
343 device->hid = hid; 341 device->hid = hid;
344 device->exist = 1; 342 device->exist = 1;
345 device->cbuf_end = 0; 343 device->cbuf_end = 0;
344 device->report_size = report_size;
346 345
347 return minor; 346 return minor;
348} 347}
@@ -357,13 +356,16 @@ void roccat_disconnect(int minor)
357 356
358 mutex_lock(&devices_lock); 357 mutex_lock(&devices_lock);
359 device = devices[minor]; 358 device = devices[minor];
360 devices[minor] = NULL;
361 mutex_unlock(&devices_lock); 359 mutex_unlock(&devices_lock);
362 360
363 device->exist = 0; /* TODO exist maybe not needed */ 361 device->exist = 0; /* TODO exist maybe not needed */
364 362
365 device_destroy(device->dev->class, MKDEV(roccat_major, minor)); 363 device_destroy(device->dev->class, MKDEV(roccat_major, minor));
366 364
365 mutex_lock(&devices_lock);
366 devices[minor] = NULL;
367 mutex_unlock(&devices_lock);
368
367 if (device->open) { 369 if (device->open) {
368 hid_hw_close(device->hid); 370 hid_hw_close(device->hid);
369 wake_up_interruptible(&device->wait); 371 wake_up_interruptible(&device->wait);
@@ -373,6 +375,34 @@ void roccat_disconnect(int minor)
373} 375}
374EXPORT_SYMBOL_GPL(roccat_disconnect); 376EXPORT_SYMBOL_GPL(roccat_disconnect);
375 377
378static long roccat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
379{
380 struct inode *inode = file->f_path.dentry->d_inode;
381 struct roccat_device *device;
382 unsigned int minor = iminor(inode);
383 long retval = 0;
384
385 mutex_lock(&devices_lock);
386
387 device = devices[minor];
388 if (!device) {
389 retval = -ENODEV;
390 goto out;
391 }
392
393 switch (cmd) {
394 case ROCCATIOCGREPSIZE:
395 if (put_user(device->report_size, (int __user *)arg))
396 retval = -EFAULT;
397 break;
398 default:
399 retval = -ENOTTY;
400 }
401out:
402 mutex_unlock(&devices_lock);
403 return retval;
404}
405
376static const struct file_operations roccat_ops = { 406static const struct file_operations roccat_ops = {
377 .owner = THIS_MODULE, 407 .owner = THIS_MODULE,
378 .read = roccat_read, 408 .read = roccat_read,
@@ -380,6 +410,7 @@ static const struct file_operations roccat_ops = {
380 .open = roccat_open, 410 .open = roccat_open,
381 .release = roccat_release, 411 .release = roccat_release,
382 .llseek = noop_llseek, 412 .llseek = noop_llseek,
413 .unlocked_ioctl = roccat_ioctl,
383}; 414};
384 415
385static int __init roccat_init(void) 416static int __init roccat_init(void)
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 68d7b36e31e4..93819a08121a 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -46,6 +46,16 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
46 return rdesc; 46 return rdesc;
47} 47}
48 48
49/*
50 * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
51 * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
52 * so we need to override that forcing HID Output Reports on the Control EP.
53 *
54 * There is also another issue about HID Output Reports via USB, the Sixaxis
55 * does not want the report_id as part of the data packet, so we have to
56 * discard buf[0] when sending the actual control message, even for numbered
57 * reports, humpf!
58 */
49static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, 59static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
50 size_t count, unsigned char report_type) 60 size_t count, unsigned char report_type)
51{ 61{
@@ -55,6 +65,12 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
55 int report_id = buf[0]; 65 int report_id = buf[0];
56 int ret; 66 int ret;
57 67
68 if (report_type == HID_OUTPUT_REPORT) {
69 /* Don't send the Report ID */
70 buf++;
71 count--;
72 }
73
58 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 74 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
59 HID_REQ_SET_REPORT, 75 HID_REQ_SET_REPORT,
60 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 76 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
@@ -62,6 +78,10 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
62 interface->desc.bInterfaceNumber, buf, count, 78 interface->desc.bInterfaceNumber, buf, count,
63 USB_CTRL_SET_TIMEOUT); 79 USB_CTRL_SET_TIMEOUT);
64 80
81 /* Count also the Report ID, in case of an Output report. */
82 if (ret > 0 && report_type == HID_OUTPUT_REPORT)
83 ret++;
84
65 return ret; 85 return ret;
66} 86}
67 87
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 468e87b53ed2..54409cba018c 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -91,7 +91,7 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
91 ret = -EFAULT; 91 ret = -EFAULT;
92 goto out; 92 goto out;
93 } 93 }
94 ret += len; 94 ret = len;
95 95
96 kfree(list->buffer[list->tail].value); 96 kfree(list->buffer[list->tail].value);
97 list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); 97 list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
@@ -102,15 +102,14 @@ out:
102} 102}
103 103
104/* the first byte is expected to be a report number */ 104/* the first byte is expected to be a report number */
105static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) 105/* This function is to be called with the minors_lock mutex held */
106static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type)
106{ 107{
107 unsigned int minor = iminor(file->f_path.dentry->d_inode); 108 unsigned int minor = iminor(file->f_path.dentry->d_inode);
108 struct hid_device *dev; 109 struct hid_device *dev;
109 __u8 *buf; 110 __u8 *buf;
110 int ret = 0; 111 int ret = 0;
111 112
112 mutex_lock(&minors_lock);
113
114 if (!hidraw_table[minor]) { 113 if (!hidraw_table[minor]) {
115 ret = -ENODEV; 114 ret = -ENODEV;
116 goto out; 115 goto out;
@@ -148,14 +147,92 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
148 goto out_free; 147 goto out_free;
149 } 148 }
150 149
151 ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT); 150 ret = dev->hid_output_raw_report(dev, buf, count, report_type);
152out_free: 151out_free:
153 kfree(buf); 152 kfree(buf);
154out: 153out:
154 return ret;
155}
156
157/* the first byte is expected to be a report number */
158static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
159{
160 ssize_t ret;
161 mutex_lock(&minors_lock);
162 ret = hidraw_send_report(file, buffer, count, HID_OUTPUT_REPORT);
155 mutex_unlock(&minors_lock); 163 mutex_unlock(&minors_lock);
156 return ret; 164 return ret;
157} 165}
158 166
167
168/* This function performs a Get_Report transfer over the control endpoint
169 per section 7.2.1 of the HID specification, version 1.1. The first byte
170 of buffer is the report number to request, or 0x0 if the defice does not
171 use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
172 or HID_INPUT_REPORT. This function is to be called with the minors_lock
173 mutex held. */
174static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type)
175{
176 unsigned int minor = iminor(file->f_path.dentry->d_inode);
177 struct hid_device *dev;
178 __u8 *buf;
179 int ret = 0, len;
180 unsigned char report_number;
181
182 dev = hidraw_table[minor]->hid;
183
184 if (!dev->hid_get_raw_report) {
185 ret = -ENODEV;
186 goto out;
187 }
188
189 if (count > HID_MAX_BUFFER_SIZE) {
190 printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
191 task_pid_nr(current));
192 ret = -EINVAL;
193 goto out;
194 }
195
196 if (count < 2) {
197 printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
198 task_pid_nr(current));
199 ret = -EINVAL;
200 goto out;
201 }
202
203 buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
204 if (!buf) {
205 ret = -ENOMEM;
206 goto out;
207 }
208
209 /* Read the first byte from the user. This is the report number,
210 which is passed to dev->hid_get_raw_report(). */
211 if (copy_from_user(&report_number, buffer, 1)) {
212 ret = -EFAULT;
213 goto out_free;
214 }
215
216 ret = dev->hid_get_raw_report(dev, report_number, buf, count, report_type);
217
218 if (ret < 0)
219 goto out_free;
220
221 len = (ret < count) ? ret : count;
222
223 if (copy_to_user(buffer, buf, len)) {
224 ret = -EFAULT;
225 goto out_free;
226 }
227
228 ret = len;
229
230out_free:
231 kfree(buf);
232out:
233 return ret;
234}
235
159static unsigned int hidraw_poll(struct file *file, poll_table *wait) 236static unsigned int hidraw_poll(struct file *file, poll_table *wait)
160{ 237{
161 struct hidraw_list *list = file->private_data; 238 struct hidraw_list *list = file->private_data;
@@ -295,7 +372,24 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
295 default: 372 default:
296 { 373 {
297 struct hid_device *hid = dev->hid; 374 struct hid_device *hid = dev->hid;
298 if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) { 375 if (_IOC_TYPE(cmd) != 'H') {
376 ret = -EINVAL;
377 break;
378 }
379
380 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCSFEATURE(0))) {
381 int len = _IOC_SIZE(cmd);
382 ret = hidraw_send_report(file, user_arg, len, HID_FEATURE_REPORT);
383 break;
384 }
385 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGFEATURE(0))) {
386 int len = _IOC_SIZE(cmd);
387 ret = hidraw_get_report(file, user_arg, len, HID_FEATURE_REPORT);
388 break;
389 }
390
391 /* Begin Read-only ioctls. */
392 if (_IOC_DIR(cmd) != _IOC_READ) {
299 ret = -EINVAL; 393 ret = -EINVAL;
300 break; 394 break;
301 } 395 }
@@ -327,7 +421,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
327 -EFAULT : len; 421 -EFAULT : len;
328 break; 422 break;
329 } 423 }
330 } 424 }
331 425
332 ret = -ENOTTY; 426 ret = -ENOTTY;
333 } 427 }
@@ -428,12 +522,12 @@ void hidraw_disconnect(struct hid_device *hid)
428 522
429 hidraw->exist = 0; 523 hidraw->exist = 0;
430 524
525 device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
526
431 mutex_lock(&minors_lock); 527 mutex_lock(&minors_lock);
432 hidraw_table[hidraw->minor] = NULL; 528 hidraw_table[hidraw->minor] = NULL;
433 mutex_unlock(&minors_lock); 529 mutex_unlock(&minors_lock);
434 530
435 device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
436
437 if (hidraw->open) { 531 if (hidraw->open) {
438 hid_hw_close(hid); 532 hid_hw_close(hid);
439 wake_up_interruptible(&hidraw->wait); 533 wake_up_interruptible(&hidraw->wait);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index b336dd84036f..38c261a40c74 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -799,6 +799,40 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
799 return 0; 799 return 0;
800} 800}
801 801
802static int usbhid_get_raw_report(struct hid_device *hid,
803 unsigned char report_number, __u8 *buf, size_t count,
804 unsigned char report_type)
805{
806 struct usbhid_device *usbhid = hid->driver_data;
807 struct usb_device *dev = hid_to_usb_dev(hid);
808 struct usb_interface *intf = usbhid->intf;
809 struct usb_host_interface *interface = intf->cur_altsetting;
810 int skipped_report_id = 0;
811 int ret;
812
813 /* Byte 0 is the report number. Report data starts at byte 1.*/
814 buf[0] = report_number;
815 if (report_number == 0x0) {
816 /* Offset the return buffer by 1, so that the report ID
817 will remain in byte 0. */
818 buf++;
819 count--;
820 skipped_report_id = 1;
821 }
822 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
823 HID_REQ_GET_REPORT,
824 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
825 ((report_type + 1) << 8) | report_number,
826 interface->desc.bInterfaceNumber, buf, count,
827 USB_CTRL_SET_TIMEOUT);
828
829 /* count also the report id */
830 if (ret > 0 && skipped_report_id)
831 ret++;
832
833 return ret;
834}
835
802static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count, 836static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
803 unsigned char report_type) 837 unsigned char report_type)
804{ 838{
@@ -1139,6 +1173,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
1139 1173
1140 usb_set_intfdata(intf, hid); 1174 usb_set_intfdata(intf, hid);
1141 hid->ll_driver = &usb_hid_driver; 1175 hid->ll_driver = &usb_hid_driver;
1176 hid->hid_get_raw_report = usbhid_get_raw_report;
1142 hid->hid_output_raw_report = usbhid_output_raw_report; 1177 hid->hid_output_raw_report = usbhid_output_raw_report;
1143 hid->ff_init = hid_pidff_init; 1178 hid->ff_init = hid_pidff_init;
1144#ifdef CONFIG_USB_HIDDEV 1179#ifdef CONFIG_USB_HIDDEV
diff --git a/drivers/hid/hid-roccat.h b/include/linux/hid-roccat.h
index 5784281d613f..24e1ca01f9a0 100644
--- a/drivers/hid/hid-roccat.h
+++ b/include/linux/hid-roccat.h
@@ -15,18 +15,15 @@
15#include <linux/hid.h> 15#include <linux/hid.h>
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18#if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE) 18#define ROCCATIOCGREPSIZE _IOR('H', 0xf1, int)
19int roccat_connect(struct class *klass, struct hid_device *hid); 19
20#ifdef __KERNEL__
21
22int roccat_connect(struct class *klass, struct hid_device *hid,
23 int report_size);
20void roccat_disconnect(int minor); 24void roccat_disconnect(int minor);
21int roccat_report_event(int minor, u8 const *data, int len); 25int roccat_report_event(int minor, u8 const *data);
22#else 26
23static inline int roccat_connect(struct class *klass,
24 struct hid_device *hid) { return -1; }
25static inline void roccat_disconnect(int minor) {}
26static inline int roccat_report_event(int minor, u8 const *data, int len)
27{
28 return 0;
29}
30#endif 27#endif
31 28
32#endif 29#endif
diff --git a/include/linux/hid.h b/include/linux/hid.h
index d91c25e253c8..bb29bb1dbd2f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -504,6 +504,9 @@ struct hid_device { /* device report descriptor */
504 struct hid_usage *, __s32); 504 struct hid_usage *, __s32);
505 void (*hiddev_report_event) (struct hid_device *, struct hid_report *); 505 void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
506 506
507 /* handler for raw input (Get_Report) data, used by hidraw */
508 int (*hid_get_raw_report) (struct hid_device *, unsigned char, __u8 *, size_t, unsigned char);
509
507 /* handler for raw output data, used by hidraw */ 510 /* handler for raw output data, used by hidraw */
508 int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char); 511 int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char);
509 512
@@ -638,7 +641,7 @@ struct hid_driver {
638 struct hid_input *hidinput, struct hid_field *field, 641 struct hid_input *hidinput, struct hid_field *field,
639 struct hid_usage *usage, unsigned long **bit, int *max); 642 struct hid_usage *usage, unsigned long **bit, int *max);
640 void (*feature_mapping)(struct hid_device *hdev, 643 void (*feature_mapping)(struct hid_device *hdev,
641 struct hid_input *hidinput, struct hid_field *field, 644 struct hid_field *field,
642 struct hid_usage *usage); 645 struct hid_usage *usage);
643#ifdef CONFIG_PM 646#ifdef CONFIG_PM
644 int (*suspend)(struct hid_device *hdev, pm_message_t message); 647 int (*suspend)(struct hid_device *hdev, pm_message_t message);
diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h
index dd8d69269176..4b88e697c4e9 100644
--- a/include/linux/hidraw.h
+++ b/include/linux/hidraw.h
@@ -35,6 +35,9 @@ struct hidraw_devinfo {
35#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo) 35#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
36#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len) 36#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len)
37#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len) 37#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len)
38/* The first byte of SFEATURE and GFEATURE is the report number */
39#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
40#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
38 41
39#define HIDRAW_FIRST_MINOR 0 42#define HIDRAW_FIRST_MINOR 0
40#define HIDRAW_MAX_DEVICES 64 43#define HIDRAW_MAX_DEVICES 64
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 29544c21f4b5..3c036b0933c1 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -36,6 +36,7 @@
36#include <linux/file.h> 36#include <linux/file.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/wait.h> 38#include <linux/wait.h>
39#include <linux/mutex.h>
39#include <net/sock.h> 40#include <net/sock.h>
40 41
41#include <linux/input.h> 42#include <linux/input.h>
@@ -313,24 +314,144 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
313 return hidp_queue_report(session, buf, rsize); 314 return hidp_queue_report(session, buf, rsize);
314} 315}
315 316
317static int hidp_get_raw_report(struct hid_device *hid,
318 unsigned char report_number,
319 unsigned char *data, size_t count,
320 unsigned char report_type)
321{
322 struct hidp_session *session = hid->driver_data;
323 struct sk_buff *skb;
324 size_t len;
325 int numbered_reports = hid->report_enum[report_type].numbered;
326
327 switch (report_type) {
328 case HID_FEATURE_REPORT:
329 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE;
330 break;
331 case HID_INPUT_REPORT:
332 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_INPUT;
333 break;
334 case HID_OUTPUT_REPORT:
335 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_OUPUT;
336 break;
337 default:
338 return -EINVAL;
339 }
340
341 if (mutex_lock_interruptible(&session->report_mutex))
342 return -ERESTARTSYS;
343
344 /* Set up our wait, and send the report request to the device. */
345 session->waiting_report_type = report_type & HIDP_DATA_RTYPE_MASK;
346 session->waiting_report_number = numbered_reports ? report_number : -1;
347 set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
348 data[0] = report_number;
349 if (hidp_send_ctrl_message(hid->driver_data, report_type, data, 1))
350 goto err_eio;
351
352 /* Wait for the return of the report. The returned report
353 gets put in session->report_return. */
354 while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) {
355 int res;
356
357 res = wait_event_interruptible_timeout(session->report_queue,
358 !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags),
359 5*HZ);
360 if (res == 0) {
361 /* timeout */
362 goto err_eio;
363 }
364 if (res < 0) {
365 /* signal */
366 goto err_restartsys;
367 }
368 }
369
370 skb = session->report_return;
371 if (skb) {
372 len = skb->len < count ? skb->len : count;
373 memcpy(data, skb->data, len);
374
375 kfree_skb(skb);
376 session->report_return = NULL;
377 } else {
378 /* Device returned a HANDSHAKE, indicating protocol error. */
379 len = -EIO;
380 }
381
382 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
383 mutex_unlock(&session->report_mutex);
384
385 return len;
386
387err_restartsys:
388 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
389 mutex_unlock(&session->report_mutex);
390 return -ERESTARTSYS;
391err_eio:
392 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
393 mutex_unlock(&session->report_mutex);
394 return -EIO;
395}
396
316static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, 397static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
317 unsigned char report_type) 398 unsigned char report_type)
318{ 399{
400 struct hidp_session *session = hid->driver_data;
401 int ret;
402
319 switch (report_type) { 403 switch (report_type) {
320 case HID_FEATURE_REPORT: 404 case HID_FEATURE_REPORT:
321 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; 405 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
322 break; 406 break;
323 case HID_OUTPUT_REPORT: 407 case HID_OUTPUT_REPORT:
324 report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; 408 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
325 break; 409 break;
326 default: 410 default:
327 return -EINVAL; 411 return -EINVAL;
328 } 412 }
329 413
414 if (mutex_lock_interruptible(&session->report_mutex))
415 return -ERESTARTSYS;
416
417 /* Set up our wait, and send the report request to the device. */
418 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
330 if (hidp_send_ctrl_message(hid->driver_data, report_type, 419 if (hidp_send_ctrl_message(hid->driver_data, report_type,
331 data, count)) 420 data, count)) {
332 return -ENOMEM; 421 ret = -ENOMEM;
333 return count; 422 goto err;
423 }
424
425 /* Wait for the ACK from the device. */
426 while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) {
427 int res;
428
429 res = wait_event_interruptible_timeout(session->report_queue,
430 !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags),
431 10*HZ);
432 if (res == 0) {
433 /* timeout */
434 ret = -EIO;
435 goto err;
436 }
437 if (res < 0) {
438 /* signal */
439 ret = -ERESTARTSYS;
440 goto err;
441 }
442 }
443
444 if (!session->output_report_success) {
445 ret = -EIO;
446 goto err;
447 }
448
449 ret = count;
450
451err:
452 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
453 mutex_unlock(&session->report_mutex);
454 return ret;
334} 455}
335 456
336static void hidp_idle_timeout(unsigned long arg) 457static void hidp_idle_timeout(unsigned long arg)
@@ -357,16 +478,22 @@ static void hidp_process_handshake(struct hidp_session *session,
357 unsigned char param) 478 unsigned char param)
358{ 479{
359 BT_DBG("session %p param 0x%02x", session, param); 480 BT_DBG("session %p param 0x%02x", session, param);
481 session->output_report_success = 0; /* default condition */
360 482
361 switch (param) { 483 switch (param) {
362 case HIDP_HSHK_SUCCESSFUL: 484 case HIDP_HSHK_SUCCESSFUL:
363 /* FIXME: Call into SET_ GET_ handlers here */ 485 /* FIXME: Call into SET_ GET_ handlers here */
486 session->output_report_success = 1;
364 break; 487 break;
365 488
366 case HIDP_HSHK_NOT_READY: 489 case HIDP_HSHK_NOT_READY:
367 case HIDP_HSHK_ERR_INVALID_REPORT_ID: 490 case HIDP_HSHK_ERR_INVALID_REPORT_ID:
368 case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST: 491 case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
369 case HIDP_HSHK_ERR_INVALID_PARAMETER: 492 case HIDP_HSHK_ERR_INVALID_PARAMETER:
493 if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) {
494 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
495 wake_up_interruptible(&session->report_queue);
496 }
370 /* FIXME: Call into SET_ GET_ handlers here */ 497 /* FIXME: Call into SET_ GET_ handlers here */
371 break; 498 break;
372 499
@@ -385,6 +512,12 @@ static void hidp_process_handshake(struct hidp_session *session,
385 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); 512 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
386 break; 513 break;
387 } 514 }
515
516 /* Wake up the waiting thread. */
517 if (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) {
518 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
519 wake_up_interruptible(&session->report_queue);
520 }
388} 521}
389 522
390static void hidp_process_hid_control(struct hidp_session *session, 523static void hidp_process_hid_control(struct hidp_session *session,
@@ -403,9 +536,11 @@ static void hidp_process_hid_control(struct hidp_session *session,
403 } 536 }
404} 537}
405 538
406static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, 539/* Returns true if the passed-in skb should be freed by the caller. */
540static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
407 unsigned char param) 541 unsigned char param)
408{ 542{
543 int done_with_skb = 1;
409 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); 544 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
410 545
411 switch (param) { 546 switch (param) {
@@ -417,7 +552,6 @@ static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
417 552
418 if (session->hid) 553 if (session->hid)
419 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0); 554 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0);
420
421 break; 555 break;
422 556
423 case HIDP_DATA_RTYPE_OTHER: 557 case HIDP_DATA_RTYPE_OTHER:
@@ -429,12 +563,27 @@ static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
429 __hidp_send_ctrl_message(session, 563 __hidp_send_ctrl_message(session,
430 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); 564 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
431 } 565 }
566
567 if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) &&
568 param == session->waiting_report_type) {
569 if (session->waiting_report_number < 0 ||
570 session->waiting_report_number == skb->data[0]) {
571 /* hidp_get_raw_report() is waiting on this report. */
572 session->report_return = skb;
573 done_with_skb = 0;
574 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
575 wake_up_interruptible(&session->report_queue);
576 }
577 }
578
579 return done_with_skb;
432} 580}
433 581
434static void hidp_recv_ctrl_frame(struct hidp_session *session, 582static void hidp_recv_ctrl_frame(struct hidp_session *session,
435 struct sk_buff *skb) 583 struct sk_buff *skb)
436{ 584{
437 unsigned char hdr, type, param; 585 unsigned char hdr, type, param;
586 int free_skb = 1;
438 587
439 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 588 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
440 589
@@ -454,7 +603,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
454 break; 603 break;
455 604
456 case HIDP_TRANS_DATA: 605 case HIDP_TRANS_DATA:
457 hidp_process_data(session, skb, param); 606 free_skb = hidp_process_data(session, skb, param);
458 break; 607 break;
459 608
460 default: 609 default:
@@ -463,7 +612,8 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
463 break; 612 break;
464 } 613 }
465 614
466 kfree_skb(skb); 615 if (free_skb)
616 kfree_skb(skb);
467} 617}
468 618
469static void hidp_recv_intr_frame(struct hidp_session *session, 619static void hidp_recv_intr_frame(struct hidp_session *session,
@@ -563,6 +713,8 @@ static int hidp_session(void *arg)
563 init_waitqueue_entry(&intr_wait, current); 713 init_waitqueue_entry(&intr_wait, current);
564 add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); 714 add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
565 add_wait_queue(sk_sleep(intr_sk), &intr_wait); 715 add_wait_queue(sk_sleep(intr_sk), &intr_wait);
716 session->waiting_for_startup = 0;
717 wake_up_interruptible(&session->startup_queue);
566 while (!atomic_read(&session->terminate)) { 718 while (!atomic_read(&session->terminate)) {
567 set_current_state(TASK_INTERRUPTIBLE); 719 set_current_state(TASK_INTERRUPTIBLE);
568 720
@@ -754,6 +906,8 @@ static struct hid_ll_driver hidp_hid_driver = {
754 .hidinput_input_event = hidp_hidinput_event, 906 .hidinput_input_event = hidp_hidinput_event,
755}; 907};
756 908
909/* This function sets up the hid device. It does not add it
910 to the HID system. That is done in hidp_add_connection(). */
757static int hidp_setup_hid(struct hidp_session *session, 911static int hidp_setup_hid(struct hidp_session *session,
758 struct hidp_connadd_req *req) 912 struct hidp_connadd_req *req)
759{ 913{
@@ -793,18 +947,11 @@ static int hidp_setup_hid(struct hidp_session *session,
793 hid->dev.parent = hidp_get_device(session); 947 hid->dev.parent = hidp_get_device(session);
794 hid->ll_driver = &hidp_hid_driver; 948 hid->ll_driver = &hidp_hid_driver;
795 949
950 hid->hid_get_raw_report = hidp_get_raw_report;
796 hid->hid_output_raw_report = hidp_output_raw_report; 951 hid->hid_output_raw_report = hidp_output_raw_report;
797 952
798 err = hid_add_device(hid);
799 if (err < 0)
800 goto failed;
801
802 return 0; 953 return 0;
803 954
804failed:
805 hid_destroy_device(hid);
806 session->hid = NULL;
807
808fault: 955fault:
809 kfree(session->rd_data); 956 kfree(session->rd_data);
810 session->rd_data = NULL; 957 session->rd_data = NULL;
@@ -853,6 +1000,10 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
853 skb_queue_head_init(&session->ctrl_transmit); 1000 skb_queue_head_init(&session->ctrl_transmit);
854 skb_queue_head_init(&session->intr_transmit); 1001 skb_queue_head_init(&session->intr_transmit);
855 1002
1003 mutex_init(&session->report_mutex);
1004 init_waitqueue_head(&session->report_queue);
1005 init_waitqueue_head(&session->startup_queue);
1006 session->waiting_for_startup = 1;
856 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); 1007 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
857 session->idle_to = req->idle_to; 1008 session->idle_to = req->idle_to;
858 1009
@@ -875,6 +1026,14 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
875 err = kernel_thread(hidp_session, session, CLONE_KERNEL); 1026 err = kernel_thread(hidp_session, session, CLONE_KERNEL);
876 if (err < 0) 1027 if (err < 0)
877 goto unlink; 1028 goto unlink;
1029 while (session->waiting_for_startup) {
1030 wait_event_interruptible(session->startup_queue,
1031 !session->waiting_for_startup);
1032 }
1033
1034 err = hid_add_device(session->hid);
1035 if (err < 0)
1036 goto err_add_device;
878 1037
879 if (session->input) { 1038 if (session->input) {
880 hidp_send_ctrl_message(session, 1039 hidp_send_ctrl_message(session,
@@ -888,6 +1047,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
888 up_write(&hidp_session_sem); 1047 up_write(&hidp_session_sem);
889 return 0; 1048 return 0;
890 1049
1050err_add_device:
1051 hid_destroy_device(session->hid);
1052 session->hid = NULL;
1053 atomic_inc(&session->terminate);
1054 hidp_schedule(session);
1055
891unlink: 1056unlink:
892 hidp_del_timer(session); 1057 hidp_del_timer(session);
893 1058
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index 8d934a19da0a..13de5fa03480 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -80,6 +80,8 @@
80#define HIDP_VIRTUAL_CABLE_UNPLUG 0 80#define HIDP_VIRTUAL_CABLE_UNPLUG 0
81#define HIDP_BOOT_PROTOCOL_MODE 1 81#define HIDP_BOOT_PROTOCOL_MODE 1
82#define HIDP_BLUETOOTH_VENDOR_ID 9 82#define HIDP_BLUETOOTH_VENDOR_ID 9
83#define HIDP_WAITING_FOR_RETURN 10
84#define HIDP_WAITING_FOR_SEND_ACK 11
83 85
84struct hidp_connadd_req { 86struct hidp_connadd_req {
85 int ctrl_sock; // Connected control socket 87 int ctrl_sock; // Connected control socket
@@ -154,9 +156,22 @@ struct hidp_session {
154 struct sk_buff_head ctrl_transmit; 156 struct sk_buff_head ctrl_transmit;
155 struct sk_buff_head intr_transmit; 157 struct sk_buff_head intr_transmit;
156 158
159 /* Used in hidp_get_raw_report() */
160 int waiting_report_type; /* HIDP_DATA_RTYPE_* */
161 int waiting_report_number; /* -1 for not numbered */
162 struct mutex report_mutex;
163 struct sk_buff *report_return;
164 wait_queue_head_t report_queue;
165
166 /* Used in hidp_output_raw_report() */
167 int output_report_success; /* boolean */
168
157 /* Report descriptor */ 169 /* Report descriptor */
158 __u8 *rd_data; 170 __u8 *rd_data;
159 uint rd_size; 171 uint rd_size;
172
173 wait_queue_head_t startup_queue;
174 int waiting_for_startup;
160}; 175};
161 176
162static inline void hidp_schedule(struct hidp_session *session) 177static inline void hidp_schedule(struct hidp_session *session)