Commit 5772f63613ce0a6777e82a7e8fb553e49da27719
Committed by
Jiri Kosina
1 parent
a28764ef80
Exists in
master
and in
7 other branches
HID: roccat: Introduce module hid-roccat-common
Module hid-roccat-common contains functions used by roccat device driver modules to reduce code duplication. At the moment it contains just two wrapper methods for usb_control_msg that ensure that the buffer used for transfer is dma capable which wasn't the case before. The kconfig option is not visible to the user but will be selected by the device specific drivers. Signed-off-by: Stefan Achatz <erazor_de@users.sourceforge.net> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Showing 8 changed files with 254 additions and 426 deletions Inline Diff
drivers/hid/Kconfig
1 | # | 1 | # |
2 | # HID driver configuration | 2 | # HID driver configuration |
3 | # | 3 | # |
4 | menuconfig HID_SUPPORT | 4 | menuconfig HID_SUPPORT |
5 | bool "HID Devices" | 5 | bool "HID Devices" |
6 | depends on INPUT | 6 | depends on INPUT |
7 | default y | 7 | default y |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here to get to see options for various computer-human interface | 9 | Say Y here to get to see options for various computer-human interface |
10 | device drivers. This option alone does not add any kernel code. | 10 | device drivers. This option alone does not add any kernel code. |
11 | 11 | ||
12 | If you say N, all options in this submenu will be skipped and disabled. | 12 | If you say N, all options in this submenu will be skipped and disabled. |
13 | 13 | ||
14 | if HID_SUPPORT | 14 | if HID_SUPPORT |
15 | 15 | ||
16 | config HID | 16 | config HID |
17 | tristate "Generic HID support" | 17 | tristate "Generic HID support" |
18 | depends on INPUT | 18 | depends on INPUT |
19 | default y | 19 | default y |
20 | ---help--- | 20 | ---help--- |
21 | A human interface device (HID) is a type of computer device that | 21 | A human interface device (HID) is a type of computer device that |
22 | interacts directly with and takes input from humans. The term "HID" | 22 | interacts directly with and takes input from humans. The term "HID" |
23 | most commonly used to refer to the USB-HID specification, but other | 23 | most commonly used to refer to the USB-HID specification, but other |
24 | devices (such as, but not strictly limited to, Bluetooth) are | 24 | devices (such as, but not strictly limited to, Bluetooth) are |
25 | designed using HID specification (this involves certain keyboards, | 25 | designed using HID specification (this involves certain keyboards, |
26 | mice, tablets, etc). This option compiles into kernel the generic | 26 | mice, tablets, etc). This option compiles into kernel the generic |
27 | HID layer code (parser, usages, etc.), which can then be used by | 27 | HID layer code (parser, usages, etc.), which can then be used by |
28 | transport-specific HID implementation (like USB or Bluetooth). | 28 | transport-specific HID implementation (like USB or Bluetooth). |
29 | 29 | ||
30 | For docs and specs, see http://www.usb.org/developers/hidpage/ | 30 | For docs and specs, see http://www.usb.org/developers/hidpage/ |
31 | 31 | ||
32 | If unsure, say Y. | 32 | If unsure, say Y. |
33 | 33 | ||
34 | config HIDRAW | 34 | config HIDRAW |
35 | bool "/dev/hidraw raw HID device support" | 35 | bool "/dev/hidraw raw HID device support" |
36 | depends on HID | 36 | depends on HID |
37 | ---help--- | 37 | ---help--- |
38 | Say Y here if you want to support HID devices (from the USB | 38 | Say Y here if you want to support HID devices (from the USB |
39 | specification standpoint) that aren't strictly user interface | 39 | specification standpoint) that aren't strictly user interface |
40 | devices, like monitor controls and Uninterruptable Power Supplies. | 40 | devices, like monitor controls and Uninterruptable Power Supplies. |
41 | 41 | ||
42 | This module supports these devices separately using a separate | 42 | This module supports these devices separately using a separate |
43 | event interface on /dev/hidraw. | 43 | event interface on /dev/hidraw. |
44 | 44 | ||
45 | There is also a /dev/hiddev configuration option in the USB HID | 45 | There is also a /dev/hiddev configuration option in the USB HID |
46 | configuration menu. In comparison to hiddev, this device does not process | 46 | configuration menu. In comparison to hiddev, this device does not process |
47 | the hid events at all (no parsing, no lookups). This lets applications | 47 | the hid events at all (no parsing, no lookups). This lets applications |
48 | to work on raw hid events when they want to, and avoid using transport-specific | 48 | to work on raw hid events when they want to, and avoid using transport-specific |
49 | userspace libhid/libusb libraries. | 49 | userspace libhid/libusb libraries. |
50 | 50 | ||
51 | If unsure, say Y. | 51 | If unsure, say Y. |
52 | 52 | ||
53 | source "drivers/hid/usbhid/Kconfig" | 53 | source "drivers/hid/usbhid/Kconfig" |
54 | 54 | ||
55 | menu "Special HID drivers" | 55 | menu "Special HID drivers" |
56 | depends on HID | 56 | depends on HID |
57 | 57 | ||
58 | config HID_3M_PCT | 58 | config HID_3M_PCT |
59 | tristate "3M PCT touchscreen" | 59 | tristate "3M PCT touchscreen" |
60 | depends on USB_HID | 60 | depends on USB_HID |
61 | ---help--- | 61 | ---help--- |
62 | Support for 3M PCT touch screens. | 62 | Support for 3M PCT touch screens. |
63 | 63 | ||
64 | config HID_A4TECH | 64 | config HID_A4TECH |
65 | tristate "A4 tech mice" if EMBEDDED | 65 | tristate "A4 tech mice" if EMBEDDED |
66 | depends on USB_HID | 66 | depends on USB_HID |
67 | default !EMBEDDED | 67 | default !EMBEDDED |
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 | ||
71 | config HID_ACRUX_FF | 71 | config HID_ACRUX_FF |
72 | tristate "ACRUX force feedback" | 72 | tristate "ACRUX force feedback" |
73 | depends on USB_HID | 73 | depends on USB_HID |
74 | select INPUT_FF_MEMLESS | 74 | select INPUT_FF_MEMLESS |
75 | ---help--- | 75 | ---help--- |
76 | Say Y here if you want to enable force feedback support for ACRUX | 76 | Say Y here if you want to enable force feedback support for ACRUX |
77 | game controllers. | 77 | game controllers. |
78 | 78 | ||
79 | config HID_APPLE | 79 | config HID_APPLE |
80 | tristate "Apple {i,Power,Mac}Books" if EMBEDDED | 80 | tristate "Apple {i,Power,Mac}Books" if EMBEDDED |
81 | depends on (USB_HID || BT_HIDP) | 81 | depends on (USB_HID || BT_HIDP) |
82 | default !EMBEDDED | 82 | default !EMBEDDED |
83 | ---help--- | 83 | ---help--- |
84 | Support for some Apple devices which less or more break | 84 | Support for some Apple devices which less or more break |
85 | HID specification. | 85 | HID specification. |
86 | 86 | ||
87 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, | 87 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, |
88 | MacBooks, MacBook Pros and Apple Aluminum. | 88 | MacBooks, MacBook Pros and Apple Aluminum. |
89 | 89 | ||
90 | config HID_BELKIN | 90 | config HID_BELKIN |
91 | tristate "Belkin Flip KVM and Wireless keyboard" if EMBEDDED | 91 | tristate "Belkin Flip KVM and Wireless keyboard" if EMBEDDED |
92 | depends on USB_HID | 92 | depends on USB_HID |
93 | default !EMBEDDED | 93 | default !EMBEDDED |
94 | ---help--- | 94 | ---help--- |
95 | Support for Belkin Flip KVM and Wireless keyboard. | 95 | Support for Belkin Flip KVM and Wireless keyboard. |
96 | 96 | ||
97 | config HID_CANDO | 97 | config HID_CANDO |
98 | tristate "Cando dual touch panel" | 98 | tristate "Cando dual touch panel" |
99 | depends on USB_HID | 99 | depends on USB_HID |
100 | ---help--- | 100 | ---help--- |
101 | Support for Cando dual touch panel. | 101 | Support for Cando dual touch panel. |
102 | 102 | ||
103 | config HID_CHERRY | 103 | config HID_CHERRY |
104 | tristate "Cherry Cymotion keyboard" if EMBEDDED | 104 | tristate "Cherry Cymotion keyboard" if EMBEDDED |
105 | depends on USB_HID | 105 | depends on USB_HID |
106 | default !EMBEDDED | 106 | default !EMBEDDED |
107 | ---help--- | 107 | ---help--- |
108 | Support for Cherry Cymotion keyboard. | 108 | Support for Cherry Cymotion keyboard. |
109 | 109 | ||
110 | config HID_CHICONY | 110 | config HID_CHICONY |
111 | tristate "Chicony Tactical pad" if EMBEDDED | 111 | tristate "Chicony Tactical pad" if EMBEDDED |
112 | depends on USB_HID | 112 | depends on USB_HID |
113 | default !EMBEDDED | 113 | default !EMBEDDED |
114 | ---help--- | 114 | ---help--- |
115 | Support for Chicony Tactical pad. | 115 | Support for Chicony Tactical pad. |
116 | 116 | ||
117 | config HID_PRODIKEYS | 117 | config HID_PRODIKEYS |
118 | tristate "Prodikeys PC-MIDI Keyboard support" | 118 | tristate "Prodikeys PC-MIDI Keyboard support" |
119 | depends on USB_HID && SND | 119 | depends on USB_HID && SND |
120 | select SND_RAWMIDI | 120 | select SND_RAWMIDI |
121 | ---help--- | 121 | ---help--- |
122 | Support for Prodikeys PC-MIDI Keyboard device support. | 122 | Support for Prodikeys PC-MIDI Keyboard device support. |
123 | Say Y here to enable support for this device. | 123 | Say Y here to enable support for this device. |
124 | - Prodikeys PC-MIDI keyboard. | 124 | - Prodikeys PC-MIDI keyboard. |
125 | The Prodikeys PC-MIDI acts as a USB Audio device, with one MIDI | 125 | The Prodikeys PC-MIDI acts as a USB Audio device, with one MIDI |
126 | input and one MIDI output. These MIDI jacks appear as | 126 | input and one MIDI output. These MIDI jacks appear as |
127 | a sound "card" in the ALSA sound system. | 127 | a sound "card" in the ALSA sound system. |
128 | Note: if you say N here, this device will still function as a basic | 128 | Note: if you say N here, this device will still function as a basic |
129 | multimedia keyboard, but will lack support for the musical keyboard | 129 | multimedia keyboard, but will lack support for the musical keyboard |
130 | and some additional multimedia keys. | 130 | and some additional multimedia keys. |
131 | 131 | ||
132 | config HID_CYPRESS | 132 | config HID_CYPRESS |
133 | tristate "Cypress mouse and barcode readers" if EMBEDDED | 133 | tristate "Cypress mouse and barcode readers" if EMBEDDED |
134 | depends on USB_HID | 134 | depends on USB_HID |
135 | default !EMBEDDED | 135 | default !EMBEDDED |
136 | ---help--- | 136 | ---help--- |
137 | Support for cypress mouse and barcode readers. | 137 | Support for cypress mouse and barcode readers. |
138 | 138 | ||
139 | config HID_DRAGONRISE | 139 | config HID_DRAGONRISE |
140 | tristate "DragonRise Inc. game controller" | 140 | tristate "DragonRise Inc. game controller" |
141 | depends on USB_HID | 141 | depends on USB_HID |
142 | ---help--- | 142 | ---help--- |
143 | Say Y here if you have DragonRise Inc.game controllers. | 143 | Say Y here if you have DragonRise Inc.game controllers. |
144 | 144 | ||
145 | config DRAGONRISE_FF | 145 | config DRAGONRISE_FF |
146 | bool "DragonRise Inc. force feedback" | 146 | bool "DragonRise Inc. force feedback" |
147 | depends on HID_DRAGONRISE | 147 | depends on HID_DRAGONRISE |
148 | select INPUT_FF_MEMLESS | 148 | select INPUT_FF_MEMLESS |
149 | ---help--- | 149 | ---help--- |
150 | Say Y here if you want to enable force feedback support for DragonRise Inc. | 150 | Say Y here if you want to enable force feedback support for DragonRise Inc. |
151 | game controllers. | 151 | game controllers. |
152 | 152 | ||
153 | config HID_EMS_FF | 153 | config HID_EMS_FF |
154 | tristate "EMS Production Inc. force feedback support" | 154 | tristate "EMS Production Inc. force feedback support" |
155 | depends on USB_HID | 155 | depends on USB_HID |
156 | select INPUT_FF_MEMLESS | 156 | select INPUT_FF_MEMLESS |
157 | ---help--- | 157 | ---help--- |
158 | Say Y here if you want to enable force feedback support for devices by | 158 | Say Y here if you want to enable force feedback support for devices by |
159 | EMS Production Ltd. | 159 | EMS Production Ltd. |
160 | Currently the following devices are known to be supported: | 160 | Currently the following devices are known to be supported: |
161 | - Trio Linker Plus II | 161 | - Trio Linker Plus II |
162 | 162 | ||
163 | config HID_EGALAX | 163 | config HID_EGALAX |
164 | tristate "eGalax multi-touch panel" | 164 | tristate "eGalax multi-touch panel" |
165 | depends on USB_HID | 165 | depends on USB_HID |
166 | ---help--- | 166 | ---help--- |
167 | Support for the eGalax dual-touch panels, including the | 167 | Support for the eGalax dual-touch panels, including the |
168 | Joojoo and Wetab tablets. | 168 | Joojoo and Wetab tablets. |
169 | 169 | ||
170 | config HID_ELECOM | 170 | config HID_ELECOM |
171 | tristate "ELECOM BM084 bluetooth mouse" | 171 | tristate "ELECOM BM084 bluetooth mouse" |
172 | depends on BT_HIDP | 172 | depends on BT_HIDP |
173 | ---help--- | 173 | ---help--- |
174 | Support for the ELECOM BM084 (bluetooth mouse). | 174 | Support for the ELECOM BM084 (bluetooth mouse). |
175 | 175 | ||
176 | config HID_EZKEY | 176 | config HID_EZKEY |
177 | tristate "Ezkey BTC 8193 keyboard" if EMBEDDED | 177 | tristate "Ezkey BTC 8193 keyboard" if EMBEDDED |
178 | depends on USB_HID | 178 | depends on USB_HID |
179 | default !EMBEDDED | 179 | default !EMBEDDED |
180 | ---help--- | 180 | ---help--- |
181 | Support for Ezkey BTC 8193 keyboard. | 181 | Support for Ezkey BTC 8193 keyboard. |
182 | 182 | ||
183 | config HID_KYE | 183 | config HID_KYE |
184 | tristate "Kye/Genius Ergo Mouse" if EMBEDDED | 184 | tristate "Kye/Genius Ergo Mouse" if EMBEDDED |
185 | depends on USB_HID | 185 | depends on USB_HID |
186 | default !EMBEDDED | 186 | default !EMBEDDED |
187 | ---help--- | 187 | ---help--- |
188 | Support for Kye/Genius Ergo Mouse. | 188 | Support for Kye/Genius Ergo Mouse. |
189 | 189 | ||
190 | config HID_UCLOGIC | 190 | config HID_UCLOGIC |
191 | tristate "UC-Logic" | 191 | tristate "UC-Logic" |
192 | depends on USB_HID | 192 | depends on USB_HID |
193 | ---help--- | 193 | ---help--- |
194 | Support for UC-Logic tablets. | 194 | Support for UC-Logic tablets. |
195 | 195 | ||
196 | config HID_WALTOP | 196 | config HID_WALTOP |
197 | tristate "Waltop" | 197 | tristate "Waltop" |
198 | depends on USB_HID | 198 | depends on USB_HID |
199 | ---help--- | 199 | ---help--- |
200 | Support for Waltop tablets. | 200 | Support for Waltop tablets. |
201 | 201 | ||
202 | config HID_GYRATION | 202 | config HID_GYRATION |
203 | tristate "Gyration remote control" | 203 | tristate "Gyration remote control" |
204 | depends on USB_HID | 204 | depends on USB_HID |
205 | ---help--- | 205 | ---help--- |
206 | Support for Gyration remote control. | 206 | Support for Gyration remote control. |
207 | 207 | ||
208 | config HID_TWINHAN | 208 | config HID_TWINHAN |
209 | tristate "Twinhan IR remote control" | 209 | tristate "Twinhan IR remote control" |
210 | depends on USB_HID | 210 | depends on USB_HID |
211 | ---help--- | 211 | ---help--- |
212 | Support for Twinhan IR remote control. | 212 | Support for Twinhan IR remote control. |
213 | 213 | ||
214 | config HID_KENSINGTON | 214 | config HID_KENSINGTON |
215 | tristate "Kensington Slimblade Trackball" if EMBEDDED | 215 | tristate "Kensington Slimblade Trackball" if EMBEDDED |
216 | depends on USB_HID | 216 | depends on USB_HID |
217 | default !EMBEDDED | 217 | default !EMBEDDED |
218 | ---help--- | 218 | ---help--- |
219 | Support for Kensington Slimblade Trackball. | 219 | Support for Kensington Slimblade Trackball. |
220 | 220 | ||
221 | config HID_LOGITECH | 221 | config HID_LOGITECH |
222 | tristate "Logitech devices" if EMBEDDED | 222 | tristate "Logitech devices" if EMBEDDED |
223 | depends on USB_HID | 223 | depends on USB_HID |
224 | default !EMBEDDED | 224 | default !EMBEDDED |
225 | ---help--- | 225 | ---help--- |
226 | Support for Logitech devices that are not fully compliant with HID standard. | 226 | Support for Logitech devices that are not fully compliant with HID standard. |
227 | 227 | ||
228 | config LOGITECH_FF | 228 | config LOGITECH_FF |
229 | bool "Logitech force feedback support" | 229 | bool "Logitech force feedback support" |
230 | depends on HID_LOGITECH | 230 | depends on HID_LOGITECH |
231 | select INPUT_FF_MEMLESS | 231 | select INPUT_FF_MEMLESS |
232 | help | 232 | help |
233 | Say Y here if you have one of these devices: | 233 | Say Y here if you have one of these devices: |
234 | - Logitech WingMan Cordless RumblePad | 234 | - Logitech WingMan Cordless RumblePad |
235 | - Logitech WingMan Cordless RumblePad 2 | 235 | - Logitech WingMan Cordless RumblePad 2 |
236 | - Logitech WingMan Force 3D | 236 | - Logitech WingMan Force 3D |
237 | - Logitech Formula Force EX | 237 | - Logitech Formula Force EX |
238 | - Logitech WingMan Formula Force GP | 238 | - Logitech WingMan Formula Force GP |
239 | - Logitech MOMO Force wheel | 239 | - Logitech MOMO Force wheel |
240 | 240 | ||
241 | and if you want to enable force feedback for them. | 241 | and if you want to enable force feedback for them. |
242 | Note: if you say N here, this device will still be supported, but without | 242 | Note: if you say N here, this device will still be supported, but without |
243 | force feedback. | 243 | force feedback. |
244 | 244 | ||
245 | config LOGIRUMBLEPAD2_FF | 245 | config LOGIRUMBLEPAD2_FF |
246 | bool "Logitech RumblePad/Rumblepad 2 force feedback support" | 246 | bool "Logitech RumblePad/Rumblepad 2 force feedback support" |
247 | depends on HID_LOGITECH | 247 | depends on HID_LOGITECH |
248 | select INPUT_FF_MEMLESS | 248 | select INPUT_FF_MEMLESS |
249 | help | 249 | help |
250 | Say Y here if you want to enable force feedback support for Logitech | 250 | Say Y here if you want to enable force feedback support for Logitech |
251 | RumblePad and Rumblepad 2 devices. | 251 | RumblePad and Rumblepad 2 devices. |
252 | 252 | ||
253 | config LOGIG940_FF | 253 | config LOGIG940_FF |
254 | bool "Logitech Flight System G940 force feedback support" | 254 | bool "Logitech Flight System G940 force feedback support" |
255 | depends on HID_LOGITECH | 255 | depends on HID_LOGITECH |
256 | select INPUT_FF_MEMLESS | 256 | select INPUT_FF_MEMLESS |
257 | help | 257 | help |
258 | Say Y here if you want to enable force feedback support for Logitech | 258 | Say Y here if you want to enable force feedback support for Logitech |
259 | Flight System G940 devices. | 259 | Flight System G940 devices. |
260 | 260 | ||
261 | config LOGIWII_FF | 261 | config LOGIWII_FF |
262 | bool "Logitech Speed Force Wireless force feedback support" | 262 | bool "Logitech Speed Force Wireless force feedback support" |
263 | depends on HID_LOGITECH | 263 | depends on HID_LOGITECH |
264 | select INPUT_FF_MEMLESS | 264 | select INPUT_FF_MEMLESS |
265 | help | 265 | help |
266 | Say Y here if you want to enable force feedback support for Logitech | 266 | Say Y here if you want to enable force feedback support for Logitech |
267 | Speed Force Wireless (Wii) devices. | 267 | Speed Force Wireless (Wii) devices. |
268 | 268 | ||
269 | config HID_MAGICMOUSE | 269 | config HID_MAGICMOUSE |
270 | tristate "Apple MagicMouse multi-touch support" | 270 | tristate "Apple MagicMouse multi-touch support" |
271 | depends on BT_HIDP | 271 | depends on BT_HIDP |
272 | ---help--- | 272 | ---help--- |
273 | Support for the Apple Magic Mouse multi-touch. | 273 | Support for the Apple Magic Mouse multi-touch. |
274 | 274 | ||
275 | Say Y here if you want support for the multi-touch features of the | 275 | Say Y here if you want support for the multi-touch features of the |
276 | Apple Wireless "Magic" Mouse. | 276 | Apple Wireless "Magic" Mouse. |
277 | 277 | ||
278 | config HID_MICROSOFT | 278 | config HID_MICROSOFT |
279 | tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED | 279 | tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED |
280 | depends on USB_HID | 280 | depends on USB_HID |
281 | default !EMBEDDED | 281 | default !EMBEDDED |
282 | ---help--- | 282 | ---help--- |
283 | Support for Microsoft devices that are not fully compliant with HID standard. | 283 | Support for Microsoft devices that are not fully compliant with HID standard. |
284 | 284 | ||
285 | config HID_MOSART | 285 | config HID_MOSART |
286 | tristate "MosArt dual-touch panels" | 286 | tristate "MosArt dual-touch panels" |
287 | depends on USB_HID | 287 | depends on USB_HID |
288 | ---help--- | 288 | ---help--- |
289 | Support for MosArt dual-touch panels. | 289 | Support for MosArt dual-touch panels. |
290 | 290 | ||
291 | config HID_MONTEREY | 291 | config HID_MONTEREY |
292 | tristate "Monterey Genius KB29E keyboard" if EMBEDDED | 292 | tristate "Monterey Genius KB29E keyboard" if EMBEDDED |
293 | depends on USB_HID | 293 | depends on USB_HID |
294 | default !EMBEDDED | 294 | default !EMBEDDED |
295 | ---help--- | 295 | ---help--- |
296 | Support for Monterey Genius KB29E. | 296 | Support for Monterey Genius KB29E. |
297 | 297 | ||
298 | config HID_MULTITOUCH | 298 | config HID_MULTITOUCH |
299 | tristate "HID Multitouch panels" | 299 | tristate "HID Multitouch panels" |
300 | depends on USB_HID | 300 | depends on USB_HID |
301 | ---help--- | 301 | ---help--- |
302 | Generic support for HID multitouch panels. | 302 | Generic support for HID multitouch panels. |
303 | 303 | ||
304 | Say Y here if you have one of the following devices: | 304 | Say Y here if you have one of the following devices: |
305 | - Cypress TrueTouch panels | 305 | - Cypress TrueTouch panels |
306 | - Hanvon dual touch panels | 306 | - Hanvon dual touch panels |
307 | - Pixcir dual touch panels | 307 | - Pixcir dual touch panels |
308 | - 'Sensing Win7-TwoFinger' panel by GeneralTouch | 308 | - 'Sensing Win7-TwoFinger' panel by GeneralTouch |
309 | 309 | ||
310 | If unsure, say N. | 310 | If unsure, say N. |
311 | 311 | ||
312 | To compile this driver as a module, choose M here: the | 312 | To compile this driver as a module, choose M here: the |
313 | module will be called hid-multitouch. | 313 | module will be called hid-multitouch. |
314 | 314 | ||
315 | config HID_NTRIG | 315 | config HID_NTRIG |
316 | tristate "N-Trig touch screen" | 316 | tristate "N-Trig touch screen" |
317 | depends on USB_HID | 317 | depends on USB_HID |
318 | ---help--- | 318 | ---help--- |
319 | Support for N-Trig touch screen. | 319 | Support for N-Trig touch screen. |
320 | 320 | ||
321 | config HID_ORTEK | 321 | config HID_ORTEK |
322 | tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad" | 322 | tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad" |
323 | depends on USB_HID | 323 | depends on USB_HID |
324 | ---help--- | 324 | ---help--- |
325 | Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. | 325 | Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. |
326 | 326 | ||
327 | config HID_PANTHERLORD | 327 | config HID_PANTHERLORD |
328 | tristate "Pantherlord/GreenAsia game controller" | 328 | tristate "Pantherlord/GreenAsia game controller" |
329 | depends on USB_HID | 329 | depends on USB_HID |
330 | ---help--- | 330 | ---help--- |
331 | Say Y here if you have a PantherLord/GreenAsia based game controller | 331 | Say Y here if you have a PantherLord/GreenAsia based game controller |
332 | or adapter. | 332 | or adapter. |
333 | 333 | ||
334 | config PANTHERLORD_FF | 334 | config PANTHERLORD_FF |
335 | bool "Pantherlord force feedback support" | 335 | bool "Pantherlord force feedback support" |
336 | depends on HID_PANTHERLORD | 336 | depends on HID_PANTHERLORD |
337 | select INPUT_FF_MEMLESS | 337 | select INPUT_FF_MEMLESS |
338 | ---help--- | 338 | ---help--- |
339 | Say Y here if you have a PantherLord/GreenAsia based game controller | 339 | Say Y here if you have a PantherLord/GreenAsia based game controller |
340 | or adapter and want to enable force feedback support for it. | 340 | or adapter and want to enable force feedback support for it. |
341 | 341 | ||
342 | config HID_PETALYNX | 342 | config HID_PETALYNX |
343 | tristate "Petalynx Maxter remote control" | 343 | tristate "Petalynx Maxter remote control" |
344 | depends on USB_HID | 344 | depends on USB_HID |
345 | ---help--- | 345 | ---help--- |
346 | Support for Petalynx Maxter remote control. | 346 | Support for Petalynx Maxter remote control. |
347 | 347 | ||
348 | config HID_PICOLCD | 348 | config HID_PICOLCD |
349 | tristate "PicoLCD (graphic version)" | 349 | tristate "PicoLCD (graphic version)" |
350 | depends on USB_HID | 350 | depends on USB_HID |
351 | ---help--- | 351 | ---help--- |
352 | This provides support for Minibox PicoLCD devices, currently | 352 | This provides support for Minibox PicoLCD devices, currently |
353 | only the graphical ones are supported. | 353 | only the graphical ones are supported. |
354 | 354 | ||
355 | This includes support for the following device features: | 355 | This includes support for the following device features: |
356 | - Keypad | 356 | - Keypad |
357 | - Switching between Firmware and Flash mode | 357 | - Switching between Firmware and Flash mode |
358 | - EEProm / Flash access (via debugfs) | 358 | - EEProm / Flash access (via debugfs) |
359 | Features selectively enabled: | 359 | Features selectively enabled: |
360 | - Framebuffer for monochrome 256x64 display | 360 | - Framebuffer for monochrome 256x64 display |
361 | - Backlight control | 361 | - Backlight control |
362 | - Contrast control | 362 | - Contrast control |
363 | - General purpose outputs | 363 | - General purpose outputs |
364 | Features that are not (yet) supported: | 364 | Features that are not (yet) supported: |
365 | - IR | 365 | - IR |
366 | 366 | ||
367 | config HID_PICOLCD_FB | 367 | config HID_PICOLCD_FB |
368 | bool "Framebuffer support" if EMBEDDED | 368 | bool "Framebuffer support" if EMBEDDED |
369 | default !EMBEDDED | 369 | default !EMBEDDED |
370 | depends on HID_PICOLCD | 370 | depends on HID_PICOLCD |
371 | depends on HID_PICOLCD=FB || FB=y | 371 | depends on HID_PICOLCD=FB || FB=y |
372 | select FB_DEFERRED_IO | 372 | select FB_DEFERRED_IO |
373 | select FB_SYS_FILLRECT | 373 | select FB_SYS_FILLRECT |
374 | select FB_SYS_COPYAREA | 374 | select FB_SYS_COPYAREA |
375 | select FB_SYS_IMAGEBLIT | 375 | select FB_SYS_IMAGEBLIT |
376 | select FB_SYS_FOPS | 376 | select FB_SYS_FOPS |
377 | ---help--- | 377 | ---help--- |
378 | Provide access to PicoLCD's 256x64 monochrome display via a | 378 | Provide access to PicoLCD's 256x64 monochrome display via a |
379 | frambuffer device. | 379 | frambuffer device. |
380 | 380 | ||
381 | config HID_PICOLCD_BACKLIGHT | 381 | config HID_PICOLCD_BACKLIGHT |
382 | bool "Backlight control" if EMBEDDED | 382 | bool "Backlight control" if EMBEDDED |
383 | default !EMBEDDED | 383 | default !EMBEDDED |
384 | depends on HID_PICOLCD | 384 | depends on HID_PICOLCD |
385 | depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y | 385 | depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y |
386 | ---help--- | 386 | ---help--- |
387 | Provide access to PicoLCD's backlight control via backlight | 387 | Provide access to PicoLCD's backlight control via backlight |
388 | class. | 388 | class. |
389 | 389 | ||
390 | config HID_PICOLCD_LCD | 390 | config HID_PICOLCD_LCD |
391 | bool "Contrast control" if EMBEDDED | 391 | bool "Contrast control" if EMBEDDED |
392 | default !EMBEDDED | 392 | default !EMBEDDED |
393 | depends on HID_PICOLCD | 393 | depends on HID_PICOLCD |
394 | depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y | 394 | depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y |
395 | ---help--- | 395 | ---help--- |
396 | Provide access to PicoLCD's LCD contrast via lcd class. | 396 | Provide access to PicoLCD's LCD contrast via lcd class. |
397 | 397 | ||
398 | config HID_PICOLCD_LEDS | 398 | config HID_PICOLCD_LEDS |
399 | bool "GPO via leds class" if EMBEDDED | 399 | bool "GPO via leds class" if EMBEDDED |
400 | default !EMBEDDED | 400 | default !EMBEDDED |
401 | depends on HID_PICOLCD | 401 | depends on HID_PICOLCD |
402 | depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y | 402 | depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y |
403 | ---help--- | 403 | ---help--- |
404 | Provide access to PicoLCD's GPO pins via leds class. | 404 | Provide access to PicoLCD's GPO pins via leds class. |
405 | 405 | ||
406 | config HID_QUANTA | 406 | config HID_QUANTA |
407 | tristate "Quanta Optical Touch panels" | 407 | tristate "Quanta Optical Touch panels" |
408 | depends on USB_HID | 408 | depends on USB_HID |
409 | ---help--- | 409 | ---help--- |
410 | Support for Quanta Optical Touch dual-touch panels. | 410 | Support for Quanta Optical Touch dual-touch panels. |
411 | 411 | ||
412 | config HID_ROCCAT | 412 | config HID_ROCCAT |
413 | tristate "Roccat special event support" | 413 | tristate "Roccat special event support" |
414 | depends on USB_HID | 414 | depends on USB_HID |
415 | ---help--- | 415 | ---help--- |
416 | Support for Roccat special events. | 416 | Support for Roccat special events. |
417 | Say Y here if you have a Roccat mouse or keyboard and want OSD or | 417 | Say Y here if you have a Roccat mouse or keyboard and want OSD or |
418 | macro execution support. | 418 | macro execution support. |
419 | 419 | ||
420 | config HID_ROCCAT_COMMON | ||
421 | tristate | ||
422 | |||
420 | config HID_ROCCAT_ARVO | 423 | config HID_ROCCAT_ARVO |
421 | tristate "Roccat Arvo keyboard support" | 424 | tristate "Roccat Arvo keyboard support" |
422 | depends on USB_HID | 425 | depends on USB_HID |
423 | select HID_ROCCAT | 426 | select HID_ROCCAT |
427 | select HID_ROCCAT_COMMON | ||
424 | ---help--- | 428 | ---help--- |
425 | Support for Roccat Arvo keyboard. | 429 | Support for Roccat Arvo keyboard. |
426 | 430 | ||
427 | config HID_ROCCAT_KONE | 431 | config HID_ROCCAT_KONE |
428 | tristate "Roccat Kone Mouse support" | 432 | tristate "Roccat Kone Mouse support" |
429 | depends on USB_HID | 433 | depends on USB_HID |
430 | select HID_ROCCAT | 434 | select HID_ROCCAT |
435 | select HID_ROCCAT_COMMON | ||
431 | ---help--- | 436 | ---help--- |
432 | Support for Roccat Kone mouse. | 437 | Support for Roccat Kone mouse. |
433 | 438 | ||
434 | config HID_ROCCAT_KONEPLUS | 439 | config HID_ROCCAT_KONEPLUS |
435 | tristate "Roccat Kone[+] mouse support" | 440 | tristate "Roccat Kone[+] mouse support" |
436 | depends on USB_HID | 441 | depends on USB_HID |
437 | select HID_ROCCAT | 442 | select HID_ROCCAT |
443 | select HID_ROCCAT_COMMON | ||
438 | ---help--- | 444 | ---help--- |
439 | Support for Roccat Kone[+] mouse. | 445 | Support for Roccat Kone[+] mouse. |
440 | 446 | ||
441 | config HID_ROCCAT_PYRA | 447 | config HID_ROCCAT_PYRA |
442 | tristate "Roccat Pyra mouse support" | 448 | tristate "Roccat Pyra mouse support" |
443 | depends on USB_HID | 449 | depends on USB_HID |
444 | select HID_ROCCAT | 450 | select HID_ROCCAT |
451 | select HID_ROCCAT_COMMON | ||
445 | ---help--- | 452 | ---help--- |
446 | Support for Roccat Pyra mouse. | 453 | Support for Roccat Pyra mouse. |
447 | 454 | ||
448 | config HID_SAMSUNG | 455 | config HID_SAMSUNG |
449 | tristate "Samsung InfraRed remote control or keyboards" | 456 | tristate "Samsung InfraRed remote control or keyboards" |
450 | depends on USB_HID | 457 | depends on USB_HID |
451 | ---help--- | 458 | ---help--- |
452 | Support for Samsung InfraRed remote control or keyboards. | 459 | Support for Samsung InfraRed remote control or keyboards. |
453 | 460 | ||
454 | config HID_SONY | 461 | config HID_SONY |
455 | tristate "Sony PS3 controller" | 462 | tristate "Sony PS3 controller" |
456 | depends on USB_HID | 463 | depends on USB_HID |
457 | ---help--- | 464 | ---help--- |
458 | Support for Sony PS3 controller. | 465 | Support for Sony PS3 controller. |
459 | 466 | ||
460 | config HID_STANTUM | 467 | config HID_STANTUM |
461 | tristate "Stantum multitouch panel" | 468 | tristate "Stantum multitouch panel" |
462 | depends on USB_HID | 469 | depends on USB_HID |
463 | ---help--- | 470 | ---help--- |
464 | Support for Stantum multitouch panel. | 471 | Support for Stantum multitouch panel. |
465 | 472 | ||
466 | config HID_SUNPLUS | 473 | config HID_SUNPLUS |
467 | tristate "Sunplus wireless desktop" | 474 | tristate "Sunplus wireless desktop" |
468 | depends on USB_HID | 475 | depends on USB_HID |
469 | ---help--- | 476 | ---help--- |
470 | Support for Sunplus wireless desktop. | 477 | Support for Sunplus wireless desktop. |
471 | 478 | ||
472 | config HID_GREENASIA | 479 | config HID_GREENASIA |
473 | tristate "GreenAsia (Product ID 0x12) game controller support" | 480 | tristate "GreenAsia (Product ID 0x12) game controller support" |
474 | depends on USB_HID | 481 | depends on USB_HID |
475 | ---help--- | 482 | ---help--- |
476 | Say Y here if you have a GreenAsia (Product ID 0x12) based game | 483 | Say Y here if you have a GreenAsia (Product ID 0x12) based game |
477 | controller or adapter. | 484 | controller or adapter. |
478 | 485 | ||
479 | config GREENASIA_FF | 486 | config GREENASIA_FF |
480 | bool "GreenAsia (Product ID 0x12) force feedback support" | 487 | bool "GreenAsia (Product ID 0x12) force feedback support" |
481 | depends on HID_GREENASIA | 488 | depends on HID_GREENASIA |
482 | select INPUT_FF_MEMLESS | 489 | select INPUT_FF_MEMLESS |
483 | ---help--- | 490 | ---help--- |
484 | Say Y here if you have a GreenAsia (Product ID 0x12) based game controller | 491 | Say Y here if you have a GreenAsia (Product ID 0x12) based game controller |
485 | (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter | 492 | (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter |
486 | and want to enable force feedback support for it. | 493 | and want to enable force feedback support for it. |
487 | 494 | ||
488 | config HID_SMARTJOYPLUS | 495 | config HID_SMARTJOYPLUS |
489 | tristate "SmartJoy PLUS PS2/USB adapter support" | 496 | tristate "SmartJoy PLUS PS2/USB adapter support" |
490 | depends on USB_HID | 497 | depends on USB_HID |
491 | ---help--- | 498 | ---help--- |
492 | Support for SmartJoy PLUS PS2/USB adapter. | 499 | Support for SmartJoy PLUS PS2/USB adapter. |
493 | 500 | ||
494 | config SMARTJOYPLUS_FF | 501 | config SMARTJOYPLUS_FF |
495 | bool "SmartJoy PLUS PS2/USB adapter force feedback support" | 502 | bool "SmartJoy PLUS PS2/USB adapter force feedback support" |
496 | depends on HID_SMARTJOYPLUS | 503 | depends on HID_SMARTJOYPLUS |
497 | select INPUT_FF_MEMLESS | 504 | select INPUT_FF_MEMLESS |
498 | ---help--- | 505 | ---help--- |
499 | Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to | 506 | Say Y here if you have a SmartJoy PLUS PS2/USB adapter and want to |
500 | enable force feedback support for it. | 507 | enable force feedback support for it. |
501 | 508 | ||
502 | config HID_TOPSEED | 509 | config HID_TOPSEED |
503 | tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" | 510 | tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" |
504 | depends on USB_HID | 511 | depends on USB_HID |
505 | ---help--- | 512 | ---help--- |
506 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic | 513 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic |
507 | CLLRCMCE remote control. | 514 | CLLRCMCE remote control. |
508 | 515 | ||
509 | config HID_THRUSTMASTER | 516 | config HID_THRUSTMASTER |
510 | tristate "ThrustMaster devices support" | 517 | tristate "ThrustMaster devices support" |
511 | depends on USB_HID | 518 | depends on USB_HID |
512 | ---help--- | 519 | ---help--- |
513 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or | 520 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or |
514 | a THRUSTMASTER Ferrari GT Rumble Wheel. | 521 | a THRUSTMASTER Ferrari GT Rumble Wheel. |
515 | 522 | ||
516 | config THRUSTMASTER_FF | 523 | config THRUSTMASTER_FF |
517 | bool "ThrustMaster devices force feedback support" | 524 | bool "ThrustMaster devices force feedback support" |
518 | depends on HID_THRUSTMASTER | 525 | depends on HID_THRUSTMASTER |
519 | select INPUT_FF_MEMLESS | 526 | select INPUT_FF_MEMLESS |
520 | ---help--- | 527 | ---help--- |
521 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3, | 528 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or 3, |
522 | a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT | 529 | a THRUSTMASTER Dual Trigger 3-in-1 or a THRUSTMASTER Ferrari GT |
523 | Rumble Force or Force Feedback Wheel. | 530 | Rumble Force or Force Feedback Wheel. |
524 | 531 | ||
525 | config HID_WACOM | 532 | config HID_WACOM |
526 | tristate "Wacom Bluetooth devices support" | 533 | tristate "Wacom Bluetooth devices support" |
527 | depends on BT_HIDP | 534 | depends on BT_HIDP |
528 | ---help--- | 535 | ---help--- |
529 | Support for Wacom Graphire Bluetooth tablet. | 536 | Support for Wacom Graphire Bluetooth tablet. |
530 | 537 | ||
531 | config HID_WACOM_POWER_SUPPLY | 538 | config HID_WACOM_POWER_SUPPLY |
532 | bool "Wacom Bluetooth devices power supply status support" | 539 | bool "Wacom Bluetooth devices power supply status support" |
533 | depends on HID_WACOM | 540 | depends on HID_WACOM |
534 | select POWER_SUPPLY | 541 | select POWER_SUPPLY |
535 | ---help--- | 542 | ---help--- |
536 | Say Y here if you want to enable power supply status monitoring for | 543 | Say Y here if you want to enable power supply status monitoring for |
537 | Wacom Bluetooth devices. | 544 | Wacom Bluetooth devices. |
538 | 545 | ||
539 | config HID_ZEROPLUS | 546 | config HID_ZEROPLUS |
540 | tristate "Zeroplus based game controller support" | 547 | tristate "Zeroplus based game controller support" |
541 | depends on USB_HID | 548 | depends on USB_HID |
542 | ---help--- | 549 | ---help--- |
543 | Say Y here if you have a Zeroplus based game controller. | 550 | Say Y here if you have a Zeroplus based game controller. |
544 | 551 | ||
545 | config ZEROPLUS_FF | 552 | config ZEROPLUS_FF |
546 | bool "Zeroplus based game controller force feedback support" | 553 | bool "Zeroplus based game controller force feedback support" |
547 | depends on HID_ZEROPLUS | 554 | depends on HID_ZEROPLUS |
548 | select INPUT_FF_MEMLESS | 555 | select INPUT_FF_MEMLESS |
549 | ---help--- | 556 | ---help--- |
550 | Say Y here if you have a Zeroplus based game controller and want | 557 | Say Y here if you have a Zeroplus based game controller and want |
551 | to have force feedback support for it. | 558 | to have force feedback support for it. |
552 | 559 | ||
553 | config HID_ZYDACRON | 560 | config HID_ZYDACRON |
554 | tristate "Zydacron remote control support" | 561 | tristate "Zydacron remote control support" |
555 | depends on USB_HID | 562 | depends on USB_HID |
556 | ---help--- | 563 | ---help--- |
557 | Support for Zydacron remote control. | 564 | Support for Zydacron remote control. |
558 | 565 | ||
559 | endmenu | 566 | endmenu |
560 | 567 | ||
561 | endif # HID_SUPPORT | 568 | endif # HID_SUPPORT |
562 | 569 |
drivers/hid/Makefile
1 | # | 1 | # |
2 | # Makefile for the HID driver | 2 | # Makefile for the HID driver |
3 | # | 3 | # |
4 | hid-y := hid-core.o hid-input.o | 4 | hid-y := hid-core.o hid-input.o |
5 | 5 | ||
6 | ifdef CONFIG_DEBUG_FS | 6 | ifdef CONFIG_DEBUG_FS |
7 | hid-objs += hid-debug.o | 7 | hid-objs += hid-debug.o |
8 | endif | 8 | endif |
9 | 9 | ||
10 | obj-$(CONFIG_HID) += hid.o | 10 | obj-$(CONFIG_HID) += hid.o |
11 | 11 | ||
12 | hid-$(CONFIG_HIDRAW) += hidraw.o | 12 | hid-$(CONFIG_HIDRAW) += hidraw.o |
13 | 13 | ||
14 | hid-logitech-y := hid-lg.o | 14 | hid-logitech-y := hid-lg.o |
15 | ifdef CONFIG_LOGITECH_FF | 15 | ifdef CONFIG_LOGITECH_FF |
16 | hid-logitech-y += hid-lgff.o | 16 | hid-logitech-y += hid-lgff.o |
17 | endif | 17 | endif |
18 | ifdef CONFIG_LOGIRUMBLEPAD2_FF | 18 | ifdef CONFIG_LOGIRUMBLEPAD2_FF |
19 | hid-logitech-y += hid-lg2ff.o | 19 | hid-logitech-y += hid-lg2ff.o |
20 | endif | 20 | endif |
21 | ifdef CONFIG_LOGIG940_FF | 21 | ifdef CONFIG_LOGIG940_FF |
22 | hid-logitech-y += hid-lg3ff.o | 22 | hid-logitech-y += hid-lg3ff.o |
23 | endif | 23 | endif |
24 | ifdef CONFIG_LOGIWII_FF | 24 | ifdef CONFIG_LOGIWII_FF |
25 | hid-logitech-y += hid-lg4ff.o | 25 | hid-logitech-y += hid-lg4ff.o |
26 | endif | 26 | endif |
27 | 27 | ||
28 | obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o | 28 | obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o |
29 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 29 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
30 | obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o | 30 | obj-$(CONFIG_HID_ACRUX_FF) += hid-axff.o |
31 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 31 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
32 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | 32 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o |
33 | obj-$(CONFIG_HID_CANDO) += hid-cando.o | 33 | obj-$(CONFIG_HID_CANDO) += hid-cando.o |
34 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 34 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
35 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o | 35 | obj-$(CONFIG_HID_CHICONY) += hid-chicony.o |
36 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | 36 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o |
37 | obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o | 37 | obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o |
38 | obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o | 38 | obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o |
39 | obj-$(CONFIG_HID_EGALAX) += hid-egalax.o | 39 | obj-$(CONFIG_HID_EGALAX) += hid-egalax.o |
40 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o | 40 | obj-$(CONFIG_HID_ELECOM) += hid-elecom.o |
41 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o | 41 | obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o |
42 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o | 42 | obj-$(CONFIG_HID_GYRATION) += hid-gyration.o |
43 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o | 43 | obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o |
44 | obj-$(CONFIG_HID_KYE) += hid-kye.o | 44 | obj-$(CONFIG_HID_KYE) += hid-kye.o |
45 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o | 45 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o |
46 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o | 46 | obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o |
47 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o | 47 | obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o |
48 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o | 48 | obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o |
49 | obj-$(CONFIG_HID_MOSART) += hid-mosart.o | 49 | obj-$(CONFIG_HID_MOSART) += hid-mosart.o |
50 | obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o | 50 | obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o |
51 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o | 51 | obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o |
52 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o | 52 | obj-$(CONFIG_HID_ORTEK) += hid-ortek.o |
53 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o | 53 | obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o |
54 | obj-$(CONFIG_HID_QUANTA) += hid-quanta.o | 54 | obj-$(CONFIG_HID_QUANTA) += hid-quanta.o |
55 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o | 55 | obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o |
56 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o | 56 | obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o |
57 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o | 57 | obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o |
58 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o | 58 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o |
59 | obj-$(CONFIG_HID_ROCCAT_COMMON) += hid-roccat-common.o | ||
59 | obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o | 60 | obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o |
60 | obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o | 61 | obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o |
61 | obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o | 62 | obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o |
62 | obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o | 63 | obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o |
63 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 64 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
64 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 65 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o |
65 | obj-$(CONFIG_HID_SONY) += hid-sony.o | 66 | obj-$(CONFIG_HID_SONY) += hid-sony.o |
66 | obj-$(CONFIG_HID_STANTUM) += hid-stantum.o | 67 | obj-$(CONFIG_HID_STANTUM) += hid-stantum.o |
67 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o | 68 | obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o |
68 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o | 69 | obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o |
69 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o | 70 | obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o |
70 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o | 71 | obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o |
71 | obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o | 72 | obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o |
72 | obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o | 73 | obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o |
73 | obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o | 74 | obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o |
74 | obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o | 75 | obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o |
75 | obj-$(CONFIG_HID_WACOM) += hid-wacom.o | 76 | obj-$(CONFIG_HID_WACOM) += hid-wacom.o |
76 | obj-$(CONFIG_HID_WALTOP) += hid-waltop.o | 77 | obj-$(CONFIG_HID_WALTOP) += hid-waltop.o |
77 | 78 | ||
78 | obj-$(CONFIG_USB_HID) += usbhid/ | 79 | obj-$(CONFIG_USB_HID) += usbhid/ |
79 | obj-$(CONFIG_USB_MOUSE) += usbhid/ | 80 | obj-$(CONFIG_USB_MOUSE) += usbhid/ |
80 | obj-$(CONFIG_USB_KBD) += usbhid/ | 81 | obj-$(CONFIG_USB_KBD) += usbhid/ |
81 | 82 | ||
82 | 83 |
drivers/hid/hid-roccat-arvo.c
1 | /* | 1 | /* |
2 | * Roccat Arvo driver for Linux | 2 | * Roccat Arvo driver for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net> | 4 | * Copyright (c) 2011 Stefan Achatz <erazor_de@users.sourceforge.net> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. | 11 | * any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Roccat Arvo is a gamer keyboard with 5 macro keys that can be configured in | 15 | * Roccat Arvo is a gamer keyboard with 5 macro keys that can be configured in |
16 | * 5 profiles. | 16 | * 5 profiles. |
17 | */ | 17 | */ |
18 | 18 | ||
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> |
25 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
26 | #include "hid-roccat.h" | 25 | #include "hid-roccat.h" |
26 | #include "hid-roccat-common.h" | ||
27 | #include "hid-roccat-arvo.h" | 27 | #include "hid-roccat-arvo.h" |
28 | 28 | ||
29 | static struct class *arvo_class; | 29 | static struct class *arvo_class; |
30 | 30 | ||
31 | static int arvo_receive(struct usb_device *usb_dev, uint usb_command, | ||
32 | void *buf, uint size) | ||
33 | { | ||
34 | int len; | ||
35 | |||
36 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
37 | USB_REQ_CLEAR_FEATURE, | ||
38 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
39 | usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT); | ||
40 | |||
41 | return (len != size) ? -EIO : 0; | ||
42 | } | ||
43 | |||
44 | static int arvo_send(struct usb_device *usb_dev, uint usb_command, | ||
45 | void const *buf, uint size) | ||
46 | { | ||
47 | int len; | ||
48 | |||
49 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | ||
50 | USB_REQ_SET_CONFIGURATION, | ||
51 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
52 | usb_command, 0, (void *)buf, size, USB_CTRL_SET_TIMEOUT); | ||
53 | |||
54 | return (len != size) ? -EIO : 0; | ||
55 | } | ||
56 | |||
57 | static ssize_t arvo_sysfs_show_mode_key(struct device *dev, | 31 | static ssize_t arvo_sysfs_show_mode_key(struct device *dev, |
58 | struct device_attribute *attr, char *buf) | 32 | struct device_attribute *attr, char *buf) |
59 | { | 33 | { |
60 | struct arvo_device *arvo = | 34 | struct arvo_device *arvo = |
61 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 35 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
62 | struct usb_device *usb_dev = | 36 | struct usb_device *usb_dev = |
63 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); | 37 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); |
64 | struct arvo_mode_key *temp_buf; | 38 | struct arvo_mode_key temp_buf; |
65 | int retval; | 39 | int retval; |
66 | 40 | ||
67 | temp_buf = kmalloc(sizeof(struct arvo_mode_key), GFP_KERNEL); | ||
68 | if (!temp_buf) | ||
69 | return -ENOMEM; | ||
70 | |||
71 | mutex_lock(&arvo->arvo_lock); | 41 | mutex_lock(&arvo->arvo_lock); |
72 | retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY, | 42 | retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY, |
73 | temp_buf, sizeof(struct arvo_mode_key)); | 43 | &temp_buf, sizeof(struct arvo_mode_key)); |
74 | mutex_unlock(&arvo->arvo_lock); | 44 | mutex_unlock(&arvo->arvo_lock); |
75 | if (retval) | 45 | if (retval) |
76 | goto out; | 46 | return retval; |
77 | 47 | ||
78 | retval = snprintf(buf, PAGE_SIZE, "%d\n", temp_buf->state); | 48 | return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.state); |
79 | out: | ||
80 | kfree(temp_buf); | ||
81 | return retval; | ||
82 | } | 49 | } |
83 | 50 | ||
84 | static ssize_t arvo_sysfs_set_mode_key(struct device *dev, | 51 | static ssize_t arvo_sysfs_set_mode_key(struct device *dev, |
85 | struct device_attribute *attr, char const *buf, size_t size) | 52 | struct device_attribute *attr, char const *buf, size_t size) |
86 | { | 53 | { |
87 | struct arvo_device *arvo = | 54 | struct arvo_device *arvo = |
88 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 55 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
89 | struct usb_device *usb_dev = | 56 | struct usb_device *usb_dev = |
90 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); | 57 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); |
91 | struct arvo_mode_key *temp_buf; | 58 | struct arvo_mode_key temp_buf; |
92 | unsigned long state; | 59 | unsigned long state; |
93 | int retval; | 60 | int retval; |
94 | 61 | ||
95 | temp_buf = kmalloc(sizeof(struct arvo_mode_key), GFP_KERNEL); | ||
96 | if (!temp_buf) | ||
97 | return -ENOMEM; | ||
98 | |||
99 | retval = strict_strtoul(buf, 10, &state); | 62 | retval = strict_strtoul(buf, 10, &state); |
100 | if (retval) | 63 | if (retval) |
101 | goto out; | 64 | return retval; |
102 | 65 | ||
103 | temp_buf->command = ARVO_COMMAND_MODE_KEY; | 66 | temp_buf.command = ARVO_COMMAND_MODE_KEY; |
104 | temp_buf->state = state; | 67 | temp_buf.state = state; |
105 | 68 | ||
106 | mutex_lock(&arvo->arvo_lock); | 69 | mutex_lock(&arvo->arvo_lock); |
107 | retval = arvo_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY, | 70 | retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY, |
108 | temp_buf, sizeof(struct arvo_mode_key)); | 71 | &temp_buf, sizeof(struct arvo_mode_key)); |
109 | mutex_unlock(&arvo->arvo_lock); | 72 | mutex_unlock(&arvo->arvo_lock); |
110 | if (retval) | 73 | if (retval) |
111 | goto out; | 74 | return retval; |
112 | 75 | ||
113 | retval = size; | 76 | return size; |
114 | out: | ||
115 | kfree(temp_buf); | ||
116 | return retval; | ||
117 | } | 77 | } |
118 | 78 | ||
119 | static ssize_t arvo_sysfs_show_key_mask(struct device *dev, | 79 | static ssize_t arvo_sysfs_show_key_mask(struct device *dev, |
120 | struct device_attribute *attr, char *buf) | 80 | struct device_attribute *attr, char *buf) |
121 | { | 81 | { |
122 | struct arvo_device *arvo = | 82 | struct arvo_device *arvo = |
123 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 83 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
124 | struct usb_device *usb_dev = | 84 | struct usb_device *usb_dev = |
125 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); | 85 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); |
126 | struct arvo_key_mask *temp_buf; | 86 | struct arvo_key_mask temp_buf; |
127 | int retval; | 87 | int retval; |
128 | 88 | ||
129 | temp_buf = kmalloc(sizeof(struct arvo_key_mask), GFP_KERNEL); | ||
130 | if (!temp_buf) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | mutex_lock(&arvo->arvo_lock); | 89 | mutex_lock(&arvo->arvo_lock); |
134 | retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK, | 90 | retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK, |
135 | temp_buf, sizeof(struct arvo_key_mask)); | 91 | &temp_buf, sizeof(struct arvo_key_mask)); |
136 | mutex_unlock(&arvo->arvo_lock); | 92 | mutex_unlock(&arvo->arvo_lock); |
137 | if (retval) | 93 | if (retval) |
138 | goto out; | 94 | return retval; |
139 | 95 | ||
140 | retval = snprintf(buf, PAGE_SIZE, "%d\n", temp_buf->key_mask); | 96 | return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.key_mask); |
141 | out: | ||
142 | kfree(temp_buf); | ||
143 | return retval; | ||
144 | } | 97 | } |
145 | 98 | ||
146 | static ssize_t arvo_sysfs_set_key_mask(struct device *dev, | 99 | static ssize_t arvo_sysfs_set_key_mask(struct device *dev, |
147 | struct device_attribute *attr, char const *buf, size_t size) | 100 | struct device_attribute *attr, char const *buf, size_t size) |
148 | { | 101 | { |
149 | struct arvo_device *arvo = | 102 | struct arvo_device *arvo = |
150 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 103 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
151 | struct usb_device *usb_dev = | 104 | struct usb_device *usb_dev = |
152 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); | 105 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); |
153 | struct arvo_key_mask *temp_buf; | 106 | struct arvo_key_mask temp_buf; |
154 | unsigned long key_mask; | 107 | unsigned long key_mask; |
155 | int retval; | 108 | int retval; |
156 | 109 | ||
157 | temp_buf = kmalloc(sizeof(struct arvo_key_mask), GFP_KERNEL); | ||
158 | if (!temp_buf) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | retval = strict_strtoul(buf, 10, &key_mask); | 110 | retval = strict_strtoul(buf, 10, &key_mask); |
162 | if (retval) | 111 | if (retval) |
163 | goto out; | 112 | return retval; |
164 | 113 | ||
165 | temp_buf->command = ARVO_COMMAND_KEY_MASK; | 114 | temp_buf.command = ARVO_COMMAND_KEY_MASK; |
166 | temp_buf->key_mask = key_mask; | 115 | temp_buf.key_mask = key_mask; |
167 | 116 | ||
168 | mutex_lock(&arvo->arvo_lock); | 117 | mutex_lock(&arvo->arvo_lock); |
169 | retval = arvo_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK, | 118 | retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK, |
170 | temp_buf, sizeof(struct arvo_key_mask)); | 119 | &temp_buf, sizeof(struct arvo_key_mask)); |
171 | mutex_unlock(&arvo->arvo_lock); | 120 | mutex_unlock(&arvo->arvo_lock); |
172 | if (retval) | 121 | if (retval) |
173 | goto out; | 122 | return retval; |
174 | 123 | ||
175 | retval = size; | 124 | return size; |
176 | out: | ||
177 | kfree(temp_buf); | ||
178 | return retval; | ||
179 | } | 125 | } |
180 | 126 | ||
181 | /* retval is 1-5 on success, < 0 on error */ | 127 | /* retval is 1-5 on success, < 0 on error */ |
182 | static int arvo_get_actual_profile(struct usb_device *usb_dev) | 128 | static int arvo_get_actual_profile(struct usb_device *usb_dev) |
183 | { | 129 | { |
184 | struct arvo_actual_profile *temp_buf; | 130 | struct arvo_actual_profile temp_buf; |
185 | int retval; | 131 | int retval; |
186 | 132 | ||
187 | temp_buf = kmalloc(sizeof(struct arvo_actual_profile), GFP_KERNEL); | 133 | retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE, |
188 | if (!temp_buf) | 134 | &temp_buf, sizeof(struct arvo_actual_profile)); |
189 | return -ENOMEM; | ||
190 | 135 | ||
191 | retval = arvo_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE, | 136 | if (retval) |
192 | temp_buf, sizeof(struct arvo_actual_profile)); | 137 | return retval; |
193 | 138 | ||
194 | if (!retval) | 139 | return temp_buf.actual_profile; |
195 | retval = temp_buf->actual_profile; | ||
196 | |||
197 | kfree(temp_buf); | ||
198 | return retval; | ||
199 | } | 140 | } |
200 | 141 | ||
201 | static ssize_t arvo_sysfs_show_actual_profile(struct device *dev, | 142 | static ssize_t arvo_sysfs_show_actual_profile(struct device *dev, |
202 | struct device_attribute *attr, char *buf) | 143 | struct device_attribute *attr, char *buf) |
203 | { | 144 | { |
204 | struct arvo_device *arvo = | 145 | struct arvo_device *arvo = |
205 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 146 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
206 | 147 | ||
207 | return snprintf(buf, PAGE_SIZE, "%d\n", arvo->actual_profile); | 148 | return snprintf(buf, PAGE_SIZE, "%d\n", arvo->actual_profile); |
208 | } | 149 | } |
209 | 150 | ||
210 | static ssize_t arvo_sysfs_set_actual_profile(struct device *dev, | 151 | static ssize_t arvo_sysfs_set_actual_profile(struct device *dev, |
211 | struct device_attribute *attr, char const *buf, size_t size) | 152 | struct device_attribute *attr, char const *buf, size_t size) |
212 | { | 153 | { |
213 | struct arvo_device *arvo = | 154 | struct arvo_device *arvo = |
214 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 155 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
215 | struct usb_device *usb_dev = | 156 | struct usb_device *usb_dev = |
216 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); | 157 | interface_to_usbdev(to_usb_interface(dev->parent->parent)); |
217 | struct arvo_actual_profile *temp_buf; | 158 | struct arvo_actual_profile temp_buf; |
218 | unsigned long profile; | 159 | unsigned long profile; |
219 | int retval; | 160 | int retval; |
220 | 161 | ||
221 | temp_buf = kmalloc(sizeof(struct arvo_actual_profile), GFP_KERNEL); | ||
222 | if (!temp_buf) | ||
223 | return -ENOMEM; | ||
224 | |||
225 | retval = strict_strtoul(buf, 10, &profile); | 162 | retval = strict_strtoul(buf, 10, &profile); |
226 | if (retval) | 163 | if (retval) |
227 | goto out; | 164 | return retval; |
228 | 165 | ||
229 | temp_buf->command = ARVO_COMMAND_ACTUAL_PROFILE; | 166 | temp_buf.command = ARVO_COMMAND_ACTUAL_PROFILE; |
230 | temp_buf->actual_profile = profile; | 167 | temp_buf.actual_profile = profile; |
231 | 168 | ||
232 | mutex_lock(&arvo->arvo_lock); | 169 | mutex_lock(&arvo->arvo_lock); |
233 | retval = arvo_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE, | 170 | retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE, |
234 | temp_buf, sizeof(struct arvo_actual_profile)); | 171 | &temp_buf, sizeof(struct arvo_actual_profile)); |
235 | if (!retval) { | 172 | if (!retval) { |
236 | arvo->actual_profile = profile; | 173 | arvo->actual_profile = profile; |
237 | retval = size; | 174 | retval = size; |
238 | } | 175 | } |
239 | mutex_unlock(&arvo->arvo_lock); | 176 | mutex_unlock(&arvo->arvo_lock); |
240 | |||
241 | out: | ||
242 | kfree(temp_buf); | ||
243 | return retval; | 177 | return retval; |
244 | } | 178 | } |
245 | 179 | ||
246 | static ssize_t arvo_sysfs_write(struct file *fp, | 180 | static ssize_t arvo_sysfs_write(struct file *fp, |
247 | struct kobject *kobj, void const *buf, | 181 | struct kobject *kobj, void const *buf, |
248 | loff_t off, size_t count, size_t real_size, uint command) | 182 | loff_t off, size_t count, size_t real_size, uint command) |
249 | { | 183 | { |
250 | struct device *dev = | 184 | struct device *dev = |
251 | container_of(kobj, struct device, kobj)->parent->parent; | 185 | container_of(kobj, struct device, kobj)->parent->parent; |
252 | struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev)); | 186 | struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev)); |
253 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 187 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
254 | int retval; | 188 | int retval; |
255 | 189 | ||
256 | if (off != 0 || count != real_size) | 190 | if (off != 0 || count != real_size) |
257 | return -EINVAL; | 191 | return -EINVAL; |
258 | 192 | ||
259 | mutex_lock(&arvo->arvo_lock); | 193 | mutex_lock(&arvo->arvo_lock); |
260 | retval = arvo_send(usb_dev, command, buf, real_size); | 194 | retval = roccat_common_send(usb_dev, command, buf, real_size); |
261 | mutex_unlock(&arvo->arvo_lock); | 195 | mutex_unlock(&arvo->arvo_lock); |
262 | 196 | ||
263 | return (retval ? retval : real_size); | 197 | return (retval ? retval : real_size); |
264 | } | 198 | } |
265 | 199 | ||
266 | static ssize_t arvo_sysfs_read(struct file *fp, | 200 | static ssize_t arvo_sysfs_read(struct file *fp, |
267 | struct kobject *kobj, void *buf, loff_t off, | 201 | struct kobject *kobj, void *buf, loff_t off, |
268 | size_t count, size_t real_size, uint command) | 202 | size_t count, size_t real_size, uint command) |
269 | { | 203 | { |
270 | struct device *dev = | 204 | struct device *dev = |
271 | container_of(kobj, struct device, kobj)->parent->parent; | 205 | container_of(kobj, struct device, kobj)->parent->parent; |
272 | struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev)); | 206 | struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev)); |
273 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 207 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
274 | int retval; | 208 | int retval; |
275 | 209 | ||
276 | if (off >= real_size) | 210 | if (off >= real_size) |
277 | return 0; | 211 | return 0; |
278 | 212 | ||
279 | if (off != 0 || count != real_size) | 213 | if (off != 0 || count != real_size) |
280 | return -EINVAL; | 214 | return -EINVAL; |
281 | 215 | ||
282 | mutex_lock(&arvo->arvo_lock); | 216 | mutex_lock(&arvo->arvo_lock); |
283 | retval = arvo_receive(usb_dev, command, buf, real_size); | 217 | retval = roccat_common_receive(usb_dev, command, buf, real_size); |
284 | mutex_unlock(&arvo->arvo_lock); | 218 | mutex_unlock(&arvo->arvo_lock); |
285 | 219 | ||
286 | return (retval ? retval : real_size); | 220 | return (retval ? retval : real_size); |
287 | } | 221 | } |
288 | 222 | ||
289 | static ssize_t arvo_sysfs_write_button(struct file *fp, | 223 | static ssize_t arvo_sysfs_write_button(struct file *fp, |
290 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 224 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
291 | loff_t off, size_t count) | 225 | loff_t off, size_t count) |
292 | { | 226 | { |
293 | return arvo_sysfs_write(fp, kobj, buf, off, count, | 227 | return arvo_sysfs_write(fp, kobj, buf, off, count, |
294 | sizeof(struct arvo_button), ARVO_USB_COMMAND_BUTTON); | 228 | sizeof(struct arvo_button), ARVO_USB_COMMAND_BUTTON); |
295 | } | 229 | } |
296 | 230 | ||
297 | static ssize_t arvo_sysfs_read_info(struct file *fp, | 231 | static ssize_t arvo_sysfs_read_info(struct file *fp, |
298 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 232 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
299 | loff_t off, size_t count) | 233 | loff_t off, size_t count) |
300 | { | 234 | { |
301 | return arvo_sysfs_read(fp, kobj, buf, off, count, | 235 | return arvo_sysfs_read(fp, kobj, buf, off, count, |
302 | sizeof(struct arvo_info), ARVO_USB_COMMAND_INFO); | 236 | sizeof(struct arvo_info), ARVO_USB_COMMAND_INFO); |
303 | } | 237 | } |
304 | 238 | ||
305 | 239 | ||
306 | static struct device_attribute arvo_attributes[] = { | 240 | static struct device_attribute arvo_attributes[] = { |
307 | __ATTR(mode_key, 0660, | 241 | __ATTR(mode_key, 0660, |
308 | arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key), | 242 | arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key), |
309 | __ATTR(key_mask, 0660, | 243 | __ATTR(key_mask, 0660, |
310 | arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask), | 244 | arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask), |
311 | __ATTR(actual_profile, 0660, | 245 | __ATTR(actual_profile, 0660, |
312 | arvo_sysfs_show_actual_profile, | 246 | arvo_sysfs_show_actual_profile, |
313 | arvo_sysfs_set_actual_profile), | 247 | arvo_sysfs_set_actual_profile), |
314 | __ATTR_NULL | 248 | __ATTR_NULL |
315 | }; | 249 | }; |
316 | 250 | ||
317 | static struct bin_attribute arvo_bin_attributes[] = { | 251 | static struct bin_attribute arvo_bin_attributes[] = { |
318 | { | 252 | { |
319 | .attr = { .name = "button", .mode = 0220 }, | 253 | .attr = { .name = "button", .mode = 0220 }, |
320 | .size = sizeof(struct arvo_button), | 254 | .size = sizeof(struct arvo_button), |
321 | .write = arvo_sysfs_write_button | 255 | .write = arvo_sysfs_write_button |
322 | }, | 256 | }, |
323 | { | 257 | { |
324 | .attr = { .name = "info", .mode = 0440 }, | 258 | .attr = { .name = "info", .mode = 0440 }, |
325 | .size = sizeof(struct arvo_info), | 259 | .size = sizeof(struct arvo_info), |
326 | .read = arvo_sysfs_read_info | 260 | .read = arvo_sysfs_read_info |
327 | }, | 261 | }, |
328 | __ATTR_NULL | 262 | __ATTR_NULL |
329 | }; | 263 | }; |
330 | 264 | ||
331 | static int arvo_init_arvo_device_struct(struct usb_device *usb_dev, | 265 | static int arvo_init_arvo_device_struct(struct usb_device *usb_dev, |
332 | struct arvo_device *arvo) | 266 | struct arvo_device *arvo) |
333 | { | 267 | { |
334 | int retval; | 268 | int retval; |
335 | 269 | ||
336 | mutex_init(&arvo->arvo_lock); | 270 | mutex_init(&arvo->arvo_lock); |
337 | 271 | ||
338 | retval = arvo_get_actual_profile(usb_dev); | 272 | retval = arvo_get_actual_profile(usb_dev); |
339 | if (retval < 0) | 273 | if (retval < 0) |
340 | return retval; | 274 | return retval; |
341 | arvo->actual_profile = retval; | 275 | arvo->actual_profile = retval; |
342 | 276 | ||
343 | return 0; | 277 | return 0; |
344 | } | 278 | } |
345 | 279 | ||
346 | static int arvo_init_specials(struct hid_device *hdev) | 280 | static int arvo_init_specials(struct hid_device *hdev) |
347 | { | 281 | { |
348 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 282 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
349 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 283 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
350 | struct arvo_device *arvo; | 284 | struct arvo_device *arvo; |
351 | int retval; | 285 | int retval; |
352 | 286 | ||
353 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 287 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
354 | == USB_INTERFACE_PROTOCOL_KEYBOARD) { | 288 | == USB_INTERFACE_PROTOCOL_KEYBOARD) { |
355 | hid_set_drvdata(hdev, NULL); | 289 | hid_set_drvdata(hdev, NULL); |
356 | return 0; | 290 | return 0; |
357 | } | 291 | } |
358 | 292 | ||
359 | arvo = kzalloc(sizeof(*arvo), GFP_KERNEL); | 293 | arvo = kzalloc(sizeof(*arvo), GFP_KERNEL); |
360 | if (!arvo) { | 294 | if (!arvo) { |
361 | hid_err(hdev, "can't alloc device descriptor\n"); | 295 | hid_err(hdev, "can't alloc device descriptor\n"); |
362 | return -ENOMEM; | 296 | return -ENOMEM; |
363 | } | 297 | } |
364 | hid_set_drvdata(hdev, arvo); | 298 | hid_set_drvdata(hdev, arvo); |
365 | 299 | ||
366 | retval = arvo_init_arvo_device_struct(usb_dev, arvo); | 300 | retval = arvo_init_arvo_device_struct(usb_dev, arvo); |
367 | if (retval) { | 301 | if (retval) { |
368 | hid_err(hdev, "couldn't init struct arvo_device\n"); | 302 | hid_err(hdev, "couldn't init struct arvo_device\n"); |
369 | goto exit_free; | 303 | goto exit_free; |
370 | } | 304 | } |
371 | 305 | ||
372 | retval = roccat_connect(arvo_class, hdev); | 306 | retval = roccat_connect(arvo_class, hdev); |
373 | if (retval < 0) { | 307 | if (retval < 0) { |
374 | hid_err(hdev, "couldn't init char dev\n"); | 308 | hid_err(hdev, "couldn't init char dev\n"); |
375 | } else { | 309 | } else { |
376 | arvo->chrdev_minor = retval; | 310 | arvo->chrdev_minor = retval; |
377 | arvo->roccat_claimed = 1; | 311 | arvo->roccat_claimed = 1; |
378 | } | 312 | } |
379 | 313 | ||
380 | return 0; | 314 | return 0; |
381 | exit_free: | 315 | exit_free: |
382 | kfree(arvo); | 316 | kfree(arvo); |
383 | return retval; | 317 | return retval; |
384 | } | 318 | } |
385 | 319 | ||
386 | static void arvo_remove_specials(struct hid_device *hdev) | 320 | static void arvo_remove_specials(struct hid_device *hdev) |
387 | { | 321 | { |
388 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 322 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
389 | struct arvo_device *arvo; | 323 | struct arvo_device *arvo; |
390 | 324 | ||
391 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 325 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
392 | == USB_INTERFACE_PROTOCOL_KEYBOARD) | 326 | == USB_INTERFACE_PROTOCOL_KEYBOARD) |
393 | return; | 327 | return; |
394 | 328 | ||
395 | arvo = hid_get_drvdata(hdev); | 329 | arvo = hid_get_drvdata(hdev); |
396 | if (arvo->roccat_claimed) | 330 | if (arvo->roccat_claimed) |
397 | roccat_disconnect(arvo->chrdev_minor); | 331 | roccat_disconnect(arvo->chrdev_minor); |
398 | kfree(arvo); | 332 | kfree(arvo); |
399 | } | 333 | } |
400 | 334 | ||
401 | static int arvo_probe(struct hid_device *hdev, | 335 | static int arvo_probe(struct hid_device *hdev, |
402 | const struct hid_device_id *id) | 336 | const struct hid_device_id *id) |
403 | { | 337 | { |
404 | int retval; | 338 | int retval; |
405 | 339 | ||
406 | retval = hid_parse(hdev); | 340 | retval = hid_parse(hdev); |
407 | if (retval) { | 341 | if (retval) { |
408 | hid_err(hdev, "parse failed\n"); | 342 | hid_err(hdev, "parse failed\n"); |
409 | goto exit; | 343 | goto exit; |
410 | } | 344 | } |
411 | 345 | ||
412 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 346 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
413 | if (retval) { | 347 | if (retval) { |
414 | hid_err(hdev, "hw start failed\n"); | 348 | hid_err(hdev, "hw start failed\n"); |
415 | goto exit; | 349 | goto exit; |
416 | } | 350 | } |
417 | 351 | ||
418 | retval = arvo_init_specials(hdev); | 352 | retval = arvo_init_specials(hdev); |
419 | if (retval) { | 353 | if (retval) { |
420 | hid_err(hdev, "couldn't install keyboard\n"); | 354 | hid_err(hdev, "couldn't install keyboard\n"); |
421 | goto exit_stop; | 355 | goto exit_stop; |
422 | } | 356 | } |
423 | 357 | ||
424 | return 0; | 358 | return 0; |
425 | 359 | ||
426 | exit_stop: | 360 | exit_stop: |
427 | hid_hw_stop(hdev); | 361 | hid_hw_stop(hdev); |
428 | exit: | 362 | exit: |
429 | return retval; | 363 | return retval; |
430 | } | 364 | } |
431 | 365 | ||
432 | static void arvo_remove(struct hid_device *hdev) | 366 | static void arvo_remove(struct hid_device *hdev) |
433 | { | 367 | { |
434 | arvo_remove_specials(hdev); | 368 | arvo_remove_specials(hdev); |
435 | hid_hw_stop(hdev); | 369 | hid_hw_stop(hdev); |
436 | } | 370 | } |
437 | 371 | ||
438 | static void arvo_report_to_chrdev(struct arvo_device const *arvo, | 372 | static void arvo_report_to_chrdev(struct arvo_device const *arvo, |
439 | u8 const *data) | 373 | u8 const *data) |
440 | { | 374 | { |
441 | struct arvo_special_report const *special_report; | 375 | struct arvo_special_report const *special_report; |
442 | struct arvo_roccat_report roccat_report; | 376 | struct arvo_roccat_report roccat_report; |
443 | 377 | ||
444 | special_report = (struct arvo_special_report const *)data; | 378 | special_report = (struct arvo_special_report const *)data; |
445 | 379 | ||
446 | roccat_report.profile = arvo->actual_profile; | 380 | roccat_report.profile = arvo->actual_profile; |
447 | roccat_report.button = special_report->event & | 381 | roccat_report.button = special_report->event & |
448 | ARVO_SPECIAL_REPORT_EVENT_MASK_BUTTON; | 382 | ARVO_SPECIAL_REPORT_EVENT_MASK_BUTTON; |
449 | if ((special_report->event & ARVO_SPECIAL_REPORT_EVENT_MASK_ACTION) == | 383 | if ((special_report->event & ARVO_SPECIAL_REPORT_EVENT_MASK_ACTION) == |
450 | ARVO_SPECIAL_REPORT_EVENT_ACTION_PRESS) | 384 | ARVO_SPECIAL_REPORT_EVENT_ACTION_PRESS) |
451 | roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_PRESS; | 385 | roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_PRESS; |
452 | else | 386 | else |
453 | roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_RELEASE; | 387 | roccat_report.action = ARVO_ROCCAT_REPORT_ACTION_RELEASE; |
454 | 388 | ||
455 | roccat_report_event(arvo->chrdev_minor, (uint8_t const *)&roccat_report, | 389 | roccat_report_event(arvo->chrdev_minor, (uint8_t const *)&roccat_report, |
456 | sizeof(struct arvo_roccat_report)); | 390 | sizeof(struct arvo_roccat_report)); |
457 | } | 391 | } |
458 | 392 | ||
459 | static int arvo_raw_event(struct hid_device *hdev, | 393 | static int arvo_raw_event(struct hid_device *hdev, |
460 | struct hid_report *report, u8 *data, int size) | 394 | struct hid_report *report, u8 *data, int size) |
461 | { | 395 | { |
462 | struct arvo_device *arvo = hid_get_drvdata(hdev); | 396 | struct arvo_device *arvo = hid_get_drvdata(hdev); |
463 | 397 | ||
464 | if (size != 3) | 398 | if (size != 3) |
465 | return 0; | 399 | return 0; |
466 | 400 | ||
467 | if (arvo->roccat_claimed) | 401 | if (arvo->roccat_claimed) |
468 | arvo_report_to_chrdev(arvo, data); | 402 | arvo_report_to_chrdev(arvo, data); |
469 | 403 | ||
470 | return 0; | 404 | return 0; |
471 | } | 405 | } |
472 | 406 | ||
473 | static const struct hid_device_id arvo_devices[] = { | 407 | static const struct hid_device_id arvo_devices[] = { |
474 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, | 408 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, |
475 | { } | 409 | { } |
476 | }; | 410 | }; |
477 | 411 | ||
478 | MODULE_DEVICE_TABLE(hid, arvo_devices); | 412 | MODULE_DEVICE_TABLE(hid, arvo_devices); |
479 | 413 | ||
480 | static struct hid_driver arvo_driver = { | 414 | static struct hid_driver arvo_driver = { |
481 | .name = "arvo", | 415 | .name = "arvo", |
482 | .id_table = arvo_devices, | 416 | .id_table = arvo_devices, |
483 | .probe = arvo_probe, | 417 | .probe = arvo_probe, |
484 | .remove = arvo_remove, | 418 | .remove = arvo_remove, |
485 | .raw_event = arvo_raw_event | 419 | .raw_event = arvo_raw_event |
486 | }; | 420 | }; |
487 | 421 | ||
488 | static int __init arvo_init(void) | 422 | static int __init arvo_init(void) |
489 | { | 423 | { |
490 | int retval; | 424 | int retval; |
491 | 425 | ||
492 | arvo_class = class_create(THIS_MODULE, "arvo"); | 426 | arvo_class = class_create(THIS_MODULE, "arvo"); |
493 | if (IS_ERR(arvo_class)) | 427 | if (IS_ERR(arvo_class)) |
494 | return PTR_ERR(arvo_class); | 428 | return PTR_ERR(arvo_class); |
495 | arvo_class->dev_attrs = arvo_attributes; | 429 | arvo_class->dev_attrs = arvo_attributes; |
496 | arvo_class->dev_bin_attrs = arvo_bin_attributes; | 430 | arvo_class->dev_bin_attrs = arvo_bin_attributes; |
497 | 431 | ||
498 | retval = hid_register_driver(&arvo_driver); | 432 | retval = hid_register_driver(&arvo_driver); |
499 | if (retval) | 433 | if (retval) |
500 | class_destroy(arvo_class); | 434 | class_destroy(arvo_class); |
501 | return retval; | 435 | return retval; |
502 | } | 436 | } |
503 | 437 | ||
504 | static void __exit arvo_exit(void) | 438 | static void __exit arvo_exit(void) |
505 | { | 439 | { |
506 | class_destroy(arvo_class); | 440 | class_destroy(arvo_class); |
507 | hid_unregister_driver(&arvo_driver); | 441 | hid_unregister_driver(&arvo_driver); |
508 | } | 442 | } |
509 | 443 | ||
510 | module_init(arvo_init); | 444 | module_init(arvo_init); |
511 | module_exit(arvo_exit); | 445 | module_exit(arvo_exit); |
512 | 446 | ||
513 | MODULE_AUTHOR("Stefan Achatz"); | 447 | MODULE_AUTHOR("Stefan Achatz"); |
514 | MODULE_DESCRIPTION("USB Roccat Arvo driver"); | 448 | MODULE_DESCRIPTION("USB Roccat Arvo driver"); |
515 | MODULE_LICENSE("GPL v2"); | 449 | MODULE_LICENSE("GPL v2"); |
drivers/hid/hid-roccat-common.c
File was created | 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 | |||
17 | int 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 | } | ||
36 | EXPORT_SYMBOL_GPL(roccat_common_receive); | ||
37 | |||
38 | int 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 | } | ||
58 | EXPORT_SYMBOL_GPL(roccat_common_send); | ||
59 | |||
60 | MODULE_AUTHOR("Stefan Achatz"); | ||
61 | MODULE_DESCRIPTION("USB Roccat common driver"); | ||
62 | MODULE_LICENSE("GPL v2"); | ||
63 |
drivers/hid/hid-roccat-common.h
File was created | 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 | |||
18 | int roccat_common_receive(struct usb_device *usb_dev, uint usb_command, | ||
19 | void *data, uint size); | ||
20 | int roccat_common_send(struct usb_device *usb_dev, uint usb_command, | ||
21 | void const *data, uint size); | ||
22 | |||
23 | #endif | ||
24 |
drivers/hid/hid-roccat-kone.c
1 | /* | 1 | /* |
2 | * Roccat Kone driver for Linux | 2 | * Roccat Kone driver for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> | 4 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. | 11 | * any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard | 15 | * Roccat Kone is a gamer mouse which consists of a mouse part and a keyboard |
16 | * part. The keyboard part enables the mouse to execute stored macros with mixed | 16 | * part. The keyboard part enables the mouse to execute stored macros with mixed |
17 | * key- and button-events. | 17 | * key- and button-events. |
18 | * | 18 | * |
19 | * TODO implement on-the-fly polling-rate change | 19 | * TODO implement on-the-fly polling-rate change |
20 | * The windows driver has the ability to change the polling rate of the | 20 | * The windows driver has the ability to change the polling rate of the |
21 | * device on the press of a mousebutton. | 21 | * device on the press of a mousebutton. |
22 | * Is it possible to remove and reinstall the urb in raw-event- or any | 22 | * Is it possible to remove and reinstall the urb in raw-event- or any |
23 | * other handler, or to defer this action to be executed somewhere else? | 23 | * other handler, or to defer this action to be executed somewhere else? |
24 | * | 24 | * |
25 | * TODO is it possible to overwrite group for sysfs attributes via udev? | 25 | * TODO is it possible to overwrite group for sysfs attributes via udev? |
26 | */ | 26 | */ |
27 | 27 | ||
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> |
34 | #include "hid-ids.h" | 33 | #include "hid-ids.h" |
35 | #include "hid-roccat.h" | 34 | #include "hid-roccat.h" |
35 | #include "hid-roccat-common.h" | ||
36 | #include "hid-roccat-kone.h" | 36 | #include "hid-roccat-kone.h" |
37 | 37 | ||
38 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; | 38 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; |
39 | 39 | ||
40 | /* kone_class is used for creating sysfs attributes via roccat char device */ | 40 | /* kone_class is used for creating sysfs attributes via roccat char device */ |
41 | static struct class *kone_class; | 41 | static struct class *kone_class; |
42 | 42 | ||
43 | static void kone_set_settings_checksum(struct kone_settings *settings) | 43 | static void kone_set_settings_checksum(struct kone_settings *settings) |
44 | { | 44 | { |
45 | uint16_t checksum = 0; | 45 | uint16_t checksum = 0; |
46 | unsigned char *address = (unsigned char *)settings; | 46 | unsigned char *address = (unsigned char *)settings; |
47 | int i; | 47 | int i; |
48 | 48 | ||
49 | for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address) | 49 | for (i = 0; i < sizeof(struct kone_settings) - 2; ++i, ++address) |
50 | checksum += *address; | 50 | checksum += *address; |
51 | settings->checksum = cpu_to_le16(checksum); | 51 | settings->checksum = cpu_to_le16(checksum); |
52 | } | 52 | } |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * Checks success after writing data to mouse | 55 | * Checks success after writing data to mouse |
56 | * On success returns 0 | 56 | * On success returns 0 |
57 | * On failure returns errno | 57 | * On failure returns errno |
58 | */ | 58 | */ |
59 | static int kone_check_write(struct usb_device *usb_dev) | 59 | static 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 | 63 | ||
64 | data = kmalloc(1, GFP_KERNEL); | ||
65 | if (!data) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | do { | 64 | do { |
69 | /* | 65 | /* |
70 | * Mouse needs 50 msecs until it says ok, but there are | 66 | * Mouse needs 50 msecs until it says ok, but there are |
71 | * 30 more msecs needed for next write to work. | 67 | * 30 more msecs needed for next write to work. |
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 | 75 | ||
82 | if (len != 1) { | ||
83 | kfree(data); | ||
84 | return -EIO; | ||
85 | } | ||
86 | |||
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 | */ |
110 | static int kone_get_settings(struct usb_device *usb_dev, | 96 | static 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 | /* |
128 | * Writes settings from @buf to mouse | 104 | * Writes settings from @buf to mouse |
129 | * On success returns 0 | 105 | * On success returns 0 |
130 | * On failure returns errno | 106 | * On failure returns errno |
131 | */ | 107 | */ |
132 | static int kone_set_settings(struct usb_device *usb_dev, | 108 | static 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 | /* |
154 | * Reads profile data from mouse and stores it in @buf | 120 | * Reads profile data from mouse and stores it in @buf |
155 | * @number: profile number to read | 121 | * @number: profile number to read |
156 | * On success returns 0 | 122 | * On success returns 0 |
157 | * On failure returns errno | 123 | * On failure returns errno |
158 | */ | 124 | */ |
159 | static int kone_get_profile(struct usb_device *usb_dev, | 125 | static int kone_get_profile(struct usb_device *usb_dev, |
160 | struct kone_profile *buf, int number) | 126 | struct kone_profile *buf, int number) |
161 | { | 127 | { |
162 | int len; | 128 | int len; |
163 | 129 | ||
164 | if (number < 1 || number > 5) | 130 | if (number < 1 || number > 5) |
165 | return -EINVAL; | 131 | return -EINVAL; |
166 | 132 | ||
167 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 133 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
168 | USB_REQ_CLEAR_FEATURE, | 134 | USB_REQ_CLEAR_FEATURE, |
169 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 135 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
170 | kone_command_profile, number, buf, | 136 | kone_command_profile, number, buf, |
171 | sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT); | 137 | sizeof(struct kone_profile), USB_CTRL_SET_TIMEOUT); |
172 | 138 | ||
173 | if (len != sizeof(struct kone_profile)) | 139 | if (len != sizeof(struct kone_profile)) |
174 | return -EIO; | 140 | return -EIO; |
175 | 141 | ||
176 | return 0; | 142 | return 0; |
177 | } | 143 | } |
178 | 144 | ||
179 | /* | 145 | /* |
180 | * Writes profile data to mouse. | 146 | * Writes profile data to mouse. |
181 | * @number: profile number to write | 147 | * @number: profile number to write |
182 | * On success returns 0 | 148 | * On success returns 0 |
183 | * On failure returns errno | 149 | * On failure returns errno |
184 | */ | 150 | */ |
185 | static int kone_set_profile(struct usb_device *usb_dev, | 151 | static int kone_set_profile(struct usb_device *usb_dev, |
186 | struct kone_profile const *profile, int number) | 152 | struct kone_profile const *profile, int number) |
187 | { | 153 | { |
188 | int len; | 154 | int len; |
189 | 155 | ||
190 | if (number < 1 || number > 5) | 156 | if (number < 1 || number > 5) |
191 | return -EINVAL; | 157 | return -EINVAL; |
192 | 158 | ||
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 | ||
200 | if (len != sizeof(struct kone_profile)) | 166 | if (len != sizeof(struct kone_profile)) |
201 | return len; | 167 | return len; |
202 | 168 | ||
203 | if (kone_check_write(usb_dev)) | 169 | if (kone_check_write(usb_dev)) |
204 | return -EIO; | 170 | return -EIO; |
205 | 171 | ||
206 | return 0; | 172 | return 0; |
207 | } | 173 | } |
208 | 174 | ||
209 | /* | 175 | /* |
210 | * Reads value of "fast-clip-weight" and stores it in @result | 176 | * Reads value of "fast-clip-weight" and stores it in @result |
211 | * On success returns 0 | 177 | * On success returns 0 |
212 | * On failure returns errno | 178 | * On failure returns errno |
213 | */ | 179 | */ |
214 | static int kone_get_weight(struct usb_device *usb_dev, int *result) | 180 | static 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 | ||
237 | /* | 194 | /* |
238 | * Reads firmware_version of mouse and stores it in @result | 195 | * Reads firmware_version of mouse and stores it in @result |
239 | * On success returns 0 | 196 | * On success returns 0 |
240 | * On failure returns errno | 197 | * On failure returns errno |
241 | */ | 198 | */ |
242 | static int kone_get_firmware_version(struct usb_device *usb_dev, int *result) | 199 | static 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 | 203 | ||
247 | data = kmalloc(2, GFP_KERNEL); | 204 | retval = roccat_common_receive(usb_dev, kone_command_firmware_version, |
248 | if (!data) | 205 | &data, 2); |
249 | return -ENOMEM; | 206 | if (retval) |
207 | return retval; | ||
250 | 208 | ||
251 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 209 | *result = le16_to_cpu(data); |
252 | USB_REQ_CLEAR_FEATURE, | ||
253 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
254 | kone_command_firmware_version, 0, data, 2, | ||
255 | USB_CTRL_SET_TIMEOUT); | ||
256 | |||
257 | if (len != 2) { | ||
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 | ||
266 | static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, | 213 | static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj, |
267 | struct bin_attribute *attr, char *buf, | 214 | struct bin_attribute *attr, char *buf, |
268 | loff_t off, size_t count) { | 215 | loff_t off, size_t count) { |
269 | struct device *dev = | 216 | struct device *dev = |
270 | container_of(kobj, struct device, kobj)->parent->parent; | 217 | container_of(kobj, struct device, kobj)->parent->parent; |
271 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); | 218 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); |
272 | 219 | ||
273 | if (off >= sizeof(struct kone_settings)) | 220 | if (off >= sizeof(struct kone_settings)) |
274 | return 0; | 221 | return 0; |
275 | 222 | ||
276 | if (off + count > sizeof(struct kone_settings)) | 223 | if (off + count > sizeof(struct kone_settings)) |
277 | count = sizeof(struct kone_settings) - off; | 224 | count = sizeof(struct kone_settings) - off; |
278 | 225 | ||
279 | mutex_lock(&kone->kone_lock); | 226 | mutex_lock(&kone->kone_lock); |
280 | memcpy(buf, ((char const *)&kone->settings) + off, count); | 227 | memcpy(buf, ((char const *)&kone->settings) + off, count); |
281 | mutex_unlock(&kone->kone_lock); | 228 | mutex_unlock(&kone->kone_lock); |
282 | 229 | ||
283 | return count; | 230 | return count; |
284 | } | 231 | } |
285 | 232 | ||
286 | /* | 233 | /* |
287 | * Writing settings automatically activates startup_profile. | 234 | * Writing settings automatically activates startup_profile. |
288 | * This function keeps values in kone_device up to date and assumes that in | 235 | * This function keeps values in kone_device up to date and assumes that in |
289 | * case of error the old data is still valid | 236 | * case of error the old data is still valid |
290 | */ | 237 | */ |
291 | static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, | 238 | static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, |
292 | struct bin_attribute *attr, char *buf, | 239 | struct bin_attribute *attr, char *buf, |
293 | loff_t off, size_t count) { | 240 | loff_t off, size_t count) { |
294 | struct device *dev = | 241 | struct device *dev = |
295 | container_of(kobj, struct device, kobj)->parent->parent; | 242 | container_of(kobj, struct device, kobj)->parent->parent; |
296 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); | 243 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); |
297 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 244 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
298 | int retval = 0, difference; | 245 | int retval = 0, difference; |
299 | 246 | ||
300 | /* I need to get my data in one piece */ | 247 | /* I need to get my data in one piece */ |
301 | if (off != 0 || count != sizeof(struct kone_settings)) | 248 | if (off != 0 || count != sizeof(struct kone_settings)) |
302 | return -EINVAL; | 249 | return -EINVAL; |
303 | 250 | ||
304 | mutex_lock(&kone->kone_lock); | 251 | mutex_lock(&kone->kone_lock); |
305 | difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings)); | 252 | difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings)); |
306 | if (difference) { | 253 | if (difference) { |
307 | retval = kone_set_settings(usb_dev, | 254 | retval = kone_set_settings(usb_dev, |
308 | (struct kone_settings const *)buf); | 255 | (struct kone_settings const *)buf); |
309 | if (!retval) | 256 | if (!retval) |
310 | memcpy(&kone->settings, buf, | 257 | memcpy(&kone->settings, buf, |
311 | sizeof(struct kone_settings)); | 258 | sizeof(struct kone_settings)); |
312 | } | 259 | } |
313 | mutex_unlock(&kone->kone_lock); | 260 | mutex_unlock(&kone->kone_lock); |
314 | 261 | ||
315 | if (retval) | 262 | if (retval) |
316 | return retval; | 263 | return retval; |
317 | 264 | ||
318 | /* | 265 | /* |
319 | * If we get here, treat settings as okay and update actual values | 266 | * If we get here, treat settings as okay and update actual values |
320 | * according to startup_profile | 267 | * according to startup_profile |
321 | */ | 268 | */ |
322 | kone->actual_profile = kone->settings.startup_profile; | 269 | kone->actual_profile = kone->settings.startup_profile; |
323 | kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi; | 270 | kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi; |
324 | 271 | ||
325 | return sizeof(struct kone_settings); | 272 | return sizeof(struct kone_settings); |
326 | } | 273 | } |
327 | 274 | ||
328 | static ssize_t kone_sysfs_read_profilex(struct file *fp, | 275 | static ssize_t kone_sysfs_read_profilex(struct file *fp, |
329 | struct kobject *kobj, struct bin_attribute *attr, | 276 | struct kobject *kobj, struct bin_attribute *attr, |
330 | char *buf, loff_t off, size_t count) { | 277 | char *buf, loff_t off, size_t count) { |
331 | struct device *dev = | 278 | struct device *dev = |
332 | container_of(kobj, struct device, kobj)->parent->parent; | 279 | container_of(kobj, struct device, kobj)->parent->parent; |
333 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); | 280 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); |
334 | 281 | ||
335 | if (off >= sizeof(struct kone_profile)) | 282 | if (off >= sizeof(struct kone_profile)) |
336 | return 0; | 283 | return 0; |
337 | 284 | ||
338 | if (off + count > sizeof(struct kone_profile)) | 285 | if (off + count > sizeof(struct kone_profile)) |
339 | count = sizeof(struct kone_profile) - off; | 286 | count = sizeof(struct kone_profile) - off; |
340 | 287 | ||
341 | mutex_lock(&kone->kone_lock); | 288 | mutex_lock(&kone->kone_lock); |
342 | memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count); | 289 | memcpy(buf, ((char const *)&kone->profiles[*(uint *)(attr->private)]) + off, count); |
343 | mutex_unlock(&kone->kone_lock); | 290 | mutex_unlock(&kone->kone_lock); |
344 | 291 | ||
345 | return count; | 292 | return count; |
346 | } | 293 | } |
347 | 294 | ||
348 | /* Writes data only if different to stored data */ | 295 | /* Writes data only if different to stored data */ |
349 | static ssize_t kone_sysfs_write_profilex(struct file *fp, | 296 | static ssize_t kone_sysfs_write_profilex(struct file *fp, |
350 | struct kobject *kobj, struct bin_attribute *attr, | 297 | struct kobject *kobj, struct bin_attribute *attr, |
351 | char *buf, loff_t off, size_t count) { | 298 | char *buf, loff_t off, size_t count) { |
352 | struct device *dev = | 299 | struct device *dev = |
353 | container_of(kobj, struct device, kobj)->parent->parent; | 300 | container_of(kobj, struct device, kobj)->parent->parent; |
354 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); | 301 | struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); |
355 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 302 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
356 | struct kone_profile *profile; | 303 | struct kone_profile *profile; |
357 | int retval = 0, difference; | 304 | int retval = 0, difference; |
358 | 305 | ||
359 | /* I need to get my data in one piece */ | 306 | /* I need to get my data in one piece */ |
360 | if (off != 0 || count != sizeof(struct kone_profile)) | 307 | if (off != 0 || count != sizeof(struct kone_profile)) |
361 | return -EINVAL; | 308 | return -EINVAL; |
362 | 309 | ||
363 | profile = &kone->profiles[*(uint *)(attr->private)]; | 310 | profile = &kone->profiles[*(uint *)(attr->private)]; |
364 | 311 | ||
365 | mutex_lock(&kone->kone_lock); | 312 | mutex_lock(&kone->kone_lock); |
366 | difference = memcmp(buf, profile, sizeof(struct kone_profile)); | 313 | difference = memcmp(buf, profile, sizeof(struct kone_profile)); |
367 | if (difference) { | 314 | if (difference) { |
368 | retval = kone_set_profile(usb_dev, | 315 | retval = kone_set_profile(usb_dev, |
369 | (struct kone_profile const *)buf, | 316 | (struct kone_profile const *)buf, |
370 | *(uint *)(attr->private) + 1); | 317 | *(uint *)(attr->private) + 1); |
371 | if (!retval) | 318 | if (!retval) |
372 | memcpy(profile, buf, sizeof(struct kone_profile)); | 319 | memcpy(profile, buf, sizeof(struct kone_profile)); |
373 | } | 320 | } |
374 | mutex_unlock(&kone->kone_lock); | 321 | mutex_unlock(&kone->kone_lock); |
375 | 322 | ||
376 | if (retval) | 323 | if (retval) |
377 | return retval; | 324 | return retval; |
378 | 325 | ||
379 | return sizeof(struct kone_profile); | 326 | return sizeof(struct kone_profile); |
380 | } | 327 | } |
381 | 328 | ||
382 | static ssize_t kone_sysfs_show_actual_profile(struct device *dev, | 329 | static ssize_t kone_sysfs_show_actual_profile(struct device *dev, |
383 | struct device_attribute *attr, char *buf) | 330 | struct device_attribute *attr, char *buf) |
384 | { | 331 | { |
385 | struct kone_device *kone = | 332 | struct kone_device *kone = |
386 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 333 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
387 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile); | 334 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile); |
388 | } | 335 | } |
389 | 336 | ||
390 | static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, | 337 | static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, |
391 | struct device_attribute *attr, char *buf) | 338 | struct device_attribute *attr, char *buf) |
392 | { | 339 | { |
393 | struct kone_device *kone = | 340 | struct kone_device *kone = |
394 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 341 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
395 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi); | 342 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi); |
396 | } | 343 | } |
397 | 344 | ||
398 | /* weight is read each time, since we don't get informed when it's changed */ | 345 | /* weight is read each time, since we don't get informed when it's changed */ |
399 | static ssize_t kone_sysfs_show_weight(struct device *dev, | 346 | static ssize_t kone_sysfs_show_weight(struct device *dev, |
400 | struct device_attribute *attr, char *buf) | 347 | struct device_attribute *attr, char *buf) |
401 | { | 348 | { |
402 | struct kone_device *kone; | 349 | struct kone_device *kone; |
403 | struct usb_device *usb_dev; | 350 | struct usb_device *usb_dev; |
404 | int weight = 0; | 351 | int weight = 0; |
405 | int retval; | 352 | int retval; |
406 | 353 | ||
407 | dev = dev->parent->parent; | 354 | dev = dev->parent->parent; |
408 | kone = hid_get_drvdata(dev_get_drvdata(dev)); | 355 | kone = hid_get_drvdata(dev_get_drvdata(dev)); |
409 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 356 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
410 | 357 | ||
411 | mutex_lock(&kone->kone_lock); | 358 | mutex_lock(&kone->kone_lock); |
412 | retval = kone_get_weight(usb_dev, &weight); | 359 | retval = kone_get_weight(usb_dev, &weight); |
413 | mutex_unlock(&kone->kone_lock); | 360 | mutex_unlock(&kone->kone_lock); |
414 | 361 | ||
415 | if (retval) | 362 | if (retval) |
416 | return retval; | 363 | return retval; |
417 | return snprintf(buf, PAGE_SIZE, "%d\n", weight); | 364 | return snprintf(buf, PAGE_SIZE, "%d\n", weight); |
418 | } | 365 | } |
419 | 366 | ||
420 | static ssize_t kone_sysfs_show_firmware_version(struct device *dev, | 367 | static ssize_t kone_sysfs_show_firmware_version(struct device *dev, |
421 | struct device_attribute *attr, char *buf) | 368 | struct device_attribute *attr, char *buf) |
422 | { | 369 | { |
423 | struct kone_device *kone = | 370 | struct kone_device *kone = |
424 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 371 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
425 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version); | 372 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version); |
426 | } | 373 | } |
427 | 374 | ||
428 | static ssize_t kone_sysfs_show_tcu(struct device *dev, | 375 | static ssize_t kone_sysfs_show_tcu(struct device *dev, |
429 | struct device_attribute *attr, char *buf) | 376 | struct device_attribute *attr, char *buf) |
430 | { | 377 | { |
431 | struct kone_device *kone = | 378 | struct kone_device *kone = |
432 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 379 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
433 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu); | 380 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.tcu); |
434 | } | 381 | } |
435 | 382 | ||
436 | static int kone_tcu_command(struct usb_device *usb_dev, int number) | 383 | static 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 | /* |
458 | * Calibrating the tcu is the only action that changes settings data inside the | 391 | * Calibrating the tcu is the only action that changes settings data inside the |
459 | * mouse, so this data needs to be reread | 392 | * mouse, so this data needs to be reread |
460 | */ | 393 | */ |
461 | static ssize_t kone_sysfs_set_tcu(struct device *dev, | 394 | static ssize_t kone_sysfs_set_tcu(struct device *dev, |
462 | struct device_attribute *attr, char const *buf, size_t size) | 395 | struct device_attribute *attr, char const *buf, size_t size) |
463 | { | 396 | { |
464 | struct kone_device *kone; | 397 | struct kone_device *kone; |
465 | struct usb_device *usb_dev; | 398 | struct usb_device *usb_dev; |
466 | int retval; | 399 | int retval; |
467 | unsigned long state; | 400 | unsigned long state; |
468 | 401 | ||
469 | dev = dev->parent->parent; | 402 | dev = dev->parent->parent; |
470 | kone = hid_get_drvdata(dev_get_drvdata(dev)); | 403 | kone = hid_get_drvdata(dev_get_drvdata(dev)); |
471 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 404 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
472 | 405 | ||
473 | retval = strict_strtoul(buf, 10, &state); | 406 | retval = strict_strtoul(buf, 10, &state); |
474 | if (retval) | 407 | if (retval) |
475 | return retval; | 408 | return retval; |
476 | 409 | ||
477 | if (state != 0 && state != 1) | 410 | if (state != 0 && state != 1) |
478 | return -EINVAL; | 411 | return -EINVAL; |
479 | 412 | ||
480 | mutex_lock(&kone->kone_lock); | 413 | mutex_lock(&kone->kone_lock); |
481 | 414 | ||
482 | if (state == 1) { /* state activate */ | 415 | if (state == 1) { /* state activate */ |
483 | retval = kone_tcu_command(usb_dev, 1); | 416 | retval = kone_tcu_command(usb_dev, 1); |
484 | if (retval) | 417 | if (retval) |
485 | goto exit_unlock; | 418 | goto exit_unlock; |
486 | retval = kone_tcu_command(usb_dev, 2); | 419 | retval = kone_tcu_command(usb_dev, 2); |
487 | if (retval) | 420 | if (retval) |
488 | goto exit_unlock; | 421 | goto exit_unlock; |
489 | ssleep(5); /* tcu needs this time for calibration */ | 422 | ssleep(5); /* tcu needs this time for calibration */ |
490 | retval = kone_tcu_command(usb_dev, 3); | 423 | retval = kone_tcu_command(usb_dev, 3); |
491 | if (retval) | 424 | if (retval) |
492 | goto exit_unlock; | 425 | goto exit_unlock; |
493 | retval = kone_tcu_command(usb_dev, 0); | 426 | retval = kone_tcu_command(usb_dev, 0); |
494 | if (retval) | 427 | if (retval) |
495 | goto exit_unlock; | 428 | goto exit_unlock; |
496 | retval = kone_tcu_command(usb_dev, 4); | 429 | retval = kone_tcu_command(usb_dev, 4); |
497 | if (retval) | 430 | if (retval) |
498 | goto exit_unlock; | 431 | goto exit_unlock; |
499 | /* | 432 | /* |
500 | * Kone needs this time to settle things. | 433 | * Kone needs this time to settle things. |
501 | * Reading settings too early will result in invalid data. | 434 | * Reading settings too early will result in invalid data. |
502 | * Roccat's driver waits 1 sec, maybe this time could be | 435 | * Roccat's driver waits 1 sec, maybe this time could be |
503 | * shortened. | 436 | * shortened. |
504 | */ | 437 | */ |
505 | ssleep(1); | 438 | ssleep(1); |
506 | } | 439 | } |
507 | 440 | ||
508 | /* calibration changes values in settings, so reread */ | 441 | /* calibration changes values in settings, so reread */ |
509 | retval = kone_get_settings(usb_dev, &kone->settings); | 442 | retval = kone_get_settings(usb_dev, &kone->settings); |
510 | if (retval) | 443 | if (retval) |
511 | goto exit_no_settings; | 444 | goto exit_no_settings; |
512 | 445 | ||
513 | /* only write settings back if activation state is different */ | 446 | /* only write settings back if activation state is different */ |
514 | if (kone->settings.tcu != state) { | 447 | if (kone->settings.tcu != state) { |
515 | kone->settings.tcu = state; | 448 | kone->settings.tcu = state; |
516 | kone_set_settings_checksum(&kone->settings); | 449 | kone_set_settings_checksum(&kone->settings); |
517 | 450 | ||
518 | retval = kone_set_settings(usb_dev, &kone->settings); | 451 | retval = kone_set_settings(usb_dev, &kone->settings); |
519 | if (retval) { | 452 | if (retval) { |
520 | hid_err(usb_dev, "couldn't set tcu state\n"); | 453 | hid_err(usb_dev, "couldn't set tcu state\n"); |
521 | /* | 454 | /* |
522 | * try to reread valid settings into buffer overwriting | 455 | * try to reread valid settings into buffer overwriting |
523 | * first error code | 456 | * first error code |
524 | */ | 457 | */ |
525 | retval = kone_get_settings(usb_dev, &kone->settings); | 458 | retval = kone_get_settings(usb_dev, &kone->settings); |
526 | if (retval) | 459 | if (retval) |
527 | goto exit_no_settings; | 460 | goto exit_no_settings; |
528 | goto exit_unlock; | 461 | goto exit_unlock; |
529 | } | 462 | } |
530 | } | 463 | } |
531 | 464 | ||
532 | retval = size; | 465 | retval = size; |
533 | exit_no_settings: | 466 | exit_no_settings: |
534 | hid_err(usb_dev, "couldn't read settings\n"); | 467 | hid_err(usb_dev, "couldn't read settings\n"); |
535 | exit_unlock: | 468 | exit_unlock: |
536 | mutex_unlock(&kone->kone_lock); | 469 | mutex_unlock(&kone->kone_lock); |
537 | return retval; | 470 | return retval; |
538 | } | 471 | } |
539 | 472 | ||
540 | static ssize_t kone_sysfs_show_startup_profile(struct device *dev, | 473 | static ssize_t kone_sysfs_show_startup_profile(struct device *dev, |
541 | struct device_attribute *attr, char *buf) | 474 | struct device_attribute *attr, char *buf) |
542 | { | 475 | { |
543 | struct kone_device *kone = | 476 | struct kone_device *kone = |
544 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 477 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
545 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile); | 478 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->settings.startup_profile); |
546 | } | 479 | } |
547 | 480 | ||
548 | static ssize_t kone_sysfs_set_startup_profile(struct device *dev, | 481 | static ssize_t kone_sysfs_set_startup_profile(struct device *dev, |
549 | struct device_attribute *attr, char const *buf, size_t size) | 482 | struct device_attribute *attr, char const *buf, size_t size) |
550 | { | 483 | { |
551 | struct kone_device *kone; | 484 | struct kone_device *kone; |
552 | struct usb_device *usb_dev; | 485 | struct usb_device *usb_dev; |
553 | int retval; | 486 | int retval; |
554 | unsigned long new_startup_profile; | 487 | unsigned long new_startup_profile; |
555 | 488 | ||
556 | dev = dev->parent->parent; | 489 | dev = dev->parent->parent; |
557 | kone = hid_get_drvdata(dev_get_drvdata(dev)); | 490 | kone = hid_get_drvdata(dev_get_drvdata(dev)); |
558 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 491 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
559 | 492 | ||
560 | retval = strict_strtoul(buf, 10, &new_startup_profile); | 493 | retval = strict_strtoul(buf, 10, &new_startup_profile); |
561 | if (retval) | 494 | if (retval) |
562 | return retval; | 495 | return retval; |
563 | 496 | ||
564 | if (new_startup_profile < 1 || new_startup_profile > 5) | 497 | if (new_startup_profile < 1 || new_startup_profile > 5) |
565 | return -EINVAL; | 498 | return -EINVAL; |
566 | 499 | ||
567 | mutex_lock(&kone->kone_lock); | 500 | mutex_lock(&kone->kone_lock); |
568 | 501 | ||
569 | kone->settings.startup_profile = new_startup_profile; | 502 | kone->settings.startup_profile = new_startup_profile; |
570 | kone_set_settings_checksum(&kone->settings); | 503 | kone_set_settings_checksum(&kone->settings); |
571 | 504 | ||
572 | retval = kone_set_settings(usb_dev, &kone->settings); | 505 | retval = kone_set_settings(usb_dev, &kone->settings); |
573 | 506 | ||
574 | mutex_unlock(&kone->kone_lock); | 507 | mutex_unlock(&kone->kone_lock); |
575 | 508 | ||
576 | if (retval) | 509 | if (retval) |
577 | return retval; | 510 | return retval; |
578 | 511 | ||
579 | /* changing the startup profile immediately activates this profile */ | 512 | /* changing the startup profile immediately activates this profile */ |
580 | kone->actual_profile = new_startup_profile; | 513 | kone->actual_profile = new_startup_profile; |
581 | kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi; | 514 | kone->actual_dpi = kone->profiles[kone->actual_profile - 1].startup_dpi; |
582 | 515 | ||
583 | return size; | 516 | return size; |
584 | } | 517 | } |
585 | 518 | ||
586 | static struct device_attribute kone_attributes[] = { | 519 | static struct device_attribute kone_attributes[] = { |
587 | /* | 520 | /* |
588 | * Read actual dpi settings. | 521 | * Read actual dpi settings. |
589 | * Returns raw value for further processing. Refer to enum | 522 | * Returns raw value for further processing. Refer to enum |
590 | * kone_polling_rates to get real value. | 523 | * kone_polling_rates to get real value. |
591 | */ | 524 | */ |
592 | __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL), | 525 | __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL), |
593 | __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL), | 526 | __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL), |
594 | 527 | ||
595 | /* | 528 | /* |
596 | * The mouse can be equipped with one of four supplied weights from 5 | 529 | * The mouse can be equipped with one of four supplied weights from 5 |
597 | * to 20 grams which are recognized and its value can be read out. | 530 | * to 20 grams which are recognized and its value can be read out. |
598 | * This returns the raw value reported by the mouse for easy evaluation | 531 | * This returns the raw value reported by the mouse for easy evaluation |
599 | * by software. Refer to enum kone_weights to get corresponding real | 532 | * by software. Refer to enum kone_weights to get corresponding real |
600 | * weight. | 533 | * weight. |
601 | */ | 534 | */ |
602 | __ATTR(weight, 0440, kone_sysfs_show_weight, NULL), | 535 | __ATTR(weight, 0440, kone_sysfs_show_weight, NULL), |
603 | 536 | ||
604 | /* | 537 | /* |
605 | * Prints firmware version stored in mouse as integer. | 538 | * Prints firmware version stored in mouse as integer. |
606 | * The raw value reported by the mouse is returned for easy evaluation, | 539 | * The raw value reported by the mouse is returned for easy evaluation, |
607 | * to get the real version number the decimal point has to be shifted 2 | 540 | * to get the real version number the decimal point has to be shifted 2 |
608 | * positions to the left. E.g. a value of 138 means 1.38. | 541 | * positions to the left. E.g. a value of 138 means 1.38. |
609 | */ | 542 | */ |
610 | __ATTR(firmware_version, 0440, | 543 | __ATTR(firmware_version, 0440, |
611 | kone_sysfs_show_firmware_version, NULL), | 544 | kone_sysfs_show_firmware_version, NULL), |
612 | 545 | ||
613 | /* | 546 | /* |
614 | * Prints state of Tracking Control Unit as number where 0 = off and | 547 | * Prints state of Tracking Control Unit as number where 0 = off and |
615 | * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and | 548 | * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and |
616 | * activates the tcu | 549 | * activates the tcu |
617 | */ | 550 | */ |
618 | __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu), | 551 | __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu), |
619 | 552 | ||
620 | /* Prints and takes the number of the profile the mouse starts with */ | 553 | /* Prints and takes the number of the profile the mouse starts with */ |
621 | __ATTR(startup_profile, 0660, | 554 | __ATTR(startup_profile, 0660, |
622 | kone_sysfs_show_startup_profile, | 555 | kone_sysfs_show_startup_profile, |
623 | kone_sysfs_set_startup_profile), | 556 | kone_sysfs_set_startup_profile), |
624 | __ATTR_NULL | 557 | __ATTR_NULL |
625 | }; | 558 | }; |
626 | 559 | ||
627 | static struct bin_attribute kone_bin_attributes[] = { | 560 | static struct bin_attribute kone_bin_attributes[] = { |
628 | { | 561 | { |
629 | .attr = { .name = "settings", .mode = 0660 }, | 562 | .attr = { .name = "settings", .mode = 0660 }, |
630 | .size = sizeof(struct kone_settings), | 563 | .size = sizeof(struct kone_settings), |
631 | .read = kone_sysfs_read_settings, | 564 | .read = kone_sysfs_read_settings, |
632 | .write = kone_sysfs_write_settings | 565 | .write = kone_sysfs_write_settings |
633 | }, | 566 | }, |
634 | { | 567 | { |
635 | .attr = { .name = "profile1", .mode = 0660 }, | 568 | .attr = { .name = "profile1", .mode = 0660 }, |
636 | .size = sizeof(struct kone_profile), | 569 | .size = sizeof(struct kone_profile), |
637 | .read = kone_sysfs_read_profilex, | 570 | .read = kone_sysfs_read_profilex, |
638 | .write = kone_sysfs_write_profilex, | 571 | .write = kone_sysfs_write_profilex, |
639 | .private = &profile_numbers[0] | 572 | .private = &profile_numbers[0] |
640 | }, | 573 | }, |
641 | { | 574 | { |
642 | .attr = { .name = "profile2", .mode = 0660 }, | 575 | .attr = { .name = "profile2", .mode = 0660 }, |
643 | .size = sizeof(struct kone_profile), | 576 | .size = sizeof(struct kone_profile), |
644 | .read = kone_sysfs_read_profilex, | 577 | .read = kone_sysfs_read_profilex, |
645 | .write = kone_sysfs_write_profilex, | 578 | .write = kone_sysfs_write_profilex, |
646 | .private = &profile_numbers[1] | 579 | .private = &profile_numbers[1] |
647 | }, | 580 | }, |
648 | { | 581 | { |
649 | .attr = { .name = "profile3", .mode = 0660 }, | 582 | .attr = { .name = "profile3", .mode = 0660 }, |
650 | .size = sizeof(struct kone_profile), | 583 | .size = sizeof(struct kone_profile), |
651 | .read = kone_sysfs_read_profilex, | 584 | .read = kone_sysfs_read_profilex, |
652 | .write = kone_sysfs_write_profilex, | 585 | .write = kone_sysfs_write_profilex, |
653 | .private = &profile_numbers[2] | 586 | .private = &profile_numbers[2] |
654 | }, | 587 | }, |
655 | { | 588 | { |
656 | .attr = { .name = "profile4", .mode = 0660 }, | 589 | .attr = { .name = "profile4", .mode = 0660 }, |
657 | .size = sizeof(struct kone_profile), | 590 | .size = sizeof(struct kone_profile), |
658 | .read = kone_sysfs_read_profilex, | 591 | .read = kone_sysfs_read_profilex, |
659 | .write = kone_sysfs_write_profilex, | 592 | .write = kone_sysfs_write_profilex, |
660 | .private = &profile_numbers[3] | 593 | .private = &profile_numbers[3] |
661 | }, | 594 | }, |
662 | { | 595 | { |
663 | .attr = { .name = "profile5", .mode = 0660 }, | 596 | .attr = { .name = "profile5", .mode = 0660 }, |
664 | .size = sizeof(struct kone_profile), | 597 | .size = sizeof(struct kone_profile), |
665 | .read = kone_sysfs_read_profilex, | 598 | .read = kone_sysfs_read_profilex, |
666 | .write = kone_sysfs_write_profilex, | 599 | .write = kone_sysfs_write_profilex, |
667 | .private = &profile_numbers[4] | 600 | .private = &profile_numbers[4] |
668 | }, | 601 | }, |
669 | __ATTR_NULL | 602 | __ATTR_NULL |
670 | }; | 603 | }; |
671 | 604 | ||
672 | static int kone_init_kone_device_struct(struct usb_device *usb_dev, | 605 | static int kone_init_kone_device_struct(struct usb_device *usb_dev, |
673 | struct kone_device *kone) | 606 | struct kone_device *kone) |
674 | { | 607 | { |
675 | uint i; | 608 | uint i; |
676 | int retval; | 609 | int retval; |
677 | 610 | ||
678 | mutex_init(&kone->kone_lock); | 611 | mutex_init(&kone->kone_lock); |
679 | 612 | ||
680 | for (i = 0; i < 5; ++i) { | 613 | for (i = 0; i < 5; ++i) { |
681 | retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1); | 614 | retval = kone_get_profile(usb_dev, &kone->profiles[i], i + 1); |
682 | if (retval) | 615 | if (retval) |
683 | return retval; | 616 | return retval; |
684 | } | 617 | } |
685 | 618 | ||
686 | retval = kone_get_settings(usb_dev, &kone->settings); | 619 | retval = kone_get_settings(usb_dev, &kone->settings); |
687 | if (retval) | 620 | if (retval) |
688 | return retval; | 621 | return retval; |
689 | 622 | ||
690 | retval = kone_get_firmware_version(usb_dev, &kone->firmware_version); | 623 | retval = kone_get_firmware_version(usb_dev, &kone->firmware_version); |
691 | if (retval) | 624 | if (retval) |
692 | return retval; | 625 | return retval; |
693 | 626 | ||
694 | kone->actual_profile = kone->settings.startup_profile; | 627 | kone->actual_profile = kone->settings.startup_profile; |
695 | kone->actual_dpi = kone->profiles[kone->actual_profile].startup_dpi; | 628 | kone->actual_dpi = kone->profiles[kone->actual_profile].startup_dpi; |
696 | 629 | ||
697 | return 0; | 630 | return 0; |
698 | } | 631 | } |
699 | 632 | ||
700 | /* | 633 | /* |
701 | * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to | 634 | * Since IGNORE_MOUSE quirk moved to hid-apple, there is no way to bind only to |
702 | * mousepart if usb_hid is compiled into the kernel and kone is compiled as | 635 | * mousepart if usb_hid is compiled into the kernel and kone is compiled as |
703 | * module. | 636 | * module. |
704 | * Secial behaviour is bound only to mousepart since only mouseevents contain | 637 | * Secial behaviour is bound only to mousepart since only mouseevents contain |
705 | * additional notifications. | 638 | * additional notifications. |
706 | */ | 639 | */ |
707 | static int kone_init_specials(struct hid_device *hdev) | 640 | static int kone_init_specials(struct hid_device *hdev) |
708 | { | 641 | { |
709 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 642 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
710 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 643 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
711 | struct kone_device *kone; | 644 | struct kone_device *kone; |
712 | int retval; | 645 | int retval; |
713 | 646 | ||
714 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 647 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
715 | == USB_INTERFACE_PROTOCOL_MOUSE) { | 648 | == USB_INTERFACE_PROTOCOL_MOUSE) { |
716 | 649 | ||
717 | kone = kzalloc(sizeof(*kone), GFP_KERNEL); | 650 | kone = kzalloc(sizeof(*kone), GFP_KERNEL); |
718 | if (!kone) { | 651 | if (!kone) { |
719 | hid_err(hdev, "can't alloc device descriptor\n"); | 652 | hid_err(hdev, "can't alloc device descriptor\n"); |
720 | return -ENOMEM; | 653 | return -ENOMEM; |
721 | } | 654 | } |
722 | hid_set_drvdata(hdev, kone); | 655 | hid_set_drvdata(hdev, kone); |
723 | 656 | ||
724 | retval = kone_init_kone_device_struct(usb_dev, kone); | 657 | retval = kone_init_kone_device_struct(usb_dev, kone); |
725 | if (retval) { | 658 | if (retval) { |
726 | hid_err(hdev, "couldn't init struct kone_device\n"); | 659 | hid_err(hdev, "couldn't init struct kone_device\n"); |
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); |
731 | if (retval < 0) { | 664 | if (retval < 0) { |
732 | hid_err(hdev, "couldn't init char dev\n"); | 665 | hid_err(hdev, "couldn't init char dev\n"); |
733 | /* be tolerant about not getting chrdev */ | 666 | /* be tolerant about not getting chrdev */ |
734 | } else { | 667 | } else { |
735 | kone->roccat_claimed = 1; | 668 | kone->roccat_claimed = 1; |
736 | kone->chrdev_minor = retval; | 669 | kone->chrdev_minor = retval; |
737 | } | 670 | } |
738 | } else { | 671 | } else { |
739 | hid_set_drvdata(hdev, NULL); | 672 | hid_set_drvdata(hdev, NULL); |
740 | } | 673 | } |
741 | 674 | ||
742 | return 0; | 675 | return 0; |
743 | exit_free: | 676 | exit_free: |
744 | kfree(kone); | 677 | kfree(kone); |
745 | return retval; | 678 | return retval; |
746 | } | 679 | } |
747 | 680 | ||
748 | static void kone_remove_specials(struct hid_device *hdev) | 681 | static void kone_remove_specials(struct hid_device *hdev) |
749 | { | 682 | { |
750 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 683 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
751 | struct kone_device *kone; | 684 | struct kone_device *kone; |
752 | 685 | ||
753 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 686 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
754 | == USB_INTERFACE_PROTOCOL_MOUSE) { | 687 | == USB_INTERFACE_PROTOCOL_MOUSE) { |
755 | kone = hid_get_drvdata(hdev); | 688 | kone = hid_get_drvdata(hdev); |
756 | if (kone->roccat_claimed) | 689 | if (kone->roccat_claimed) |
757 | roccat_disconnect(kone->chrdev_minor); | 690 | roccat_disconnect(kone->chrdev_minor); |
758 | kfree(hid_get_drvdata(hdev)); | 691 | kfree(hid_get_drvdata(hdev)); |
759 | } | 692 | } |
760 | } | 693 | } |
761 | 694 | ||
762 | static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) | 695 | static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) |
763 | { | 696 | { |
764 | int retval; | 697 | int retval; |
765 | 698 | ||
766 | retval = hid_parse(hdev); | 699 | retval = hid_parse(hdev); |
767 | if (retval) { | 700 | if (retval) { |
768 | hid_err(hdev, "parse failed\n"); | 701 | hid_err(hdev, "parse failed\n"); |
769 | goto exit; | 702 | goto exit; |
770 | } | 703 | } |
771 | 704 | ||
772 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 705 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
773 | if (retval) { | 706 | if (retval) { |
774 | hid_err(hdev, "hw start failed\n"); | 707 | hid_err(hdev, "hw start failed\n"); |
775 | goto exit; | 708 | goto exit; |
776 | } | 709 | } |
777 | 710 | ||
778 | retval = kone_init_specials(hdev); | 711 | retval = kone_init_specials(hdev); |
779 | if (retval) { | 712 | if (retval) { |
780 | hid_err(hdev, "couldn't install mouse\n"); | 713 | hid_err(hdev, "couldn't install mouse\n"); |
781 | goto exit_stop; | 714 | goto exit_stop; |
782 | } | 715 | } |
783 | 716 | ||
784 | return 0; | 717 | return 0; |
785 | 718 | ||
786 | exit_stop: | 719 | exit_stop: |
787 | hid_hw_stop(hdev); | 720 | hid_hw_stop(hdev); |
788 | exit: | 721 | exit: |
789 | return retval; | 722 | return retval; |
790 | } | 723 | } |
791 | 724 | ||
792 | static void kone_remove(struct hid_device *hdev) | 725 | static void kone_remove(struct hid_device *hdev) |
793 | { | 726 | { |
794 | kone_remove_specials(hdev); | 727 | kone_remove_specials(hdev); |
795 | hid_hw_stop(hdev); | 728 | hid_hw_stop(hdev); |
796 | } | 729 | } |
797 | 730 | ||
798 | /* handle special events and keep actual profile and dpi values up to date */ | 731 | /* handle special events and keep actual profile and dpi values up to date */ |
799 | static void kone_keep_values_up_to_date(struct kone_device *kone, | 732 | static void kone_keep_values_up_to_date(struct kone_device *kone, |
800 | struct kone_mouse_event const *event) | 733 | struct kone_mouse_event const *event) |
801 | { | 734 | { |
802 | switch (event->event) { | 735 | switch (event->event) { |
803 | case kone_mouse_event_switch_profile: | 736 | case kone_mouse_event_switch_profile: |
804 | case kone_mouse_event_osd_profile: | 737 | case kone_mouse_event_osd_profile: |
805 | kone->actual_profile = event->value; | 738 | kone->actual_profile = event->value; |
806 | kone->actual_dpi = kone->profiles[kone->actual_profile - 1]. | 739 | kone->actual_dpi = kone->profiles[kone->actual_profile - 1]. |
807 | startup_dpi; | 740 | startup_dpi; |
808 | break; | 741 | break; |
809 | case kone_mouse_event_switch_dpi: | 742 | case kone_mouse_event_switch_dpi: |
810 | case kone_mouse_event_osd_dpi: | 743 | case kone_mouse_event_osd_dpi: |
811 | kone->actual_dpi = event->value; | 744 | kone->actual_dpi = event->value; |
812 | break; | 745 | break; |
813 | } | 746 | } |
814 | } | 747 | } |
815 | 748 | ||
816 | static void kone_report_to_chrdev(struct kone_device const *kone, | 749 | static void kone_report_to_chrdev(struct kone_device const *kone, |
817 | struct kone_mouse_event const *event) | 750 | struct kone_mouse_event const *event) |
818 | { | 751 | { |
819 | struct kone_roccat_report roccat_report; | 752 | struct kone_roccat_report roccat_report; |
820 | 753 | ||
821 | switch (event->event) { | 754 | switch (event->event) { |
822 | case kone_mouse_event_switch_profile: | 755 | case kone_mouse_event_switch_profile: |
823 | case kone_mouse_event_switch_dpi: | 756 | case kone_mouse_event_switch_dpi: |
824 | case kone_mouse_event_osd_profile: | 757 | case kone_mouse_event_osd_profile: |
825 | case kone_mouse_event_osd_dpi: | 758 | case kone_mouse_event_osd_dpi: |
826 | roccat_report.event = event->event; | 759 | roccat_report.event = event->event; |
827 | roccat_report.value = event->value; | 760 | roccat_report.value = event->value; |
828 | roccat_report.key = 0; | 761 | roccat_report.key = 0; |
829 | roccat_report_event(kone->chrdev_minor, | 762 | roccat_report_event(kone->chrdev_minor, |
830 | (uint8_t *)&roccat_report, | 763 | (uint8_t *)&roccat_report, |
831 | sizeof(struct kone_roccat_report)); | 764 | 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) { |
835 | roccat_report.event = kone_mouse_event_call_overlong_macro; | 768 | roccat_report.event = kone_mouse_event_call_overlong_macro; |
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)); | 773 | sizeof(struct kone_roccat_report)); |
841 | } | 774 | } |
842 | break; | 775 | break; |
843 | } | 776 | } |
844 | 777 | ||
845 | } | 778 | } |
846 | 779 | ||
847 | /* | 780 | /* |
848 | * Is called for keyboard- and mousepart. | 781 | * Is called for keyboard- and mousepart. |
849 | * Only mousepart gets informations about special events in its extended event | 782 | * Only mousepart gets informations about special events in its extended event |
850 | * structure. | 783 | * structure. |
851 | */ | 784 | */ |
852 | static int kone_raw_event(struct hid_device *hdev, struct hid_report *report, | 785 | static int kone_raw_event(struct hid_device *hdev, struct hid_report *report, |
853 | u8 *data, int size) | 786 | u8 *data, int size) |
854 | { | 787 | { |
855 | struct kone_device *kone = hid_get_drvdata(hdev); | 788 | struct kone_device *kone = hid_get_drvdata(hdev); |
856 | struct kone_mouse_event *event = (struct kone_mouse_event *)data; | 789 | struct kone_mouse_event *event = (struct kone_mouse_event *)data; |
857 | 790 | ||
858 | /* keyboard events are always processed by default handler */ | 791 | /* keyboard events are always processed by default handler */ |
859 | if (size != sizeof(struct kone_mouse_event)) | 792 | if (size != sizeof(struct kone_mouse_event)) |
860 | return 0; | 793 | return 0; |
861 | 794 | ||
862 | /* | 795 | /* |
863 | * Firmware 1.38 introduced new behaviour for tilt and special buttons. | 796 | * Firmware 1.38 introduced new behaviour for tilt and special buttons. |
864 | * Pressed button is reported in each movement event. | 797 | * Pressed button is reported in each movement event. |
865 | * Workaround sends only one event per press. | 798 | * Workaround sends only one event per press. |
866 | */ | 799 | */ |
867 | if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5)) | 800 | if (memcmp(&kone->last_mouse_event.tilt, &event->tilt, 5)) |
868 | memcpy(&kone->last_mouse_event, event, | 801 | memcpy(&kone->last_mouse_event, event, |
869 | sizeof(struct kone_mouse_event)); | 802 | sizeof(struct kone_mouse_event)); |
870 | else | 803 | else |
871 | memset(&event->tilt, 0, 5); | 804 | memset(&event->tilt, 0, 5); |
872 | 805 | ||
873 | kone_keep_values_up_to_date(kone, event); | 806 | kone_keep_values_up_to_date(kone, event); |
874 | 807 | ||
875 | if (kone->roccat_claimed) | 808 | if (kone->roccat_claimed) |
876 | kone_report_to_chrdev(kone, event); | 809 | kone_report_to_chrdev(kone, event); |
877 | 810 | ||
878 | return 0; /* always do further processing */ | 811 | return 0; /* always do further processing */ |
879 | } | 812 | } |
880 | 813 | ||
881 | static const struct hid_device_id kone_devices[] = { | 814 | static const struct hid_device_id kone_devices[] = { |
882 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, | 815 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, |
883 | { } | 816 | { } |
884 | }; | 817 | }; |
885 | 818 | ||
886 | MODULE_DEVICE_TABLE(hid, kone_devices); | 819 | MODULE_DEVICE_TABLE(hid, kone_devices); |
887 | 820 | ||
888 | static struct hid_driver kone_driver = { | 821 | static struct hid_driver kone_driver = { |
889 | .name = "kone", | 822 | .name = "kone", |
890 | .id_table = kone_devices, | 823 | .id_table = kone_devices, |
891 | .probe = kone_probe, | 824 | .probe = kone_probe, |
892 | .remove = kone_remove, | 825 | .remove = kone_remove, |
893 | .raw_event = kone_raw_event | 826 | .raw_event = kone_raw_event |
894 | }; | 827 | }; |
895 | 828 | ||
896 | static int __init kone_init(void) | 829 | static int __init kone_init(void) |
897 | { | 830 | { |
898 | int retval; | 831 | int retval; |
899 | 832 | ||
900 | /* class name has to be same as driver name */ | 833 | /* class name has to be same as driver name */ |
901 | kone_class = class_create(THIS_MODULE, "kone"); | 834 | kone_class = class_create(THIS_MODULE, "kone"); |
902 | if (IS_ERR(kone_class)) | 835 | if (IS_ERR(kone_class)) |
903 | return PTR_ERR(kone_class); | 836 | return PTR_ERR(kone_class); |
904 | kone_class->dev_attrs = kone_attributes; | 837 | kone_class->dev_attrs = kone_attributes; |
905 | kone_class->dev_bin_attrs = kone_bin_attributes; | 838 | kone_class->dev_bin_attrs = kone_bin_attributes; |
906 | 839 | ||
907 | retval = hid_register_driver(&kone_driver); | 840 | retval = hid_register_driver(&kone_driver); |
908 | if (retval) | 841 | if (retval) |
909 | class_destroy(kone_class); | 842 | class_destroy(kone_class); |
910 | return retval; | 843 | return retval; |
911 | } | 844 | } |
912 | 845 | ||
913 | static void __exit kone_exit(void) | 846 | static void __exit kone_exit(void) |
914 | { | 847 | { |
915 | class_destroy(kone_class); | 848 | class_destroy(kone_class); |
916 | hid_unregister_driver(&kone_driver); | 849 | hid_unregister_driver(&kone_driver); |
917 | } | 850 | } |
918 | 851 | ||
919 | module_init(kone_init); | 852 | module_init(kone_init); |
920 | module_exit(kone_exit); | 853 | module_exit(kone_exit); |
921 | 854 | ||
922 | MODULE_AUTHOR("Stefan Achatz"); | 855 | MODULE_AUTHOR("Stefan Achatz"); |
923 | MODULE_DESCRIPTION("USB Roccat Kone driver"); | 856 | MODULE_DESCRIPTION("USB Roccat Kone driver"); |
drivers/hid/hid-roccat-koneplus.c
1 | /* | 1 | /* |
2 | * Roccat Kone[+] driver for Linux | 2 | * Roccat Kone[+] driver for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> | 4 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. | 11 | * any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Roccat Kone[+] is an updated/improved version of the Kone with more memory | 15 | * Roccat Kone[+] is an updated/improved version of the Kone with more memory |
16 | * and functionality and without the non-standard behaviours the Kone had. | 16 | * and functionality and without the non-standard behaviours the Kone had. |
17 | */ | 17 | */ |
18 | 18 | ||
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> |
25 | #include "hid-ids.h" | 24 | #include "hid-ids.h" |
26 | #include "hid-roccat.h" | 25 | #include "hid-roccat.h" |
26 | #include "hid-roccat-common.h" | ||
27 | #include "hid-roccat-koneplus.h" | 27 | #include "hid-roccat-koneplus.h" |
28 | 28 | ||
29 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; | 29 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; |
30 | 30 | ||
31 | static struct class *koneplus_class; | 31 | static struct class *koneplus_class; |
32 | 32 | ||
33 | static void koneplus_profile_activated(struct koneplus_device *koneplus, | 33 | static void koneplus_profile_activated(struct koneplus_device *koneplus, |
34 | uint new_profile) | 34 | uint new_profile) |
35 | { | 35 | { |
36 | koneplus->actual_profile = new_profile; | 36 | koneplus->actual_profile = new_profile; |
37 | } | 37 | } |
38 | 38 | ||
39 | static int koneplus_send_control(struct usb_device *usb_dev, uint value, | 39 | static 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 | } | 55 | } |
72 | 56 | ||
73 | static 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 | } | ||
84 | |||
85 | static int koneplus_receive_control_status(struct usb_device *usb_dev) | 57 | static 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 | 61 | ||
90 | control = kmalloc(sizeof(struct koneplus_control), GFP_KERNEL); | ||
91 | if (!control) | ||
92 | return -ENOMEM; | ||
93 | |||
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 | 82 | ||
119 | hid_err(usb_dev, "koneplus_receive_control_status: " | 83 | hid_err(usb_dev, "koneplus_receive_control_status: " |
120 | "unknown response value 0x%x\n", control->value); | 84 | "unknown response value 0x%x\n", control.value); |
121 | retval = -EINVAL; | 85 | return -EINVAL; |
122 | goto out; | ||
123 | |||
124 | } while (1); | 86 | } while (1); |
125 | out: | ||
126 | kfree(control); | ||
127 | return retval; | ||
128 | } | 87 | } |
129 | 88 | ||
130 | static int koneplus_send(struct usb_device *usb_dev, uint command, | 89 | static 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 | { |
92 | int retval; | ||
133 | 93 | ||
134 | len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), | 94 | retval = roccat_common_send(usb_dev, command, buf, size); |
135 | USB_REQ_SET_CONFIGURATION, | 95 | if (retval) |
136 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 96 | return retval; |
137 | command, 0, buf, size, USB_CTRL_SET_TIMEOUT); | ||
138 | 97 | ||
139 | if (len != size) | 98 | return koneplus_receive_control_status(usb_dev); |
140 | return -EIO; | ||
141 | |||
142 | if (koneplus_receive_control_status(usb_dev)) | ||
143 | return -EIO; | ||
144 | |||
145 | return 0; | ||
146 | } | 99 | } |
147 | 100 | ||
148 | static int koneplus_select_profile(struct usb_device *usb_dev, uint number, | 101 | static int koneplus_select_profile(struct usb_device *usb_dev, uint number, |
149 | enum koneplus_control_requests request) | 102 | enum koneplus_control_requests request) |
150 | { | 103 | { |
151 | int retval; | 104 | int retval; |
152 | 105 | ||
153 | retval = koneplus_send_control(usb_dev, number, request); | 106 | retval = koneplus_send_control(usb_dev, number, request); |
154 | if (retval) | 107 | if (retval) |
155 | return retval; | 108 | return retval; |
156 | 109 | ||
157 | /* allow time to settle things - windows driver uses 500 */ | 110 | /* allow time to settle things - windows driver uses 500 */ |
158 | msleep(100); | 111 | msleep(100); |
159 | 112 | ||
160 | retval = koneplus_receive_control_status(usb_dev); | 113 | retval = koneplus_receive_control_status(usb_dev); |
161 | if (retval) | 114 | if (retval) |
162 | return retval; | 115 | return retval; |
163 | 116 | ||
164 | return 0; | 117 | return 0; |
165 | } | 118 | } |
166 | 119 | ||
167 | static int koneplus_get_info(struct usb_device *usb_dev, | 120 | static 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 | ||
174 | static int koneplus_get_profile_settings(struct usb_device *usb_dev, | 127 | static int koneplus_get_profile_settings(struct usb_device *usb_dev, |
175 | struct koneplus_profile_settings *buf, uint number) | 128 | struct koneplus_profile_settings *buf, uint number) |
176 | { | 129 | { |
177 | int retval; | 130 | int retval; |
178 | 131 | ||
179 | retval = koneplus_select_profile(usb_dev, number, | 132 | retval = koneplus_select_profile(usb_dev, number, |
180 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); | 133 | KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); |
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 | ||
188 | static int koneplus_set_profile_settings(struct usb_device *usb_dev, | 141 | 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 | ||
195 | static int koneplus_get_profile_buttons(struct usb_device *usb_dev, | 148 | static int koneplus_get_profile_buttons(struct usb_device *usb_dev, |
196 | struct koneplus_profile_buttons *buf, int number) | 149 | struct koneplus_profile_buttons *buf, int number) |
197 | { | 150 | { |
198 | int retval; | 151 | int retval; |
199 | 152 | ||
200 | retval = koneplus_select_profile(usb_dev, number, | 153 | retval = koneplus_select_profile(usb_dev, number, |
201 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); | 154 | KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); |
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 | ||
209 | static int koneplus_set_profile_buttons(struct usb_device *usb_dev, | 162 | 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 */ |
217 | static int koneplus_get_startup_profile(struct usb_device *usb_dev) | 170 | static 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, |
223 | if (buf == NULL) | 176 | &buf, sizeof(struct koneplus_startup_profile)); |
224 | return -ENOMEM; | ||
225 | 177 | ||
226 | retval = koneplus_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, | 178 | return retval ? retval : buf.startup_profile; |
227 | buf, sizeof(struct koneplus_startup_profile)); | ||
228 | |||
229 | if (retval) | ||
230 | goto out; | ||
231 | |||
232 | retval = buf->startup_profile; | ||
233 | out: | ||
234 | kfree(buf); | ||
235 | return retval; | ||
236 | } | 179 | } |
237 | 180 | ||
238 | static int koneplus_set_startup_profile(struct usb_device *usb_dev, | 181 | static int koneplus_set_startup_profile(struct usb_device *usb_dev, |
239 | int startup_profile) | 182 | int startup_profile) |
240 | { | 183 | { |
241 | struct koneplus_startup_profile buf; | 184 | struct koneplus_startup_profile buf; |
242 | 185 | ||
243 | buf.command = KONEPLUS_COMMAND_STARTUP_PROFILE; | 186 | buf.command = KONEPLUS_COMMAND_STARTUP_PROFILE; |
244 | buf.size = sizeof(struct koneplus_startup_profile); | 187 | buf.size = sizeof(struct koneplus_startup_profile); |
245 | buf.startup_profile = startup_profile; | 188 | buf.startup_profile = startup_profile; |
246 | 189 | ||
247 | return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, | 190 | return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE, |
248 | (char *)&buf, sizeof(struct koneplus_profile_buttons)); | 191 | &buf, sizeof(struct koneplus_profile_buttons)); |
249 | } | 192 | } |
250 | 193 | ||
251 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, | 194 | static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj, |
252 | char *buf, loff_t off, size_t count, | 195 | char *buf, loff_t off, size_t count, |
253 | size_t real_size, uint command) | 196 | size_t real_size, uint command) |
254 | { | 197 | { |
255 | struct device *dev = | 198 | struct device *dev = |
256 | container_of(kobj, struct device, kobj)->parent->parent; | 199 | container_of(kobj, struct device, kobj)->parent->parent; |
257 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 200 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
258 | 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)); |
259 | int retval; | 202 | int retval; |
260 | 203 | ||
261 | if (off >= real_size) | 204 | if (off >= real_size) |
262 | return 0; | 205 | return 0; |
263 | 206 | ||
264 | if (off != 0 || count != real_size) | 207 | if (off != 0 || count != real_size) |
265 | return -EINVAL; | 208 | return -EINVAL; |
266 | 209 | ||
267 | mutex_lock(&koneplus->koneplus_lock); | 210 | mutex_lock(&koneplus->koneplus_lock); |
268 | retval = koneplus_receive(usb_dev, command, buf, real_size); | 211 | retval = roccat_common_receive(usb_dev, command, buf, real_size); |
269 | mutex_unlock(&koneplus->koneplus_lock); | 212 | mutex_unlock(&koneplus->koneplus_lock); |
270 | 213 | ||
271 | if (retval) | 214 | if (retval) |
272 | return retval; | 215 | return retval; |
273 | 216 | ||
274 | return real_size; | 217 | return real_size; |
275 | } | 218 | } |
276 | 219 | ||
277 | static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, | 220 | static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj, |
278 | void const *buf, loff_t off, size_t count, | 221 | void const *buf, loff_t off, size_t count, |
279 | size_t real_size, uint command) | 222 | size_t real_size, uint command) |
280 | { | 223 | { |
281 | struct device *dev = | 224 | struct device *dev = |
282 | container_of(kobj, struct device, kobj)->parent->parent; | 225 | container_of(kobj, struct device, kobj)->parent->parent; |
283 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 226 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
284 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 227 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
285 | int retval; | 228 | int retval; |
286 | 229 | ||
287 | if (off != 0 || count != real_size) | 230 | if (off != 0 || count != real_size) |
288 | return -EINVAL; | 231 | return -EINVAL; |
289 | 232 | ||
290 | mutex_lock(&koneplus->koneplus_lock); | 233 | mutex_lock(&koneplus->koneplus_lock); |
291 | retval = koneplus_send(usb_dev, command, (void *)buf, real_size); | 234 | retval = koneplus_send(usb_dev, command, buf, real_size); |
292 | mutex_unlock(&koneplus->koneplus_lock); | 235 | mutex_unlock(&koneplus->koneplus_lock); |
293 | 236 | ||
294 | if (retval) | 237 | if (retval) |
295 | return retval; | 238 | return retval; |
296 | 239 | ||
297 | return real_size; | 240 | return real_size; |
298 | } | 241 | } |
299 | 242 | ||
300 | static ssize_t koneplus_sysfs_write_macro(struct file *fp, | 243 | static ssize_t koneplus_sysfs_write_macro(struct file *fp, |
301 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 244 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
302 | loff_t off, size_t count) | 245 | loff_t off, size_t count) |
303 | { | 246 | { |
304 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 247 | return koneplus_sysfs_write(fp, kobj, buf, off, count, |
305 | sizeof(struct koneplus_macro), KONEPLUS_USB_COMMAND_MACRO); | 248 | sizeof(struct koneplus_macro), KONEPLUS_USB_COMMAND_MACRO); |
306 | } | 249 | } |
307 | 250 | ||
308 | static ssize_t koneplus_sysfs_read_sensor(struct file *fp, | 251 | static ssize_t koneplus_sysfs_read_sensor(struct file *fp, |
309 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 252 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
310 | loff_t off, size_t count) | 253 | loff_t off, size_t count) |
311 | { | 254 | { |
312 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | 255 | return koneplus_sysfs_read(fp, kobj, buf, off, count, |
313 | sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); | 256 | sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); |
314 | } | 257 | } |
315 | 258 | ||
316 | static ssize_t koneplus_sysfs_write_sensor(struct file *fp, | 259 | static ssize_t koneplus_sysfs_write_sensor(struct file *fp, |
317 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 260 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
318 | loff_t off, size_t count) | 261 | loff_t off, size_t count) |
319 | { | 262 | { |
320 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 263 | return koneplus_sysfs_write(fp, kobj, buf, off, count, |
321 | sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); | 264 | sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); |
322 | } | 265 | } |
323 | 266 | ||
324 | static ssize_t koneplus_sysfs_write_tcu(struct file *fp, | 267 | static ssize_t koneplus_sysfs_write_tcu(struct file *fp, |
325 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 268 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
326 | loff_t off, size_t count) | 269 | loff_t off, size_t count) |
327 | { | 270 | { |
328 | return koneplus_sysfs_write(fp, kobj, buf, off, count, | 271 | return koneplus_sysfs_write(fp, kobj, buf, off, count, |
329 | sizeof(struct koneplus_tcu), KONEPLUS_USB_COMMAND_TCU); | 272 | sizeof(struct koneplus_tcu), KONEPLUS_USB_COMMAND_TCU); |
330 | } | 273 | } |
331 | 274 | ||
332 | static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, | 275 | static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, |
333 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 276 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
334 | loff_t off, size_t count) | 277 | loff_t off, size_t count) |
335 | { | 278 | { |
336 | return koneplus_sysfs_read(fp, kobj, buf, off, count, | 279 | return koneplus_sysfs_read(fp, kobj, buf, off, count, |
337 | sizeof(struct koneplus_tcu_image), KONEPLUS_USB_COMMAND_TCU); | 280 | sizeof(struct koneplus_tcu_image), KONEPLUS_USB_COMMAND_TCU); |
338 | } | 281 | } |
339 | 282 | ||
340 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, | 283 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, |
341 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 284 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
342 | loff_t off, size_t count) | 285 | loff_t off, size_t count) |
343 | { | 286 | { |
344 | struct device *dev = | 287 | struct device *dev = |
345 | container_of(kobj, struct device, kobj)->parent->parent; | 288 | container_of(kobj, struct device, kobj)->parent->parent; |
346 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 289 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
347 | 290 | ||
348 | if (off >= sizeof(struct koneplus_profile_settings)) | 291 | if (off >= sizeof(struct koneplus_profile_settings)) |
349 | return 0; | 292 | return 0; |
350 | 293 | ||
351 | if (off + count > sizeof(struct koneplus_profile_settings)) | 294 | if (off + count > sizeof(struct koneplus_profile_settings)) |
352 | count = sizeof(struct koneplus_profile_settings) - off; | 295 | count = sizeof(struct koneplus_profile_settings) - off; |
353 | 296 | ||
354 | mutex_lock(&koneplus->koneplus_lock); | 297 | mutex_lock(&koneplus->koneplus_lock); |
355 | memcpy(buf, ((void const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, | 298 | memcpy(buf, ((char const *)&koneplus->profile_settings[*(uint *)(attr->private)]) + off, |
356 | count); | 299 | count); |
357 | mutex_unlock(&koneplus->koneplus_lock); | 300 | mutex_unlock(&koneplus->koneplus_lock); |
358 | 301 | ||
359 | return count; | 302 | return count; |
360 | } | 303 | } |
361 | 304 | ||
362 | static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp, | 305 | static ssize_t koneplus_sysfs_write_profile_settings(struct file *fp, |
363 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 306 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
364 | loff_t off, size_t count) | 307 | loff_t off, size_t count) |
365 | { | 308 | { |
366 | struct device *dev = | 309 | struct device *dev = |
367 | container_of(kobj, struct device, kobj)->parent->parent; | 310 | container_of(kobj, struct device, kobj)->parent->parent; |
368 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 311 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
369 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 312 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
370 | int retval = 0; | 313 | int retval = 0; |
371 | int difference; | 314 | int difference; |
372 | int profile_number; | 315 | int profile_number; |
373 | struct koneplus_profile_settings *profile_settings; | 316 | struct koneplus_profile_settings *profile_settings; |
374 | 317 | ||
375 | if (off != 0 || count != sizeof(struct koneplus_profile_settings)) | 318 | if (off != 0 || count != sizeof(struct koneplus_profile_settings)) |
376 | return -EINVAL; | 319 | return -EINVAL; |
377 | 320 | ||
378 | profile_number = ((struct koneplus_profile_settings const *)buf)->number; | 321 | profile_number = ((struct koneplus_profile_settings const *)buf)->number; |
379 | profile_settings = &koneplus->profile_settings[profile_number]; | 322 | profile_settings = &koneplus->profile_settings[profile_number]; |
380 | 323 | ||
381 | mutex_lock(&koneplus->koneplus_lock); | 324 | mutex_lock(&koneplus->koneplus_lock); |
382 | difference = memcmp(buf, profile_settings, | 325 | difference = memcmp(buf, profile_settings, |
383 | sizeof(struct koneplus_profile_settings)); | 326 | sizeof(struct koneplus_profile_settings)); |
384 | if (difference) { | 327 | if (difference) { |
385 | retval = koneplus_set_profile_settings(usb_dev, | 328 | retval = koneplus_set_profile_settings(usb_dev, |
386 | (struct koneplus_profile_settings const *)buf); | 329 | (struct koneplus_profile_settings const *)buf); |
387 | if (!retval) | 330 | if (!retval) |
388 | memcpy(profile_settings, buf, | 331 | memcpy(profile_settings, buf, |
389 | sizeof(struct koneplus_profile_settings)); | 332 | sizeof(struct koneplus_profile_settings)); |
390 | } | 333 | } |
391 | mutex_unlock(&koneplus->koneplus_lock); | 334 | mutex_unlock(&koneplus->koneplus_lock); |
392 | 335 | ||
393 | if (retval) | 336 | if (retval) |
394 | return retval; | 337 | return retval; |
395 | 338 | ||
396 | return sizeof(struct koneplus_profile_settings); | 339 | return sizeof(struct koneplus_profile_settings); |
397 | } | 340 | } |
398 | 341 | ||
399 | static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, | 342 | static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, |
400 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 343 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
401 | loff_t off, size_t count) | 344 | loff_t off, size_t count) |
402 | { | 345 | { |
403 | struct device *dev = | 346 | struct device *dev = |
404 | container_of(kobj, struct device, kobj)->parent->parent; | 347 | container_of(kobj, struct device, kobj)->parent->parent; |
405 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 348 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
406 | 349 | ||
407 | if (off >= sizeof(struct koneplus_profile_buttons)) | 350 | if (off >= sizeof(struct koneplus_profile_buttons)) |
408 | return 0; | 351 | return 0; |
409 | 352 | ||
410 | if (off + count > sizeof(struct koneplus_profile_buttons)) | 353 | if (off + count > sizeof(struct koneplus_profile_buttons)) |
411 | count = sizeof(struct koneplus_profile_buttons) - off; | 354 | count = sizeof(struct koneplus_profile_buttons) - off; |
412 | 355 | ||
413 | mutex_lock(&koneplus->koneplus_lock); | 356 | mutex_lock(&koneplus->koneplus_lock); |
414 | memcpy(buf, ((void const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, | 357 | memcpy(buf, ((char const *)&koneplus->profile_buttons[*(uint *)(attr->private)]) + off, |
415 | count); | 358 | count); |
416 | mutex_unlock(&koneplus->koneplus_lock); | 359 | mutex_unlock(&koneplus->koneplus_lock); |
417 | 360 | ||
418 | return count; | 361 | return count; |
419 | } | 362 | } |
420 | 363 | ||
421 | static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, | 364 | static ssize_t koneplus_sysfs_write_profile_buttons(struct file *fp, |
422 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 365 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
423 | loff_t off, size_t count) | 366 | loff_t off, size_t count) |
424 | { | 367 | { |
425 | struct device *dev = | 368 | struct device *dev = |
426 | container_of(kobj, struct device, kobj)->parent->parent; | 369 | container_of(kobj, struct device, kobj)->parent->parent; |
427 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 370 | struct koneplus_device *koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
428 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 371 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
429 | int retval = 0; | 372 | int retval = 0; |
430 | int difference; | 373 | int difference; |
431 | uint profile_number; | 374 | uint profile_number; |
432 | struct koneplus_profile_buttons *profile_buttons; | 375 | struct koneplus_profile_buttons *profile_buttons; |
433 | 376 | ||
434 | if (off != 0 || count != sizeof(struct koneplus_profile_buttons)) | 377 | if (off != 0 || count != sizeof(struct koneplus_profile_buttons)) |
435 | return -EINVAL; | 378 | return -EINVAL; |
436 | 379 | ||
437 | profile_number = ((struct koneplus_profile_buttons const *)buf)->number; | 380 | profile_number = ((struct koneplus_profile_buttons const *)buf)->number; |
438 | profile_buttons = &koneplus->profile_buttons[profile_number]; | 381 | profile_buttons = &koneplus->profile_buttons[profile_number]; |
439 | 382 | ||
440 | mutex_lock(&koneplus->koneplus_lock); | 383 | mutex_lock(&koneplus->koneplus_lock); |
441 | difference = memcmp(buf, profile_buttons, | 384 | difference = memcmp(buf, profile_buttons, |
442 | sizeof(struct koneplus_profile_buttons)); | 385 | sizeof(struct koneplus_profile_buttons)); |
443 | if (difference) { | 386 | if (difference) { |
444 | retval = koneplus_set_profile_buttons(usb_dev, | 387 | retval = koneplus_set_profile_buttons(usb_dev, |
445 | (struct koneplus_profile_buttons const *)buf); | 388 | (struct koneplus_profile_buttons const *)buf); |
446 | if (!retval) | 389 | if (!retval) |
447 | memcpy(profile_buttons, buf, | 390 | memcpy(profile_buttons, buf, |
448 | sizeof(struct koneplus_profile_buttons)); | 391 | sizeof(struct koneplus_profile_buttons)); |
449 | } | 392 | } |
450 | mutex_unlock(&koneplus->koneplus_lock); | 393 | mutex_unlock(&koneplus->koneplus_lock); |
451 | 394 | ||
452 | if (retval) | 395 | if (retval) |
453 | return retval; | 396 | return retval; |
454 | 397 | ||
455 | return sizeof(struct koneplus_profile_buttons); | 398 | return sizeof(struct koneplus_profile_buttons); |
456 | } | 399 | } |
457 | 400 | ||
458 | static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev, | 401 | static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev, |
459 | struct device_attribute *attr, char *buf) | 402 | struct device_attribute *attr, char *buf) |
460 | { | 403 | { |
461 | struct koneplus_device *koneplus = | 404 | struct koneplus_device *koneplus = |
462 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 405 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
463 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->startup_profile); | 406 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->startup_profile); |
464 | } | 407 | } |
465 | 408 | ||
466 | static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, | 409 | static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev, |
467 | struct device_attribute *attr, char const *buf, size_t size) | 410 | struct device_attribute *attr, char const *buf, size_t size) |
468 | { | 411 | { |
469 | struct koneplus_device *koneplus; | 412 | struct koneplus_device *koneplus; |
470 | struct usb_device *usb_dev; | 413 | struct usb_device *usb_dev; |
471 | unsigned long profile; | 414 | unsigned long profile; |
472 | int retval; | 415 | int retval; |
473 | 416 | ||
474 | dev = dev->parent->parent; | 417 | dev = dev->parent->parent; |
475 | koneplus = hid_get_drvdata(dev_get_drvdata(dev)); | 418 | koneplus = hid_get_drvdata(dev_get_drvdata(dev)); |
476 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 419 | usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
477 | 420 | ||
478 | retval = strict_strtoul(buf, 10, &profile); | 421 | retval = strict_strtoul(buf, 10, &profile); |
479 | if (retval) | 422 | if (retval) |
480 | return retval; | 423 | return retval; |
481 | 424 | ||
482 | mutex_lock(&koneplus->koneplus_lock); | 425 | mutex_lock(&koneplus->koneplus_lock); |
483 | retval = koneplus_set_startup_profile(usb_dev, profile); | 426 | retval = koneplus_set_startup_profile(usb_dev, profile); |
484 | mutex_unlock(&koneplus->koneplus_lock); | 427 | mutex_unlock(&koneplus->koneplus_lock); |
485 | if (retval) | 428 | if (retval) |
486 | return retval; | 429 | return retval; |
487 | 430 | ||
488 | return size; | 431 | return size; |
489 | } | 432 | } |
490 | 433 | ||
491 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, | 434 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, |
492 | struct device_attribute *attr, char *buf) | 435 | struct device_attribute *attr, char *buf) |
493 | { | 436 | { |
494 | struct koneplus_device *koneplus = | 437 | struct koneplus_device *koneplus = |
495 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 438 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
496 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); | 439 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile); |
497 | } | 440 | } |
498 | 441 | ||
499 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, | 442 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, |
500 | struct device_attribute *attr, char *buf) | 443 | struct device_attribute *attr, char *buf) |
501 | { | 444 | { |
502 | struct koneplus_device *koneplus = | 445 | struct koneplus_device *koneplus = |
503 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 446 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
504 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version); | 447 | return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->info.firmware_version); |
505 | } | 448 | } |
506 | 449 | ||
507 | static struct device_attribute koneplus_attributes[] = { | 450 | static struct device_attribute koneplus_attributes[] = { |
508 | __ATTR(startup_profile, 0660, | 451 | __ATTR(startup_profile, 0660, |
509 | koneplus_sysfs_show_startup_profile, | 452 | koneplus_sysfs_show_startup_profile, |
510 | koneplus_sysfs_set_startup_profile), | 453 | koneplus_sysfs_set_startup_profile), |
511 | __ATTR(actual_profile, 0440, | 454 | __ATTR(actual_profile, 0440, |
512 | koneplus_sysfs_show_actual_profile, NULL), | 455 | koneplus_sysfs_show_actual_profile, NULL), |
513 | __ATTR(firmware_version, 0440, | 456 | __ATTR(firmware_version, 0440, |
514 | koneplus_sysfs_show_firmware_version, NULL), | 457 | koneplus_sysfs_show_firmware_version, NULL), |
515 | __ATTR_NULL | 458 | __ATTR_NULL |
516 | }; | 459 | }; |
517 | 460 | ||
518 | static struct bin_attribute koneplus_bin_attributes[] = { | 461 | static struct bin_attribute koneplus_bin_attributes[] = { |
519 | { | 462 | { |
520 | .attr = { .name = "sensor", .mode = 0220 }, | 463 | .attr = { .name = "sensor", .mode = 0220 }, |
521 | .size = sizeof(struct koneplus_sensor), | 464 | .size = sizeof(struct koneplus_sensor), |
522 | .read = koneplus_sysfs_read_sensor, | 465 | .read = koneplus_sysfs_read_sensor, |
523 | .write = koneplus_sysfs_write_sensor | 466 | .write = koneplus_sysfs_write_sensor |
524 | }, | 467 | }, |
525 | { | 468 | { |
526 | .attr = { .name = "tcu", .mode = 0220 }, | 469 | .attr = { .name = "tcu", .mode = 0220 }, |
527 | .size = sizeof(struct koneplus_tcu), | 470 | .size = sizeof(struct koneplus_tcu), |
528 | .write = koneplus_sysfs_write_tcu | 471 | .write = koneplus_sysfs_write_tcu |
529 | }, | 472 | }, |
530 | { | 473 | { |
531 | .attr = { .name = "tcu_image", .mode = 0440 }, | 474 | .attr = { .name = "tcu_image", .mode = 0440 }, |
532 | .size = sizeof(struct koneplus_tcu_image), | 475 | .size = sizeof(struct koneplus_tcu_image), |
533 | .read = koneplus_sysfs_read_tcu_image | 476 | .read = koneplus_sysfs_read_tcu_image |
534 | }, | 477 | }, |
535 | { | 478 | { |
536 | .attr = { .name = "profile_settings", .mode = 0220 }, | 479 | .attr = { .name = "profile_settings", .mode = 0220 }, |
537 | .size = sizeof(struct koneplus_profile_settings), | 480 | .size = sizeof(struct koneplus_profile_settings), |
538 | .write = koneplus_sysfs_write_profile_settings | 481 | .write = koneplus_sysfs_write_profile_settings |
539 | }, | 482 | }, |
540 | { | 483 | { |
541 | .attr = { .name = "profile1_settings", .mode = 0440 }, | 484 | .attr = { .name = "profile1_settings", .mode = 0440 }, |
542 | .size = sizeof(struct koneplus_profile_settings), | 485 | .size = sizeof(struct koneplus_profile_settings), |
543 | .read = koneplus_sysfs_read_profilex_settings, | 486 | .read = koneplus_sysfs_read_profilex_settings, |
544 | .private = &profile_numbers[0] | 487 | .private = &profile_numbers[0] |
545 | }, | 488 | }, |
546 | { | 489 | { |
547 | .attr = { .name = "profile2_settings", .mode = 0440 }, | 490 | .attr = { .name = "profile2_settings", .mode = 0440 }, |
548 | .size = sizeof(struct koneplus_profile_settings), | 491 | .size = sizeof(struct koneplus_profile_settings), |
549 | .read = koneplus_sysfs_read_profilex_settings, | 492 | .read = koneplus_sysfs_read_profilex_settings, |
550 | .private = &profile_numbers[1] | 493 | .private = &profile_numbers[1] |
551 | }, | 494 | }, |
552 | { | 495 | { |
553 | .attr = { .name = "profile3_settings", .mode = 0440 }, | 496 | .attr = { .name = "profile3_settings", .mode = 0440 }, |
554 | .size = sizeof(struct koneplus_profile_settings), | 497 | .size = sizeof(struct koneplus_profile_settings), |
555 | .read = koneplus_sysfs_read_profilex_settings, | 498 | .read = koneplus_sysfs_read_profilex_settings, |
556 | .private = &profile_numbers[2] | 499 | .private = &profile_numbers[2] |
557 | }, | 500 | }, |
558 | { | 501 | { |
559 | .attr = { .name = "profile4_settings", .mode = 0440 }, | 502 | .attr = { .name = "profile4_settings", .mode = 0440 }, |
560 | .size = sizeof(struct koneplus_profile_settings), | 503 | .size = sizeof(struct koneplus_profile_settings), |
561 | .read = koneplus_sysfs_read_profilex_settings, | 504 | .read = koneplus_sysfs_read_profilex_settings, |
562 | .private = &profile_numbers[3] | 505 | .private = &profile_numbers[3] |
563 | }, | 506 | }, |
564 | { | 507 | { |
565 | .attr = { .name = "profile5_settings", .mode = 0440 }, | 508 | .attr = { .name = "profile5_settings", .mode = 0440 }, |
566 | .size = sizeof(struct koneplus_profile_settings), | 509 | .size = sizeof(struct koneplus_profile_settings), |
567 | .read = koneplus_sysfs_read_profilex_settings, | 510 | .read = koneplus_sysfs_read_profilex_settings, |
568 | .private = &profile_numbers[4] | 511 | .private = &profile_numbers[4] |
569 | }, | 512 | }, |
570 | { | 513 | { |
571 | .attr = { .name = "profile_buttons", .mode = 0220 }, | 514 | .attr = { .name = "profile_buttons", .mode = 0220 }, |
572 | .size = sizeof(struct koneplus_profile_buttons), | 515 | .size = sizeof(struct koneplus_profile_buttons), |
573 | .write = koneplus_sysfs_write_profile_buttons | 516 | .write = koneplus_sysfs_write_profile_buttons |
574 | }, | 517 | }, |
575 | { | 518 | { |
576 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | 519 | .attr = { .name = "profile1_buttons", .mode = 0440 }, |
577 | .size = sizeof(struct koneplus_profile_buttons), | 520 | .size = sizeof(struct koneplus_profile_buttons), |
578 | .read = koneplus_sysfs_read_profilex_buttons, | 521 | .read = koneplus_sysfs_read_profilex_buttons, |
579 | .private = &profile_numbers[0] | 522 | .private = &profile_numbers[0] |
580 | }, | 523 | }, |
581 | { | 524 | { |
582 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | 525 | .attr = { .name = "profile2_buttons", .mode = 0440 }, |
583 | .size = sizeof(struct koneplus_profile_buttons), | 526 | .size = sizeof(struct koneplus_profile_buttons), |
584 | .read = koneplus_sysfs_read_profilex_buttons, | 527 | .read = koneplus_sysfs_read_profilex_buttons, |
585 | .private = &profile_numbers[1] | 528 | .private = &profile_numbers[1] |
586 | }, | 529 | }, |
587 | { | 530 | { |
588 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | 531 | .attr = { .name = "profile3_buttons", .mode = 0440 }, |
589 | .size = sizeof(struct koneplus_profile_buttons), | 532 | .size = sizeof(struct koneplus_profile_buttons), |
590 | .read = koneplus_sysfs_read_profilex_buttons, | 533 | .read = koneplus_sysfs_read_profilex_buttons, |
591 | .private = &profile_numbers[2] | 534 | .private = &profile_numbers[2] |
592 | }, | 535 | }, |
593 | { | 536 | { |
594 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | 537 | .attr = { .name = "profile4_buttons", .mode = 0440 }, |
595 | .size = sizeof(struct koneplus_profile_buttons), | 538 | .size = sizeof(struct koneplus_profile_buttons), |
596 | .read = koneplus_sysfs_read_profilex_buttons, | 539 | .read = koneplus_sysfs_read_profilex_buttons, |
597 | .private = &profile_numbers[3] | 540 | .private = &profile_numbers[3] |
598 | }, | 541 | }, |
599 | { | 542 | { |
600 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | 543 | .attr = { .name = "profile5_buttons", .mode = 0440 }, |
601 | .size = sizeof(struct koneplus_profile_buttons), | 544 | .size = sizeof(struct koneplus_profile_buttons), |
602 | .read = koneplus_sysfs_read_profilex_buttons, | 545 | .read = koneplus_sysfs_read_profilex_buttons, |
603 | .private = &profile_numbers[4] | 546 | .private = &profile_numbers[4] |
604 | }, | 547 | }, |
605 | { | 548 | { |
606 | .attr = { .name = "macro", .mode = 0220 }, | 549 | .attr = { .name = "macro", .mode = 0220 }, |
607 | .size = sizeof(struct koneplus_macro), | 550 | .size = sizeof(struct koneplus_macro), |
608 | .write = koneplus_sysfs_write_macro | 551 | .write = koneplus_sysfs_write_macro |
609 | }, | 552 | }, |
610 | __ATTR_NULL | 553 | __ATTR_NULL |
611 | }; | 554 | }; |
612 | 555 | ||
613 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, | 556 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, |
614 | struct koneplus_device *koneplus) | 557 | struct koneplus_device *koneplus) |
615 | { | 558 | { |
616 | int retval, i; | 559 | int retval, i; |
617 | static uint wait = 70; /* device will freeze with just 60 */ | 560 | static uint wait = 70; /* device will freeze with just 60 */ |
618 | 561 | ||
619 | mutex_init(&koneplus->koneplus_lock); | 562 | mutex_init(&koneplus->koneplus_lock); |
620 | 563 | ||
621 | koneplus->startup_profile = koneplus_get_startup_profile(usb_dev); | 564 | koneplus->startup_profile = koneplus_get_startup_profile(usb_dev); |
622 | if (koneplus->startup_profile < 0) | 565 | if (koneplus->startup_profile < 0) |
623 | return koneplus->startup_profile; | 566 | return koneplus->startup_profile; |
624 | 567 | ||
625 | msleep(wait); | 568 | msleep(wait); |
626 | retval = koneplus_get_info(usb_dev, &koneplus->info); | 569 | retval = koneplus_get_info(usb_dev, &koneplus->info); |
627 | if (retval) | 570 | if (retval) |
628 | return retval; | 571 | return retval; |
629 | 572 | ||
630 | for (i = 0; i < 5; ++i) { | 573 | for (i = 0; i < 5; ++i) { |
631 | msleep(wait); | 574 | msleep(wait); |
632 | retval = koneplus_get_profile_settings(usb_dev, | 575 | retval = koneplus_get_profile_settings(usb_dev, |
633 | &koneplus->profile_settings[i], i); | 576 | &koneplus->profile_settings[i], i); |
634 | if (retval) | 577 | if (retval) |
635 | return retval; | 578 | return retval; |
636 | 579 | ||
637 | msleep(wait); | 580 | msleep(wait); |
638 | retval = koneplus_get_profile_buttons(usb_dev, | 581 | retval = koneplus_get_profile_buttons(usb_dev, |
639 | &koneplus->profile_buttons[i], i); | 582 | &koneplus->profile_buttons[i], i); |
640 | if (retval) | 583 | if (retval) |
641 | return retval; | 584 | return retval; |
642 | } | 585 | } |
643 | 586 | ||
644 | koneplus_profile_activated(koneplus, koneplus->startup_profile); | 587 | koneplus_profile_activated(koneplus, koneplus->startup_profile); |
645 | 588 | ||
646 | return 0; | 589 | return 0; |
647 | } | 590 | } |
648 | 591 | ||
649 | static int koneplus_init_specials(struct hid_device *hdev) | 592 | static int koneplus_init_specials(struct hid_device *hdev) |
650 | { | 593 | { |
651 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 594 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
652 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 595 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
653 | struct koneplus_device *koneplus; | 596 | struct koneplus_device *koneplus; |
654 | int retval; | 597 | int retval; |
655 | 598 | ||
656 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 599 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
657 | == USB_INTERFACE_PROTOCOL_MOUSE) { | 600 | == USB_INTERFACE_PROTOCOL_MOUSE) { |
658 | 601 | ||
659 | koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL); | 602 | koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL); |
660 | if (!koneplus) { | 603 | if (!koneplus) { |
661 | hid_err(hdev, "can't alloc device descriptor\n"); | 604 | hid_err(hdev, "can't alloc device descriptor\n"); |
662 | return -ENOMEM; | 605 | return -ENOMEM; |
663 | } | 606 | } |
664 | hid_set_drvdata(hdev, koneplus); | 607 | hid_set_drvdata(hdev, koneplus); |
665 | 608 | ||
666 | retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus); | 609 | retval = koneplus_init_koneplus_device_struct(usb_dev, koneplus); |
667 | if (retval) { | 610 | if (retval) { |
668 | hid_err(hdev, "couldn't init struct koneplus_device\n"); | 611 | hid_err(hdev, "couldn't init struct koneplus_device\n"); |
669 | goto exit_free; | 612 | goto exit_free; |
670 | } | 613 | } |
671 | 614 | ||
672 | retval = roccat_connect(koneplus_class, hdev); | 615 | retval = roccat_connect(koneplus_class, hdev); |
673 | if (retval < 0) { | 616 | if (retval < 0) { |
674 | hid_err(hdev, "couldn't init char dev\n"); | 617 | hid_err(hdev, "couldn't init char dev\n"); |
675 | } else { | 618 | } else { |
676 | koneplus->chrdev_minor = retval; | 619 | koneplus->chrdev_minor = retval; |
677 | koneplus->roccat_claimed = 1; | 620 | koneplus->roccat_claimed = 1; |
678 | } | 621 | } |
679 | } else { | 622 | } else { |
680 | hid_set_drvdata(hdev, NULL); | 623 | hid_set_drvdata(hdev, NULL); |
681 | } | 624 | } |
682 | 625 | ||
683 | return 0; | 626 | return 0; |
684 | exit_free: | 627 | exit_free: |
685 | kfree(koneplus); | 628 | kfree(koneplus); |
686 | return retval; | 629 | return retval; |
687 | } | 630 | } |
688 | 631 | ||
689 | static void koneplus_remove_specials(struct hid_device *hdev) | 632 | static void koneplus_remove_specials(struct hid_device *hdev) |
690 | { | 633 | { |
691 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 634 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
692 | struct koneplus_device *koneplus; | 635 | struct koneplus_device *koneplus; |
693 | 636 | ||
694 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 637 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
695 | == USB_INTERFACE_PROTOCOL_MOUSE) { | 638 | == USB_INTERFACE_PROTOCOL_MOUSE) { |
696 | koneplus = hid_get_drvdata(hdev); | 639 | koneplus = hid_get_drvdata(hdev); |
697 | if (koneplus->roccat_claimed) | 640 | if (koneplus->roccat_claimed) |
698 | roccat_disconnect(koneplus->chrdev_minor); | 641 | roccat_disconnect(koneplus->chrdev_minor); |
699 | kfree(koneplus); | 642 | kfree(koneplus); |
700 | } | 643 | } |
701 | } | 644 | } |
702 | 645 | ||
703 | static int koneplus_probe(struct hid_device *hdev, | 646 | static int koneplus_probe(struct hid_device *hdev, |
704 | const struct hid_device_id *id) | 647 | const struct hid_device_id *id) |
705 | { | 648 | { |
706 | int retval; | 649 | int retval; |
707 | 650 | ||
708 | retval = hid_parse(hdev); | 651 | retval = hid_parse(hdev); |
709 | if (retval) { | 652 | if (retval) { |
710 | hid_err(hdev, "parse failed\n"); | 653 | hid_err(hdev, "parse failed\n"); |
711 | goto exit; | 654 | goto exit; |
712 | } | 655 | } |
713 | 656 | ||
714 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 657 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
715 | if (retval) { | 658 | if (retval) { |
716 | hid_err(hdev, "hw start failed\n"); | 659 | hid_err(hdev, "hw start failed\n"); |
717 | goto exit; | 660 | goto exit; |
718 | } | 661 | } |
719 | 662 | ||
720 | retval = koneplus_init_specials(hdev); | 663 | retval = koneplus_init_specials(hdev); |
721 | if (retval) { | 664 | if (retval) { |
722 | hid_err(hdev, "couldn't install mouse\n"); | 665 | hid_err(hdev, "couldn't install mouse\n"); |
723 | goto exit_stop; | 666 | goto exit_stop; |
724 | } | 667 | } |
725 | 668 | ||
726 | return 0; | 669 | return 0; |
727 | 670 | ||
728 | exit_stop: | 671 | exit_stop: |
729 | hid_hw_stop(hdev); | 672 | hid_hw_stop(hdev); |
730 | exit: | 673 | exit: |
731 | return retval; | 674 | return retval; |
732 | } | 675 | } |
733 | 676 | ||
734 | static void koneplus_remove(struct hid_device *hdev) | 677 | static void koneplus_remove(struct hid_device *hdev) |
735 | { | 678 | { |
736 | koneplus_remove_specials(hdev); | 679 | koneplus_remove_specials(hdev); |
737 | hid_hw_stop(hdev); | 680 | hid_hw_stop(hdev); |
738 | } | 681 | } |
739 | 682 | ||
740 | static void koneplus_keep_values_up_to_date(struct koneplus_device *koneplus, | 683 | static void koneplus_keep_values_up_to_date(struct koneplus_device *koneplus, |
741 | u8 const *data) | 684 | u8 const *data) |
742 | { | 685 | { |
743 | struct koneplus_mouse_report_button const *button_report; | 686 | struct koneplus_mouse_report_button const *button_report; |
744 | 687 | ||
745 | switch (data[0]) { | 688 | switch (data[0]) { |
746 | case KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON: | 689 | case KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON: |
747 | button_report = (struct koneplus_mouse_report_button const *)data; | 690 | button_report = (struct koneplus_mouse_report_button const *)data; |
748 | switch (button_report->type) { | 691 | switch (button_report->type) { |
749 | case KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE: | 692 | case KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE: |
750 | koneplus_profile_activated(koneplus, button_report->data1 - 1); | 693 | koneplus_profile_activated(koneplus, button_report->data1 - 1); |
751 | break; | 694 | break; |
752 | } | 695 | } |
753 | break; | 696 | break; |
754 | } | 697 | } |
755 | } | 698 | } |
756 | 699 | ||
757 | static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus, | 700 | static void koneplus_report_to_chrdev(struct koneplus_device const *koneplus, |
758 | u8 const *data) | 701 | u8 const *data) |
759 | { | 702 | { |
760 | struct koneplus_roccat_report roccat_report; | 703 | struct koneplus_roccat_report roccat_report; |
761 | struct koneplus_mouse_report_button const *button_report; | 704 | struct koneplus_mouse_report_button const *button_report; |
762 | 705 | ||
763 | if (data[0] != KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON) | 706 | if (data[0] != KONEPLUS_MOUSE_REPORT_NUMBER_BUTTON) |
764 | return; | 707 | return; |
765 | 708 | ||
766 | button_report = (struct koneplus_mouse_report_button const *)data; | 709 | button_report = (struct koneplus_mouse_report_button const *)data; |
767 | 710 | ||
768 | if ((button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH || | 711 | if ((button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH || |
769 | button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER) && | 712 | button_report->type == KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_TIMER) && |
770 | button_report->data2 != KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS) | 713 | button_report->data2 != KONEPLUS_MOUSE_REPORT_BUTTON_ACTION_PRESS) |
771 | return; | 714 | return; |
772 | 715 | ||
773 | roccat_report.type = button_report->type; | 716 | roccat_report.type = button_report->type; |
774 | roccat_report.data1 = button_report->data1; | 717 | roccat_report.data1 = button_report->data1; |
775 | roccat_report.data2 = button_report->data2; | 718 | roccat_report.data2 = button_report->data2; |
776 | roccat_report.profile = koneplus->actual_profile + 1; | 719 | roccat_report.profile = koneplus->actual_profile + 1; |
777 | roccat_report_event(koneplus->chrdev_minor, | 720 | roccat_report_event(koneplus->chrdev_minor, |
778 | (uint8_t const *)&roccat_report, | 721 | (uint8_t const *)&roccat_report, |
779 | sizeof(struct koneplus_roccat_report)); | 722 | sizeof(struct koneplus_roccat_report)); |
780 | } | 723 | } |
781 | 724 | ||
782 | static int koneplus_raw_event(struct hid_device *hdev, | 725 | static int koneplus_raw_event(struct hid_device *hdev, |
783 | struct hid_report *report, u8 *data, int size) | 726 | struct hid_report *report, u8 *data, int size) |
784 | { | 727 | { |
785 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 728 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
786 | struct koneplus_device *koneplus = hid_get_drvdata(hdev); | 729 | struct koneplus_device *koneplus = hid_get_drvdata(hdev); |
787 | 730 | ||
788 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 731 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
789 | != USB_INTERFACE_PROTOCOL_MOUSE) | 732 | != USB_INTERFACE_PROTOCOL_MOUSE) |
790 | return 0; | 733 | return 0; |
791 | 734 | ||
792 | koneplus_keep_values_up_to_date(koneplus, data); | 735 | koneplus_keep_values_up_to_date(koneplus, data); |
793 | 736 | ||
794 | if (koneplus->roccat_claimed) | 737 | if (koneplus->roccat_claimed) |
795 | koneplus_report_to_chrdev(koneplus, data); | 738 | koneplus_report_to_chrdev(koneplus, data); |
796 | 739 | ||
797 | return 0; | 740 | return 0; |
798 | } | 741 | } |
799 | 742 | ||
800 | static const struct hid_device_id koneplus_devices[] = { | 743 | static const struct hid_device_id koneplus_devices[] = { |
801 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, | 744 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, |
802 | { } | 745 | { } |
803 | }; | 746 | }; |
804 | 747 | ||
805 | MODULE_DEVICE_TABLE(hid, koneplus_devices); | 748 | MODULE_DEVICE_TABLE(hid, koneplus_devices); |
806 | 749 | ||
807 | static struct hid_driver koneplus_driver = { | 750 | static struct hid_driver koneplus_driver = { |
808 | .name = "koneplus", | 751 | .name = "koneplus", |
809 | .id_table = koneplus_devices, | 752 | .id_table = koneplus_devices, |
810 | .probe = koneplus_probe, | 753 | .probe = koneplus_probe, |
811 | .remove = koneplus_remove, | 754 | .remove = koneplus_remove, |
812 | .raw_event = koneplus_raw_event | 755 | .raw_event = koneplus_raw_event |
813 | }; | 756 | }; |
814 | 757 | ||
815 | static int __init koneplus_init(void) | 758 | static int __init koneplus_init(void) |
816 | { | 759 | { |
817 | int retval; | 760 | int retval; |
818 | 761 | ||
819 | /* class name has to be same as driver name */ | 762 | /* class name has to be same as driver name */ |
820 | koneplus_class = class_create(THIS_MODULE, "koneplus"); | 763 | koneplus_class = class_create(THIS_MODULE, "koneplus"); |
821 | if (IS_ERR(koneplus_class)) | 764 | if (IS_ERR(koneplus_class)) |
822 | return PTR_ERR(koneplus_class); | 765 | return PTR_ERR(koneplus_class); |
823 | koneplus_class->dev_attrs = koneplus_attributes; | 766 | koneplus_class->dev_attrs = koneplus_attributes; |
824 | koneplus_class->dev_bin_attrs = koneplus_bin_attributes; | 767 | koneplus_class->dev_bin_attrs = koneplus_bin_attributes; |
825 | 768 | ||
826 | retval = hid_register_driver(&koneplus_driver); | 769 | retval = hid_register_driver(&koneplus_driver); |
827 | if (retval) | 770 | if (retval) |
828 | class_destroy(koneplus_class); | 771 | class_destroy(koneplus_class); |
829 | return retval; | 772 | return retval; |
830 | } | 773 | } |
831 | 774 | ||
832 | static void __exit koneplus_exit(void) | 775 | static void __exit koneplus_exit(void) |
833 | { | 776 | { |
834 | class_destroy(koneplus_class); | 777 | class_destroy(koneplus_class); |
835 | hid_unregister_driver(&koneplus_driver); | 778 | hid_unregister_driver(&koneplus_driver); |
836 | } | 779 | } |
837 | 780 | ||
838 | module_init(koneplus_init); | 781 | module_init(koneplus_init); |
839 | module_exit(koneplus_exit); | 782 | module_exit(koneplus_exit); |
840 | 783 | ||
841 | MODULE_AUTHOR("Stefan Achatz"); | 784 | MODULE_AUTHOR("Stefan Achatz"); |
842 | MODULE_DESCRIPTION("USB Roccat Kone[+] driver"); | 785 | MODULE_DESCRIPTION("USB Roccat Kone[+] driver"); |
drivers/hid/hid-roccat-pyra.c
1 | /* | 1 | /* |
2 | * Roccat Pyra driver for Linux | 2 | * Roccat Pyra driver for Linux |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> | 4 | * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
8 | * This program is free software; you can redistribute it and/or modify it | 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 | 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) | 10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * any later version. | 11 | * any later version. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless | 15 | * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless |
16 | * variant. Wireless variant is not tested. | 16 | * variant. Wireless variant is not tested. |
17 | * Userland tools can be found at http://sourceforge.net/projects/roccat | 17 | * Userland tools can be found at http://sourceforge.net/projects/roccat |
18 | */ | 18 | */ |
19 | 19 | ||
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> |
26 | #include "hid-ids.h" | 25 | #include "hid-ids.h" |
27 | #include "hid-roccat.h" | 26 | #include "hid-roccat.h" |
27 | #include "hid-roccat-common.h" | ||
28 | #include "hid-roccat-pyra.h" | 28 | #include "hid-roccat-pyra.h" |
29 | 29 | ||
30 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; | 30 | static uint profile_numbers[5] = {0, 1, 2, 3, 4}; |
31 | 31 | ||
32 | /* pyra_class is used for creating sysfs attributes via roccat char device */ | 32 | /* pyra_class is used for creating sysfs attributes via roccat char device */ |
33 | static struct class *pyra_class; | 33 | static struct class *pyra_class; |
34 | 34 | ||
35 | static void profile_activated(struct pyra_device *pyra, | 35 | static void profile_activated(struct pyra_device *pyra, |
36 | unsigned int new_profile) | 36 | unsigned int new_profile) |
37 | { | 37 | { |
38 | pyra->actual_profile = new_profile; | 38 | pyra->actual_profile = new_profile; |
39 | pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; | 39 | pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi; |
40 | } | 40 | } |
41 | 41 | ||
42 | static int pyra_send_control(struct usb_device *usb_dev, int value, | 42 | static 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 || |
49 | request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && | 48 | request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && |
50 | (value < 0 || value > 4)) | 49 | (value < 0 || value > 4)) |
51 | return -EINVAL; | 50 | return -EINVAL; |
52 | 51 | ||
53 | control.command = PYRA_COMMAND_CONTROL; | 52 | control.command = PYRA_COMMAND_CONTROL; |
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 | ||
70 | static int pyra_receive_control_status(struct usb_device *usb_dev) | 60 | static 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); |
67 | retval = roccat_common_receive(usb_dev, PYRA_USB_COMMAND_CONTROL, | ||
68 | &control, sizeof(struct pyra_control)); | ||
77 | 69 | ||
78 | len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
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 | |||
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 | ||
101 | static int pyra_get_profile_settings(struct usb_device *usb_dev, | 84 | 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 | ||
125 | static int pyra_get_profile_buttons(struct usb_device *usb_dev, | 96 | static 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 | ||
149 | static int pyra_get_settings(struct usb_device *usb_dev, | 108 | static 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 | ||
163 | static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) | 115 | static 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, | ||
168 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
169 | PYRA_USB_COMMAND_INFO, 0, buf, | ||
170 | sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT); | ||
171 | if (len != sizeof(struct pyra_info)) | ||
172 | return -EIO; | ||
173 | return 0; | ||
174 | } | 119 | } |
175 | 120 | ||
121 | static int pyra_send(struct usb_device *usb_dev, uint command, | ||
122 | void const *buf, uint size) | ||
123 | { | ||
124 | int retval; | ||
125 | retval = roccat_common_send(usb_dev, command, buf, size); | ||
126 | if (retval) | ||
127 | return retval; | ||
128 | return pyra_receive_control_status(usb_dev); | ||
129 | } | ||
130 | |||
176 | static int pyra_set_profile_settings(struct usb_device *usb_dev, | 131 | static 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 | ||
193 | static int pyra_set_profile_buttons(struct usb_device *usb_dev, | 138 | static 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 | ||
210 | static int pyra_set_settings(struct usb_device *usb_dev, | 145 | static 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 | ||
226 | static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, | 156 | static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, |
227 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 157 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
228 | loff_t off, size_t count) | 158 | loff_t off, size_t count) |
229 | { | 159 | { |
230 | struct device *dev = | 160 | struct device *dev = |
231 | container_of(kobj, struct device, kobj)->parent->parent; | 161 | container_of(kobj, struct device, kobj)->parent->parent; |
232 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 162 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
233 | 163 | ||
234 | if (off >= sizeof(struct pyra_profile_settings)) | 164 | if (off >= sizeof(struct pyra_profile_settings)) |
235 | return 0; | 165 | return 0; |
236 | 166 | ||
237 | if (off + count > sizeof(struct pyra_profile_settings)) | 167 | if (off + count > sizeof(struct pyra_profile_settings)) |
238 | count = sizeof(struct pyra_profile_settings) - off; | 168 | count = sizeof(struct pyra_profile_settings) - off; |
239 | 169 | ||
240 | mutex_lock(&pyra->pyra_lock); | 170 | mutex_lock(&pyra->pyra_lock); |
241 | memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off, | 171 | memcpy(buf, ((char const *)&pyra->profile_settings[*(uint *)(attr->private)]) + off, |
242 | count); | 172 | count); |
243 | mutex_unlock(&pyra->pyra_lock); | 173 | mutex_unlock(&pyra->pyra_lock); |
244 | 174 | ||
245 | return count; | 175 | return count; |
246 | } | 176 | } |
247 | 177 | ||
248 | static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, | 178 | static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, |
249 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 179 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
250 | loff_t off, size_t count) | 180 | loff_t off, size_t count) |
251 | { | 181 | { |
252 | struct device *dev = | 182 | struct device *dev = |
253 | container_of(kobj, struct device, kobj)->parent->parent; | 183 | container_of(kobj, struct device, kobj)->parent->parent; |
254 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 184 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
255 | 185 | ||
256 | if (off >= sizeof(struct pyra_profile_buttons)) | 186 | if (off >= sizeof(struct pyra_profile_buttons)) |
257 | return 0; | 187 | return 0; |
258 | 188 | ||
259 | if (off + count > sizeof(struct pyra_profile_buttons)) | 189 | if (off + count > sizeof(struct pyra_profile_buttons)) |
260 | count = sizeof(struct pyra_profile_buttons) - off; | 190 | count = sizeof(struct pyra_profile_buttons) - off; |
261 | 191 | ||
262 | mutex_lock(&pyra->pyra_lock); | 192 | mutex_lock(&pyra->pyra_lock); |
263 | memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off, | 193 | memcpy(buf, ((char const *)&pyra->profile_buttons[*(uint *)(attr->private)]) + off, |
264 | count); | 194 | count); |
265 | mutex_unlock(&pyra->pyra_lock); | 195 | mutex_unlock(&pyra->pyra_lock); |
266 | 196 | ||
267 | return count; | 197 | return count; |
268 | } | 198 | } |
269 | 199 | ||
270 | static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, | 200 | static ssize_t pyra_sysfs_write_profile_settings(struct file *fp, |
271 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 201 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
272 | loff_t off, size_t count) | 202 | loff_t off, size_t count) |
273 | { | 203 | { |
274 | struct device *dev = | 204 | struct device *dev = |
275 | container_of(kobj, struct device, kobj)->parent->parent; | 205 | container_of(kobj, struct device, kobj)->parent->parent; |
276 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 206 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
277 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 207 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
278 | int retval = 0; | 208 | int retval = 0; |
279 | int difference; | 209 | int difference; |
280 | int profile_number; | 210 | int profile_number; |
281 | struct pyra_profile_settings *profile_settings; | 211 | struct pyra_profile_settings *profile_settings; |
282 | 212 | ||
283 | if (off != 0 || count != sizeof(struct pyra_profile_settings)) | 213 | if (off != 0 || count != sizeof(struct pyra_profile_settings)) |
284 | return -EINVAL; | 214 | return -EINVAL; |
285 | 215 | ||
286 | profile_number = ((struct pyra_profile_settings const *)buf)->number; | 216 | profile_number = ((struct pyra_profile_settings const *)buf)->number; |
287 | profile_settings = &pyra->profile_settings[profile_number]; | 217 | profile_settings = &pyra->profile_settings[profile_number]; |
288 | 218 | ||
289 | mutex_lock(&pyra->pyra_lock); | 219 | mutex_lock(&pyra->pyra_lock); |
290 | difference = memcmp(buf, profile_settings, | 220 | difference = memcmp(buf, profile_settings, |
291 | sizeof(struct pyra_profile_settings)); | 221 | sizeof(struct pyra_profile_settings)); |
292 | if (difference) { | 222 | if (difference) { |
293 | retval = pyra_set_profile_settings(usb_dev, | 223 | retval = pyra_set_profile_settings(usb_dev, |
294 | (struct pyra_profile_settings const *)buf); | 224 | (struct pyra_profile_settings const *)buf); |
295 | if (!retval) | 225 | if (!retval) |
296 | memcpy(profile_settings, buf, | 226 | memcpy(profile_settings, buf, |
297 | sizeof(struct pyra_profile_settings)); | 227 | sizeof(struct pyra_profile_settings)); |
298 | } | 228 | } |
299 | mutex_unlock(&pyra->pyra_lock); | 229 | mutex_unlock(&pyra->pyra_lock); |
300 | 230 | ||
301 | if (retval) | 231 | if (retval) |
302 | return retval; | 232 | return retval; |
303 | 233 | ||
304 | return sizeof(struct pyra_profile_settings); | 234 | return sizeof(struct pyra_profile_settings); |
305 | } | 235 | } |
306 | 236 | ||
307 | static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, | 237 | static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp, |
308 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 238 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
309 | loff_t off, size_t count) | 239 | loff_t off, size_t count) |
310 | { | 240 | { |
311 | struct device *dev = | 241 | struct device *dev = |
312 | container_of(kobj, struct device, kobj)->parent->parent; | 242 | container_of(kobj, struct device, kobj)->parent->parent; |
313 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 243 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
314 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 244 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
315 | int retval = 0; | 245 | int retval = 0; |
316 | int difference; | 246 | int difference; |
317 | int profile_number; | 247 | int profile_number; |
318 | struct pyra_profile_buttons *profile_buttons; | 248 | struct pyra_profile_buttons *profile_buttons; |
319 | 249 | ||
320 | if (off != 0 || count != sizeof(struct pyra_profile_buttons)) | 250 | if (off != 0 || count != sizeof(struct pyra_profile_buttons)) |
321 | return -EINVAL; | 251 | return -EINVAL; |
322 | 252 | ||
323 | profile_number = ((struct pyra_profile_buttons const *)buf)->number; | 253 | profile_number = ((struct pyra_profile_buttons const *)buf)->number; |
324 | profile_buttons = &pyra->profile_buttons[profile_number]; | 254 | profile_buttons = &pyra->profile_buttons[profile_number]; |
325 | 255 | ||
326 | mutex_lock(&pyra->pyra_lock); | 256 | mutex_lock(&pyra->pyra_lock); |
327 | difference = memcmp(buf, profile_buttons, | 257 | difference = memcmp(buf, profile_buttons, |
328 | sizeof(struct pyra_profile_buttons)); | 258 | sizeof(struct pyra_profile_buttons)); |
329 | if (difference) { | 259 | if (difference) { |
330 | retval = pyra_set_profile_buttons(usb_dev, | 260 | retval = pyra_set_profile_buttons(usb_dev, |
331 | (struct pyra_profile_buttons const *)buf); | 261 | (struct pyra_profile_buttons const *)buf); |
332 | if (!retval) | 262 | if (!retval) |
333 | memcpy(profile_buttons, buf, | 263 | memcpy(profile_buttons, buf, |
334 | sizeof(struct pyra_profile_buttons)); | 264 | sizeof(struct pyra_profile_buttons)); |
335 | } | 265 | } |
336 | mutex_unlock(&pyra->pyra_lock); | 266 | mutex_unlock(&pyra->pyra_lock); |
337 | 267 | ||
338 | if (retval) | 268 | if (retval) |
339 | return retval; | 269 | return retval; |
340 | 270 | ||
341 | return sizeof(struct pyra_profile_buttons); | 271 | return sizeof(struct pyra_profile_buttons); |
342 | } | 272 | } |
343 | 273 | ||
344 | static ssize_t pyra_sysfs_read_settings(struct file *fp, | 274 | static ssize_t pyra_sysfs_read_settings(struct file *fp, |
345 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 275 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
346 | loff_t off, size_t count) | 276 | loff_t off, size_t count) |
347 | { | 277 | { |
348 | struct device *dev = | 278 | struct device *dev = |
349 | container_of(kobj, struct device, kobj)->parent->parent; | 279 | container_of(kobj, struct device, kobj)->parent->parent; |
350 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 280 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
351 | 281 | ||
352 | if (off >= sizeof(struct pyra_settings)) | 282 | if (off >= sizeof(struct pyra_settings)) |
353 | return 0; | 283 | return 0; |
354 | 284 | ||
355 | if (off + count > sizeof(struct pyra_settings)) | 285 | if (off + count > sizeof(struct pyra_settings)) |
356 | count = sizeof(struct pyra_settings) - off; | 286 | count = sizeof(struct pyra_settings) - off; |
357 | 287 | ||
358 | mutex_lock(&pyra->pyra_lock); | 288 | mutex_lock(&pyra->pyra_lock); |
359 | memcpy(buf, ((char const *)&pyra->settings) + off, count); | 289 | memcpy(buf, ((char const *)&pyra->settings) + off, count); |
360 | mutex_unlock(&pyra->pyra_lock); | 290 | mutex_unlock(&pyra->pyra_lock); |
361 | 291 | ||
362 | return count; | 292 | return count; |
363 | } | 293 | } |
364 | 294 | ||
365 | static ssize_t pyra_sysfs_write_settings(struct file *fp, | 295 | static ssize_t pyra_sysfs_write_settings(struct file *fp, |
366 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 296 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
367 | loff_t off, size_t count) | 297 | loff_t off, size_t count) |
368 | { | 298 | { |
369 | struct device *dev = | 299 | struct device *dev = |
370 | container_of(kobj, struct device, kobj)->parent->parent; | 300 | container_of(kobj, struct device, kobj)->parent->parent; |
371 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); | 301 | struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev)); |
372 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 302 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
373 | int retval = 0; | 303 | int retval = 0; |
374 | int difference; | 304 | int difference; |
375 | 305 | ||
376 | if (off != 0 || count != sizeof(struct pyra_settings)) | 306 | if (off != 0 || count != sizeof(struct pyra_settings)) |
377 | return -EINVAL; | 307 | return -EINVAL; |
378 | 308 | ||
379 | mutex_lock(&pyra->pyra_lock); | 309 | mutex_lock(&pyra->pyra_lock); |
380 | difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings)); | 310 | difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings)); |
381 | if (difference) { | 311 | if (difference) { |
382 | retval = pyra_set_settings(usb_dev, | 312 | retval = pyra_set_settings(usb_dev, |
383 | (struct pyra_settings const *)buf); | 313 | (struct pyra_settings const *)buf); |
384 | if (!retval) | 314 | if (!retval) |
385 | memcpy(&pyra->settings, buf, | 315 | memcpy(&pyra->settings, buf, |
386 | sizeof(struct pyra_settings)); | 316 | sizeof(struct pyra_settings)); |
387 | } | 317 | } |
388 | mutex_unlock(&pyra->pyra_lock); | 318 | mutex_unlock(&pyra->pyra_lock); |
389 | 319 | ||
390 | if (retval) | 320 | if (retval) |
391 | return retval; | 321 | return retval; |
392 | 322 | ||
393 | profile_activated(pyra, pyra->settings.startup_profile); | 323 | profile_activated(pyra, pyra->settings.startup_profile); |
394 | 324 | ||
395 | return sizeof(struct pyra_settings); | 325 | return sizeof(struct pyra_settings); |
396 | } | 326 | } |
397 | 327 | ||
398 | 328 | ||
399 | static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, | 329 | static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, |
400 | struct device_attribute *attr, char *buf) | 330 | struct device_attribute *attr, char *buf) |
401 | { | 331 | { |
402 | struct pyra_device *pyra = | 332 | struct pyra_device *pyra = |
403 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 333 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
404 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); | 334 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); |
405 | } | 335 | } |
406 | 336 | ||
407 | static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, | 337 | static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, |
408 | struct device_attribute *attr, char *buf) | 338 | struct device_attribute *attr, char *buf) |
409 | { | 339 | { |
410 | struct pyra_device *pyra = | 340 | struct pyra_device *pyra = |
411 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 341 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
412 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile); | 342 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile); |
413 | } | 343 | } |
414 | 344 | ||
415 | static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, | 345 | static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, |
416 | struct device_attribute *attr, char *buf) | 346 | struct device_attribute *attr, char *buf) |
417 | { | 347 | { |
418 | struct pyra_device *pyra = | 348 | struct pyra_device *pyra = |
419 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 349 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
420 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version); | 350 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version); |
421 | } | 351 | } |
422 | 352 | ||
423 | static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, | 353 | static ssize_t pyra_sysfs_show_startup_profile(struct device *dev, |
424 | struct device_attribute *attr, char *buf) | 354 | struct device_attribute *attr, char *buf) |
425 | { | 355 | { |
426 | struct pyra_device *pyra = | 356 | struct pyra_device *pyra = |
427 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 357 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
428 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile); | 358 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile); |
429 | } | 359 | } |
430 | 360 | ||
431 | static struct device_attribute pyra_attributes[] = { | 361 | static struct device_attribute pyra_attributes[] = { |
432 | __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL), | 362 | __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL), |
433 | __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL), | 363 | __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL), |
434 | __ATTR(firmware_version, 0440, | 364 | __ATTR(firmware_version, 0440, |
435 | pyra_sysfs_show_firmware_version, NULL), | 365 | pyra_sysfs_show_firmware_version, NULL), |
436 | __ATTR(startup_profile, 0440, | 366 | __ATTR(startup_profile, 0440, |
437 | pyra_sysfs_show_startup_profile, NULL), | 367 | pyra_sysfs_show_startup_profile, NULL), |
438 | __ATTR_NULL | 368 | __ATTR_NULL |
439 | }; | 369 | }; |
440 | 370 | ||
441 | static struct bin_attribute pyra_bin_attributes[] = { | 371 | static struct bin_attribute pyra_bin_attributes[] = { |
442 | { | 372 | { |
443 | .attr = { .name = "profile_settings", .mode = 0220 }, | 373 | .attr = { .name = "profile_settings", .mode = 0220 }, |
444 | .size = sizeof(struct pyra_profile_settings), | 374 | .size = sizeof(struct pyra_profile_settings), |
445 | .write = pyra_sysfs_write_profile_settings | 375 | .write = pyra_sysfs_write_profile_settings |
446 | }, | 376 | }, |
447 | { | 377 | { |
448 | .attr = { .name = "profile1_settings", .mode = 0440 }, | 378 | .attr = { .name = "profile1_settings", .mode = 0440 }, |
449 | .size = sizeof(struct pyra_profile_settings), | 379 | .size = sizeof(struct pyra_profile_settings), |
450 | .read = pyra_sysfs_read_profilex_settings, | 380 | .read = pyra_sysfs_read_profilex_settings, |
451 | .private = &profile_numbers[0] | 381 | .private = &profile_numbers[0] |
452 | }, | 382 | }, |
453 | { | 383 | { |
454 | .attr = { .name = "profile2_settings", .mode = 0440 }, | 384 | .attr = { .name = "profile2_settings", .mode = 0440 }, |
455 | .size = sizeof(struct pyra_profile_settings), | 385 | .size = sizeof(struct pyra_profile_settings), |
456 | .read = pyra_sysfs_read_profilex_settings, | 386 | .read = pyra_sysfs_read_profilex_settings, |
457 | .private = &profile_numbers[1] | 387 | .private = &profile_numbers[1] |
458 | }, | 388 | }, |
459 | { | 389 | { |
460 | .attr = { .name = "profile3_settings", .mode = 0440 }, | 390 | .attr = { .name = "profile3_settings", .mode = 0440 }, |
461 | .size = sizeof(struct pyra_profile_settings), | 391 | .size = sizeof(struct pyra_profile_settings), |
462 | .read = pyra_sysfs_read_profilex_settings, | 392 | .read = pyra_sysfs_read_profilex_settings, |
463 | .private = &profile_numbers[2] | 393 | .private = &profile_numbers[2] |
464 | }, | 394 | }, |
465 | { | 395 | { |
466 | .attr = { .name = "profile4_settings", .mode = 0440 }, | 396 | .attr = { .name = "profile4_settings", .mode = 0440 }, |
467 | .size = sizeof(struct pyra_profile_settings), | 397 | .size = sizeof(struct pyra_profile_settings), |
468 | .read = pyra_sysfs_read_profilex_settings, | 398 | .read = pyra_sysfs_read_profilex_settings, |
469 | .private = &profile_numbers[3] | 399 | .private = &profile_numbers[3] |
470 | }, | 400 | }, |
471 | { | 401 | { |
472 | .attr = { .name = "profile5_settings", .mode = 0440 }, | 402 | .attr = { .name = "profile5_settings", .mode = 0440 }, |
473 | .size = sizeof(struct pyra_profile_settings), | 403 | .size = sizeof(struct pyra_profile_settings), |
474 | .read = pyra_sysfs_read_profilex_settings, | 404 | .read = pyra_sysfs_read_profilex_settings, |
475 | .private = &profile_numbers[4] | 405 | .private = &profile_numbers[4] |
476 | }, | 406 | }, |
477 | { | 407 | { |
478 | .attr = { .name = "profile_buttons", .mode = 0220 }, | 408 | .attr = { .name = "profile_buttons", .mode = 0220 }, |
479 | .size = sizeof(struct pyra_profile_buttons), | 409 | .size = sizeof(struct pyra_profile_buttons), |
480 | .write = pyra_sysfs_write_profile_buttons | 410 | .write = pyra_sysfs_write_profile_buttons |
481 | }, | 411 | }, |
482 | { | 412 | { |
483 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | 413 | .attr = { .name = "profile1_buttons", .mode = 0440 }, |
484 | .size = sizeof(struct pyra_profile_buttons), | 414 | .size = sizeof(struct pyra_profile_buttons), |
485 | .read = pyra_sysfs_read_profilex_buttons, | 415 | .read = pyra_sysfs_read_profilex_buttons, |
486 | .private = &profile_numbers[0] | 416 | .private = &profile_numbers[0] |
487 | }, | 417 | }, |
488 | { | 418 | { |
489 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | 419 | .attr = { .name = "profile2_buttons", .mode = 0440 }, |
490 | .size = sizeof(struct pyra_profile_buttons), | 420 | .size = sizeof(struct pyra_profile_buttons), |
491 | .read = pyra_sysfs_read_profilex_buttons, | 421 | .read = pyra_sysfs_read_profilex_buttons, |
492 | .private = &profile_numbers[1] | 422 | .private = &profile_numbers[1] |
493 | }, | 423 | }, |
494 | { | 424 | { |
495 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | 425 | .attr = { .name = "profile3_buttons", .mode = 0440 }, |
496 | .size = sizeof(struct pyra_profile_buttons), | 426 | .size = sizeof(struct pyra_profile_buttons), |
497 | .read = pyra_sysfs_read_profilex_buttons, | 427 | .read = pyra_sysfs_read_profilex_buttons, |
498 | .private = &profile_numbers[2] | 428 | .private = &profile_numbers[2] |
499 | }, | 429 | }, |
500 | { | 430 | { |
501 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | 431 | .attr = { .name = "profile4_buttons", .mode = 0440 }, |
502 | .size = sizeof(struct pyra_profile_buttons), | 432 | .size = sizeof(struct pyra_profile_buttons), |
503 | .read = pyra_sysfs_read_profilex_buttons, | 433 | .read = pyra_sysfs_read_profilex_buttons, |
504 | .private = &profile_numbers[3] | 434 | .private = &profile_numbers[3] |
505 | }, | 435 | }, |
506 | { | 436 | { |
507 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | 437 | .attr = { .name = "profile5_buttons", .mode = 0440 }, |
508 | .size = sizeof(struct pyra_profile_buttons), | 438 | .size = sizeof(struct pyra_profile_buttons), |
509 | .read = pyra_sysfs_read_profilex_buttons, | 439 | .read = pyra_sysfs_read_profilex_buttons, |
510 | .private = &profile_numbers[4] | 440 | .private = &profile_numbers[4] |
511 | }, | 441 | }, |
512 | { | 442 | { |
513 | .attr = { .name = "settings", .mode = 0660 }, | 443 | .attr = { .name = "settings", .mode = 0660 }, |
514 | .size = sizeof(struct pyra_settings), | 444 | .size = sizeof(struct pyra_settings), |
515 | .read = pyra_sysfs_read_settings, | 445 | .read = pyra_sysfs_read_settings, |
516 | .write = pyra_sysfs_write_settings | 446 | .write = pyra_sysfs_write_settings |
517 | }, | 447 | }, |
518 | __ATTR_NULL | 448 | __ATTR_NULL |
519 | }; | 449 | }; |
520 | 450 | ||
521 | static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, | 451 | static 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) |
542 | return retval; | 467 | return retval; |
543 | 468 | ||
544 | for (i = 0; i < 5; ++i) { | 469 | for (i = 0; i < 5; ++i) { |
545 | retval = pyra_get_profile_settings(usb_dev, | 470 | retval = pyra_get_profile_settings(usb_dev, |
546 | &pyra->profile_settings[i], i); | 471 | &pyra->profile_settings[i], i); |
547 | if (retval) | 472 | if (retval) |
548 | return retval; | 473 | return retval; |
549 | 474 | ||
550 | retval = pyra_get_profile_buttons(usb_dev, | 475 | retval = pyra_get_profile_buttons(usb_dev, |
551 | &pyra->profile_buttons[i], i); | 476 | &pyra->profile_buttons[i], i); |
552 | if (retval) | 477 | if (retval) |
553 | return retval; | 478 | return retval; |
554 | } | 479 | } |
555 | 480 | ||
556 | profile_activated(pyra, pyra->settings.startup_profile); | 481 | profile_activated(pyra, pyra->settings.startup_profile); |
557 | 482 | ||
558 | return 0; | 483 | return 0; |
559 | } | 484 | } |
560 | 485 | ||
561 | static int pyra_init_specials(struct hid_device *hdev) | 486 | static int pyra_init_specials(struct hid_device *hdev) |
562 | { | 487 | { |
563 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 488 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
564 | struct usb_device *usb_dev = interface_to_usbdev(intf); | 489 | struct usb_device *usb_dev = interface_to_usbdev(intf); |
565 | struct pyra_device *pyra; | 490 | struct pyra_device *pyra; |
566 | int retval; | 491 | int retval; |
567 | 492 | ||
568 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 493 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
569 | == USB_INTERFACE_PROTOCOL_MOUSE) { | 494 | == USB_INTERFACE_PROTOCOL_MOUSE) { |
570 | 495 | ||
571 | pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); | 496 | pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); |
572 | if (!pyra) { | 497 | if (!pyra) { |
573 | hid_err(hdev, "can't alloc device descriptor\n"); | 498 | hid_err(hdev, "can't alloc device descriptor\n"); |
574 | return -ENOMEM; | 499 | return -ENOMEM; |
575 | } | 500 | } |
576 | hid_set_drvdata(hdev, pyra); | 501 | hid_set_drvdata(hdev, pyra); |
577 | 502 | ||
578 | retval = pyra_init_pyra_device_struct(usb_dev, pyra); | 503 | retval = pyra_init_pyra_device_struct(usb_dev, pyra); |
579 | if (retval) { | 504 | if (retval) { |
580 | hid_err(hdev, "couldn't init struct pyra_device\n"); | 505 | hid_err(hdev, "couldn't init struct pyra_device\n"); |
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); |
585 | if (retval < 0) { | 510 | if (retval < 0) { |
586 | hid_err(hdev, "couldn't init char dev\n"); | 511 | hid_err(hdev, "couldn't init char dev\n"); |
587 | } else { | 512 | } else { |
588 | pyra->chrdev_minor = retval; | 513 | pyra->chrdev_minor = retval; |
589 | pyra->roccat_claimed = 1; | 514 | pyra->roccat_claimed = 1; |
590 | } | 515 | } |
591 | } else { | 516 | } else { |
592 | hid_set_drvdata(hdev, NULL); | 517 | hid_set_drvdata(hdev, NULL); |
593 | } | 518 | } |
594 | 519 | ||
595 | return 0; | 520 | return 0; |
596 | exit_free: | 521 | exit_free: |
597 | kfree(pyra); | 522 | kfree(pyra); |
598 | return retval; | 523 | return retval; |
599 | } | 524 | } |
600 | 525 | ||
601 | static void pyra_remove_specials(struct hid_device *hdev) | 526 | static void pyra_remove_specials(struct hid_device *hdev) |
602 | { | 527 | { |
603 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 528 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
604 | struct pyra_device *pyra; | 529 | struct pyra_device *pyra; |
605 | 530 | ||
606 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 531 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
607 | == USB_INTERFACE_PROTOCOL_MOUSE) { | 532 | == USB_INTERFACE_PROTOCOL_MOUSE) { |
608 | pyra = hid_get_drvdata(hdev); | 533 | pyra = hid_get_drvdata(hdev); |
609 | if (pyra->roccat_claimed) | 534 | if (pyra->roccat_claimed) |
610 | roccat_disconnect(pyra->chrdev_minor); | 535 | roccat_disconnect(pyra->chrdev_minor); |
611 | kfree(hid_get_drvdata(hdev)); | 536 | kfree(hid_get_drvdata(hdev)); |
612 | } | 537 | } |
613 | } | 538 | } |
614 | 539 | ||
615 | static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) | 540 | static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) |
616 | { | 541 | { |
617 | int retval; | 542 | int retval; |
618 | 543 | ||
619 | retval = hid_parse(hdev); | 544 | retval = hid_parse(hdev); |
620 | if (retval) { | 545 | if (retval) { |
621 | hid_err(hdev, "parse failed\n"); | 546 | hid_err(hdev, "parse failed\n"); |
622 | goto exit; | 547 | goto exit; |
623 | } | 548 | } |
624 | 549 | ||
625 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 550 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
626 | if (retval) { | 551 | if (retval) { |
627 | hid_err(hdev, "hw start failed\n"); | 552 | hid_err(hdev, "hw start failed\n"); |
628 | goto exit; | 553 | goto exit; |
629 | } | 554 | } |
630 | 555 | ||
631 | retval = pyra_init_specials(hdev); | 556 | retval = pyra_init_specials(hdev); |
632 | if (retval) { | 557 | if (retval) { |
633 | hid_err(hdev, "couldn't install mouse\n"); | 558 | hid_err(hdev, "couldn't install mouse\n"); |
634 | goto exit_stop; | 559 | goto exit_stop; |
635 | } | 560 | } |
636 | return 0; | 561 | return 0; |
637 | 562 | ||
638 | exit_stop: | 563 | exit_stop: |
639 | hid_hw_stop(hdev); | 564 | hid_hw_stop(hdev); |
640 | exit: | 565 | exit: |
641 | return retval; | 566 | return retval; |
642 | } | 567 | } |
643 | 568 | ||
644 | static void pyra_remove(struct hid_device *hdev) | 569 | static void pyra_remove(struct hid_device *hdev) |
645 | { | 570 | { |
646 | pyra_remove_specials(hdev); | 571 | pyra_remove_specials(hdev); |
647 | hid_hw_stop(hdev); | 572 | hid_hw_stop(hdev); |
648 | } | 573 | } |
649 | 574 | ||
650 | static void pyra_keep_values_up_to_date(struct pyra_device *pyra, | 575 | static void pyra_keep_values_up_to_date(struct pyra_device *pyra, |
651 | u8 const *data) | 576 | u8 const *data) |
652 | { | 577 | { |
653 | struct pyra_mouse_event_button const *button_event; | 578 | struct pyra_mouse_event_button const *button_event; |
654 | 579 | ||
655 | switch (data[0]) { | 580 | switch (data[0]) { |
656 | case PYRA_MOUSE_REPORT_NUMBER_BUTTON: | 581 | case PYRA_MOUSE_REPORT_NUMBER_BUTTON: |
657 | button_event = (struct pyra_mouse_event_button const *)data; | 582 | button_event = (struct pyra_mouse_event_button const *)data; |
658 | switch (button_event->type) { | 583 | switch (button_event->type) { |
659 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: | 584 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: |
660 | profile_activated(pyra, button_event->data1 - 1); | 585 | profile_activated(pyra, button_event->data1 - 1); |
661 | break; | 586 | break; |
662 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: | 587 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: |
663 | pyra->actual_cpi = button_event->data1; | 588 | pyra->actual_cpi = button_event->data1; |
664 | break; | 589 | break; |
665 | } | 590 | } |
666 | break; | 591 | break; |
667 | } | 592 | } |
668 | } | 593 | } |
669 | 594 | ||
670 | static void pyra_report_to_chrdev(struct pyra_device const *pyra, | 595 | static void pyra_report_to_chrdev(struct pyra_device const *pyra, |
671 | u8 const *data) | 596 | u8 const *data) |
672 | { | 597 | { |
673 | struct pyra_roccat_report roccat_report; | 598 | struct pyra_roccat_report roccat_report; |
674 | struct pyra_mouse_event_button const *button_event; | 599 | struct pyra_mouse_event_button const *button_event; |
675 | 600 | ||
676 | if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON) | 601 | if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON) |
677 | return; | 602 | return; |
678 | 603 | ||
679 | button_event = (struct pyra_mouse_event_button const *)data; | 604 | button_event = (struct pyra_mouse_event_button const *)data; |
680 | 605 | ||
681 | switch (button_event->type) { | 606 | switch (button_event->type) { |
682 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: | 607 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2: |
683 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: | 608 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI: |
684 | roccat_report.type = button_event->type; | 609 | roccat_report.type = button_event->type; |
685 | roccat_report.value = button_event->data1; | 610 | roccat_report.value = button_event->data1; |
686 | roccat_report.key = 0; | 611 | roccat_report.key = 0; |
687 | roccat_report_event(pyra->chrdev_minor, | 612 | roccat_report_event(pyra->chrdev_minor, |
688 | (uint8_t const *)&roccat_report, | 613 | (uint8_t const *)&roccat_report, |
689 | sizeof(struct pyra_roccat_report)); | 614 | 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: |
693 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH: | 618 | case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH: |
694 | if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) { | 619 | if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) { |
695 | roccat_report.type = button_event->type; | 620 | roccat_report.type = button_event->type; |
696 | roccat_report.key = button_event->data1; | 621 | roccat_report.key = button_event->data1; |
697 | /* | 622 | /* |
698 | * pyra reports profile numbers with range 1-5. | 623 | * pyra reports profile numbers with range 1-5. |
699 | * Keeping this behaviour. | 624 | * Keeping this behaviour. |
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)); | 629 | sizeof(struct pyra_roccat_report)); |
705 | } | 630 | } |
706 | break; | 631 | break; |
707 | } | 632 | } |
708 | } | 633 | } |
709 | 634 | ||
710 | static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report, | 635 | static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report, |
711 | u8 *data, int size) | 636 | u8 *data, int size) |
712 | { | 637 | { |
713 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 638 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
714 | struct pyra_device *pyra = hid_get_drvdata(hdev); | 639 | struct pyra_device *pyra = hid_get_drvdata(hdev); |
715 | 640 | ||
716 | if (intf->cur_altsetting->desc.bInterfaceProtocol | 641 | if (intf->cur_altsetting->desc.bInterfaceProtocol |
717 | != USB_INTERFACE_PROTOCOL_MOUSE) | 642 | != USB_INTERFACE_PROTOCOL_MOUSE) |
718 | return 0; | 643 | return 0; |
719 | 644 | ||
720 | pyra_keep_values_up_to_date(pyra, data); | 645 | pyra_keep_values_up_to_date(pyra, data); |
721 | 646 | ||
722 | if (pyra->roccat_claimed) | 647 | if (pyra->roccat_claimed) |
723 | pyra_report_to_chrdev(pyra, data); | 648 | pyra_report_to_chrdev(pyra, data); |
724 | 649 | ||
725 | return 0; | 650 | return 0; |
726 | } | 651 | } |
727 | 652 | ||
728 | static const struct hid_device_id pyra_devices[] = { | 653 | static const struct hid_device_id pyra_devices[] = { |
729 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, | 654 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, |
730 | USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, | 655 | USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, |
731 | /* TODO add USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS after testing */ | 656 | /* TODO add USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS after testing */ |
732 | { } | 657 | { } |
733 | }; | 658 | }; |
734 | 659 | ||
735 | MODULE_DEVICE_TABLE(hid, pyra_devices); | 660 | MODULE_DEVICE_TABLE(hid, pyra_devices); |
736 | 661 | ||
737 | static struct hid_driver pyra_driver = { | 662 | static struct hid_driver pyra_driver = { |
738 | .name = "pyra", | 663 | .name = "pyra", |
739 | .id_table = pyra_devices, | 664 | .id_table = pyra_devices, |
740 | .probe = pyra_probe, | 665 | .probe = pyra_probe, |
741 | .remove = pyra_remove, | 666 | .remove = pyra_remove, |
742 | .raw_event = pyra_raw_event | 667 | .raw_event = pyra_raw_event |
743 | }; | 668 | }; |
744 | 669 | ||
745 | static int __init pyra_init(void) | 670 | static int __init pyra_init(void) |
746 | { | 671 | { |
747 | int retval; | 672 | int retval; |
748 | 673 | ||
749 | /* class name has to be same as driver name */ | 674 | /* class name has to be same as driver name */ |
750 | pyra_class = class_create(THIS_MODULE, "pyra"); | 675 | pyra_class = class_create(THIS_MODULE, "pyra"); |
751 | if (IS_ERR(pyra_class)) | 676 | if (IS_ERR(pyra_class)) |
752 | return PTR_ERR(pyra_class); | 677 | return PTR_ERR(pyra_class); |
753 | pyra_class->dev_attrs = pyra_attributes; | 678 | pyra_class->dev_attrs = pyra_attributes; |
754 | pyra_class->dev_bin_attrs = pyra_bin_attributes; | 679 | pyra_class->dev_bin_attrs = pyra_bin_attributes; |
755 | 680 | ||
756 | retval = hid_register_driver(&pyra_driver); | 681 | retval = hid_register_driver(&pyra_driver); |
757 | if (retval) | 682 | if (retval) |
758 | class_destroy(pyra_class); | 683 | class_destroy(pyra_class); |
759 | return retval; | 684 | return retval; |
760 | } | 685 | } |
761 | 686 |