Pull HID updates from Jiri Kosina: - hid driver transport cleanup, finalizing the long-desired decoupling of core from transport layers, by Benjamin Tissoires and Henrik Rydberg - support for hybrid finger/pen multitouch HID devices, by Benjamin Tissoires - fix for long-standing issue in Logitech unifying driver sometimes not inializing properly due to device specifics, by Andrew de los Reyes - Wii remote driver updates to support 2nd generation of devices, by David Herrmann - support for Apple IR remote - roccat driver now supports new devices (Roccat Kone Pure, IskuFX), by Stefan Achatz - debugfs locking fixes in hid debug interface, by Jiri Kosina * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (43 commits) HID: protect hid_debug_list HID: debug: break out hid_dump_report() into hid-debug HID: Add PID for Japanese version of NE4K keyboard HID: hid-lg4ff add support for new version of DFGT wheel HID: icade: u16 which never < 0 HID: clarify Magic Mouse Kconfig description HID: appleir: add support for Apple ir devices HID: roccat: added media key support for Kone HID: hid-lenovo-tpkbd: remove doubled hid_get_drvdata HID: i2c-hid: fix length for set/get report in i2c hid HID: wiimote: parse reduced status reports HID: wiimote: add 2nd generation Wii Remote IDs HID: wiimote: use unique battery names HID: hidraw: warn if userspace headers are outdated HID: multitouch: force BTN_STYLUS for pen devices HID: multitouch: append " Pen" to the name of the stylus input HID: multitouch: add handling for pen in dual-sensors device HID: multitouch: change touch sensor detection in mt_input_configured() HID: multitouch: do not map usage from non used reports HID: multitouch: breaks out touch handling in specific functions ...
Unified · Split
| @@ -101,7 +101,8 @@ Date: June 2011 · 100 unmodified lines | |||
| 101 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | 101 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> |
| 102 | Description: When written, this file lets one set the backlight intensity for | 102 | Description: When written, this file lets one set the backlight intensity for |
| 103 | a specific profile. Profile number is included in written data. | 103 | a specific profile. Profile number is included in written data. |
| 104 | The data has to be 10 bytes long. | 104 | The data has to be 10 bytes long for Isku, IskuFX needs 16 bytes |
| 105 | of data. | ||
| 105 | Before reading this file, control has to be written to select | 106 | Before reading this file, control has to be written to select |
| 106 | which profile to read. | 107 | which profile to read. |
| 107 | Users: http://roccat.sourceforge.net | 108 | Users: http://roccat.sourceforge.net |
| @@ -141,3 +142,12 @@ Description: When written, this file lets one trigger easyshift functionality · 33 unmodified lines | |||
| 141 | The data has to be 16 bytes long. | 142 | The data has to be 16 bytes long. |
| 142 | This file is writeonly. | 143 | This file is writeonly. |
| 143 | Users: http://roccat.sourceforge.net | 144 | Users: http://roccat.sourceforge.net |
| 145 | |||
| 146 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/isku/roccatisku<minor>/talkfx | ||
| 147 | Date: February 2013 | ||
| 148 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 149 | Description: When written, this file lets one trigger temporary color schemes | ||
| 150 | from the host. | ||
| 151 | The data has to be 16 bytes long. | ||
| 152 | This file is writeonly. | ||
| 153 | Users: http://roccat.sourceforge.net | ||
| @@ -0,0 +1,105 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/actual_profile | ||
| 2 | Date: December 2012 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 5 | press of a button. actual_profile holds number of actual profile. | ||
| 6 | This value is persistent, so its value determines the profile | ||
| 7 | that's active when the mouse is powered on next time. | ||
| 8 | When written, the mouse activates the set profile immediately. | ||
| 9 | The data has to be 3 bytes long. | ||
| 10 | The mouse will reject invalid data. | ||
| 11 | Users: http://roccat.sourceforge.net | ||
| 12 | |||
| 13 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/control | ||
| 14 | Date: December 2012 | ||
| 15 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 16 | Description: When written, this file lets one select which data from which | ||
| 17 | profile will be read next. The data has to be 3 bytes long. | ||
| 18 | This file is writeonly. | ||
| 19 | Users: http://roccat.sourceforge.net | ||
| 20 | |||
| 21 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/info | ||
| 22 | Date: December 2012 | ||
| 23 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 24 | Description: When read, this file returns general data like firmware version. | ||
| 25 | When written, the device can be reset. | ||
| 26 | The data is 6 bytes long. | ||
| 27 | Users: http://roccat.sourceforge.net | ||
| 28 | |||
| 29 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/macro | ||
| 30 | Date: December 2012 | ||
| 31 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 32 | Description: The mouse can store a macro with max 500 key/button strokes | ||
| 33 | internally. | ||
| 34 | When written, this file lets one set the sequence for a specific | ||
| 35 | button for a specific profile. Button and profile numbers are | ||
| 36 | included in written data. The data has to be 2082 bytes long. | ||
| 37 | This file is writeonly. | ||
| 38 | Users: http://roccat.sourceforge.net | ||
| 39 | |||
| 40 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/profile_buttons | ||
| 41 | Date: December 2012 | ||
| 42 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 43 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 44 | press of a button. A profile is split in settings and buttons. | ||
| 45 | profile_buttons holds information about button layout. | ||
| 46 | When written, this file lets one write the respective profile | ||
| 47 | buttons back to the mouse. The data has to be 59 bytes long. | ||
| 48 | The mouse will reject invalid data. | ||
| 49 | Which profile to write is determined by the profile number | ||
| 50 | contained in the data. | ||
| 51 | Before reading this file, control has to be written to select | ||
| 52 | which profile to read. | ||
| 53 | Users: http://roccat.sourceforge.net | ||
| 54 | |||
| 55 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/profile_settings | ||
| 56 | Date: December 2012 | ||
| 57 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 58 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 59 | press of a button. A profile is split in settings and buttons. | ||
| 60 | profile_settings holds information like resolution, sensitivity | ||
| 61 | and light effects. | ||
| 62 | When written, this file lets one write the respective profile | ||
| 63 | settings back to the mouse. The data has to be 31 bytes long. | ||
| 64 | The mouse will reject invalid data. | ||
| 65 | Which profile to write is determined by the profile number | ||
| 66 | contained in the data. | ||
| 67 | Before reading this file, control has to be written to select | ||
| 68 | which profile to read. | ||
| 69 | Users: http://roccat.sourceforge.net | ||
| 70 | |||
| 71 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/sensor | ||
| 72 | Date: December 2012 | ||
| 73 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 74 | Description: The mouse has a tracking- and a distance-control-unit. These | ||
| 75 | can be activated/deactivated and the lift-off distance can be | ||
| 76 | set. The data has to be 6 bytes long. | ||
| 77 | This file is writeonly. | ||
| 78 | Users: http://roccat.sourceforge.net | ||
| 79 | |||
| 80 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/talk | ||
| 81 | Date: December 2012 | ||
| 82 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 83 | Description: Used to active some easy* functions of the mouse from outside. | ||
| 84 | The data has to be 16 bytes long. | ||
| 85 | This file is writeonly. | ||
| 86 | Users: http://roccat.sourceforge.net | ||
| 87 | |||
| 88 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/tcu | ||
| 89 | Date: December 2012 | ||
| 90 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 91 | Description: When written a calibration process for the tracking control unit | ||
| 92 | can be initiated/cancelled. Also lets one read/write sensor | ||
| 93 | registers. | ||
| 94 | The data has to be 4 bytes long. | ||
| 95 | Users: http://roccat.sourceforge.net | ||
| 96 | |||
| 97 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/konepure/roccatkonepure<minor>/tcu_image | ||
| 98 | Date: December 2012 | ||
| 99 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 100 | Description: When read the mouse returns a 30x30 pixel image of the | ||
| 101 | sampled underground. This works only in the course of a | ||
| 102 | calibration process initiated with tcu. | ||
| 103 | The returned data is 1028 bytes in size. | ||
| 104 | This file is readonly. | ||
| 105 | Users: http://roccat.sourceforge.net | ||
| @@ -92,14 +92,14 @@ menu "Special HID drivers" · 91 unmodified lines | |||
| 92 | 92 | ||
| 93 | config HID_A4TECH | 93 | config HID_A4TECH |
| 94 | tristate "A4 tech mice" if EXPERT | 94 | tristate "A4 tech mice" if EXPERT |
| 95 | depends on USB_HID | 95 | depends on HID |
| 96 | default !EXPERT | 96 | default !EXPERT |
| 97 | ---help--- | 97 | ---help--- |
| 98 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. | 98 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. |
| 99 | 99 | ||
| 100 | config HID_ACRUX | 100 | config HID_ACRUX |
| 101 | tristate "ACRUX game controller support" | 101 | tristate "ACRUX game controller support" |
| 102 | depends on USB_HID | 102 | depends on HID |
| 103 | ---help--- | 103 | ---help--- |
| 104 | Say Y here if you want to enable support for ACRUX game controllers. | 104 | Say Y here if you want to enable support for ACRUX game controllers. |
| 105 | 105 | ||
| @@ -113,7 +113,7 @@ config HID_ACRUX_FF · 7 unmodified lines | |||
| 113 | 113 | ||
| 114 | config HID_APPLE | 114 | config HID_APPLE |
| 115 | tristate "Apple {i,Power,Mac}Books" if EXPERT | 115 | tristate "Apple {i,Power,Mac}Books" if EXPERT |
| 116 | depends on (USB_HID || BT_HIDP) | 116 | depends on HID |
| 117 | default !EXPERT | 117 | default !EXPERT |
| 118 | ---help--- | 118 | ---help--- |
| 119 | Support for some Apple devices which less or more break | 119 | Support for some Apple devices which less or more break |
| @@ -122,36 +122,47 @@ config HID_APPLE · 2 unmodified lines | |||
| 122 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, | 122 | Say Y here if you want support for keyboards of Apple iBooks, PowerBooks, |
| 123 | MacBooks, MacBook Pros and Apple Aluminum. | 123 | MacBooks, MacBook Pros and Apple Aluminum. |
| 124 | 124 | ||
| 125 | config HID_APPLEIR | ||
| 126 | tristate "Apple infrared receiver" | ||
| 127 | depends on (USB_HID) | ||
| 128 | ---help--- | ||
| 129 | Support for Apple infrared remote control. All the Apple computers from | ||
| 130 | 2005 onwards include such a port, except the unibody Macbook (2009), | ||
| 131 | and Mac Pros. This receiver is also used in the Apple TV set-top box | ||
| 132 | prior to the 2010 model. | ||
| 133 | |||
| 134 | Say Y here if you want support for Apple infrared remote control. | ||
| 135 | |||
| 125 | config HID_AUREAL | 136 | config HID_AUREAL |
| 126 | tristate "Aureal" | 137 | tristate "Aureal" |
| 127 | depends on USB_HID | 138 | depends on HID |
| 128 | ---help--- | 139 | ---help--- |
| 129 | Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes. | 140 | Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes. |
| 130 | 141 | ||
| 131 | config HID_BELKIN | 142 | config HID_BELKIN |
| 132 | tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT | 143 | tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT |
| 133 | depends on USB_HID | 144 | depends on HID |
| 134 | default !EXPERT | 145 | default !EXPERT |
| 135 | ---help--- | 146 | ---help--- |
| 136 | Support for Belkin Flip KVM and Wireless keyboard. | 147 | Support for Belkin Flip KVM and Wireless keyboard. |
| 137 | 148 | ||
| 138 | config HID_CHERRY | 149 | config HID_CHERRY |
| 139 | tristate "Cherry Cymotion keyboard" if EXPERT | 150 | tristate "Cherry Cymotion keyboard" if EXPERT |
| 140 | depends on USB_HID | 151 | depends on HID |
| 141 | default !EXPERT | 152 | default !EXPERT |
| 142 | ---help--- | 153 | ---help--- |
| 143 | Support for Cherry Cymotion keyboard. | 154 | Support for Cherry Cymotion keyboard. |
| 144 | 155 | ||
| 145 | config HID_CHICONY | 156 | config HID_CHICONY |
| 146 | tristate "Chicony Tactical pad" if EXPERT | 157 | tristate "Chicony Tactical pad" if EXPERT |
| 147 | depends on USB_HID | 158 | depends on HID |
| 148 | default !EXPERT | 159 | default !EXPERT |
| 149 | ---help--- | 160 | ---help--- |
| 150 | Support for Chicony Tactical pad. | 161 | Support for Chicony Tactical pad. |
| 151 | 162 | ||
| 152 | config HID_PRODIKEYS | 163 | config HID_PRODIKEYS |
| 153 | tristate "Prodikeys PC-MIDI Keyboard support" | 164 | tristate "Prodikeys PC-MIDI Keyboard support" |
| 154 | depends on USB_HID && SND | 165 | depends on HID && SND |
| 155 | select SND_RAWMIDI | 166 | select SND_RAWMIDI |
| 156 | ---help--- | 167 | ---help--- |
| 157 | Support for Prodikeys PC-MIDI Keyboard device support. | 168 | Support for Prodikeys PC-MIDI Keyboard device support. |
| @@ -166,14 +177,14 @@ config HID_PRODIKEYS · 8 unmodified lines | |||
| 166 | 177 | ||
| 167 | config HID_CYPRESS | 178 | config HID_CYPRESS |
| 168 | tristate "Cypress mouse and barcode readers" if EXPERT | 179 | tristate "Cypress mouse and barcode readers" if EXPERT |
| 169 | depends on USB_HID | 180 | depends on HID |
| 170 | default !EXPERT | 181 | default !EXPERT |
| 171 | ---help--- | 182 | ---help--- |
| 172 | Support for cypress mouse and barcode readers. | 183 | Support for cypress mouse and barcode readers. |
| 173 | 184 | ||
| 174 | config HID_DRAGONRISE | 185 | config HID_DRAGONRISE |
| 175 | tristate "DragonRise Inc. game controller" | 186 | tristate "DragonRise Inc. game controller" |
| 176 | depends on USB_HID | 187 | depends on HID |
| 177 | ---help--- | 188 | ---help--- |
| 178 | Say Y here if you have DragonRise Inc. game controllers. | 189 | Say Y here if you have DragonRise Inc. game controllers. |
| 179 | These might be branded as: | 190 | These might be branded as: |
| @@ -192,7 +203,7 @@ config DRAGONRISE_FF · 12 unmodified lines | |||
| 192 | 203 | ||
| 193 | config HID_EMS_FF | 204 | config HID_EMS_FF |
| 194 | tristate "EMS Production Inc. force feedback support" | 205 | tristate "EMS Production Inc. force feedback support" |
| 195 | depends on USB_HID | 206 | depends on HID |
| 196 | select INPUT_FF_MEMLESS | 207 | select INPUT_FF_MEMLESS |
| 197 | ---help--- | 208 | ---help--- |
| 198 | Say Y here if you want to enable force feedback support for devices by | 209 | Say Y here if you want to enable force feedback support for devices by |
| @@ -202,13 +213,13 @@ config HID_EMS_FF · 3 unmodified lines | |||
| 202 | 213 | ||
| 203 | config HID_ELECOM | 214 | config HID_ELECOM |
| 204 | tristate "ELECOM BM084 bluetooth mouse" | 215 | tristate "ELECOM BM084 bluetooth mouse" |
| 205 | depends on BT_HIDP | 216 | depends on HID |
| 206 | ---help--- | 217 | ---help--- |
| 207 | Support for the ELECOM BM084 (bluetooth mouse). | 218 | Support for the ELECOM BM084 (bluetooth mouse). |
| 208 | 219 | ||
| 209 | config HID_EZKEY | 220 | config HID_EZKEY |
| 210 | tristate "Ezkey BTC 8193 keyboard" if EXPERT | 221 | tristate "Ezkey BTC 8193 keyboard" if EXPERT |
| 211 | depends on USB_HID | 222 | depends on HID |
| 212 | default !EXPERT | 223 | default !EXPERT |
| 213 | ---help--- | 224 | ---help--- |
| 214 | Support for Ezkey BTC 8193 keyboard. | 225 | Support for Ezkey BTC 8193 keyboard. |
| @@ -231,7 +242,7 @@ config HOLTEK_FF · 16 unmodified lines | |||
| 231 | 242 | ||
| 232 | config HID_KEYTOUCH | 243 | config HID_KEYTOUCH |
| 233 | tristate "Keytouch HID devices" | 244 | tristate "Keytouch HID devices" |
| 234 | depends on USB_HID | 245 | depends on HID |
| 235 | ---help--- | 246 | ---help--- |
| 236 | Support for Keytouch HID devices not fully compliant with | 247 | Support for Keytouch HID devices not fully compliant with |
| 237 | the specification. Currently supported: | 248 | the specification. Currently supported: |
| @@ -239,7 +250,7 @@ config HID_KEYTOUCH · 1 unmodified line | |||
| 239 | 250 | ||
| 240 | config HID_KYE | 251 | config HID_KYE |
| 241 | tristate "KYE/Genius devices" | 252 | tristate "KYE/Genius devices" |
| 242 | depends on USB_HID | 253 | depends on HID |
| 243 | ---help--- | 254 | ---help--- |
| 244 | Support for KYE/Genius devices not fully compliant with HID standard: | 255 | Support for KYE/Genius devices not fully compliant with HID standard: |
| 245 | - Ergo Mouse | 256 | - Ergo Mouse |
| @@ -249,25 +260,25 @@ config HID_KYE · 3 unmodified lines | |||
| 249 | 260 | ||
| 250 | config HID_UCLOGIC | 261 | config HID_UCLOGIC |
| 251 | tristate "UC-Logic" | 262 | tristate "UC-Logic" |
| 252 | depends on USB_HID | 263 | depends on HID |
| 253 | ---help--- | 264 | ---help--- |
| 254 | Support for UC-Logic tablets. | 265 | Support for UC-Logic tablets. |
| 255 | 266 | ||
| 256 | config HID_WALTOP | 267 | config HID_WALTOP |
| 257 | tristate "Waltop" | 268 | tristate "Waltop" |
| 258 | depends on USB_HID | 269 | depends on HID |
| 259 | ---help--- | 270 | ---help--- |
| 260 | Support for Waltop tablets. | 271 | Support for Waltop tablets. |
| 261 | 272 | ||
| 262 | config HID_GYRATION | 273 | config HID_GYRATION |
| 263 | tristate "Gyration remote control" | 274 | tristate "Gyration remote control" |
| 264 | depends on USB_HID | 275 | depends on HID |
| 265 | ---help--- | 276 | ---help--- |
| 266 | Support for Gyration remote control. | 277 | Support for Gyration remote control. |
| 267 | 278 | ||
| 268 | config HID_ICADE | 279 | config HID_ICADE |
| 269 | tristate "ION iCade arcade controller" | 280 | tristate "ION iCade arcade controller" |
| 270 | depends on BT_HIDP | 281 | depends on HID |
| 271 | ---help--- | 282 | ---help--- |
| 272 | Support for the ION iCade arcade controller to work as a joystick. | 283 | Support for the ION iCade arcade controller to work as a joystick. |
| 273 | 284 | ||
| @@ -276,20 +287,20 @@ config HID_ICADE · 2 unmodified lines | |||
| 276 | 287 | ||
| 277 | config HID_TWINHAN | 288 | config HID_TWINHAN |
| 278 | tristate "Twinhan IR remote control" | 289 | tristate "Twinhan IR remote control" |
| 279 | depends on USB_HID | 290 | depends on HID |
| 280 | ---help--- | 291 | ---help--- |
| 281 | Support for Twinhan IR remote control. | 292 | Support for Twinhan IR remote control. |
| 282 | 293 | ||
| 283 | config HID_KENSINGTON | 294 | config HID_KENSINGTON |
| 284 | tristate "Kensington Slimblade Trackball" if EXPERT | 295 | tristate "Kensington Slimblade Trackball" if EXPERT |
| 285 | depends on USB_HID | 296 | depends on HID |
| 286 | default !EXPERT | 297 | default !EXPERT |
| 287 | ---help--- | 298 | ---help--- |
| 288 | Support for Kensington Slimblade Trackball. | 299 | Support for Kensington Slimblade Trackball. |
| 289 | 300 | ||
| 290 | config HID_LCPOWER | 301 | config HID_LCPOWER |
| 291 | tristate "LC-Power" | 302 | tristate "LC-Power" |
| 292 | depends on USB_HID | 303 | depends on HID |
| 293 | ---help--- | 304 | ---help--- |
| 294 | Support for LC-Power RC1000MCE RF remote control. | 305 | Support for LC-Power RC1000MCE RF remote control. |
| 295 | 306 | ||
| @@ -308,7 +319,7 @@ config HID_LENOVO_TPKBD · 12 unmodified lines | |||
| 308 | 319 | ||
| 309 | config HID_LOGITECH | 320 | config HID_LOGITECH |
| 310 | tristate "Logitech devices" if EXPERT | 321 | tristate "Logitech devices" if EXPERT |
| 311 | depends on USB_HID | 322 | depends on HID |
| 312 | default !EXPERT | 323 | default !EXPERT |
| 313 | ---help--- | 324 | ---help--- |
| 314 | Support for Logitech devices that are not fully compliant with HID standard. | 325 | Support for Logitech devices that are not fully compliant with HID standard. |
| @@ -373,31 +384,31 @@ config LOGIWHEELS_FF · 58 unmodified lines | |||
| 373 | - Logitech Formula Force EX | 384 | - Logitech Formula Force EX |
| 374 | 385 | ||
| 375 | config HID_MAGICMOUSE | 386 | config HID_MAGICMOUSE |
| 376 | tristate "Apple MagicMouse multi-touch support" | 387 | tristate "Apple Magic Mouse/Trackpad multi-touch support" |
| 377 | depends on BT_HIDP | 388 | depends on HID |
| 378 | ---help--- | 389 | ---help--- |
| 379 | Support for the Apple Magic Mouse multi-touch. | 390 | Support for the Apple Magic Mouse/Trackpad multi-touch. |
| 380 | 391 | ||
| 381 | Say Y here if you want support for the multi-touch features of the | 392 | Say Y here if you want support for the multi-touch features of the |
| 382 | Apple Wireless "Magic" Mouse. | 393 | Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad. |
| 383 | 394 | ||
| 384 | config HID_MICROSOFT | 395 | config HID_MICROSOFT |
| 385 | tristate "Microsoft non-fully HID-compliant devices" if EXPERT | 396 | tristate "Microsoft non-fully HID-compliant devices" if EXPERT |
| 386 | depends on USB_HID | 397 | depends on HID |
| 387 | default !EXPERT | 398 | default !EXPERT |
| 388 | ---help--- | 399 | ---help--- |
| 389 | Support for Microsoft devices that are not fully compliant with HID standard. | 400 | Support for Microsoft devices that are not fully compliant with HID standard. |
| 390 | 401 | ||
| 391 | config HID_MONTEREY | 402 | config HID_MONTEREY |
| 392 | tristate "Monterey Genius KB29E keyboard" if EXPERT | 403 | tristate "Monterey Genius KB29E keyboard" if EXPERT |
| 393 | depends on USB_HID | 404 | depends on HID |
| 394 | default !EXPERT | 405 | default !EXPERT |
| 395 | ---help--- | 406 | ---help--- |
| 396 | Support for Monterey Genius KB29E. | 407 | Support for Monterey Genius KB29E. |
| 397 | 408 | ||
| 398 | config HID_MULTITOUCH | 409 | config HID_MULTITOUCH |
| 399 | tristate "HID Multitouch panels" | 410 | tristate "HID Multitouch panels" |
| 400 | depends on USB_HID | 411 | depends on HID |
| 401 | ---help--- | 412 | ---help--- |
| 402 | Generic support for HID multitouch panels. | 413 | Generic support for HID multitouch panels. |
| 403 | 414 | ||
| @@ -445,7 +456,7 @@ config HID_NTRIG · 41 unmodified lines | |||
| 445 | 456 | ||
| 446 | config HID_ORTEK | 457 | config HID_ORTEK |
| 447 | tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad" | 458 | tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad" |
| 448 | depends on USB_HID | 459 | depends on HID |
| 449 | ---help--- | 460 | ---help--- |
| 450 | There are certain devices which have LogicalMaximum wrong in the keyboard | 461 | There are certain devices which have LogicalMaximum wrong in the keyboard |
| 451 | usage page of their report descriptor. The most prevailing ones so far | 462 | usage page of their report descriptor. The most prevailing ones so far |
| @@ -458,7 +469,7 @@ config HID_ORTEK · 6 unmodified lines | |||
| 458 | 469 | ||
| 459 | config HID_PANTHERLORD | 470 | config HID_PANTHERLORD |
| 460 | tristate "Pantherlord/GreenAsia game controller" | 471 | tristate "Pantherlord/GreenAsia game controller" |
| 461 | depends on USB_HID | 472 | depends on HID |
| 462 | ---help--- | 473 | ---help--- |
| 463 | Say Y here if you have a PantherLord/GreenAsia based game controller | 474 | Say Y here if you have a PantherLord/GreenAsia based game controller |
| 464 | or adapter. | 475 | or adapter. |
| @@ -473,13 +484,13 @@ config PANTHERLORD_FF · 8 unmodified lines | |||
| 473 | 484 | ||
| 474 | config HID_PETALYNX | 485 | config HID_PETALYNX |
| 475 | tristate "Petalynx Maxter remote control" | 486 | tristate "Petalynx Maxter remote control" |
| 476 | depends on USB_HID | 487 | depends on HID |
| 477 | ---help--- | 488 | ---help--- |
| 478 | Support for Petalynx Maxter remote control. | 489 | Support for Petalynx Maxter remote control. |
| 479 | 490 | ||
| 480 | config HID_PICOLCD | 491 | config HID_PICOLCD |
| 481 | tristate "PicoLCD (graphic version)" | 492 | tristate "PicoLCD (graphic version)" |
| 482 | depends on USB_HID | 493 | depends on HID |
| 483 | ---help--- | 494 | ---help--- |
| 484 | This provides support for Minibox PicoLCD devices, currently | 495 | This provides support for Minibox PicoLCD devices, currently |
| 485 | only the graphical ones are supported. | 496 | only the graphical ones are supported. |
| @@ -545,14 +556,14 @@ config HID_PICOLCD_CIR · 59 unmodified lines | |||
| 545 | 556 | ||
| 546 | config HID_PRIMAX | 557 | config HID_PRIMAX |
| 547 | tristate "Primax non-fully HID-compliant devices" | 558 | tristate "Primax non-fully HID-compliant devices" |
| 548 | depends on USB_HID | 559 | depends on HID |
| 549 | ---help--- | 560 | ---help--- |
| 550 | Support for Primax devices that are not fully compliant with the | 561 | Support for Primax devices that are not fully compliant with the |
| 551 | HID standard. | 562 | HID standard. |
| 552 | 563 | ||
| 553 | config HID_PS3REMOTE | 564 | config HID_PS3REMOTE |
| 554 | tristate "Sony PS3 BD Remote Control" | 565 | tristate "Sony PS3 BD Remote Control" |
| 555 | depends on BT_HIDP | 566 | depends on HID |
| 556 | ---help--- | 567 | ---help--- |
| 557 | Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech | 568 | Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech |
| 558 | Harmony Adapter for PS3, which connect over Bluetooth. | 569 | Harmony Adapter for PS3, which connect over Bluetooth. |
| @@ -569,7 +580,7 @@ config HID_ROCCAT · 10 unmodified lines | |||
| 569 | 580 | ||
| 570 | config HID_SAITEK | 581 | config HID_SAITEK |
| 571 | tristate "Saitek non-fully HID-compliant devices" | 582 | tristate "Saitek non-fully HID-compliant devices" |
| 572 | depends on USB_HID | 583 | depends on HID |
| 573 | ---help--- | 584 | ---help--- |
| 574 | Support for Saitek devices that are not fully compliant with the | 585 | Support for Saitek devices that are not fully compliant with the |
| 575 | HID standard. | 586 | HID standard. |
| @@ -578,7 +589,7 @@ config HID_SAITEK · 2 unmodified lines | |||
| 578 | 589 | ||
| 579 | config HID_SAMSUNG | 590 | config HID_SAMSUNG |
| 580 | tristate "Samsung InfraRed remote control or keyboards" | 591 | tristate "Samsung InfraRed remote control or keyboards" |
| 581 | depends on USB_HID | 592 | depends on HID |
| 582 | ---help--- | 593 | ---help--- |
| 583 | Support for Samsung InfraRed remote control or keyboards. | 594 | Support for Samsung InfraRed remote control or keyboards. |
| 584 | 595 | ||
| @@ -592,25 +603,25 @@ config HID_SONY · 7 unmodified lines | |||
| 592 | 603 | ||
| 593 | config HID_SPEEDLINK | 604 | config HID_SPEEDLINK |
| 594 | tristate "Speedlink VAD Cezanne mouse support" | 605 | tristate "Speedlink VAD Cezanne mouse support" |
| 595 | depends on USB_HID | 606 | depends on HID |
| 596 | ---help--- | 607 | ---help--- |
| 597 | Support for Speedlink Vicious and Divine Cezanne mouse. | 608 | Support for Speedlink Vicious and Divine Cezanne mouse. |
| 598 | 609 | ||
| 599 | config HID_STEELSERIES | 610 | config HID_STEELSERIES |
| 600 | tristate "Steelseries SRW-S1 steering wheel support" | 611 | tristate "Steelseries SRW-S1 steering wheel support" |
| 601 | depends on USB_HID | 612 | depends on HID |
| 602 | ---help--- | 613 | ---help--- |
| 603 | Support for Steelseries SRW-S1 steering wheel | 614 | Support for Steelseries SRW-S1 steering wheel |
| 604 | 615 | ||
| 605 | config HID_SUNPLUS | 616 | config HID_SUNPLUS |
| 606 | tristate "Sunplus wireless desktop" | 617 | tristate "Sunplus wireless desktop" |
| 607 | depends on USB_HID | 618 | depends on HID |
| 608 | ---help--- | 619 | ---help--- |
| 609 | Support for Sunplus wireless desktop. | 620 | Support for Sunplus wireless desktop. |
| 610 | 621 | ||
| 611 | config HID_GREENASIA | 622 | config HID_GREENASIA |
| 612 | tristate "GreenAsia (Product ID 0x12) game controller support" | 623 | tristate "GreenAsia (Product ID 0x12) game controller support" |
| 613 | depends on USB_HID | 624 | depends on HID |
| 614 | ---help--- | 625 | ---help--- |
| 615 | Say Y here if you have a GreenAsia (Product ID 0x12) based game | 626 | Say Y here if you have a GreenAsia (Product ID 0x12) based game |
| 616 | controller or adapter. | 627 | controller or adapter. |
| @@ -632,7 +643,7 @@ config HID_HYPERV_MOUSE · 15 unmodified lines | |||
| 632 | 643 | ||
| 633 | config HID_SMARTJOYPLUS | 644 | config HID_SMARTJOYPLUS |
| 634 | tristate "SmartJoy PLUS PS2/USB adapter support" | 645 | tristate "SmartJoy PLUS PS2/USB adapter support" |
| 635 | depends on USB_HID | 646 | depends on HID |
| 636 | ---help--- | 647 | ---help--- |
| 637 | Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box, | 648 | Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box, |
| 638 | Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro. | 649 | Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro. |
| @@ -650,20 +661,20 @@ config SMARTJOYPLUS_FF · 11 unmodified lines | |||
| 650 | 661 | ||
| 651 | config HID_TIVO | 662 | config HID_TIVO |
| 652 | tristate "TiVo Slide Bluetooth remote control support" | 663 | tristate "TiVo Slide Bluetooth remote control support" |
| 653 | depends on (USB_HID || BT_HIDP) | 664 | depends on HID |
| 654 | ---help--- | 665 | ---help--- |
| 655 | Say Y if you have a TiVo Slide Bluetooth remote control. | 666 | Say Y if you have a TiVo Slide Bluetooth remote control. |
| 656 | 667 | ||
| 657 | config HID_TOPSEED | 668 | config HID_TOPSEED |
| 658 | tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" | 669 | tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support" |
| 659 | depends on USB_HID | 670 | depends on HID |
| 660 | ---help--- | 671 | ---help--- |
| 661 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic | 672 | Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic |
| 662 | CLLRCMCE remote control. | 673 | CLLRCMCE remote control. |
| 663 | 674 | ||
| 664 | config HID_THINGM | 675 | config HID_THINGM |
| 665 | tristate "ThingM blink(1) USB RGB LED" | 676 | tristate "ThingM blink(1) USB RGB LED" |
| 666 | depends on USB_HID | 677 | depends on HID |
| 667 | depends on LEDS_CLASS | 678 | depends on LEDS_CLASS |
| 668 | ---help--- | 679 | ---help--- |
| 669 | Support for the ThingM blink(1) USB RGB LED. This driver registers a | 680 | Support for the ThingM blink(1) USB RGB LED. This driver registers a |
| @@ -673,7 +684,7 @@ config HID_THINGM · 3 unmodified lines | |||
| 673 | 684 | ||
| 674 | config HID_THRUSTMASTER | 685 | config HID_THRUSTMASTER |
| 675 | tristate "ThrustMaster devices support" | 686 | tristate "ThrustMaster devices support" |
| 676 | depends on USB_HID | 687 | depends on HID |
| 677 | ---help--- | 688 | ---help--- |
| 678 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or | 689 | Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or |
| 679 | a THRUSTMASTER Ferrari GT Rumble Wheel. | 690 | a THRUSTMASTER Ferrari GT Rumble Wheel. |
| @@ -689,7 +700,7 @@ config THRUSTMASTER_FF · 9 unmodified lines | |||
| 689 | 700 | ||
| 690 | config HID_WACOM | 701 | config HID_WACOM |
| 691 | tristate "Wacom Bluetooth devices support" | 702 | tristate "Wacom Bluetooth devices support" |
| 692 | depends on BT_HIDP | 703 | depends on HID |
| 693 | depends on LEDS_CLASS | 704 | depends on LEDS_CLASS |
| 694 | select POWER_SUPPLY | 705 | select POWER_SUPPLY |
| 695 | ---help--- | 706 | ---help--- |
| @@ -697,7 +708,7 @@ config HID_WACOM · 1 unmodified line | |||
| 697 | 708 | ||
| 698 | config HID_WIIMOTE | 709 | config HID_WIIMOTE |
| 699 | tristate "Nintendo Wii Remote support" | 710 | tristate "Nintendo Wii Remote support" |
| 700 | depends on BT_HIDP | 711 | depends on HID |
| 701 | depends on LEDS_CLASS | 712 | depends on LEDS_CLASS |
| 702 | select POWER_SUPPLY | 713 | select POWER_SUPPLY |
| 703 | select INPUT_FF_MEMLESS | 714 | select INPUT_FF_MEMLESS |
| @@ -715,7 +726,7 @@ config HID_WIIMOTE_EXT · 11 unmodified lines | |||
| 715 | 726 | ||
| 716 | config HID_ZEROPLUS | 727 | config HID_ZEROPLUS |
| 717 | tristate "Zeroplus based game controller support" | 728 | tristate "Zeroplus based game controller support" |
| 718 | depends on USB_HID | 729 | depends on HID |
| 719 | ---help--- | 730 | ---help--- |
| 720 | Say Y here if you have a Zeroplus based game controller. | 731 | Say Y here if you have a Zeroplus based game controller. |
| 721 | 732 | ||
| @@ -729,16 +740,16 @@ config ZEROPLUS_FF · 7 unmodified lines | |||
| 729 | 740 | ||
| 730 | config HID_ZYDACRON | 741 | config HID_ZYDACRON |
| 731 | tristate "Zydacron remote control support" | 742 | tristate "Zydacron remote control support" |
| 732 | depends on USB_HID | 743 | depends on HID |
| 733 | ---help--- | 744 | ---help--- |
| 734 | Support for Zydacron remote control. | 745 | Support for Zydacron remote control. |
| 735 | 746 | ||
| 736 | config HID_SENSOR_HUB | 747 | config HID_SENSOR_HUB |
| 737 | tristate "HID Sensors framework support" | 748 | tristate "HID Sensors framework support" |
| 738 | depends on USB_HID && GENERIC_HARDIRQS | 749 | depends on HID && GENERIC_HARDIRQS |
| 739 | select MFD_CORE | 750 | select MFD_CORE |
| 740 | default n | 751 | default n |
| 741 | -- help--- | 752 | ---help--- |
| 742 | Support for HID Sensor framework. This creates a MFD instance | 753 | Support for HID Sensor framework. This creates a MFD instance |
| 743 | for a sensor hub and identifies all the sensors connected to it. | 754 | for a sensor hub and identifies all the sensors connected to it. |
| 744 | Each sensor is registered as a MFD cell, so that sensor specific | 755 | Each sensor is registered as a MFD cell, so that sensor specific |
| @@ -39,6 +39,7 @@ endif · 38 unmodified lines | |||
| 39 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 39 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
| 40 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o | 40 | obj-$(CONFIG_HID_ACRUX) += hid-axff.o |
| 41 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 41 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
| 42 | obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o | ||
| 42 | obj-$(CONFIG_HID_AUREAL) += hid-aureal.o | 43 | obj-$(CONFIG_HID_AUREAL) += hid-aureal.o |
| 43 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o | 44 | obj-$(CONFIG_HID_BELKIN) += hid-belkin.o |
| 44 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o | 45 | obj-$(CONFIG_HID_CHERRY) += hid-cherry.o |
| @@ -94,8 +95,8 @@ obj-$(CONFIG_HID_PRIMAX) += hid-primax.o · 49 unmodified lines | |||
| 94 | obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o | 95 | obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o |
| 95 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ | 96 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ |
| 96 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ | 97 | hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ |
| 97 | hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-lua.o \ | 98 | hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ |
| 98 | hid-roccat-pyra.o hid-roccat-savu.o | 99 | hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-savu.o |
| 99 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o | 100 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o |
| 100 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 101 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
| 101 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 102 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o |
| @@ -21,7 +21,6 @@ · 20 unmodified lines | |||
| 21 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
| 22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/usb.h> | ||
| 25 | 24 | ||
| 26 | #include "hid-ids.h" | 25 | #include "hid-ids.h" |
| 27 | 26 | ||
| @@ -390,10 +389,6 @@ static void apple_remove(struct hid_device *hdev) · 362 unmodified lines | |||
| 390 | } | 389 | } |
| 391 | 390 | ||
| 392 | static const struct hid_device_id apple_devices[] = { | 391 | static const struct hid_device_id apple_devices[] = { |
| 393 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL), | ||
| 394 | .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, | ||
| 395 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4), | ||
| 396 | .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT }, | ||
| 397 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), | 392 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE), |
| 398 | .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, | 393 | .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL }, |
| 399 | 394 | ||
| @@ -0,0 +1,352 @@ | |||
| 1 | /* | ||
| 2 | * HID driver for the apple ir device | ||
| 3 | * | ||
| 4 | * Original driver written by James McKenzie | ||
| 5 | * Ported to recent 2.6 kernel versions by Greg Kroah-Hartman <gregkh@suse.de> | ||
| 6 | * Updated to support newer remotes by Bastien Nocera <hadess@hadess.net> | ||
| 7 | * Ported to HID subsystem by Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 8 | * | ||
| 9 | * Copyright (C) 2006 James McKenzie | ||
| 10 | * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com> | ||
| 11 | * Copyright (C) 2008 Novell Inc. | ||
| 12 | * Copyright (C) 2010, 2012 Bastien Nocera <hadess@hadess.net> | ||
| 13 | * Copyright (C) 2013 Benjamin Tissoires <benjamin.tissoires@gmail.com> | ||
| 14 | * Copyright (C) 2013 Red Hat Inc. All Rights Reserved | ||
| 15 | * | ||
| 16 | * This software is licensed under the terms of the GNU General Public | ||
| 17 | * License version 2, as published by the Free Software Foundation, and | ||
| 18 | * may be copied, distributed, and modified under those terms. | ||
| 19 | * | ||
| 20 | * This program is distributed in the hope that it will be useful, | ||
| 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 23 | * GNU General Public License for more details. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/device.h> | ||
| 27 | #include <linux/hid.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include "hid-ids.h" | ||
| 30 | |||
| 31 | MODULE_AUTHOR("James McKenzie"); | ||
| 32 | MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>"); | ||
| 33 | MODULE_DESCRIPTION("HID Apple IR remote controls"); | ||
| 34 | MODULE_LICENSE("GPL"); | ||
| 35 | |||
| 36 | #define KEY_MASK 0x0F | ||
| 37 | #define TWO_PACKETS_MASK 0x40 | ||
| 38 | |||
| 39 | /* | ||
| 40 | * James McKenzie has two devices both of which report the following | ||
| 41 | * 25 87 ee 83 0a + | ||
| 42 | * 25 87 ee 83 0c - | ||
| 43 | * 25 87 ee 83 09 << | ||
| 44 | * 25 87 ee 83 06 >> | ||
| 45 | * 25 87 ee 83 05 >" | ||
| 46 | * 25 87 ee 83 03 menu | ||
| 47 | * 26 00 00 00 00 for key repeat | ||
| 48 | */ | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Thomas Glanzmann reports the following responses | ||
| 52 | * 25 87 ee ca 0b + | ||
| 53 | * 25 87 ee ca 0d - | ||
| 54 | * 25 87 ee ca 08 << | ||
| 55 | * 25 87 ee ca 07 >> | ||
| 56 | * 25 87 ee ca 04 >" | ||
| 57 | * 25 87 ee ca 02 menu | ||
| 58 | * 26 00 00 00 00 for key repeat | ||
| 59 | * | ||
| 60 | * He also observes the following event sometimes | ||
| 61 | * sent after a key is release, which I interpret | ||
| 62 | * as a flat battery message | ||
| 63 | * 25 87 e0 ca 06 flat battery | ||
| 64 | */ | ||
| 65 | |||
| 66 | /* | ||
| 67 | * Alexandre Karpenko reports the following responses for Device ID 0x8242 | ||
| 68 | * 25 87 ee 47 0b + | ||
| 69 | * 25 87 ee 47 0d - | ||
| 70 | * 25 87 ee 47 08 << | ||
| 71 | * 25 87 ee 47 07 >> | ||
| 72 | * 25 87 ee 47 04 >" | ||
| 73 | * 25 87 ee 47 02 menu | ||
| 74 | * 26 87 ee 47 ** for key repeat (** is the code of the key being held) | ||
| 75 | */ | ||
| 76 | |||
| 77 | /* | ||
| 78 | * Bastien Nocera's remote | ||
| 79 | * 25 87 ee 91 5f followed by | ||
| 80 | * 25 87 ee 91 05 gives you >" | ||
| 81 | * | ||
| 82 | * 25 87 ee 91 5c followed by | ||
| 83 | * 25 87 ee 91 05 gives you the middle button | ||
| 84 | */ | ||
| 85 | |||
| 86 | /* | ||
| 87 | * Fabien Andre's remote | ||
| 88 | * 25 87 ee a3 5e followed by | ||
| 89 | * 25 87 ee a3 04 gives you >" | ||
| 90 | * | ||
| 91 | * 25 87 ee a3 5d followed by | ||
| 92 | * 25 87 ee a3 04 gives you the middle button | ||
| 93 | */ | ||
| 94 | |||
| 95 | static const unsigned short appleir_key_table[] = { | ||
| 96 | KEY_RESERVED, | ||
| 97 | KEY_MENU, | ||
| 98 | KEY_PLAYPAUSE, | ||
| 99 | KEY_FORWARD, | ||
| 100 | KEY_BACK, | ||
| 101 | KEY_VOLUMEUP, | ||
| 102 | KEY_VOLUMEDOWN, | ||
| 103 | KEY_RESERVED, | ||
| 104 | KEY_RESERVED, | ||
| 105 | KEY_RESERVED, | ||
| 106 | KEY_RESERVED, | ||
| 107 | KEY_RESERVED, | ||
| 108 | KEY_RESERVED, | ||
| 109 | KEY_RESERVED, | ||
| 110 | KEY_ENTER, | ||
| 111 | KEY_PLAYPAUSE, | ||
| 112 | KEY_RESERVED, | ||
| 113 | }; | ||
| 114 | |||
| 115 | struct appleir { | ||
| 116 | struct input_dev *input_dev; | ||
| 117 | struct hid_device *hid; | ||
| 118 | unsigned short keymap[ARRAY_SIZE(appleir_key_table)]; | ||
| 119 | struct timer_list key_up_timer; /* timer for key up */ | ||
| 120 | spinlock_t lock; /* protects .current_key */ | ||
| 121 | int current_key; /* the currently pressed key */ | ||
| 122 | int prev_key_idx; /* key index in a 2 packets message */ | ||
| 123 | }; | ||
| 124 | |||
| 125 | static int get_key(int data) | ||
| 126 | { | ||
| 127 | /* | ||
| 128 | * The key is coded accross bits 2..9: | ||
| 129 | * | ||
| 130 | * 0x00 or 0x01 ( ) key: 0 -> KEY_RESERVED | ||
| 131 | * 0x02 or 0x03 ( menu ) key: 1 -> KEY_MENU | ||
| 132 | * 0x04 or 0x05 ( >" ) key: 2 -> KEY_PLAYPAUSE | ||
| 133 | * 0x06 or 0x07 ( >> ) key: 3 -> KEY_FORWARD | ||
| 134 | * 0x08 or 0x09 ( << ) key: 4 -> KEY_BACK | ||
| 135 | * 0x0a or 0x0b ( + ) key: 5 -> KEY_VOLUMEUP | ||
| 136 | * 0x0c or 0x0d ( - ) key: 6 -> KEY_VOLUMEDOWN | ||
| 137 | * 0x0e or 0x0f ( ) key: 7 -> KEY_RESERVED | ||
| 138 | * 0x50 or 0x51 ( ) key: 8 -> KEY_RESERVED | ||
| 139 | * 0x52 or 0x53 ( ) key: 9 -> KEY_RESERVED | ||
| 140 | * 0x54 or 0x55 ( ) key: 10 -> KEY_RESERVED | ||
| 141 | * 0x56 or 0x57 ( ) key: 11 -> KEY_RESERVED | ||
| 142 | * 0x58 or 0x59 ( ) key: 12 -> KEY_RESERVED | ||
| 143 | * 0x5a or 0x5b ( ) key: 13 -> KEY_RESERVED | ||
| 144 | * 0x5c or 0x5d ( middle ) key: 14 -> KEY_ENTER | ||
| 145 | * 0x5e or 0x5f ( >" ) key: 15 -> KEY_PLAYPAUSE | ||
| 146 | * | ||
| 147 | * Packets starting with 0x5 are part of a two-packets message, | ||
| 148 | * we notify the caller by sending a negative value. | ||
| 149 | */ | ||
| 150 | int key = (data >> 1) & KEY_MASK; | ||
| 151 | |||
| 152 | if ((data & TWO_PACKETS_MASK)) | ||
| 153 | /* Part of a 2 packets-command */ | ||
| 154 | key = -key; | ||
| 155 | |||
| 156 | return key; | ||
| 157 | } | ||
| 158 | |||
| 159 | static void key_up(struct hid_device *hid, struct appleir *appleir, int key) | ||
| 160 | { | ||
| 161 | input_report_key(appleir->input_dev, key, 0); | ||
| 162 | input_sync(appleir->input_dev); | ||
| 163 | } | ||
| 164 | |||
| 165 | static void key_down(struct hid_device *hid, struct appleir *appleir, int key) | ||
| 166 | { | ||
| 167 | input_report_key(appleir->input_dev, key, 1); | ||
| 168 | input_sync(appleir->input_dev); | ||
| 169 | } | ||
| 170 | |||
| 171 | static void battery_flat(struct appleir *appleir) | ||
| 172 | { | ||
| 173 | dev_err(&appleir->input_dev->dev, "possible flat battery?\n"); | ||
| 174 | } | ||
| 175 | |||
| 176 | static void key_up_tick(unsigned long data) | ||
| 177 | { | ||
| 178 | struct appleir *appleir = (struct appleir *)data; | ||
| 179 | struct hid_device *hid = appleir->hid; | ||
| 180 | unsigned long flags; | ||
| 181 | |||
| 182 | spin_lock_irqsave(&appleir->lock, flags); | ||
| 183 | if (appleir->current_key) { | ||
| 184 | key_up(hid, appleir, appleir->current_key); | ||
| 185 | appleir->current_key = 0; | ||
| 186 | } | ||
| 187 | spin_unlock_irqrestore(&appleir->lock, flags); | ||
| 188 | } | ||
| 189 | |||
| 190 | static int appleir_raw_event(struct hid_device *hid, struct hid_report *report, | ||
| 191 | u8 *data, int len) | ||
| 192 | { | ||
| 193 | struct appleir *appleir = hid_get_drvdata(hid); | ||
| 194 | static const u8 keydown[] = { 0x25, 0x87, 0xee }; | ||
| 195 | static const u8 keyrepeat[] = { 0x26, }; | ||
| 196 | static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 }; | ||
| 197 | unsigned long flags; | ||
| 198 | |||
| 199 | if (len != 5) | ||
| 200 | goto out; | ||
| 201 | |||
| 202 | if (!memcmp(data, keydown, sizeof(keydown))) { | ||
| 203 | int index; | ||
| 204 | |||
| 205 | spin_lock_irqsave(&appleir->lock, flags); | ||
| 206 | /* | ||
| 207 | * If we already have a key down, take it up before marking | ||
| 208 | * this one down | ||
| 209 | */ | ||
| 210 | if (appleir->current_key) | ||
| 211 | key_up(hid, appleir, appleir->current_key); | ||
| 212 | |||
| 213 | /* Handle dual packet commands */ | ||
| 214 | if (appleir->prev_key_idx > 0) | ||
| 215 | index = appleir->prev_key_idx; | ||
| 216 | else | ||
| 217 | index = get_key(data[4]); | ||
| 218 | |||
| 219 | if (index >= 0) { | ||
| 220 | appleir->current_key = appleir->keymap[index]; | ||
| 221 | |||
| 222 | key_down(hid, appleir, appleir->current_key); | ||
| 223 | /* | ||
| 224 | * Remote doesn't do key up, either pull them up, in | ||
| 225 | * the test above, or here set a timer which pulls | ||
| 226 | * them up after 1/8 s | ||
| 227 | */ | ||
| 228 | mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); | ||
| 229 | appleir->prev_key_idx = 0; | ||
| 230 | } else | ||
| 231 | /* Remember key for next packet */ | ||
| 232 | appleir->prev_key_idx = -index; | ||
| 233 | spin_unlock_irqrestore(&appleir->lock, flags); | ||
| 234 | goto out; | ||
| 235 | } | ||
| 236 | |||
| 237 | appleir->prev_key_idx = 0; | ||
| 238 | |||
| 239 | if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) { | ||
| 240 | key_down(hid, appleir, appleir->current_key); | ||
| 241 | /* | ||
| 242 | * Remote doesn't do key up, either pull them up, in the test | ||
| 243 | * above, or here set a timer which pulls them up after 1/8 s | ||
| 244 | */ | ||
| 245 | mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); | ||
| 246 | goto out; | ||
| 247 | } | ||
| 248 | |||
| 249 | if (!memcmp(data, flatbattery, sizeof(flatbattery))) { | ||
| 250 | battery_flat(appleir); | ||
| 251 | /* Fall through */ | ||
| 252 | } | ||
| 253 | |||
| 254 | out: | ||
| 255 | /* let hidraw and hiddev handle the report */ | ||
| 256 | return 0; | ||
| 257 | } | ||
| 258 | |||
| 259 | static void appleir_input_configured(struct hid_device *hid, | ||
| 260 | struct hid_input *hidinput) | ||
| 261 | { | ||
| 262 | struct input_dev *input_dev = hidinput->input; | ||
| 263 | struct appleir *appleir = hid_get_drvdata(hid); | ||
| 264 | int i; | ||
| 265 | |||
| 266 | appleir->input_dev = input_dev; | ||
| 267 | |||
| 268 | input_dev->keycode = appleir->keymap; | ||
| 269 | input_dev->keycodesize = sizeof(unsigned short); | ||
| 270 | input_dev->keycodemax = ARRAY_SIZE(appleir->keymap); | ||
| 271 | |||
| 272 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | ||
| 273 | |||
| 274 | memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap)); | ||
| 275 | for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++) | ||
| 276 | set_bit(appleir->keymap[i], input_dev->keybit); | ||
| 277 | clear_bit(KEY_RESERVED, input_dev->keybit); | ||
| 278 | } | ||
| 279 | |||
| 280 | static int appleir_input_mapping(struct hid_device *hid, | ||
| 281 | struct hid_input *hi, struct hid_field *field, | ||
| 282 | struct hid_usage *usage, unsigned long **bit, int *max) | ||
| 283 | { | ||
| 284 | return -1; | ||
| 285 | } | ||
| 286 | |||
| 287 | static int appleir_probe(struct hid_device *hid, const struct hid_device_id *id) | ||
| 288 | { | ||
| 289 | int ret; | ||
| 290 | struct appleir *appleir; | ||
| 291 | |||
| 292 | appleir = kzalloc(sizeof(struct appleir), GFP_KERNEL); | ||
| 293 | if (!appleir) { | ||
| 294 | ret = -ENOMEM; | ||
| 295 | goto allocfail; | ||
| 296 | } | ||
| 297 | |||
| 298 | appleir->hid = hid; | ||
| 299 | |||
| 300 | spin_lock_init(&appleir->lock); | ||
| 301 | setup_timer(&appleir->key_up_timer, | ||
| 302 | key_up_tick, (unsigned long) appleir); | ||
| 303 | |||
| 304 | hid_set_drvdata(hid, appleir); | ||
| 305 | |||
| 306 | ret = hid_parse(hid); | ||
| 307 | if (ret) { | ||
| 308 | hid_err(hid, "parse failed\n"); | ||
| 309 | goto fail; | ||
| 310 | } | ||
| 311 | |||
| 312 | ret = hid_hw_start(hid, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE); | ||
| 313 | if (ret) { | ||
| 314 | hid_err(hid, "hw start failed\n"); | ||
| 315 | goto fail; | ||
| 316 | } | ||
| 317 | |||
| 318 | return 0; | ||
| 319 | fail: | ||
| 320 | kfree(appleir); | ||
| 321 | allocfail: | ||
| 322 | return ret; | ||
| 323 | } | ||
| 324 | |||
| 325 | static void appleir_remove(struct hid_device *hid) | ||
| 326 | { | ||
| 327 | struct appleir *appleir = hid_get_drvdata(hid); | ||
| 328 | hid_hw_stop(hid); | ||
| 329 | del_timer_sync(&appleir->key_up_timer); | ||
| 330 | kfree(appleir); | ||
| 331 | } | ||
| 332 | |||
| 333 | static const struct hid_device_id appleir_devices[] = { | ||
| 334 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, | ||
| 335 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) }, | ||
| 336 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) }, | ||
| 337 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | ||
| 338 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) }, | ||
| 339 | { } | ||
| 340 | }; | ||
| 341 | MODULE_DEVICE_TABLE(hid, appleir_devices); | ||
| 342 | |||
| 343 | static struct hid_driver appleir_driver = { | ||
| 344 | .name = "appleir", | ||
| 345 | .id_table = appleir_devices, | ||
| 346 | .raw_event = appleir_raw_event, | ||
| 347 | .input_configured = appleir_input_configured, | ||
| 348 | .probe = appleir_probe, | ||
| 349 | .remove = appleir_remove, | ||
| 350 | .input_mapping = appleir_input_mapping, | ||
| 351 | }; | ||
| 352 | module_hid_driver(appleir_driver); | ||
| @@ -29,14 +29,12 @@ · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/usb.h> | ||
| 33 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
| 34 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 35 | 34 | ||
| 36 | #include "hid-ids.h" | 35 | #include "hid-ids.h" |
| 37 | 36 | ||
| 38 | #ifdef CONFIG_HID_ACRUX_FF | 37 | #ifdef CONFIG_HID_ACRUX_FF |
| 39 | #include "usbhid/usbhid.h" | ||
| 40 | 38 | ||
| 41 | struct axff_device { | 39 | struct axff_device { |
| 42 | struct hid_report *report; | 40 | struct hid_report *report; |
| @@ -68,7 +66,7 @@ static int axff_play(struct input_dev *dev, void *data, struct ff_effect *effect · 25 unmodified lines | |||
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | dbg_hid("running with 0x%02x 0x%02x", left, right); | 68 | dbg_hid("running with 0x%02x 0x%02x", left, right); |
| 71 | usbhid_submit_report(hid, axff->report, USB_DIR_OUT); | 69 | hid_hw_request(hid, axff->report, HID_REQ_SET_REPORT); |
| 72 | 70 | ||
| 73 | return 0; | 71 | return 0; |
| 74 | } | 72 | } |
| @@ -114,7 +112,7 @@ static int axff_init(struct hid_device *hid) · 39 unmodified lines | |||
| 114 | goto err_free_mem; | 112 | goto err_free_mem; |
| 115 | 113 | ||
| 116 | axff->report = report; | 114 | axff->report = report; |
| 117 | usbhid_submit_report(hid, axff->report, USB_DIR_OUT); | 115 | hid_hw_request(hid, axff->report, HID_REQ_SET_REPORT); |
| 118 | 116 | ||
| 119 | hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun <x0r@dv-life.ru>\n"); | 117 | hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun <x0r@dv-life.ru>\n"); |
| 120 | 118 | ||
| @@ -728,8 +728,7 @@ static int hid_scan_report(struct hid_device *hid) · 727 unmodified lines | |||
| 728 | } else if (page == HID_UP_SENSOR && | 728 | } else if (page == HID_UP_SENSOR && |
| 729 | item.type == HID_ITEM_TYPE_MAIN && | 729 | item.type == HID_ITEM_TYPE_MAIN && |
| 730 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && | 730 | item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION && |
| 731 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL && | 731 | (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL) |
| 732 | (hid->bus == BUS_USB || hid->bus == BUS_I2C)) | ||
| 733 | hid->group = HID_GROUP_SENSOR_HUB; | 732 | hid->group = HID_GROUP_SENSOR_HUB; |
| 734 | } | 733 | } |
| 735 | 734 | ||
| @@ -1260,14 +1259,12 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i · 524 unmodified lines | |||
| 1260 | struct hid_report_enum *report_enum; | 1259 | struct hid_report_enum *report_enum; |
| 1261 | struct hid_driver *hdrv; | 1260 | struct hid_driver *hdrv; |
| 1262 | struct hid_report *report; | 1261 | struct hid_report *report; |
| 1263 | char *buf; | ||
| 1264 | unsigned int i; | ||
| 1265 | int ret = 0; | 1262 | int ret = 0; |
| 1266 | 1263 | ||
| 1267 | if (!hid) | 1264 | if (!hid) |
| 1268 | return -ENODEV; | 1265 | return -ENODEV; |
| 1269 | 1266 | ||
| 1270 | if (down_trylock(&hid->driver_lock)) | 1267 | if (down_trylock(&hid->driver_input_lock)) |
| 1271 | return -EBUSY; | 1268 | return -EBUSY; |
| 1272 | 1269 | ||
| 1273 | if (!hid->driver) { | 1270 | if (!hid->driver) { |
| @@ -1284,28 +1281,9 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i · 10 unmodified lines | |||
| 1284 | } | 1281 | } |
| 1285 | 1282 | ||
| 1286 | /* Avoid unnecessary overhead if debugfs is disabled */ | 1283 | /* Avoid unnecessary overhead if debugfs is disabled */ |
| 1287 | if (list_empty(&hid->debug_list)) | 1284 | if (!list_empty(&hid->debug_list)) |
| 1288 | goto nomem; | 1285 | hid_dump_report(hid, type, data, size); |
| 1289 | |||
| 1290 | buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); | ||
| 1291 | |||
| 1292 | if (!buf) | ||
| 1293 | goto nomem; | ||
| 1294 | |||
| 1295 | /* dump the report */ | ||
| 1296 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, | ||
| 1297 | "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un"); | ||
| 1298 | hid_debug_event(hid, buf); | ||
| 1299 | |||
| 1300 | for (i = 0; i < size; i++) { | ||
| 1301 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, | ||
| 1302 | " %02x", data[i]); | ||
| 1303 | hid_debug_event(hid, buf); | ||
| 1304 | } | ||
| 1305 | hid_debug_event(hid, "\n"); | ||
| 1306 | kfree(buf); | ||
| 1307 | 1286 | ||
| 1308 | nomem: | ||
| 1309 | report = hid_get_report(report_enum, data); | 1287 | report = hid_get_report(report_enum, data); |
| 1310 | 1288 | ||
| 1311 | if (!report) { | 1289 | if (!report) { |
| @@ -1324,7 +1302,7 @@ nomem: · 12 unmodified lines | |||
| 1324 | ret = hid_report_raw_event(hid, type, data, size, interrupt); | 1302 | ret = hid_report_raw_event(hid, type, data, size, interrupt); |
| 1325 | 1303 | ||
| 1326 | unlock: | 1304 | unlock: |
| 1327 | up(&hid->driver_lock); | 1305 | up(&hid->driver_input_lock); |
| 1328 | return ret; | 1306 | return ret; |
| 1329 | } | 1307 | } |
| 1330 | EXPORT_SYMBOL_GPL(hid_input_report); | 1308 | EXPORT_SYMBOL_GPL(hid_input_report); |
| @@ -1502,8 +1480,6 @@ static const struct hid_device_id hid_have_special_driver[] = { · 171 unmodified lines | |||
| 1502 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | 1480 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, |
| 1503 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, | 1481 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, |
| 1504 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, | 1482 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, |
| 1505 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) }, | ||
| 1506 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | ||
| 1507 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | 1483 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, |
| 1508 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, | 1484 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, |
| 1509 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, | 1485 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, |
| @@ -1527,6 +1503,11 @@ static const struct hid_device_id hid_have_special_driver[] = { · 17 unmodified lines | |||
| 1527 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, | 1503 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, |
| 1528 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, | 1504 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, |
| 1529 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, | 1505 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, |
| 1506 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, | ||
| 1507 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) }, | ||
| 1508 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) }, | ||
| 1509 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | ||
| 1510 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) }, | ||
| 1530 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, | 1511 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) }, |
| 1531 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, | 1512 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) }, |
| 1532 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, | 1513 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) }, |
| @@ -1654,6 +1635,7 @@ static const struct hid_device_id hid_have_special_driver[] = { · 121 unmodified lines | |||
| 1654 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, | 1635 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, |
| 1655 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, | 1636 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, |
| 1656 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, | 1637 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, |
| 1638 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) }, | ||
| 1657 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, | 1639 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, |
| 1658 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, | 1640 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, |
| 1659 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, | 1641 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, |
| @@ -1687,6 +1669,7 @@ static const struct hid_device_id hid_have_special_driver[] = { · 27 unmodified lines | |||
| 1687 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, | 1669 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, |
| 1688 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, | 1670 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, |
| 1689 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, | 1671 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, |
| 1672 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) }, | ||
| 1690 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, | 1673 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, |
| 1691 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, | 1674 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, |
| 1692 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, | 1675 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, |
| @@ -1747,6 +1730,7 @@ static const struct hid_device_id hid_have_special_driver[] = { · 54 unmodified lines | |||
| 1747 | 1730 | ||
| 1748 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, | 1731 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, |
| 1749 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, | 1732 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, |
| 1733 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, | ||
| 1750 | { } | 1734 | { } |
| 1751 | }; | 1735 | }; |
| 1752 | 1736 | ||
| @@ -1845,6 +1829,11 @@ static int hid_device_probe(struct device *dev) · 92 unmodified lines | |||
| 1845 | 1829 | ||
| 1846 | if (down_interruptible(&hdev->driver_lock)) | 1830 | if (down_interruptible(&hdev->driver_lock)) |
| 1847 | return -EINTR; | 1831 | return -EINTR; |
| 1832 | if (down_interruptible(&hdev->driver_input_lock)) { | ||
| 1833 | ret = -EINTR; | ||
| 1834 | goto unlock_driver_lock; | ||
| 1835 | } | ||
| 1836 | hdev->io_started = false; | ||
| 1848 | 1837 | ||
| 1849 | if (!hdev->driver) { | 1838 | if (!hdev->driver) { |
| 1850 | id = hid_match_device(hdev, hdrv); | 1839 | id = hid_match_device(hdev, hdrv); |
| @@ -1867,6 +1856,9 @@ static int hid_device_probe(struct device *dev) · 16 unmodified lines | |||
| 1867 | } | 1856 | } |
| 1868 | } | 1857 | } |
| 1869 | unlock: | 1858 | unlock: |
| 1859 | if (!hdev->io_started) | ||
| 1860 | up(&hdev->driver_input_lock); | ||
| 1861 | unlock_driver_lock: | ||
| 1870 | up(&hdev->driver_lock); | 1862 | up(&hdev->driver_lock); |
| 1871 | return ret; | 1863 | return ret; |
| 1872 | } | 1864 | } |
| @@ -1875,9 +1867,15 @@ static int hid_device_remove(struct device *dev) · 2 unmodified lines | |||
| 1875 | { | 1867 | { |
| 1876 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 1868 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
| 1877 | struct hid_driver *hdrv; | 1869 | struct hid_driver *hdrv; |
| 1870 | int ret = 0; | ||
| 1878 | 1871 | ||
| 1879 | if (down_interruptible(&hdev->driver_lock)) | 1872 | if (down_interruptible(&hdev->driver_lock)) |
| 1880 | return -EINTR; | 1873 | return -EINTR; |
| 1874 | if (down_interruptible(&hdev->driver_input_lock)) { | ||
| 1875 | ret = -EINTR; | ||
| 1876 | goto unlock_driver_lock; | ||
| 1877 | } | ||
| 1878 | hdev->io_started = false; | ||
| 1881 | 1879 | ||
| 1882 | hdrv = hdev->driver; | 1880 | hdrv = hdev->driver; |
| 1883 | if (hdrv) { | 1881 | if (hdrv) { |
| @@ -1889,8 +1887,11 @@ static int hid_device_remove(struct device *dev) · 5 unmodified lines | |||
| 1889 | hdev->driver = NULL; | 1887 | hdev->driver = NULL; |
| 1890 | } | 1888 | } |
| 1891 | 1889 | ||
| 1890 | if (!hdev->io_started) | ||
| 1891 | up(&hdev->driver_input_lock); | ||
| 1892 | unlock_driver_lock: | ||
| 1892 | up(&hdev->driver_lock); | 1893 | up(&hdev->driver_lock); |
| 1893 | return 0; | 1894 | return ret; |
| 1894 | } | 1895 | } |
| 1895 | 1896 | ||
| 1896 | static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | 1897 | static ssize_t modalias_show(struct device *dev, struct device_attribute *a, |
| @@ -2340,7 +2341,9 @@ struct hid_device *hid_allocate_device(void) · 443 unmodified lines | |||
| 2340 | 2341 | ||
| 2341 | init_waitqueue_head(&hdev->debug_wait); | 2342 | init_waitqueue_head(&hdev->debug_wait); |
| 2342 | INIT_LIST_HEAD(&hdev->debug_list); | 2343 | INIT_LIST_HEAD(&hdev->debug_list); |
| 2344 | mutex_init(&hdev->debug_list_lock); | ||
| 2343 | sema_init(&hdev->driver_lock, 1); | 2345 | sema_init(&hdev->driver_lock, 1); |
| 2346 | sema_init(&hdev->driver_input_lock, 1); | ||
| 2344 | 2347 | ||
| 2345 | return hdev; | 2348 | return hdev; |
| 2346 | } | 2349 | } |
| @@ -580,17 +580,49 @@ void hid_debug_event(struct hid_device *hdev, char *buf) · 579 unmodified lines | |||
| 580 | int i; | 580 | int i; |
| 581 | struct hid_debug_list *list; | 581 | struct hid_debug_list *list; |
| 582 | 582 | ||
| 583 | mutex_lock(&hdev->debug_list_lock); | ||
| 583 | list_for_each_entry(list, &hdev->debug_list, node) { | 584 | list_for_each_entry(list, &hdev->debug_list, node) { |
| 584 | for (i = 0; i < strlen(buf); i++) | 585 | for (i = 0; i < strlen(buf); i++) |
| 585 | list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] = | 586 | list->hid_debug_buf[(list->tail + i) % HID_DEBUG_BUFSIZE] = |
| 586 | buf[i]; | 587 | buf[i]; |
| 587 | list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; | 588 | list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; |
| 588 | } | 589 | } |
| 590 | mutex_unlock(&hdev->debug_list_lock); | ||
| 589 | 591 | ||
| 590 | wake_up_interruptible(&hdev->debug_wait); | 592 | wake_up_interruptible(&hdev->debug_wait); |
| 591 | } | 593 | } |
| 592 | EXPORT_SYMBOL_GPL(hid_debug_event); | 594 | EXPORT_SYMBOL_GPL(hid_debug_event); |
| 593 | 595 | ||
| 596 | void hid_dump_report(struct hid_device *hid, int type, u8 *data, | ||
| 597 | int size) | ||
| 598 | { | ||
| 599 | struct hid_report_enum *report_enum; | ||
| 600 | char *buf; | ||
| 601 | unsigned int i; | ||
| 602 | |||
| 603 | buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); | ||
| 604 | |||
| 605 | if (!buf) | ||
| 606 | return; | ||
| 607 | |||
| 608 | report_enum = hid->report_enum + type; | ||
| 609 | |||
| 610 | /* dump the report */ | ||
| 611 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, | ||
| 612 | "\nreport (size %u) (%snumbered) = ", size, | ||
| 613 | report_enum->numbered ? "" : "un"); | ||
| 614 | hid_debug_event(hid, buf); | ||
| 615 | |||
| 616 | for (i = 0; i < size; i++) { | ||
| 617 | snprintf(buf, HID_DEBUG_BUFSIZE - 1, | ||
| 618 | " %02x", data[i]); | ||
| 619 | hid_debug_event(hid, buf); | ||
| 620 | } | ||
| 621 | hid_debug_event(hid, "\n"); | ||
| 622 | kfree(buf); | ||
| 623 | } | ||
| 624 | EXPORT_SYMBOL_GPL(hid_dump_report); | ||
| 625 | |||
| 594 | void hid_dump_input(struct hid_device *hdev, struct hid_usage *usage, __s32 value) | 626 | void hid_dump_input(struct hid_device *hdev, struct hid_usage *usage, __s32 value) |
| 595 | { | 627 | { |
| 596 | char *buf; | 628 | char *buf; |
| @@ -960,7 +992,9 @@ static int hid_debug_events_open(struct inode *inode, struct file *file) · 363 unmodified lines | |||
| 960 | file->private_data = list; | 992 | file->private_data = list; |
| 961 | mutex_init(&list->read_mutex); | 993 | mutex_init(&list->read_mutex); |
| 962 | 994 | ||
| 995 | mutex_lock(&list->hdev->debug_list_lock); | ||
| 963 | list_add_tail(&list->node, &list->hdev->debug_list); | 996 | list_add_tail(&list->node, &list->hdev->debug_list); |
| 997 | mutex_unlock(&list->hdev->debug_list_lock); | ||
| 964 | 998 | ||
| 965 | out: | 999 | out: |
| 966 | return err; | 1000 | return err; |
| @@ -1055,7 +1089,9 @@ static int hid_debug_events_release(struct inode *inode, struct file *file) · 88 unmodified lines | |||
| 1055 | { | 1089 | { |
| 1056 | struct hid_debug_list *list = file->private_data; | 1090 | struct hid_debug_list *list = file->private_data; |
| 1057 | 1091 | ||
| 1092 | mutex_lock(&list->hdev->debug_list_lock); | ||
| 1058 | list_del(&list->node); | 1093 | list_del(&list->node); |
| 1094 | mutex_unlock(&list->hdev->debug_list_lock); | ||
| 1059 | kfree(list->hid_debug_buf); | 1095 | kfree(list->hid_debug_buf); |
| 1060 | kfree(list); | 1096 | kfree(list); |
| 1061 | 1097 | ||
| @@ -29,14 +29,12 @@ · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/usb.h> | ||
| 33 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
| 34 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 35 | 34 | ||
| 36 | #include "hid-ids.h" | 35 | #include "hid-ids.h" |
| 37 | 36 | ||
| 38 | #ifdef CONFIG_DRAGONRISE_FF | 37 | #ifdef CONFIG_DRAGONRISE_FF |
| 39 | #include "usbhid/usbhid.h" | ||
| 40 | 38 | ||
| 41 | struct drff_device { | 39 | struct drff_device { |
| 42 | struct hid_report *report; | 40 | struct hid_report *report; |
| @@ -68,7 +66,7 @@ static int drff_play(struct input_dev *dev, void *data, · 25 unmodified lines | |||
| 68 | drff->report->field[0]->value[1] = 0x00; | 66 | drff->report->field[0]->value[1] = 0x00; |
| 69 | drff->report->field[0]->value[2] = weak; | 67 | drff->report->field[0]->value[2] = weak; |
| 70 | drff->report->field[0]->value[4] = strong; | 68 | drff->report->field[0]->value[4] = strong; |
| 71 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); | 69 | hid_hw_request(hid, drff->report, HID_REQ_SET_REPORT); |
| 72 | 70 | ||
| 73 | drff->report->field[0]->value[0] = 0xfa; | 71 | drff->report->field[0]->value[0] = 0xfa; |
| 74 | drff->report->field[0]->value[1] = 0xfe; | 72 | drff->report->field[0]->value[1] = 0xfe; |
| @@ -80,7 +78,7 @@ static int drff_play(struct input_dev *dev, void *data, · 5 unmodified lines | |||
| 80 | drff->report->field[0]->value[2] = 0x00; | 78 | drff->report->field[0]->value[2] = 0x00; |
| 81 | drff->report->field[0]->value[4] = 0x00; | 79 | drff->report->field[0]->value[4] = 0x00; |
| 82 | dbg_hid("running with 0x%02x 0x%02x", strong, weak); | 80 | dbg_hid("running with 0x%02x 0x%02x", strong, weak); |
| 83 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); | 81 | hid_hw_request(hid, drff->report, HID_REQ_SET_REPORT); |
| 84 | 82 | ||
| 85 | return 0; | 83 | return 0; |
| 86 | } | 84 | } |
| @@ -132,7 +130,7 @@ static int drff_init(struct hid_device *hid) · 45 unmodified lines | |||
| 132 | drff->report->field[0]->value[4] = 0x00; | 130 | drff->report->field[0]->value[4] = 0x00; |
| 133 | drff->report->field[0]->value[5] = 0x00; | 131 | drff->report->field[0]->value[5] = 0x00; |
| 134 | drff->report->field[0]->value[6] = 0x00; | 132 | drff->report->field[0]->value[6] = 0x00; |
| 135 | usbhid_submit_report(hid, drff->report, USB_DIR_OUT); | 133 | hid_hw_request(hid, drff->report, HID_REQ_SET_REPORT); |
| 136 | 134 | ||
| 137 | hid_info(hid, "Force Feedback for DragonRise Inc. " | 135 | hid_info(hid, "Force Feedback for DragonRise Inc. " |
| 138 | "game controllers by Richard Walmsley <richwalm@gmail.com>\n"); | 136 | "game controllers by Richard Walmsley <richwalm@gmail.com>\n"); |
| @@ -23,11 +23,9 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | #include <linux/hid.h> | 24 | #include <linux/hid.h> |
| 25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
| 26 | #include <linux/usb.h> | ||
| 27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 28 | 27 | ||
| 29 | #include "hid-ids.h" | 28 | #include "hid-ids.h" |
| 30 | #include "usbhid/usbhid.h" | ||
| 31 | 29 | ||
| 32 | struct emsff_device { | 30 | struct emsff_device { |
| 33 | struct hid_report *report; | 31 | struct hid_report *report; |
| @@ -52,7 +50,7 @@ static int emsff_play(struct input_dev *dev, void *data, · 18 unmodified lines | |||
| 52 | emsff->report->field[0]->value[2] = strong; | 50 | emsff->report->field[0]->value[2] = strong; |
| 53 | 51 | ||
| 54 | dbg_hid("running with 0x%02x 0x%02x\n", strong, weak); | 52 | dbg_hid("running with 0x%02x 0x%02x\n", strong, weak); |
| 55 | usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); | 53 | hid_hw_request(hid, emsff->report, HID_REQ_SET_REPORT); |
| 56 | 54 | ||
| 57 | return 0; | 55 | return 0; |
| 58 | } | 56 | } |
| @@ -104,7 +102,7 @@ static int emsff_init(struct hid_device *hid) · 45 unmodified lines | |||
| 104 | emsff->report->field[0]->value[4] = 0x00; | 102 | emsff->report->field[0]->value[4] = 0x00; |
| 105 | emsff->report->field[0]->value[5] = 0x00; | 103 | emsff->report->field[0]->value[5] = 0x00; |
| 106 | emsff->report->field[0]->value[6] = 0x00; | 104 | emsff->report->field[0]->value[6] = 0x00; |
| 107 | usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); | 105 | hid_hw_request(hid, emsff->report, HID_REQ_SET_REPORT); |
| 108 | 106 | ||
| 109 | hid_info(hid, "force feedback for EMS based devices by Ignaz Forster <ignaz.forster@gmx.de>\n"); | 107 | hid_info(hid, "force feedback for EMS based devices by Ignaz Forster <ignaz.forster@gmx.de>\n"); |
| 110 | 108 | ||
| @@ -29,13 +29,11 @@ · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
| 31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| 32 | #include <linux/usb.h> | ||
| 33 | #include <linux/hid.h> | 32 | #include <linux/hid.h> |
| 34 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 35 | #include "hid-ids.h" | 34 | #include "hid-ids.h" |
| 36 | 35 | ||
| 37 | #ifdef CONFIG_GREENASIA_FF | 36 | #ifdef CONFIG_GREENASIA_FF |
| 38 | #include "usbhid/usbhid.h" | ||
| 39 | 37 | ||
| 40 | struct gaff_device { | 38 | struct gaff_device { |
| 41 | struct hid_report *report; | 39 | struct hid_report *report; |
| @@ -63,14 +61,14 @@ static int hid_gaff_play(struct input_dev *dev, void *data, · 21 unmodified lines | |||
| 63 | gaff->report->field[0]->value[4] = left; | 61 | gaff->report->field[0]->value[4] = left; |
| 64 | gaff->report->field[0]->value[5] = 0; | 62 | gaff->report->field[0]->value[5] = 0; |
| 65 | dbg_hid("running with 0x%02x 0x%02x", left, right); | 63 | dbg_hid("running with 0x%02x 0x%02x", left, right); |
| 66 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 64 | hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); |
| 67 | 65 | ||
| 68 | gaff->report->field[0]->value[0] = 0xfa; | 66 | gaff->report->field[0]->value[0] = 0xfa; |
| 69 | gaff->report->field[0]->value[1] = 0xfe; | 67 | gaff->report->field[0]->value[1] = 0xfe; |
| 70 | gaff->report->field[0]->value[2] = 0x0; | 68 | gaff->report->field[0]->value[2] = 0x0; |
| 71 | gaff->report->field[0]->value[4] = 0x0; | 69 | gaff->report->field[0]->value[4] = 0x0; |
| 72 | 70 | ||
| 73 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 71 | hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); |
| 74 | 72 | ||
| 75 | return 0; | 73 | return 0; |
| 76 | } | 74 | } |
| @@ -122,12 +120,12 @@ static int gaff_init(struct hid_device *hid) · 45 unmodified lines | |||
| 122 | gaff->report->field[0]->value[1] = 0x00; | 120 | gaff->report->field[0]->value[1] = 0x00; |
| 123 | gaff->report->field[0]->value[2] = 0x00; | 121 | gaff->report->field[0]->value[2] = 0x00; |
| 124 | gaff->report->field[0]->value[3] = 0x00; | 122 | gaff->report->field[0]->value[3] = 0x00; |
| 125 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 123 | hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); |
| 126 | 124 | ||
| 127 | gaff->report->field[0]->value[0] = 0xfa; | 125 | gaff->report->field[0]->value[0] = 0xfa; |
| 128 | gaff->report->field[0]->value[1] = 0xfe; | 126 | gaff->report->field[0]->value[1] = 0xfe; |
| 129 | 127 | ||
| 130 | usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); | 128 | hid_hw_request(hid, gaff->report, HID_REQ_SET_REPORT); |
| 131 | 129 | ||
| 132 | hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n"); | 130 | hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski <lukasz@lubojanski.info>\n"); |
| 133 | 131 | ||
| @@ -27,12 +27,10 @@ · 26 unmodified lines | |||
| 27 | #include <linux/input.h> | 27 | #include <linux/input.h> |
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 30 | #include <linux/usb.h> | ||
| 31 | 30 | ||
| 32 | #include "hid-ids.h" | 31 | #include "hid-ids.h" |
| 33 | 32 | ||
| 34 | #ifdef CONFIG_HOLTEK_FF | 33 | #ifdef CONFIG_HOLTEK_FF |
| 35 | #include "usbhid/usbhid.h" | ||
| 36 | 34 | ||
| 37 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
| 38 | MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>"); | 36 | MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>"); |
| @@ -102,7 +100,7 @@ static void holtekff_send(struct holtekff_device *holtekff, · 63 unmodified lines | |||
| 102 | 100 | ||
| 103 | dbg_hid("sending %*ph\n", 7, data); | 101 | dbg_hid("sending %*ph\n", 7, data); |
| 104 | 102 | ||
| 105 | usbhid_submit_report(hid, holtekff->field->report, USB_DIR_OUT); | 103 | hid_hw_request(hid, holtekff->field->report, HID_REQ_SET_REPORT); |
| 106 | } | 104 | } |
| 107 | 105 | ||
| 108 | static int holtekff_play(struct input_dev *dev, void *data, | 106 | static int holtekff_play(struct input_dev *dev, void *data, |
| @@ -159,7 +159,7 @@ static const struct icade_key icade_usage_table[30] = { · 158 unmodified lines | |||
| 159 | 159 | ||
| 160 | static const struct icade_key *icade_find_translation(u16 from) | 160 | static const struct icade_key *icade_find_translation(u16 from) |
| 161 | { | 161 | { |
| 162 | if (from < 0 || from > ICADE_MAX_USAGE) | 162 | if (from > ICADE_MAX_USAGE) |
| 163 | return NULL; | 163 | return NULL; |
| 164 | return &icade_usage_table[from]; | 164 | return &icade_usage_table[from]; |
| 165 | } | 165 | } |
| @@ -137,8 +137,11 @@ · 136 unmodified lines | |||
| 137 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 | 137 | #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 |
| 138 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 138 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
| 139 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 139 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
| 140 | #define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 | 140 | #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 |
| 141 | #define USB_DEVICE_ID_APPLE_IRCONTROL2 0x1440 | ||
| 142 | #define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241 | ||
| 141 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 | 143 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 |
| 144 | #define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243 | ||
| 142 | 145 | ||
| 143 | #define USB_VENDOR_ID_ASUS 0x0486 | 146 | #define USB_VENDOR_ID_ASUS 0x0486 |
| 144 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 | 147 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 |
| @@ -577,6 +580,7 @@ · 432 unmodified lines | |||
| 577 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b | 580 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b |
| 578 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d | 581 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d |
| 579 | #define USB_DEVICE_ID_MS_NE4K 0x00db | 582 | #define USB_DEVICE_ID_MS_NE4K 0x00db |
| 583 | #define USB_DEVICE_ID_MS_NE4K_JP 0x00dc | ||
| 580 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 | 584 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 |
| 581 | #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 | 585 | #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 |
| 582 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | 586 | #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 |
| @@ -613,6 +617,7 @@ · 30 unmodified lines | |||
| 613 | 617 | ||
| 614 | #define USB_VENDOR_ID_NINTENDO 0x057e | 618 | #define USB_VENDOR_ID_NINTENDO 0x057e |
| 615 | #define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306 | 619 | #define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306 |
| 620 | #define USB_DEVICE_ID_NINTENDO_WIIMOTE2 0x0330 | ||
| 616 | 621 | ||
| 617 | #define USB_VENDOR_ID_NOVATEK 0x0603 | 622 | #define USB_VENDOR_ID_NOVATEK 0x0603 |
| 618 | #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 | 623 | #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 |
| @@ -692,8 +697,10 @@ · 73 unmodified lines | |||
| 692 | #define USB_VENDOR_ID_ROCCAT 0x1e7d | 697 | #define USB_VENDOR_ID_ROCCAT 0x1e7d |
| 693 | #define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4 | 698 | #define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4 |
| 694 | #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c | 699 | #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c |
| 700 | #define USB_DEVICE_ID_ROCCAT_ISKUFX 0x3264 | ||
| 695 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced | 701 | #define USB_DEVICE_ID_ROCCAT_KONE 0x2ced |
| 696 | #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 | 702 | #define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 |
| 703 | #define USB_DEVICE_ID_ROCCAT_KONEPURE 0x2dbe | ||
| 697 | #define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22 | 704 | #define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22 |
| 698 | #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 | 705 | #define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 |
| 699 | #define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e | 706 | #define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e |
| @@ -1198,6 +1198,67 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid) · 1197 unmodified lines | |||
| 1198 | return hidinput; | 1198 | return hidinput; |
| 1199 | } | 1199 | } |
| 1200 | 1200 | ||
| 1201 | static bool hidinput_has_been_populated(struct hid_input *hidinput) | ||
| 1202 | { | ||
| 1203 | int i; | ||
| 1204 | unsigned long r = 0; | ||
| 1205 | |||
| 1206 | for (i = 0; i < BITS_TO_LONGS(EV_CNT); i++) | ||
| 1207 | r |= hidinput->input->evbit[i]; | ||
| 1208 | |||
| 1209 | for (i = 0; i < BITS_TO_LONGS(KEY_CNT); i++) | ||
| 1210 | r |= hidinput->input->keybit[i]; | ||
| 1211 | |||
| 1212 | for (i = 0; i < BITS_TO_LONGS(REL_CNT); i++) | ||
| 1213 | r |= hidinput->input->relbit[i]; | ||
| 1214 | |||
| 1215 | for (i = 0; i < BITS_TO_LONGS(ABS_CNT); i++) | ||
| 1216 | r |= hidinput->input->absbit[i]; | ||
| 1217 | |||
| 1218 | for (i = 0; i < BITS_TO_LONGS(MSC_CNT); i++) | ||
| 1219 | r |= hidinput->input->mscbit[i]; | ||
| 1220 | |||
| 1221 | for (i = 0; i < BITS_TO_LONGS(LED_CNT); i++) | ||
| 1222 | r |= hidinput->input->ledbit[i]; | ||
| 1223 | |||
| 1224 | for (i = 0; i < BITS_TO_LONGS(SND_CNT); i++) | ||
| 1225 | r |= hidinput->input->sndbit[i]; | ||
| 1226 | |||
| 1227 | for (i = 0; i < BITS_TO_LONGS(FF_CNT); i++) | ||
| 1228 | r |= hidinput->input->ffbit[i]; | ||
| 1229 | |||
| 1230 | for (i = 0; i < BITS_TO_LONGS(SW_CNT); i++) | ||
| 1231 | r |= hidinput->input->swbit[i]; | ||
| 1232 | |||
| 1233 | return !!r; | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | static void hidinput_cleanup_hidinput(struct hid_device *hid, | ||
| 1237 | struct hid_input *hidinput) | ||
| 1238 | { | ||
| 1239 | struct hid_report *report; | ||
| 1240 | int i, k; | ||
| 1241 | |||
| 1242 | list_del(&hidinput->list); | ||
| 1243 | input_free_device(hidinput->input); | ||
| 1244 | |||
| 1245 | for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { | ||
| 1246 | if (k == HID_OUTPUT_REPORT && | ||
| 1247 | hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORTS) | ||
| 1248 | continue; | ||
| 1249 | |||
| 1250 | list_for_each_entry(report, &hid->report_enum[k].report_list, | ||
| 1251 | list) { | ||
| 1252 | |||
| 1253 | for (i = 0; i < report->maxfield; i++) | ||
| 1254 | if (report->field[i]->hidinput == hidinput) | ||
| 1255 | report->field[i]->hidinput = NULL; | ||
| 1256 | } | ||
| 1257 | } | ||
| 1258 | |||
| 1259 | kfree(hidinput); | ||
| 1260 | } | ||
| 1261 | |||
| 1201 | /* | 1262 | /* |
| 1202 | * Register the input device; print a message. | 1263 | * Register the input device; print a message. |
| 1203 | * Configure the input layer interface | 1264 | * Configure the input layer interface |
| @@ -1249,6 +1310,10 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) · 45 unmodified lines | |||
| 1249 | hidinput_configure_usage(hidinput, report->field[i], | 1310 | hidinput_configure_usage(hidinput, report->field[i], |
| 1250 | report->field[i]->usage + j); | 1311 | report->field[i]->usage + j); |
| 1251 | 1312 | ||
| 1313 | if ((hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) && | ||
| 1314 | !hidinput_has_been_populated(hidinput)) | ||
| 1315 | continue; | ||
| 1316 | |||
| 1252 | if (hid->quirks & HID_QUIRK_MULTI_INPUT) { | 1317 | if (hid->quirks & HID_QUIRK_MULTI_INPUT) { |
| 1253 | /* This will leave hidinput NULL, so that it | 1318 | /* This will leave hidinput NULL, so that it |
| 1254 | * allocates another one if we have more inputs on | 1319 | * allocates another one if we have more inputs on |
| @@ -1265,6 +1330,18 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) · 10 unmodified lines | |||
| 1265 | } | 1330 | } |
| 1266 | } | 1331 | } |
| 1267 | 1332 | ||
| 1333 | if (hidinput && (hid->quirks & HID_QUIRK_NO_EMPTY_INPUT) && | ||
| 1334 | !hidinput_has_been_populated(hidinput)) { | ||
| 1335 | /* no need to register an input device not populated */ | ||
| 1336 | hidinput_cleanup_hidinput(hid, hidinput); | ||
| 1337 | hidinput = NULL; | ||
| 1338 | } | ||
| 1339 | |||
| 1340 | if (list_empty(&hid->inputs)) { | ||
| 1341 | hid_err(hid, "No inputs registered, leaving\n"); | ||
| 1342 | goto out_unwind; | ||
| 1343 | } | ||
| 1344 | |||
| 1268 | if (hidinput) { | 1345 | if (hidinput) { |
| 1269 | if (drv->input_configured) | 1346 | if (drv->input_configured) |
| 1270 | drv->input_configured(hid, hidinput); | 1347 | drv->input_configured(hid, hidinput); |
| @@ -16,8 +16,6 @@ · 15 unmodified lines | |||
| 16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 17 | #include <linux/hid.h> | 17 | #include <linux/hid.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/usb.h> | ||
| 20 | #include "usbhid/usbhid.h" | ||
| 21 | 19 | ||
| 22 | #include "hid-ids.h" | 20 | #include "hid-ids.h" |
| 23 | 21 | ||
| @@ -361,7 +359,7 @@ static int kye_tablet_enable(struct hid_device *hdev) · 337 unmodified lines | |||
| 361 | value[4] = 0x00; | 359 | value[4] = 0x00; |
| 362 | value[5] = 0x00; | 360 | value[5] = 0x00; |
| 363 | value[6] = 0x00; | 361 | value[6] = 0x00; |
| 364 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 362 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); |
| 365 | 363 | ||
| 366 | return 0; | 364 | return 0; |
| 367 | } | 365 | } |
| @@ -68,7 +68,7 @@ static int tpkbd_features_set(struct hid_device *hdev) · 67 unmodified lines | |||
| 68 | report->field[2]->value[0] = data_pointer->sensitivity; | 68 | report->field[2]->value[0] = data_pointer->sensitivity; |
| 69 | report->field[3]->value[0] = data_pointer->press_speed; | 69 | report->field[3]->value[0] = data_pointer->press_speed; |
| 70 | 70 | ||
| 71 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 71 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); |
| 72 | return 0; | 72 | return 0; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| @@ -228,8 +228,6 @@ static ssize_t pointer_press_speed_show(struct device *dev, · 153 unmodified lines | |||
| 228 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | 228 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); |
| 229 | struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev); | 229 | struct tpkbd_data_pointer *data_pointer = hid_get_drvdata(hdev); |
| 230 | 230 | ||
| 231 | data_pointer = hid_get_drvdata(hdev); | ||
| 232 | |||
| 233 | return snprintf(buf, PAGE_SIZE, "%u\n", | 231 | return snprintf(buf, PAGE_SIZE, "%u\n", |
| 234 | data_pointer->press_speed); | 232 | data_pointer->press_speed); |
| 235 | } | 233 | } |
| @@ -332,7 +330,7 @@ static void tpkbd_led_brightness_set(struct led_classdev *led_cdev, · 96 unmodified lines | |||
| 332 | report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; | 330 | report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; |
| 333 | report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; | 331 | report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; |
| 334 | report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; | 332 | report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; |
| 335 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 333 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); |
| 336 | } | 334 | } |
| 337 | 335 | ||
| 338 | static int tpkbd_probe_tp(struct hid_device *hdev) | 336 | static int tpkbd_probe_tp(struct hid_device *hdev) |
| @@ -23,10 +23,8 @@ · 22 unmodified lines | |||
| 23 | 23 | ||
| 24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/usb.h> | ||
| 27 | #include <linux/hid.h> | 26 | #include <linux/hid.h> |
| 28 | 27 | ||
| 29 | #include "usbhid/usbhid.h" | ||
| 30 | #include "hid-lg.h" | 28 | #include "hid-lg.h" |
| 31 | 29 | ||
| 32 | struct lg2ff_device { | 30 | struct lg2ff_device { |
| @@ -56,7 +54,7 @@ static int play_effect(struct input_dev *dev, void *data, · 23 unmodified lines | |||
| 56 | lg2ff->report->field[0]->value[4] = 0x00; | 54 | lg2ff->report->field[0]->value[4] = 0x00; |
| 57 | } | 55 | } |
| 58 | 56 | ||
| 59 | usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT); | 57 | hid_hw_request(hid, lg2ff->report, HID_REQ_SET_REPORT); |
| 60 | return 0; | 58 | return 0; |
| 61 | } | 59 | } |
| 62 | 60 | ||
| @@ -108,7 +106,7 @@ int lg2ff_init(struct hid_device *hid) · 45 unmodified lines | |||
| 108 | report->field[0]->value[5] = 0x00; | 106 | report->field[0]->value[5] = 0x00; |
| 109 | report->field[0]->value[6] = 0x00; | 107 | report->field[0]->value[6] = 0x00; |
| 110 | 108 | ||
| 111 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 109 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 112 | 110 | ||
| 113 | hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula <anssi.hannula@gmail.com>\n"); | 111 | hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula <anssi.hannula@gmail.com>\n"); |
| 114 | 112 | ||
| @@ -22,10 +22,8 @@ · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
| 25 | #include <linux/usb.h> | ||
| 26 | #include <linux/hid.h> | 25 | #include <linux/hid.h> |
| 27 | 26 | ||
| 28 | #include "usbhid/usbhid.h" | ||
| 29 | #include "hid-lg.h" | 27 | #include "hid-lg.h" |
| 30 | 28 | ||
| 31 | /* | 29 | /* |
| @@ -92,7 +90,7 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data, · 60 unmodified lines | |||
| 92 | report->field[0]->value[1] = (unsigned char)(-x); | 90 | report->field[0]->value[1] = (unsigned char)(-x); |
| 93 | report->field[0]->value[31] = (unsigned char)(-y); | 91 | report->field[0]->value[31] = (unsigned char)(-y); |
| 94 | 92 | ||
| 95 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 93 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 96 | break; | 94 | break; |
| 97 | } | 95 | } |
| 98 | return 0; | 96 | return 0; |
| @@ -118,7 +116,7 @@ static void hid_lg3ff_set_autocenter(struct input_dev *dev, u16 magnitude) · 19 unmodified lines | |||
| 118 | report->field[0]->value[33] = 0x7F; | 116 | report->field[0]->value[33] = 0x7F; |
| 119 | report->field[0]->value[34] = 0x7F; | 117 | report->field[0]->value[34] = 0x7F; |
| 120 | 118 | ||
| 121 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 119 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 122 | } | 120 | } |
| 123 | 121 | ||
| 124 | 122 | ||
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | 34 | ||
| 35 | #define DFGT_REV_MAJ 0x13 | 35 | #define DFGT_REV_MAJ 0x13 |
| 36 | #define DFGT_REV_MIN 0x22 | 36 | #define DFGT_REV_MIN 0x22 |
| 37 | #define DFGT2_REV_MIN 0x26 | ||
| 37 | #define DFP_REV_MAJ 0x11 | 38 | #define DFP_REV_MAJ 0x11 |
| 38 | #define DFP_REV_MIN 0x06 | 39 | #define DFP_REV_MIN 0x06 |
| 39 | #define FFEX_REV_MAJ 0x21 | 40 | #define FFEX_REV_MAJ 0x21 |
| @@ -125,6 +126,7 @@ static const struct lg4ff_native_cmd native_g27 = { · 85 unmodified lines | |||
| 125 | 126 | ||
| 126 | static const struct lg4ff_usb_revision lg4ff_revs[] = { | 127 | static const struct lg4ff_usb_revision lg4ff_revs[] = { |
| 127 | {DFGT_REV_MAJ, DFGT_REV_MIN, &native_dfgt}, /* Driving Force GT */ | 128 | {DFGT_REV_MAJ, DFGT_REV_MIN, &native_dfgt}, /* Driving Force GT */ |
| 129 | {DFGT_REV_MAJ, DFGT2_REV_MIN, &native_dfgt}, /* Driving Force GT v2 */ | ||
| 128 | {DFP_REV_MAJ, DFP_REV_MIN, &native_dfp}, /* Driving Force Pro */ | 130 | {DFP_REV_MAJ, DFP_REV_MIN, &native_dfp}, /* Driving Force Pro */ |
| 129 | {G25_REV_MAJ, G25_REV_MIN, &native_g25}, /* G25 */ | 131 | {G25_REV_MAJ, G25_REV_MIN, &native_g25}, /* G25 */ |
| 130 | {G27_REV_MAJ, G27_REV_MIN, &native_g27}, /* G27 */ | 132 | {G27_REV_MAJ, G27_REV_MIN, &native_g27}, /* G27 */ |
| @@ -202,7 +204,7 @@ static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *e · 71 unmodified lines | |||
| 202 | value[5] = 0x00; | 204 | value[5] = 0x00; |
| 203 | value[6] = 0x00; | 205 | value[6] = 0x00; |
| 204 | 206 | ||
| 205 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 207 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 206 | break; | 208 | break; |
| 207 | } | 209 | } |
| 208 | return 0; | 210 | return 0; |
| @@ -225,7 +227,7 @@ static void hid_lg4ff_set_autocenter_default(struct input_dev *dev, u16 magnitud · 16 unmodified lines | |||
| 225 | value[5] = 0x00; | 227 | value[5] = 0x00; |
| 226 | value[6] = 0x00; | 228 | value[6] = 0x00; |
| 227 | 229 | ||
| 228 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 230 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 229 | } | 231 | } |
| 230 | 232 | ||
| 231 | /* Sends autocentering command compatible with Formula Force EX */ | 233 | /* Sends autocentering command compatible with Formula Force EX */ |
| @@ -245,7 +247,7 @@ static void hid_lg4ff_set_autocenter_ffex(struct input_dev *dev, u16 magnitude) · 13 unmodified lines | |||
| 245 | value[5] = 0x00; | 247 | value[5] = 0x00; |
| 246 | value[6] = 0x00; | 248 | value[6] = 0x00; |
| 247 | 249 | ||
| 248 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 250 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 249 | } | 251 | } |
| 250 | 252 | ||
| 251 | /* Sends command to set range compatible with G25/G27/Driving Force GT */ | 253 | /* Sends command to set range compatible with G25/G27/Driving Force GT */ |
| @@ -265,7 +267,7 @@ static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range) · 13 unmodified lines | |||
| 265 | value[5] = 0x00; | 267 | value[5] = 0x00; |
| 266 | value[6] = 0x00; | 268 | value[6] = 0x00; |
| 267 | 269 | ||
| 268 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 270 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 269 | } | 271 | } |
| 270 | 272 | ||
| 271 | /* Sends commands to set range compatible with Driving Force Pro wheel */ | 273 | /* Sends commands to set range compatible with Driving Force Pro wheel */ |
| @@ -294,7 +296,7 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range) · 22 unmodified lines | |||
| 294 | report->field[0]->value[1] = 0x02; | 296 | report->field[0]->value[1] = 0x02; |
| 295 | full_range = 200; | 297 | full_range = 200; |
| 296 | } | 298 | } |
| 297 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 299 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 298 | 300 | ||
| 299 | /* Prepare "fine" limit command */ | 301 | /* Prepare "fine" limit command */ |
| 300 | value[0] = 0x81; | 302 | value[0] = 0x81; |
| @@ -306,7 +308,7 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range) · 5 unmodified lines | |||
| 306 | value[6] = 0x00; | 308 | value[6] = 0x00; |
| 307 | 309 | ||
| 308 | if (range == 200 || range == 900) { /* Do not apply any fine limit */ | 310 | if (range == 200 || range == 900) { /* Do not apply any fine limit */ |
| 309 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 311 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 310 | return; | 312 | return; |
| 311 | } | 313 | } |
| 312 | 314 | ||
| @@ -320,7 +322,7 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range) · 7 unmodified lines | |||
| 320 | value[5] = (start_right & 0xe) << 4 | (start_left & 0xe); | 322 | value[5] = (start_right & 0xe) << 4 | (start_left & 0xe); |
| 321 | value[6] = 0xff; | 323 | value[6] = 0xff; |
| 322 | 324 | ||
| 323 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 325 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 324 | } | 326 | } |
| 325 | 327 | ||
| 326 | static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd) | 328 | static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd) |
| @@ -334,7 +336,7 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n · 7 unmodified lines | |||
| 334 | for (i = 0; i < 7; i++) | 336 | for (i = 0; i < 7; i++) |
| 335 | report->field[0]->value[i] = cmd->cmd[j++]; | 337 | report->field[0]->value[i] = cmd->cmd[j++]; |
| 336 | 338 | ||
| 337 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 339 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 338 | } | 340 | } |
| 339 | } | 341 | } |
| 340 | 342 | ||
| @@ -410,7 +412,7 @@ static void lg4ff_set_leds(struct hid_device *hid, __u8 leds) · 69 unmodified lines | |||
| 410 | value[4] = 0x00; | 412 | value[4] = 0x00; |
| 411 | value[5] = 0x00; | 413 | value[5] = 0x00; |
| 412 | value[6] = 0x00; | 414 | value[6] = 0x00; |
| 413 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 415 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 414 | } | 416 | } |
| 415 | 417 | ||
| 416 | static void lg4ff_led_set_brightness(struct led_classdev *led_cdev, | 418 | static void lg4ff_led_set_brightness(struct led_classdev *led_cdev, |
| @@ -30,10 +30,8 @@ · 29 unmodified lines | |||
| 30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 30 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 31 | 31 | ||
| 32 | #include <linux/input.h> | 32 | #include <linux/input.h> |
| 33 | #include <linux/usb.h> | ||
| 34 | #include <linux/hid.h> | 33 | #include <linux/hid.h> |
| 35 | 34 | ||
| 36 | #include "usbhid/usbhid.h" | ||
| 37 | #include "hid-lg.h" | 35 | #include "hid-lg.h" |
| 38 | 36 | ||
| 39 | struct dev_type { | 37 | struct dev_type { |
| @@ -89,7 +87,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef · 49 unmodified lines | |||
| 89 | report->field[0]->value[2] = x; | 87 | report->field[0]->value[2] = x; |
| 90 | report->field[0]->value[3] = y; | 88 | report->field[0]->value[3] = y; |
| 91 | dbg_hid("(x, y)=(%04x, %04x)\n", x, y); | 89 | dbg_hid("(x, y)=(%04x, %04x)\n", x, y); |
| 92 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 90 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 93 | break; | 91 | break; |
| 94 | 92 | ||
| 95 | case FF_RUMBLE: | 93 | case FF_RUMBLE: |
| @@ -104,7 +102,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef · 8 unmodified lines | |||
| 104 | report->field[0]->value[2] = left; | 102 | report->field[0]->value[2] = left; |
| 105 | report->field[0]->value[3] = right; | 103 | report->field[0]->value[3] = right; |
| 106 | dbg_hid("(left, right)=(%04x, %04x)\n", left, right); | 104 | dbg_hid("(left, right)=(%04x, %04x)\n", left, right); |
| 107 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 105 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 108 | break; | 106 | break; |
| 109 | } | 107 | } |
| 110 | return 0; | 108 | return 0; |
| @@ -124,7 +122,7 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude) · 13 unmodified lines | |||
| 124 | *value++ = 0x80; | 122 | *value++ = 0x80; |
| 125 | *value++ = 0x00; | 123 | *value++ = 0x00; |
| 126 | *value = 0x00; | 124 | *value = 0x00; |
| 127 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 125 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 128 | } | 126 | } |
| 129 | 127 | ||
| 130 | int lgff_init(struct hid_device* hid) | 128 | int lgff_init(struct hid_device* hid) |
| @@ -27,7 +27,6 @@ · 26 unmodified lines | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/usb.h> | 28 | #include <linux/usb.h> |
| 29 | #include <asm/unaligned.h> | 29 | #include <asm/unaligned.h> |
| 30 | #include "usbhid/usbhid.h" | ||
| 31 | #include "hid-ids.h" | 30 | #include "hid-ids.h" |
| 32 | #include "hid-logitech-dj.h" | 31 | #include "hid-logitech-dj.h" |
| 33 | 32 | ||
| @@ -193,7 +192,6 @@ static struct hid_ll_driver logi_dj_ll_driver; · 159 unmodified lines | |||
| 193 | static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, | 192 | static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf, |
| 194 | size_t count, | 193 | size_t count, |
| 195 | unsigned char report_type); | 194 | unsigned char report_type); |
| 196 | static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev); | ||
| 197 | 195 | ||
| 198 | static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, | 196 | static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev, |
| 199 | struct dj_report *dj_report) | 197 | struct dj_report *dj_report) |
| @@ -234,7 +232,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, · 34 unmodified lines | |||
| 234 | if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] & | 232 | if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] & |
| 235 | SPFUNCTION_DEVICE_LIST_EMPTY) { | 233 | SPFUNCTION_DEVICE_LIST_EMPTY) { |
| 236 | dbg_hid("%s: device list is empty\n", __func__); | 234 | dbg_hid("%s: device list is empty\n", __func__); |
| 237 | djrcv_dev->querying_devices = false; | ||
| 238 | return; | 235 | return; |
| 239 | } | 236 | } |
| 240 | 237 | ||
| @@ -245,12 +242,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, · 4 unmodified lines | |||
| 245 | return; | 242 | return; |
| 246 | } | 243 | } |
| 247 | 244 | ||
| 248 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { | ||
| 249 | /* The device is already known. No need to reallocate it. */ | ||
| 250 | dbg_hid("%s: device is already known\n", __func__); | ||
| 251 | return; | ||
| 252 | } | ||
| 253 | |||
| 254 | dj_hiddev = hid_allocate_device(); | 245 | dj_hiddev = hid_allocate_device(); |
| 255 | if (IS_ERR(dj_hiddev)) { | 246 | if (IS_ERR(dj_hiddev)) { |
| 256 | dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n", | 247 | dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n", |
| @@ -314,7 +305,6 @@ static void delayedwork_callback(struct work_struct *work) · 57 unmodified lines | |||
| 314 | struct dj_report dj_report; | 305 | struct dj_report dj_report; |
| 315 | unsigned long flags; | 306 | unsigned long flags; |
| 316 | int count; | 307 | int count; |
| 317 | int retval; | ||
| 318 | 308 | ||
| 319 | dbg_hid("%s\n", __func__); | 309 | dbg_hid("%s\n", __func__); |
| 320 | 310 | ||
| @@ -347,25 +337,6 @@ static void delayedwork_callback(struct work_struct *work) · 26 unmodified lines | |||
| 347 | logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report); | 337 | logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report); |
| 348 | break; | 338 | break; |
| 349 | default: | 339 | default: |
| 350 | /* A normal report (i. e. not belonging to a pair/unpair notification) | ||
| 351 | * arriving here, means that the report arrived but we did not have a | ||
| 352 | * paired dj_device associated to the report's device_index, this | ||
| 353 | * means that the original "device paired" notification corresponding | ||
| 354 | * to this dj_device never arrived to this driver. The reason is that | ||
| 355 | * hid-core discards all packets coming from a device while probe() is | ||
| 356 | * executing. */ | ||
| 357 | if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) { | ||
| 358 | /* ok, we don't know the device, just re-ask the | ||
| 359 | * receiver for the list of connected devices. */ | ||
| 360 | retval = logi_dj_recv_query_paired_devices(djrcv_dev); | ||
| 361 | if (!retval) { | ||
| 362 | /* everything went fine, so just leave */ | ||
| 363 | break; | ||
| 364 | } | ||
| 365 | dev_err(&djrcv_dev->hdev->dev, | ||
| 366 | "%s:logi_dj_recv_query_paired_devices " | ||
| 367 | "error:%d\n", __func__, retval); | ||
| 368 | } | ||
| 369 | dbg_hid("%s: unexpected report type\n", __func__); | 340 | dbg_hid("%s: unexpected report type\n", __func__); |
| 370 | } | 341 | } |
| 371 | } | 342 | } |
| @@ -396,12 +367,6 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev, · 24 unmodified lines | |||
| 396 | if (!djdev) { | 367 | if (!djdev) { |
| 397 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" | 368 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" |
| 398 | " is NULL, index %d\n", dj_report->device_index); | 369 | " is NULL, index %d\n", dj_report->device_index); |
| 399 | kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); | ||
| 400 | |||
| 401 | if (schedule_work(&djrcv_dev->work) == 0) { | ||
| 402 | dbg_hid("%s: did not schedule the work item, was already " | ||
| 403 | "queued\n", __func__); | ||
| 404 | } | ||
| 405 | return; | 370 | return; |
| 406 | } | 371 | } |
| 407 | 372 | ||
| @@ -432,12 +397,6 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev, · 24 unmodified lines | |||
| 432 | if (dj_device == NULL) { | 397 | if (dj_device == NULL) { |
| 433 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" | 398 | dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]" |
| 434 | " is NULL, index %d\n", dj_report->device_index); | 399 | " is NULL, index %d\n", dj_report->device_index); |
| 435 | kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report)); | ||
| 436 | |||
| 437 | if (schedule_work(&djrcv_dev->work) == 0) { | ||
| 438 | dbg_hid("%s: did not schedule the work item, was already " | ||
| 439 | "queued\n", __func__); | ||
| 440 | } | ||
| 441 | return; | 400 | return; |
| 442 | } | 401 | } |
| 443 | 402 | ||
| @@ -475,7 +434,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, · 31 unmodified lines | |||
| 475 | for (i = 0; i < report->field[0]->report_count; i++) | 434 | for (i = 0; i < report->field[0]->report_count; i++) |
| 476 | report->field[0]->value[i] = data[i]; | 435 | report->field[0]->value[i] = data[i]; |
| 477 | 436 | ||
| 478 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 437 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); |
| 479 | 438 | ||
| 480 | return 0; | 439 | return 0; |
| 481 | } | 440 | } |
| @@ -485,10 +444,6 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) · 3 unmodified lines | |||
| 485 | struct dj_report *dj_report; | 444 | struct dj_report *dj_report; |
| 486 | int retval; | 445 | int retval; |
| 487 | 446 | ||
| 488 | /* no need to protect djrcv_dev->querying_devices */ | ||
| 489 | if (djrcv_dev->querying_devices) | ||
| 490 | return 0; | ||
| 491 | |||
| 492 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); | 447 | dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); |
| 493 | if (!dj_report) | 448 | if (!dj_report) |
| 494 | return -ENOMEM; | 449 | return -ENOMEM; |
| @@ -500,7 +455,6 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) · 5 unmodified lines | |||
| 500 | return retval; | 455 | return retval; |
| 501 | } | 456 | } |
| 502 | 457 | ||
| 503 | |||
| 504 | static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, | 458 | static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, |
| 505 | unsigned timeout) | 459 | unsigned timeout) |
| 506 | { | 460 | { |
| @@ -644,7 +598,7 @@ static int logi_dj_ll_input_event(struct input_dev *dev, unsigned int type, · 137 unmodified lines | |||
| 644 | hid_set_field(report->field[0], 1, REPORT_TYPE_LEDS); | 598 | hid_set_field(report->field[0], 1, REPORT_TYPE_LEDS); |
| 645 | hid_set_field(report->field[0], 2, data[1]); | 599 | hid_set_field(report->field[0], 2, data[1]); |
| 646 | 600 | ||
| 647 | usbhid_submit_report(dj_rcv_hiddev, report, USB_DIR_OUT); | 601 | hid_hw_request(dj_rcv_hiddev, report, HID_REQ_SET_REPORT); |
| 648 | 602 | ||
| 649 | return 0; | 603 | return 0; |
| 650 | 604 | ||
| @@ -809,6 +763,9 @@ static int logi_dj_probe(struct hid_device *hdev, · 158 unmodified lines | |||
| 809 | goto llopen_failed; | 763 | goto llopen_failed; |
| 810 | } | 764 | } |
| 811 | 765 | ||
| 766 | /* Allow incoming packets to arrive: */ | ||
| 767 | hid_device_io_start(hdev); | ||
| 768 | |||
| 812 | retval = logi_dj_recv_query_paired_devices(djrcv_dev); | 769 | retval = logi_dj_recv_query_paired_devices(djrcv_dev); |
| 813 | if (retval < 0) { | 770 | if (retval < 0) { |
| 814 | dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices " | 771 | dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices " |
| @@ -101,7 +101,6 @@ struct dj_receiver_dev { · 100 unmodified lines | |||
| 101 | struct work_struct work; | 101 | struct work_struct work; |
| 102 | struct kfifo notif_fifo; | 102 | struct kfifo notif_fifo; |
| 103 | spinlock_t lock; | 103 | spinlock_t lock; |
| 104 | bool querying_devices; | ||
| 105 | }; | 104 | }; |
| 106 | 105 | ||
| 107 | struct dj_device { | 106 | struct dj_device { |
| @@ -19,7 +19,6 @@ · 18 unmodified lines | |||
| 19 | #include <linux/input/mt.h> | 19 | #include <linux/input/mt.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/usb.h> | ||
| 23 | 22 | ||
| 24 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
| 25 | 24 | ||
| @@ -195,6 +195,8 @@ static const struct hid_device_id ms_devices[] = { · 194 unmodified lines | |||
| 195 | .driver_data = MS_HIDINPUT }, | 195 | .driver_data = MS_HIDINPUT }, |
| 196 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K), | 196 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K), |
| 197 | .driver_data = MS_ERGONOMY }, | 197 | .driver_data = MS_ERGONOMY }, |
| 198 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP), | ||
| 199 | .driver_data = MS_ERGONOMY }, | ||
| 198 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), | 200 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K), |
| 199 | .driver_data = MS_ERGONOMY | MS_RDESC }, | 201 | .driver_data = MS_ERGONOMY | MS_RDESC }, |
| 200 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), | 202 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), |
| @@ -2,8 +2,9 @@ · 1 unmodified line | |||
| 2 | * HID driver for multitouch panels | 2 | * HID driver for multitouch panels |
| 3 | * | 3 | * |
| 4 | * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> | 4 | * Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr> |
| 5 | * Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com> | 5 | * Copyright (c) 2010-2013 Benjamin Tissoires <benjamin.tissoires@gmail.com> |
| 6 | * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France | 6 | * Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France |
| 7 | * Copyright (c) 2012-2013 Red Hat, Inc | ||
| 7 | * | 8 | * |
| 8 | * This code is partly based on hid-egalax.c: | 9 | * This code is partly based on hid-egalax.c: |
| 9 | * | 10 | * |
| @@ -26,13 +27,24 @@ · 16 unmodified lines | |||
| 26 | * any later version. | 27 | * any later version. |
| 27 | */ | 28 | */ |
| 28 | 29 | ||
| 30 | /* | ||
| 31 | * This driver is regularly tested thanks to the tool hid-test[1]. | ||
| 32 | * This tool relies on hid-replay[2] and a database of hid devices[3]. | ||
| 33 | * Please run these regression tests before patching this module so that | ||
| 34 | * your patch won't break existing known devices. | ||
| 35 | * | ||
| 36 | * [1] https://github.com/bentiss/hid-test | ||
| 37 | * [2] https://github.com/bentiss/hid-replay | ||
| 38 | * [3] https://github.com/bentiss/hid-devices | ||
| 39 | */ | ||
| 40 | |||
| 29 | #include <linux/device.h> | 41 | #include <linux/device.h> |
| 30 | #include <linux/hid.h> | 42 | #include <linux/hid.h> |
| 31 | #include <linux/module.h> | 43 | #include <linux/module.h> |
| 32 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
| 33 | #include <linux/usb.h> | 45 | #include <linux/usb.h> |
| 34 | #include <linux/input/mt.h> | 46 | #include <linux/input/mt.h> |
| 35 | #include "usbhid/usbhid.h" | 47 | #include <linux/string.h> |
| 36 | 48 | ||
| 37 | 49 | ||
| 38 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); | 50 | MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); |
| @@ -86,9 +98,9 @@ struct mt_device { · 47 unmodified lines | |||
| 86 | multitouch fields */ | 98 | multitouch fields */ |
| 87 | int cc_index; /* contact count field index in the report */ | 99 | int cc_index; /* contact count field index in the report */ |
| 88 | int cc_value_index; /* contact count value index in the field */ | 100 | int cc_value_index; /* contact count value index in the field */ |
| 89 | unsigned last_field_index; /* last field index of the report */ | ||
| 90 | unsigned last_slot_field; /* the last field of a slot */ | 101 | unsigned last_slot_field; /* the last field of a slot */ |
| 91 | unsigned mt_report_id; /* the report ID of the multitouch device */ | 102 | unsigned mt_report_id; /* the report ID of the multitouch device */ |
| 103 | unsigned pen_report_id; /* the report ID of the pen device */ | ||
| 92 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ | 104 | __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ |
| 93 | __s8 inputmode_index; /* InputMode HID feature index in the report */ | 105 | __s8 inputmode_index; /* InputMode HID feature index in the report */ |
| 94 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, | 106 | __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, |
| @@ -104,6 +116,9 @@ struct mt_device { · 9 unmodified lines | |||
| 104 | unsigned mt_flags; /* flags to pass to input-mt */ | 116 | unsigned mt_flags; /* flags to pass to input-mt */ |
| 105 | }; | 117 | }; |
| 106 | 118 | ||
| 119 | static void mt_post_parse_default_settings(struct mt_device *td); | ||
| 120 | static void mt_post_parse(struct mt_device *td); | ||
| 121 | |||
| 107 | /* classes of device behavior */ | 122 | /* classes of device behavior */ |
| 108 | #define MT_CLS_DEFAULT 0x0001 | 123 | #define MT_CLS_DEFAULT 0x0001 |
| 109 | 124 | ||
| @@ -246,6 +261,14 @@ static struct mt_class mt_classes[] = { · 136 unmodified lines | |||
| 246 | { } | 261 | { } |
| 247 | }; | 262 | }; |
| 248 | 263 | ||
| 264 | static void mt_free_input_name(struct hid_input *hi) | ||
| 265 | { | ||
| 266 | struct hid_device *hdev = hi->report->device; | ||
| 267 | |||
| 268 | if (hi->input->name != hdev->name) | ||
| 269 | kfree(hi->input->name); | ||
| 270 | } | ||
| 271 | |||
| 249 | static ssize_t mt_show_quirks(struct device *dev, | 272 | static ssize_t mt_show_quirks(struct device *dev, |
| 250 | struct device_attribute *attr, | 273 | struct device_attribute *attr, |
| 251 | char *buf) | 274 | char *buf) |
| @@ -354,7 +377,53 @@ static void mt_store_field(struct hid_usage *usage, struct mt_device *td, · 102 unmodified lines | |||
| 354 | f->usages[f->length++] = usage->hid; | 377 | f->usages[f->length++] = usage->hid; |
| 355 | } | 378 | } |
| 356 | 379 | ||
| 357 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 380 | static int mt_pen_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
| 381 | struct hid_field *field, struct hid_usage *usage, | ||
| 382 | unsigned long **bit, int *max) | ||
| 383 | { | ||
| 384 | struct mt_device *td = hid_get_drvdata(hdev); | ||
| 385 | |||
| 386 | td->pen_report_id = field->report->id; | ||
| 387 | |||
| 388 | return 0; | ||
| 389 | } | ||
| 390 | |||
| 391 | static int mt_pen_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
| 392 | struct hid_field *field, struct hid_usage *usage, | ||
| 393 | unsigned long **bit, int *max) | ||
| 394 | { | ||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | static int mt_pen_event(struct hid_device *hid, struct hid_field *field, | ||
| 399 | struct hid_usage *usage, __s32 value) | ||
| 400 | { | ||
| 401 | /* let hid-input handle it */ | ||
| 402 | return 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | static void mt_pen_report(struct hid_device *hid, struct hid_report *report) | ||
| 406 | { | ||
| 407 | struct hid_field *field = report->field[0]; | ||
| 408 | |||
| 409 | input_sync(field->hidinput->input); | ||
| 410 | } | ||
| 411 | |||
| 412 | static void mt_pen_input_configured(struct hid_device *hdev, | ||
| 413 | struct hid_input *hi) | ||
| 414 | { | ||
| 415 | char *name = kzalloc(strlen(hi->input->name) + 5, GFP_KERNEL); | ||
| 416 | if (name) { | ||
| 417 | sprintf(name, "%s Pen", hi->input->name); | ||
| 418 | mt_free_input_name(hi); | ||
| 419 | hi->input->name = name; | ||
| 420 | } | ||
| 421 | |||
| 422 | /* force BTN_STYLUS to allow tablet matching in udev */ | ||
| 423 | __set_bit(BTN_STYLUS, hi->input->keybit); | ||
| 424 | } | ||
| 425 | |||
| 426 | static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
| 358 | struct hid_field *field, struct hid_usage *usage, | 427 | struct hid_field *field, struct hid_usage *usage, |
| 359 | unsigned long **bit, int *max) | 428 | unsigned long **bit, int *max) |
| 360 | { | 429 | { |
| @@ -363,13 +432,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 2 unmodified lines | |||
| 363 | int code; | 432 | int code; |
| 364 | struct hid_usage *prev_usage = NULL; | 433 | struct hid_usage *prev_usage = NULL; |
| 365 | 434 | ||
| 366 | /* Only map fields from TouchScreen or TouchPad collections. | ||
| 367 | * We need to ignore fields that belong to other collections | ||
| 368 | * such as Mouse that might have the same GenericDesktop usages. */ | ||
| 369 | if (field->application == HID_DG_TOUCHSCREEN) | 435 | if (field->application == HID_DG_TOUCHSCREEN) |
| 370 | td->mt_flags |= INPUT_MT_DIRECT; | 436 | td->mt_flags |= INPUT_MT_DIRECT; |
| 371 | else if (field->application != HID_DG_TOUCHPAD) | ||
| 372 | return 0; | ||
| 373 | 437 | ||
| 374 | /* | 438 | /* |
| 375 | * Model touchscreens providing buttons as touchpads. | 439 | * Model touchscreens providing buttons as touchpads. |
| @@ -378,12 +442,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 2 unmodified lines | |||
| 378 | (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) | 442 | (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) |
| 379 | td->mt_flags |= INPUT_MT_POINTER; | 443 | td->mt_flags |= INPUT_MT_POINTER; |
| 380 | 444 | ||
| 381 | /* eGalax devices provide a Digitizer.Stylus input which overrides | ||
| 382 | * the correct Digitizers.Finger X/Y ranges. | ||
| 383 | * Let's just ignore this input. */ | ||
| 384 | if (field->physical == HID_DG_STYLUS) | ||
| 385 | return -1; | ||
| 386 | |||
| 387 | if (usage->usage_index) | 445 | if (usage->usage_index) |
| 388 | prev_usage = &field->usage[usage->usage_index - 1]; | 446 | prev_usage = &field->usage[usage->usage_index - 1]; |
| 389 | 447 | ||
| @@ -405,7 +463,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 15 unmodified lines | |||
| 405 | } | 463 | } |
| 406 | 464 | ||
| 407 | mt_store_field(usage, td, hi); | 465 | mt_store_field(usage, td, hi); |
| 408 | td->last_field_index = field->index; | ||
| 409 | return 1; | 466 | return 1; |
| 410 | case HID_GD_Y: | 467 | case HID_GD_Y: |
| 411 | if (prev_usage && (prev_usage->hid == usage->hid)) { | 468 | if (prev_usage && (prev_usage->hid == usage->hid)) { |
| @@ -421,7 +478,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 9 unmodified lines | |||
| 421 | } | 478 | } |
| 422 | 479 | ||
| 423 | mt_store_field(usage, td, hi); | 480 | mt_store_field(usage, td, hi); |
| 424 | td->last_field_index = field->index; | ||
| 425 | return 1; | 481 | return 1; |
| 426 | } | 482 | } |
| 427 | return 0; | 483 | return 0; |
| @@ -436,21 +492,17 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 8 unmodified lines | |||
| 436 | ABS_MT_DISTANCE, 0, 1, 0, 0); | 492 | ABS_MT_DISTANCE, 0, 1, 0, 0); |
| 437 | } | 493 | } |
| 438 | mt_store_field(usage, td, hi); | 494 | mt_store_field(usage, td, hi); |
| 439 | td->last_field_index = field->index; | ||
| 440 | return 1; | 495 | return 1; |
| 441 | case HID_DG_CONFIDENCE: | 496 | case HID_DG_CONFIDENCE: |
| 442 | mt_store_field(usage, td, hi); | 497 | mt_store_field(usage, td, hi); |
| 443 | td->last_field_index = field->index; | ||
| 444 | return 1; | 498 | return 1; |
| 445 | case HID_DG_TIPSWITCH: | 499 | case HID_DG_TIPSWITCH: |
| 446 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 500 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
| 447 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | 501 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); |
| 448 | mt_store_field(usage, td, hi); | 502 | mt_store_field(usage, td, hi); |
| 449 | td->last_field_index = field->index; | ||
| 450 | return 1; | 503 | return 1; |
| 451 | case HID_DG_CONTACTID: | 504 | case HID_DG_CONTACTID: |
| 452 | mt_store_field(usage, td, hi); | 505 | mt_store_field(usage, td, hi); |
| 453 | td->last_field_index = field->index; | ||
| 454 | td->touches_by_report++; | 506 | td->touches_by_report++; |
| 455 | td->mt_report_id = field->report->id; | 507 | td->mt_report_id = field->report->id; |
| 456 | return 1; | 508 | return 1; |
| @@ -461,7 +513,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 4 unmodified lines | |||
| 461 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, | 513 | set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, |
| 462 | cls->sn_width); | 514 | cls->sn_width); |
| 463 | mt_store_field(usage, td, hi); | 515 | mt_store_field(usage, td, hi); |
| 464 | td->last_field_index = field->index; | ||
| 465 | return 1; | 516 | return 1; |
| 466 | case HID_DG_HEIGHT: | 517 | case HID_DG_HEIGHT: |
| 467 | hid_map_usage(hi, usage, bit, max, | 518 | hid_map_usage(hi, usage, bit, max, |
| @@ -473,7 +524,6 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 5 unmodified lines | |||
| 473 | ABS_MT_ORIENTATION, 0, 1, 0, 0); | 524 | ABS_MT_ORIENTATION, 0, 1, 0, 0); |
| 474 | } | 525 | } |
| 475 | mt_store_field(usage, td, hi); | 526 | mt_store_field(usage, td, hi); |
| 476 | td->last_field_index = field->index; | ||
| 477 | return 1; | 527 | return 1; |
| 478 | case HID_DG_TIPPRESSURE: | 528 | case HID_DG_TIPPRESSURE: |
| 479 | hid_map_usage(hi, usage, bit, max, | 529 | hid_map_usage(hi, usage, bit, max, |
| @@ -481,17 +531,14 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 1 unmodified line | |||
| 481 | set_abs(hi->input, ABS_MT_PRESSURE, field, | 531 | set_abs(hi->input, ABS_MT_PRESSURE, field, |
| 482 | cls->sn_pressure); | 532 | cls->sn_pressure); |
| 483 | mt_store_field(usage, td, hi); | 533 | mt_store_field(usage, td, hi); |
| 484 | td->last_field_index = field->index; | ||
| 485 | return 1; | 534 | return 1; |
| 486 | case HID_DG_CONTACTCOUNT: | 535 | case HID_DG_CONTACTCOUNT: |
| 487 | td->cc_index = field->index; | 536 | td->cc_index = field->index; |
| 488 | td->cc_value_index = usage->usage_index; | 537 | td->cc_value_index = usage->usage_index; |
| 489 | td->last_field_index = field->index; | ||
| 490 | return 1; | 538 | return 1; |
| 491 | case HID_DG_CONTACTMAX: | 539 | case HID_DG_CONTACTMAX: |
| 492 | /* we don't set td->last_slot_field as contactcount and | 540 | /* we don't set td->last_slot_field as contactcount and |
| 493 | * contact max are global to the report */ | 541 | * contact max are global to the report */ |
| 494 | td->last_field_index = field->index; | ||
| 495 | return -1; | 542 | return -1; |
| 496 | case HID_DG_TOUCH: | 543 | case HID_DG_TOUCH: |
| 497 | /* Legacy devices use TIPSWITCH and not TOUCH. | 544 | /* Legacy devices use TIPSWITCH and not TOUCH. |
| @@ -515,7 +562,7 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 17 unmodified lines | |||
| 515 | return 0; | 562 | return 0; |
| 516 | } | 563 | } |
| 517 | 564 | ||
| 518 | static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 565 | static int mt_touch_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
| 519 | struct hid_field *field, struct hid_usage *usage, | 566 | struct hid_field *field, struct hid_usage *usage, |
| 520 | unsigned long **bit, int *max) | 567 | unsigned long **bit, int *max) |
| 521 | { | 568 | { |
| @@ -606,7 +653,7 @@ static void mt_sync_frame(struct mt_device *td, struct input_dev *input) · 84 unmodified lines | |||
| 606 | td->num_received = 0; | 653 | td->num_received = 0; |
| 607 | } | 654 | } |
| 608 | 655 | ||
| 609 | static int mt_event(struct hid_device *hid, struct hid_field *field, | 656 | static int mt_touch_event(struct hid_device *hid, struct hid_field *field, |
| 610 | struct hid_usage *usage, __s32 value) | 657 | struct hid_usage *usage, __s32 value) |
| 611 | { | 658 | { |
| 612 | /* we will handle the hidinput part later, now remains hiddev */ | 659 | /* we will handle the hidinput part later, now remains hiddev */ |
| @@ -680,29 +727,19 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field, · 67 unmodified lines | |||
| 680 | if (usage->usage_index + 1 == field->report_count) { | 727 | if (usage->usage_index + 1 == field->report_count) { |
| 681 | /* we only take into account the last report. */ | 728 | /* we only take into account the last report. */ |
| 682 | if (usage->hid == td->last_slot_field) | 729 | if (usage->hid == td->last_slot_field) |
| 683 | mt_complete_slot(td, input); | 730 | mt_complete_slot(td, field->hidinput->input); |
| 684 | |||
| 685 | if (field->index == td->last_field_index | ||
| 686 | && td->num_received >= td->num_expected) | ||
| 687 | mt_sync_frame(td, field->hidinput->input); | ||
| 688 | } | 731 | } |
| 689 | 732 | ||
| 690 | } | 733 | } |
| 691 | } | 734 | } |
| 692 | 735 | ||
| 693 | static void mt_report(struct hid_device *hid, struct hid_report *report) | 736 | static void mt_touch_report(struct hid_device *hid, struct hid_report *report) |
| 694 | { | 737 | { |
| 695 | struct mt_device *td = hid_get_drvdata(hid); | 738 | struct mt_device *td = hid_get_drvdata(hid); |
| 696 | struct hid_field *field; | 739 | struct hid_field *field; |
| 697 | unsigned count; | 740 | unsigned count; |
| 698 | int r, n; | 741 | int r, n; |
| 699 | 742 | ||
| 700 | if (report->id != td->mt_report_id) | ||
| 701 | return; | ||
| 702 | |||
| 703 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | ||
| 704 | return; | ||
| 705 | |||
| 706 | /* | 743 | /* |
| 707 | * Includes multi-packet support where subsequent | 744 | * Includes multi-packet support where subsequent |
| 708 | * packets are sent with zero contactcount. | 745 | * packets are sent with zero contactcount. |
| @@ -725,6 +762,91 @@ static void mt_report(struct hid_device *hid, struct hid_report *report) · 16 unmodified lines | |||
| 725 | mt_process_mt_event(hid, field, &field->usage[n], | 762 | mt_process_mt_event(hid, field, &field->usage[n], |
| 726 | field->value[n]); | 763 | field->value[n]); |
| 727 | } | 764 | } |
| 765 | |||
| 766 | if (td->num_received >= td->num_expected) | ||
| 767 | mt_sync_frame(td, report->field[0]->hidinput->input); | ||
| 768 | } | ||
| 769 | |||
| 770 | static void mt_touch_input_configured(struct hid_device *hdev, | ||
| 771 | struct hid_input *hi) | ||
| 772 | { | ||
| 773 | struct mt_device *td = hid_get_drvdata(hdev); | ||
| 774 | struct mt_class *cls = &td->mtclass; | ||
| 775 | struct input_dev *input = hi->input; | ||
| 776 | |||
| 777 | if (!td->maxcontacts) | ||
| 778 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | ||
| 779 | |||
| 780 | mt_post_parse(td); | ||
| 781 | if (td->serial_maybe) | ||
| 782 | mt_post_parse_default_settings(td); | ||
| 783 | |||
| 784 | if (cls->is_indirect) | ||
| 785 | td->mt_flags |= INPUT_MT_POINTER; | ||
| 786 | |||
| 787 | if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) | ||
| 788 | td->mt_flags |= INPUT_MT_DROP_UNUSED; | ||
| 789 | |||
| 790 | input_mt_init_slots(input, td->maxcontacts, td->mt_flags); | ||
| 791 | |||
| 792 | td->mt_flags = 0; | ||
| 793 | } | ||
| 794 | |||
| 795 | static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, | ||
| 796 | struct hid_field *field, struct hid_usage *usage, | ||
| 797 | unsigned long **bit, int *max) | ||
| 798 | { | ||
| 799 | /* Only map fields from TouchScreen or TouchPad collections. | ||
| 800 | * We need to ignore fields that belong to other collections | ||
| 801 | * such as Mouse that might have the same GenericDesktop usages. */ | ||
| 802 | if (field->application != HID_DG_TOUCHSCREEN && | ||
| 803 | field->application != HID_DG_PEN && | ||
| 804 | field->application != HID_DG_TOUCHPAD) | ||
| 805 | return -1; | ||
| 806 | |||
| 807 | if (field->physical == HID_DG_STYLUS) | ||
| 808 | return mt_pen_input_mapping(hdev, hi, field, usage, bit, max); | ||
| 809 | |||
| 810 | return mt_touch_input_mapping(hdev, hi, field, usage, bit, max); | ||
| 811 | } | ||
| 812 | |||
| 813 | static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
| 814 | struct hid_field *field, struct hid_usage *usage, | ||
| 815 | unsigned long **bit, int *max) | ||
| 816 | { | ||
| 817 | if (field->physical == HID_DG_STYLUS) | ||
| 818 | return mt_pen_input_mapped(hdev, hi, field, usage, bit, max); | ||
| 819 | |||
| 820 | return mt_touch_input_mapped(hdev, hi, field, usage, bit, max); | ||
| 821 | } | ||
| 822 | |||
| 823 | static int mt_event(struct hid_device *hid, struct hid_field *field, | ||
| 824 | struct hid_usage *usage, __s32 value) | ||
| 825 | { | ||
| 826 | struct mt_device *td = hid_get_drvdata(hid); | ||
| 827 | |||
| 828 | if (field->report->id == td->mt_report_id) | ||
| 829 | return mt_touch_event(hid, field, usage, value); | ||
| 830 | |||
| 831 | if (field->report->id == td->pen_report_id) | ||
| 832 | return mt_pen_event(hid, field, usage, value); | ||
| 833 | |||
| 834 | /* ignore other reports */ | ||
| 835 | return 1; | ||
| 836 | } | ||
| 837 | |||
| 838 | static void mt_report(struct hid_device *hid, struct hid_report *report) | ||
| 839 | { | ||
| 840 | struct mt_device *td = hid_get_drvdata(hid); | ||
| 841 | |||
| 842 | if (!(hid->claimed & HID_CLAIMED_INPUT)) | ||
| 843 | return; | ||
| 844 | |||
| 845 | if (report->id == td->mt_report_id) | ||
| 846 | mt_touch_report(hid, report); | ||
| 847 | |||
| 848 | if (report->id == td->pen_report_id) | ||
| 849 | mt_pen_report(hid, report); | ||
| 728 | } | 850 | } |
| 729 | 851 | ||
| 730 | static void mt_set_input_mode(struct hid_device *hdev) | 852 | static void mt_set_input_mode(struct hid_device *hdev) |
| @@ -740,7 +862,7 @@ static void mt_set_input_mode(struct hid_device *hdev) · 9 unmodified lines | |||
| 740 | r = re->report_id_hash[td->inputmode]; | 862 | r = re->report_id_hash[td->inputmode]; |
| 741 | if (r) { | 863 | if (r) { |
| 742 | r->field[0]->value[td->inputmode_index] = 0x02; | 864 | r->field[0]->value[td->inputmode_index] = 0x02; |
| 743 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | 865 | hid_hw_request(hdev, r, HID_REQ_SET_REPORT); |
| 744 | } | 866 | } |
| 745 | } | 867 | } |
| 746 | 868 | ||
| @@ -765,7 +887,7 @@ static void mt_set_maxcontacts(struct hid_device *hdev) · 18 unmodified lines | |||
| 765 | max = min(fieldmax, max); | 887 | max = min(fieldmax, max); |
| 766 | if (r->field[0]->value[0] != max) { | 888 | if (r->field[0]->value[0] != max) { |
| 767 | r->field[0]->value[0] = max; | 889 | r->field[0]->value[0] = max; |
| 768 | usbhid_submit_report(hdev, r, USB_DIR_OUT); | 890 | hid_hw_request(hdev, r, HID_REQ_SET_REPORT); |
| 769 | } | 891 | } |
| 770 | } | 892 | } |
| 771 | } | 893 | } |
| @@ -801,32 +923,18 @@ static void mt_post_parse(struct mt_device *td) · 29 unmodified lines | |||
| 801 | } | 923 | } |
| 802 | 924 | ||
| 803 | static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) | 925 | static void mt_input_configured(struct hid_device *hdev, struct hid_input *hi) |
| 804 | |||
| 805 | { | 926 | { |
| 806 | struct mt_device *td = hid_get_drvdata(hdev); | 927 | struct mt_device *td = hid_get_drvdata(hdev); |
| 807 | struct mt_class *cls = &td->mtclass; | 928 | char *name = kstrdup(hdev->name, GFP_KERNEL); |
| 808 | struct input_dev *input = hi->input; | ||
| 809 | 929 | ||
| 810 | /* Only initialize slots for MT input devices */ | 930 | if (name) |
| 811 | if (!test_bit(ABS_MT_POSITION_X, input->absbit)) | 931 | hi->input->name = name; |
| 812 | return; | ||
| 813 | 932 | ||
| 814 | if (!td->maxcontacts) | 933 | if (hi->report->id == td->mt_report_id) |
| 815 | td->maxcontacts = MT_DEFAULT_MAXCONTACT; | 934 | mt_touch_input_configured(hdev, hi); |
| 816 | 935 | ||
| 817 | mt_post_parse(td); | 936 | if (hi->report->id == td->pen_report_id) |
| 818 | if (td->serial_maybe) | 937 | mt_pen_input_configured(hdev, hi); |
| 819 | mt_post_parse_default_settings(td); | ||
| 820 | |||
| 821 | if (cls->is_indirect) | ||
| 822 | td->mt_flags |= INPUT_MT_POINTER; | ||
| 823 | |||
| 824 | if (cls->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) | ||
| 825 | td->mt_flags |= INPUT_MT_DROP_UNUSED; | ||
| 826 | |||
| 827 | input_mt_init_slots(input, td->maxcontacts, td->mt_flags); | ||
| 828 | |||
| 829 | td->mt_flags = 0; | ||
| 830 | } | 938 | } |
| 831 | 939 | ||
| 832 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) | 940 | static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) |
| @@ -834,6 +942,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 1 unmodified line | |||
| 834 | int ret, i; | 942 | int ret, i; |
| 835 | struct mt_device *td; | 943 | struct mt_device *td; |
| 836 | struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ | 944 | struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ |
| 945 | struct hid_input *hi; | ||
| 837 | 946 | ||
| 838 | for (i = 0; mt_classes[i].name ; i++) { | 947 | for (i = 0; mt_classes[i].name ; i++) { |
| 839 | if (id->driver_data == mt_classes[i].name) { | 948 | if (id->driver_data == mt_classes[i].name) { |
| @@ -847,6 +956,14 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 7 unmodified lines | |||
| 847 | */ | 956 | */ |
| 848 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | 957 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; |
| 849 | 958 | ||
| 959 | /* | ||
| 960 | * This allows the driver to handle different input sensors | ||
| 961 | * that emits events through different reports on the same HID | ||
| 962 | * device. | ||
| 963 | */ | ||
| 964 | hdev->quirks |= HID_QUIRK_MULTI_INPUT; | ||
| 965 | hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT; | ||
| 966 | |||
| 850 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); | 967 | td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); |
| 851 | if (!td) { | 968 | if (!td) { |
| 852 | dev_err(&hdev->dev, "cannot allocate multitouch data\n"); | 969 | dev_err(&hdev->dev, "cannot allocate multitouch data\n"); |
| @@ -856,6 +973,8 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 3 unmodified lines | |||
| 856 | td->inputmode = -1; | 973 | td->inputmode = -1; |
| 857 | td->maxcontact_report_id = -1; | 974 | td->maxcontact_report_id = -1; |
| 858 | td->cc_index = -1; | 975 | td->cc_index = -1; |
| 976 | td->mt_report_id = -1; | ||
| 977 | td->pen_report_id = -1; | ||
| 859 | hid_set_drvdata(hdev, td); | 978 | hid_set_drvdata(hdev, td); |
| 860 | 979 | ||
| 861 | td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); | 980 | td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL); |
| @@ -874,7 +993,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 12 unmodified lines | |||
| 874 | 993 | ||
| 875 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | 994 | ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); |
| 876 | if (ret) | 995 | if (ret) |
| 877 | goto fail; | 996 | goto hid_fail; |
| 878 | 997 | ||
| 879 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); | 998 | ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); |
| 880 | 999 | ||
| @@ -886,6 +1005,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) · 5 unmodified lines | |||
| 886 | 1005 | ||
| 887 | return 0; | 1006 | return 0; |
| 888 | 1007 | ||
| 1008 | hid_fail: | ||
| 1009 | list_for_each_entry(hi, &hdev->inputs, list) | ||
| 1010 | mt_free_input_name(hi); | ||
| 889 | fail: | 1011 | fail: |
| 890 | kfree(td->fields); | 1012 | kfree(td->fields); |
| 891 | kfree(td); | 1013 | kfree(td); |
| @@ -902,26 +1024,11 @@ static int mt_reset_resume(struct hid_device *hdev) · 10 unmodified lines | |||
| 902 | 1024 | ||
| 903 | static int mt_resume(struct hid_device *hdev) | 1025 | static int mt_resume(struct hid_device *hdev) |
| 904 | { | 1026 | { |
| 905 | struct usb_interface *intf; | ||
| 906 | struct usb_host_interface *interface; | ||
| 907 | struct usb_device *dev; | ||
| 908 | |||
| 909 | if (hdev->bus != BUS_USB) | ||
| 910 | return 0; | ||
| 911 | |||
| 912 | intf = to_usb_interface(hdev->dev.parent); | ||
| 913 | interface = intf->cur_altsetting; | ||
| 914 | dev = hid_to_usb_dev(hdev); | ||
| 915 | |||
| 916 | /* Some Elan legacy devices require SET_IDLE to be set on resume. | 1027 | /* Some Elan legacy devices require SET_IDLE to be set on resume. |
| 917 | * It should be safe to send it to other devices too. | 1028 | * It should be safe to send it to other devices too. |
| 918 | * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */ | 1029 | * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */ |
| 919 | 1030 | ||
| 920 | usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1031 | hid_hw_idle(hdev, 0, 0, HID_REQ_SET_IDLE); |
| 921 | HID_REQ_SET_IDLE, | ||
| 922 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
| 923 | 0, interface->desc.bInterfaceNumber, | ||
| 924 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
| 925 | 1032 | ||
| 926 | return 0; | 1033 | return 0; |
| 927 | } | 1034 | } |
| @@ -930,8 +1037,14 @@ static int mt_resume(struct hid_device *hdev) · 2 unmodified lines | |||
| 930 | static void mt_remove(struct hid_device *hdev) | 1037 | static void mt_remove(struct hid_device *hdev) |
| 931 | { | 1038 | { |
| 932 | struct mt_device *td = hid_get_drvdata(hdev); | 1039 | struct mt_device *td = hid_get_drvdata(hdev); |
| 1040 | struct hid_input *hi; | ||
| 1041 | |||
| 933 | sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); | 1042 | sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); |
| 934 | hid_hw_stop(hdev); | 1043 | hid_hw_stop(hdev); |
| 1044 | |||
| 1045 | list_for_each_entry(hi, &hdev->inputs, list) | ||
| 1046 | mt_free_input_name(hi); | ||
| 1047 | |||
| 935 | kfree(td); | 1048 | kfree(td); |
| 936 | hid_set_drvdata(hdev, NULL); | 1049 | hid_set_drvdata(hdev, NULL); |
| 937 | } | 1050 | } |
| @@ -118,8 +118,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev) · 117 unmodified lines | |||
| 118 | if (!report) | 118 | if (!report) |
| 119 | return -EINVAL; | 119 | return -EINVAL; |
| 120 | 120 | ||
| 121 | usbhid_submit_report(hdev, report, USB_DIR_IN); | 121 | hid_hw_request(hdev, report, HID_REQ_GET_REPORT); |
| 122 | usbhid_wait_io(hdev); | 122 | hid_hw_wait(hdev); |
| 123 | return (int)report->field[0]->value[0]; | 123 | return (int)report->field[0]->value[0]; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| @@ -137,7 +137,7 @@ static inline void ntrig_set_mode(struct hid_device *hdev, const int mode) · 11 unmodified lines | |||
| 137 | if (!report) | 137 | if (!report) |
| 138 | return; | 138 | return; |
| 139 | 139 | ||
| 140 | usbhid_submit_report(hdev, report, USB_DIR_IN); | 140 | hid_hw_request(hdev, report, HID_REQ_GET_REPORT); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static void ntrig_report_version(struct hid_device *hdev) | 143 | static void ntrig_report_version(struct hid_device *hdev) |
| @@ -937,8 +937,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) · 793 unmodified lines | |||
| 937 | if (report) { | 937 | if (report) { |
| 938 | /* Let the device settle to ensure the wakeup message gets | 938 | /* Let the device settle to ensure the wakeup message gets |
| 939 | * through */ | 939 | * through */ |
| 940 | usbhid_wait_io(hdev); | 940 | hid_hw_wait(hdev); |
| 941 | usbhid_submit_report(hdev, report, USB_DIR_IN); | 941 | hid_hw_request(hdev, report, HID_REQ_GET_REPORT); |
| 942 | 942 | ||
| 943 | /* | 943 | /* |
| 944 | * Sanity check: if the current mode is invalid reset it to | 944 | * Sanity check: if the current mode is invalid reset it to |
| @@ -142,10 +142,10 @@ struct hid_report *picolcd_report(int id, struct hid_device *hdev, int dir); · 141 unmodified lines | |||
| 142 | #ifdef CONFIG_DEBUG_FS | 142 | #ifdef CONFIG_DEBUG_FS |
| 143 | void picolcd_debug_out_report(struct picolcd_data *data, | 143 | void picolcd_debug_out_report(struct picolcd_data *data, |
| 144 | struct hid_device *hdev, struct hid_report *report); | 144 | struct hid_device *hdev, struct hid_report *report); |
| 145 | #define usbhid_submit_report(a, b, c) \ | 145 | #define hid_hw_request(a, b, c) \ |
| 146 | do { \ | 146 | do { \ |
| 147 | picolcd_debug_out_report(hid_get_drvdata(a), a, b); \ | 147 | picolcd_debug_out_report(hid_get_drvdata(a), a, b); \ |
| 148 | usbhid_submit_report(a, b, c); \ | 148 | hid_hw_request(a, b, c); \ |
| 149 | } while (0) | 149 | } while (0) |
| 150 | 150 | ||
| 151 | void picolcd_debug_raw_event(struct picolcd_data *data, | 151 | void picolcd_debug_raw_event(struct picolcd_data *data, |
| @@ -302,7 +302,7 @@ static inline int picolcd_init_cir(struct picolcd_data *data, struct hid_report · 150 unmodified lines | |||
| 302 | static inline void picolcd_exit_cir(struct picolcd_data *data) | 302 | static inline void picolcd_exit_cir(struct picolcd_data *data) |
| 303 | { | 303 | { |
| 304 | } | 304 | } |
| 305 | #endif /* CONFIG_HID_PICOLCD_LIRC */ | 305 | #endif /* CONFIG_HID_PICOLCD_CIR */ |
| 306 | 306 | ||
| 307 | int picolcd_reset(struct hid_device *hdev); | 307 | int picolcd_reset(struct hid_device *hdev); |
| 308 | struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev, | 308 | struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev, |
| @@ -18,8 +18,6 @@ · 17 unmodified lines | |||
| 18 | ***************************************************************************/ | 18 | ***************************************************************************/ |
| 19 | 19 | ||
| 20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
| 21 | #include "usbhid/usbhid.h" | ||
| 22 | #include <linux/usb.h> | ||
| 23 | 21 | ||
| 24 | #include <linux/fb.h> | 22 | #include <linux/fb.h> |
| 25 | #include <linux/backlight.h> | 23 | #include <linux/backlight.h> |
| @@ -46,7 +44,7 @@ static int picolcd_set_brightness(struct backlight_device *bdev) · 20 unmodified lines | |||
| 46 | spin_lock_irqsave(&data->lock, flags); | 44 | spin_lock_irqsave(&data->lock, flags); |
| 47 | hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0); | 45 | hid_set_field(report->field[0], 0, data->lcd_power == FB_BLANK_UNBLANK ? data->lcd_brightness : 0); |
| 48 | if (!(data->status & PICOLCD_FAILED)) | 46 | if (!(data->status & PICOLCD_FAILED)) |
| 49 | usbhid_submit_report(data->hdev, report, USB_DIR_OUT); | 47 | hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); |
| 50 | spin_unlock_irqrestore(&data->lock, flags); | 48 | spin_unlock_irqrestore(&data->lock, flags); |
| 51 | return 0; | 49 | return 0; |
| 52 | } | 50 | } |
| @@ -21,8 +21,6 @@ · 20 unmodified lines | |||
| 21 | #include <linux/hid-debug.h> | 21 | #include <linux/hid-debug.h> |
| 22 | #include <linux/input.h> | 22 | #include <linux/input.h> |
| 23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
| 24 | #include "usbhid/usbhid.h" | ||
| 25 | #include <linux/usb.h> | ||
| 26 | 24 | ||
| 27 | #include <linux/fb.h> | 25 | #include <linux/fb.h> |
| 28 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
| @@ -21,8 +21,6 @@ · 20 unmodified lines | |||
| 21 | #include <linux/hid-debug.h> | 21 | #include <linux/hid-debug.h> |
| 22 | #include <linux/input.h> | 22 | #include <linux/input.h> |
| 23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
| 24 | #include "usbhid/usbhid.h" | ||
| 25 | #include <linux/usb.h> | ||
| 26 | 24 | ||
| 27 | #include <linux/fb.h> | 25 | #include <linux/fb.h> |
| 28 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
| @@ -110,7 +108,7 @@ struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev, · 81 unmodified lines | |||
| 110 | work = NULL; | 108 | work = NULL; |
| 111 | } else { | 109 | } else { |
| 112 | data->pending = work; | 110 | data->pending = work; |
| 113 | usbhid_submit_report(data->hdev, report, USB_DIR_OUT); | 111 | hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); |
| 114 | spin_unlock_irqrestore(&data->lock, flags); | 112 | spin_unlock_irqrestore(&data->lock, flags); |
| 115 | wait_for_completion_interruptible_timeout(&work->ready, HZ*2); | 113 | wait_for_completion_interruptible_timeout(&work->ready, HZ*2); |
| 116 | spin_lock_irqsave(&data->lock, flags); | 114 | spin_lock_irqsave(&data->lock, flags); |
| @@ -244,7 +242,7 @@ int picolcd_reset(struct hid_device *hdev) · 127 unmodified lines | |||
| 244 | spin_unlock_irqrestore(&data->lock, flags); | 242 | spin_unlock_irqrestore(&data->lock, flags); |
| 245 | return -ENODEV; | 243 | return -ENODEV; |
| 246 | } | 244 | } |
| 247 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 245 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); |
| 248 | spin_unlock_irqrestore(&data->lock, flags); | 246 | spin_unlock_irqrestore(&data->lock, flags); |
| 249 | 247 | ||
| 250 | error = picolcd_check_version(hdev); | 248 | error = picolcd_check_version(hdev); |
| @@ -303,7 +301,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev, · 52 unmodified lines | |||
| 303 | spin_lock_irqsave(&data->lock, flags); | 301 | spin_lock_irqsave(&data->lock, flags); |
| 304 | hid_set_field(report->field[0], 0, timeout & 0xff); | 302 | hid_set_field(report->field[0], 0, timeout & 0xff); |
| 305 | hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff); | 303 | hid_set_field(report->field[0], 1, (timeout >> 8) & 0xff); |
| 306 | usbhid_submit_report(data->hdev, report, USB_DIR_OUT); | 304 | hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); |
| 307 | spin_unlock_irqrestore(&data->lock, flags); | 305 | spin_unlock_irqrestore(&data->lock, flags); |
| 308 | return count; | 306 | return count; |
| 309 | } | 307 | } |
| @@ -19,8 +19,6 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
| 21 | #include <linux/hid-debug.h> | 21 | #include <linux/hid-debug.h> |
| 22 | #include "usbhid/usbhid.h" | ||
| 23 | #include <linux/usb.h> | ||
| 24 | 22 | ||
| 25 | #include <linux/fb.h> | 23 | #include <linux/fb.h> |
| 26 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
| @@ -19,8 +19,6 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
| 21 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
| 22 | #include "usbhid/usbhid.h" | ||
| 23 | #include <linux/usb.h> | ||
| 24 | 22 | ||
| 25 | #include <linux/fb.h> | 23 | #include <linux/fb.h> |
| 26 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| @@ -143,8 +141,8 @@ static int picolcd_fb_send_tile(struct picolcd_data *data, u8 *vbitmap, · 116 unmodified lines | |||
| 143 | else | 141 | else |
| 144 | hid_set_field(report2->field[0], 4 + i - 32, tdata[i]); | 142 | hid_set_field(report2->field[0], 4 + i - 32, tdata[i]); |
| 145 | 143 | ||
| 146 | usbhid_submit_report(data->hdev, report1, USB_DIR_OUT); | 144 | hid_hw_request(data->hdev, report1, HID_REQ_SET_REPORT); |
| 147 | usbhid_submit_report(data->hdev, report2, USB_DIR_OUT); | 145 | hid_hw_request(data->hdev, report2, HID_REQ_SET_REPORT); |
| 148 | spin_unlock_irqrestore(&data->lock, flags); | 146 | spin_unlock_irqrestore(&data->lock, flags); |
| 149 | return 0; | 147 | return 0; |
| 150 | } | 148 | } |
| @@ -214,7 +212,7 @@ int picolcd_fb_reset(struct picolcd_data *data, int clear) · 63 unmodified lines | |||
| 214 | hid_set_field(report->field[0], j, mapcmd[j]); | 212 | hid_set_field(report->field[0], j, mapcmd[j]); |
| 215 | else | 213 | else |
| 216 | hid_set_field(report->field[0], j, 0); | 214 | hid_set_field(report->field[0], j, 0); |
| 217 | usbhid_submit_report(data->hdev, report, USB_DIR_OUT); | 215 | hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); |
| 218 | } | 216 | } |
| 219 | spin_unlock_irqrestore(&data->lock, flags); | 217 | spin_unlock_irqrestore(&data->lock, flags); |
| 220 | 218 | ||
| @@ -270,7 +268,7 @@ static void picolcd_fb_update(struct fb_info *info) · 49 unmodified lines | |||
| 270 | mutex_unlock(&info->lock); | 268 | mutex_unlock(&info->lock); |
| 271 | if (!data) | 269 | if (!data) |
| 272 | return; | 270 | return; |
| 273 | usbhid_wait_io(data->hdev); | 271 | hid_hw_wait(data->hdev); |
| 274 | mutex_lock(&info->lock); | 272 | mutex_lock(&info->lock); |
| 275 | n = 0; | 273 | n = 0; |
| 276 | } | 274 | } |
| @@ -288,7 +286,7 @@ static void picolcd_fb_update(struct fb_info *info) · 11 unmodified lines | |||
| 288 | spin_unlock_irqrestore(&fbdata->lock, flags); | 286 | spin_unlock_irqrestore(&fbdata->lock, flags); |
| 289 | mutex_unlock(&info->lock); | 287 | mutex_unlock(&info->lock); |
| 290 | if (data) | 288 | if (data) |
| 291 | usbhid_wait_io(data->hdev); | 289 | hid_hw_wait(data->hdev); |
| 292 | return; | 290 | return; |
| 293 | } | 291 | } |
| 294 | out: | 292 | out: |
| @@ -18,8 +18,6 @@ · 17 unmodified lines | |||
| 18 | ***************************************************************************/ | 18 | ***************************************************************************/ |
| 19 | 19 | ||
| 20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
| 21 | #include "usbhid/usbhid.h" | ||
| 22 | #include <linux/usb.h> | ||
| 23 | 21 | ||
| 24 | #include <linux/fb.h> | 22 | #include <linux/fb.h> |
| 25 | #include <linux/lcd.h> | 23 | #include <linux/lcd.h> |
| @@ -48,7 +46,7 @@ static int picolcd_set_contrast(struct lcd_device *ldev, int contrast) · 22 unmodified lines | |||
| 48 | spin_lock_irqsave(&data->lock, flags); | 46 | spin_lock_irqsave(&data->lock, flags); |
| 49 | hid_set_field(report->field[0], 0, data->lcd_contrast); | 47 | hid_set_field(report->field[0], 0, data->lcd_contrast); |
| 50 | if (!(data->status & PICOLCD_FAILED)) | 48 | if (!(data->status & PICOLCD_FAILED)) |
| 51 | usbhid_submit_report(data->hdev, report, USB_DIR_OUT); | 49 | hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); |
| 52 | spin_unlock_irqrestore(&data->lock, flags); | 50 | spin_unlock_irqrestore(&data->lock, flags); |
| 53 | return 0; | 51 | return 0; |
| 54 | } | 52 | } |
| @@ -21,8 +21,6 @@ · 20 unmodified lines | |||
| 21 | #include <linux/hid-debug.h> | 21 | #include <linux/hid-debug.h> |
| 22 | #include <linux/input.h> | 22 | #include <linux/input.h> |
| 23 | #include "hid-ids.h" | 23 | #include "hid-ids.h" |
| 24 | #include "usbhid/usbhid.h" | ||
| 25 | #include <linux/usb.h> | ||
| 26 | 24 | ||
| 27 | #include <linux/fb.h> | 25 | #include <linux/fb.h> |
| 28 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
| @@ -55,7 +53,7 @@ void picolcd_leds_set(struct picolcd_data *data) · 26 unmodified lines | |||
| 55 | spin_lock_irqsave(&data->lock, flags); | 53 | spin_lock_irqsave(&data->lock, flags); |
| 56 | hid_set_field(report->field[0], 0, data->led_state); | 54 | hid_set_field(report->field[0], 0, data->led_state); |
| 57 | if (!(data->status & PICOLCD_FAILED)) | 55 | if (!(data->status & PICOLCD_FAILED)) |
| 58 | usbhid_submit_report(data->hdev, report, USB_DIR_OUT); | 56 | hid_hw_request(data->hdev, report, HID_REQ_SET_REPORT); |
| 59 | spin_unlock_irqrestore(&data->lock, flags); | 57 | spin_unlock_irqrestore(&data->lock, flags); |
| 60 | } | 58 | } |
| 61 | 59 | ||
| @@ -43,13 +43,11 @@ · 42 unmodified lines | |||
| 43 | #include <linux/input.h> | 43 | #include <linux/input.h> |
| 44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
| 45 | #include <linux/module.h> | 45 | #include <linux/module.h> |
| 46 | #include <linux/usb.h> | ||
| 47 | #include <linux/hid.h> | 46 | #include <linux/hid.h> |
| 48 | 47 | ||
| 49 | #include "hid-ids.h" | 48 | #include "hid-ids.h" |
| 50 | 49 | ||
| 51 | #ifdef CONFIG_PANTHERLORD_FF | 50 | #ifdef CONFIG_PANTHERLORD_FF |
| 52 | #include "usbhid/usbhid.h" | ||
| 53 | 51 | ||
| 54 | struct plff_device { | 52 | struct plff_device { |
| 55 | struct hid_report *report; | 53 | struct hid_report *report; |
| @@ -75,7 +73,7 @@ static int hid_plff_play(struct input_dev *dev, void *data, · 19 unmodified lines | |||
| 75 | *plff->strong = left; | 73 | *plff->strong = left; |
| 76 | *plff->weak = right; | 74 | *plff->weak = right; |
| 77 | debug("running with 0x%02x 0x%02x", left, right); | 75 | debug("running with 0x%02x 0x%02x", left, right); |
| 78 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | 76 | hid_hw_request(hid, plff->report, HID_REQ_SET_REPORT); |
| 79 | 77 | ||
| 80 | return 0; | 78 | return 0; |
| 81 | } | 79 | } |
| @@ -169,7 +167,7 @@ static int plff_init(struct hid_device *hid) · 87 unmodified lines | |||
| 169 | 167 | ||
| 170 | *strong = 0x00; | 168 | *strong = 0x00; |
| 171 | *weak = 0x00; | 169 | *weak = 0x00; |
| 172 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | 170 | hid_hw_request(hid, plff->report, HID_REQ_SET_REPORT); |
| 173 | } | 171 | } |
| 174 | 172 | ||
| 175 | hid_info(hid, "Force feedback for PantherLord/GreenAsia devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); | 173 | hid_info(hid, "Force feedback for PantherLord/GreenAsia devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | |||
| 26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
| 27 | #include <sound/initval.h> | 27 | #include <sound/initval.h> |
| 28 | #include <sound/rawmidi.h> | 28 | #include <sound/rawmidi.h> |
| 29 | #include "usbhid/usbhid.h" | ||
| 30 | #include "hid-ids.h" | 29 | #include "hid-ids.h" |
| 31 | 30 | ||
| 32 | 31 | ||
| @@ -306,7 +305,7 @@ static void pcmidi_submit_output_report(struct pcmidi_snd *pm, int state) · 273 unmodified lines | |||
| 306 | report->field[0]->value[0] = 0x01; | 305 | report->field[0]->value[0] = 0x01; |
| 307 | report->field[0]->value[1] = state; | 306 | report->field[0]->value[1] = state; |
| 308 | 307 | ||
| 309 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 308 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); |
| 310 | } | 309 | } |
| 311 | 310 | ||
| 312 | static int pcmidi_handle_report1(struct pcmidi_snd *pm, u8 *data) | 311 | static int pcmidi_handle_report1(struct pcmidi_snd *pm, u8 *data) |
| @@ -130,14 +130,14 @@ static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj, · 129 unmodified lines | |||
| 130 | if (off >= real_size) | 130 | if (off >= real_size) |
| 131 | return 0; | 131 | return 0; |
| 132 | 132 | ||
| 133 | if (off != 0 || count != real_size) | 133 | if (off != 0 || count > real_size) |
| 134 | return -EINVAL; | 134 | return -EINVAL; |
| 135 | 135 | ||
| 136 | mutex_lock(&isku->isku_lock); | 136 | mutex_lock(&isku->isku_lock); |
| 137 | retval = isku_receive(usb_dev, command, buf, real_size); | 137 | retval = isku_receive(usb_dev, command, buf, count); |
| 138 | mutex_unlock(&isku->isku_lock); | 138 | mutex_unlock(&isku->isku_lock); |
| 139 | 139 | ||
| 140 | return retval ? retval : real_size; | 140 | return retval ? retval : count; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, | 143 | static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, |
| @@ -150,15 +150,15 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj, · 6 unmodified lines | |||
| 150 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 150 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); |
| 151 | int retval; | 151 | int retval; |
| 152 | 152 | ||
| 153 | if (off != 0 || count != real_size) | 153 | if (off != 0 || count > real_size) |
| 154 | return -EINVAL; | 154 | return -EINVAL; |
| 155 | 155 | ||
| 156 | mutex_lock(&isku->isku_lock); | 156 | mutex_lock(&isku->isku_lock); |
| 157 | retval = roccat_common2_send_with_status(usb_dev, command, | 157 | retval = roccat_common2_send_with_status(usb_dev, command, |
| 158 | (void *)buf, real_size); | 158 | (void *)buf, count); |
| 159 | mutex_unlock(&isku->isku_lock); | 159 | mutex_unlock(&isku->isku_lock); |
| 160 | 160 | ||
| 161 | return retval ? retval : real_size; | 161 | return retval ? retval : count; |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | #define ISKU_SYSFS_W(thingy, THINGY) \ | 164 | #define ISKU_SYSFS_W(thingy, THINGY) \ |
| @@ -216,6 +216,7 @@ ISKU_SYSFS_RW(light, LIGHT) · 51 unmodified lines | |||
| 216 | ISKU_SYSFS_RW(key_mask, KEY_MASK) | 216 | ISKU_SYSFS_RW(key_mask, KEY_MASK) |
| 217 | ISKU_SYSFS_RW(last_set, LAST_SET) | 217 | ISKU_SYSFS_RW(last_set, LAST_SET) |
| 218 | ISKU_SYSFS_W(talk, TALK) | 218 | ISKU_SYSFS_W(talk, TALK) |
| 219 | ISKU_SYSFS_W(talkfx, TALKFX) | ||
| 219 | ISKU_SYSFS_R(info, INFO) | 220 | ISKU_SYSFS_R(info, INFO) |
| 220 | ISKU_SYSFS_W(control, CONTROL) | 221 | ISKU_SYSFS_W(control, CONTROL) |
| 221 | ISKU_SYSFS_W(reset, RESET) | 222 | ISKU_SYSFS_W(reset, RESET) |
| @@ -232,6 +233,7 @@ static struct bin_attribute isku_bin_attributes[] = { · 10 unmodified lines | |||
| 232 | ISKU_BIN_ATTR_RW(key_mask, KEY_MASK), | 233 | ISKU_BIN_ATTR_RW(key_mask, KEY_MASK), |
| 233 | ISKU_BIN_ATTR_RW(last_set, LAST_SET), | 234 | ISKU_BIN_ATTR_RW(last_set, LAST_SET), |
| 234 | ISKU_BIN_ATTR_W(talk, TALK), | 235 | ISKU_BIN_ATTR_W(talk, TALK), |
| 236 | ISKU_BIN_ATTR_W(talkfx, TALKFX), | ||
| 235 | ISKU_BIN_ATTR_R(info, INFO), | 237 | ISKU_BIN_ATTR_R(info, INFO), |
| 236 | ISKU_BIN_ATTR_W(control, CONTROL), | 238 | ISKU_BIN_ATTR_W(control, CONTROL), |
| 237 | ISKU_BIN_ATTR_W(reset, RESET), | 239 | ISKU_BIN_ATTR_W(reset, RESET), |
| @@ -405,6 +407,7 @@ static int isku_raw_event(struct hid_device *hdev, · 167 unmodified lines | |||
| 405 | 407 | ||
| 406 | static const struct hid_device_id isku_devices[] = { | 408 | static const struct hid_device_id isku_devices[] = { |
| 407 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, | 409 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, |
| 410 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKUFX) }, | ||
| 408 | { } | 411 | { } |
| 409 | }; | 412 | }; |
| 410 | 413 | ||
| @@ -443,5 +446,5 @@ module_init(isku_init); · 32 unmodified lines | |||
| 443 | module_exit(isku_exit); | 446 | module_exit(isku_exit); |
| 444 | 447 | ||
| 445 | MODULE_AUTHOR("Stefan Achatz"); | 448 | MODULE_AUTHOR("Stefan Achatz"); |
| 446 | MODULE_DESCRIPTION("USB Roccat Isku driver"); | 449 | MODULE_DESCRIPTION("USB Roccat Isku/FX driver"); |
| 447 | MODULE_LICENSE("GPL v2"); | 450 | MODULE_LICENSE("GPL v2"); |
| @@ -25,10 +25,11 @@ enum { · 24 unmodified lines | |||
| 25 | ISKU_SIZE_KEYS_MACRO = 0x23, | 25 | ISKU_SIZE_KEYS_MACRO = 0x23, |
| 26 | ISKU_SIZE_KEYS_CAPSLOCK = 0x06, | 26 | ISKU_SIZE_KEYS_CAPSLOCK = 0x06, |
| 27 | ISKU_SIZE_LAST_SET = 0x14, | 27 | ISKU_SIZE_LAST_SET = 0x14, |
| 28 | ISKU_SIZE_LIGHT = 0x0a, | 28 | ISKU_SIZE_LIGHT = 0x10, |
| 29 | ISKU_SIZE_MACRO = 0x823, | 29 | ISKU_SIZE_MACRO = 0x823, |
| 30 | ISKU_SIZE_RESET = 0x03, | 30 | ISKU_SIZE_RESET = 0x03, |
| 31 | ISKU_SIZE_TALK = 0x10, | 31 | ISKU_SIZE_TALK = 0x10, |
| 32 | ISKU_SIZE_TALKFX = 0x10, | ||
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | enum { | 35 | enum { |
| @@ -59,6 +60,7 @@ enum isku_commands { · 24 unmodified lines | |||
| 59 | ISKU_COMMAND_LAST_SET = 0x14, | 60 | ISKU_COMMAND_LAST_SET = 0x14, |
| 60 | ISKU_COMMAND_15 = 0x15, | 61 | ISKU_COMMAND_15 = 0x15, |
| 61 | ISKU_COMMAND_TALK = 0x16, | 62 | ISKU_COMMAND_TALK = 0x16, |
| 63 | ISKU_COMMAND_TALKFX = 0x17, | ||
| 62 | ISKU_COMMAND_FIRMWARE_WRITE = 0x1b, | 64 | ISKU_COMMAND_FIRMWARE_WRITE = 0x1b, |
| 63 | ISKU_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c, | 65 | ISKU_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c, |
| 64 | }; | 66 | }; |
| @@ -818,8 +818,9 @@ static void kone_report_to_chrdev(struct kone_device const *kone, · 817 unmodified lines | |||
| 818 | (uint8_t *)&roccat_report); | 818 | (uint8_t *)&roccat_report); |
| 819 | break; | 819 | break; |
| 820 | case kone_mouse_event_call_overlong_macro: | 820 | case kone_mouse_event_call_overlong_macro: |
| 821 | case kone_mouse_event_multimedia: | ||
| 821 | if (event->value == kone_keystroke_action_press) { | 822 | if (event->value == kone_keystroke_action_press) { |
| 822 | roccat_report.event = kone_mouse_event_call_overlong_macro; | 823 | roccat_report.event = event->event; |
| 823 | roccat_report.value = kone->actual_profile; | 824 | roccat_report.value = kone->actual_profile; |
| 824 | roccat_report.key = event->macro_key; | 825 | roccat_report.key = event->macro_key; |
| 825 | roccat_report_event(kone->chrdev_minor, | 826 | roccat_report_event(kone->chrdev_minor, |
| @@ -169,6 +169,7 @@ enum kone_mouse_events { · 168 unmodified lines | |||
| 169 | /* TODO clarify meaning and occurence of kone_mouse_event_calibration */ | 169 | /* TODO clarify meaning and occurence of kone_mouse_event_calibration */ |
| 170 | kone_mouse_event_calibration = 0xc0, | 170 | kone_mouse_event_calibration = 0xc0, |
| 171 | kone_mouse_event_call_overlong_macro = 0xe0, | 171 | kone_mouse_event_call_overlong_macro = 0xe0, |
| 172 | kone_mouse_event_multimedia = 0xe1, | ||
| 172 | /* switch events notify if user changed values with mousebutton click */ | 173 | /* switch events notify if user changed values with mousebutton click */ |
| 173 | kone_mouse_event_switch_dpi = 0xf0, | 174 | kone_mouse_event_switch_dpi = 0xf0, |
| 174 | kone_mouse_event_switch_profile = 0xf1 | 175 | kone_mouse_event_switch_profile = 0xf1 |
| @@ -0,0 +1,304 @@ | |||
| 1 | /* | ||
| 2 | * Roccat KonePure driver for Linux | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the Free | ||
| 10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 11 | * any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | /* | ||
| 15 | * Roccat KonePure is a smaller version of KoneXTD with less buttons and lights. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/device.h> | ||
| 19 | #include <linux/input.h> | ||
| 20 | #include <linux/hid.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/hid-roccat.h> | ||
| 24 | #include "hid-ids.h" | ||
| 25 | #include "hid-roccat-common.h" | ||
| 26 | #include "hid-roccat-konepure.h" | ||
| 27 | |||
| 28 | static struct class *konepure_class; | ||
| 29 | |||
| 30 | static ssize_t konepure_sysfs_read(struct file *fp, struct kobject *kobj, | ||
| 31 | char *buf, loff_t off, size_t count, | ||
| 32 | size_t real_size, uint command) | ||
| 33 | { | ||
| 34 | struct device *dev = | ||
| 35 | container_of(kobj, struct device, kobj)->parent->parent; | ||
| 36 | struct konepure_device *konepure = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 37 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 38 | int retval; | ||
| 39 | |||
| 40 | if (off >= real_size) | ||
| 41 | return 0; | ||
| 42 | |||
| 43 | if (off != 0 || count != real_size) | ||
| 44 | return -EINVAL; | ||
| 45 | |||
| 46 | mutex_lock(&konepure->konepure_lock); | ||
| 47 | retval = roccat_common2_receive(usb_dev, command, buf, real_size); | ||
| 48 | mutex_unlock(&konepure->konepure_lock); | ||
| 49 | |||
| 50 | return retval ? retval : real_size; | ||
| 51 | } | ||
| 52 | |||
| 53 | static ssize_t konepure_sysfs_write(struct file *fp, struct kobject *kobj, | ||
| 54 | void const *buf, loff_t off, size_t count, | ||
| 55 | size_t real_size, uint command) | ||
| 56 | { | ||
| 57 | struct device *dev = | ||
| 58 | container_of(kobj, struct device, kobj)->parent->parent; | ||
| 59 | struct konepure_device *konepure = hid_get_drvdata(dev_get_drvdata(dev)); | ||
| 60 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | ||
| 61 | int retval; | ||
| 62 | |||
| 63 | if (off != 0 || count != real_size) | ||
| 64 | return -EINVAL; | ||
| 65 | |||
| 66 | mutex_lock(&konepure->konepure_lock); | ||
| 67 | retval = roccat_common2_send_with_status(usb_dev, command, | ||
| 68 | (void *)buf, real_size); | ||
| 69 | mutex_unlock(&konepure->konepure_lock); | ||
| 70 | |||
| 71 | return retval ? retval : real_size; | ||
| 72 | } | ||
| 73 | |||
| 74 | #define KONEPURE_SYSFS_W(thingy, THINGY) \ | ||
| 75 | static ssize_t konepure_sysfs_write_ ## thingy(struct file *fp, \ | ||
| 76 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ | ||
| 77 | loff_t off, size_t count) \ | ||
| 78 | { \ | ||
| 79 | return konepure_sysfs_write(fp, kobj, buf, off, count, \ | ||
| 80 | KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \ | ||
| 81 | } | ||
| 82 | |||
| 83 | #define KONEPURE_SYSFS_R(thingy, THINGY) \ | ||
| 84 | static ssize_t konepure_sysfs_read_ ## thingy(struct file *fp, \ | ||
| 85 | struct kobject *kobj, struct bin_attribute *attr, char *buf, \ | ||
| 86 | loff_t off, size_t count) \ | ||
| 87 | { \ | ||
| 88 | return konepure_sysfs_read(fp, kobj, buf, off, count, \ | ||
| 89 | KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \ | ||
| 90 | } | ||
| 91 | |||
| 92 | #define KONEPURE_SYSFS_RW(thingy, THINGY) \ | ||
| 93 | KONEPURE_SYSFS_W(thingy, THINGY) \ | ||
| 94 | KONEPURE_SYSFS_R(thingy, THINGY) | ||
| 95 | |||
| 96 | #define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | ||
| 97 | { \ | ||
| 98 | .attr = { .name = #thingy, .mode = 0660 }, \ | ||
| 99 | .size = KONEPURE_SIZE_ ## THINGY, \ | ||
| 100 | .read = konepure_sysfs_read_ ## thingy, \ | ||
| 101 | .write = konepure_sysfs_write_ ## thingy \ | ||
| 102 | } | ||
| 103 | |||
| 104 | #define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \ | ||
| 105 | { \ | ||
| 106 | .attr = { .name = #thingy, .mode = 0440 }, \ | ||
| 107 | .size = KONEPURE_SIZE_ ## THINGY, \ | ||
| 108 | .read = konepure_sysfs_read_ ## thingy, \ | ||
| 109 | } | ||
| 110 | |||
| 111 | #define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \ | ||
| 112 | { \ | ||
| 113 | .attr = { .name = #thingy, .mode = 0220 }, \ | ||
| 114 | .size = KONEPURE_SIZE_ ## THINGY, \ | ||
| 115 | .write = konepure_sysfs_write_ ## thingy \ | ||
| 116 | } | ||
| 117 | |||
| 118 | KONEPURE_SYSFS_RW(actual_profile, ACTUAL_PROFILE) | ||
| 119 | KONEPURE_SYSFS_W(control, CONTROL) | ||
| 120 | KONEPURE_SYSFS_RW(info, INFO) | ||
| 121 | KONEPURE_SYSFS_W(talk, TALK) | ||
| 122 | KONEPURE_SYSFS_W(macro, MACRO) | ||
| 123 | KONEPURE_SYSFS_RW(sensor, SENSOR) | ||
| 124 | KONEPURE_SYSFS_RW(tcu, TCU) | ||
| 125 | KONEPURE_SYSFS_R(tcu_image, TCU_IMAGE) | ||
| 126 | KONEPURE_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | ||
| 127 | KONEPURE_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) | ||
| 128 | |||
| 129 | static struct bin_attribute konepure_bin_attributes[] = { | ||
| 130 | KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE), | ||
| 131 | KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL), | ||
| 132 | KONEPURE_BIN_ATTRIBUTE_RW(info, INFO), | ||
| 133 | KONEPURE_BIN_ATTRIBUTE_W(talk, TALK), | ||
| 134 | KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO), | ||
| 135 | KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR), | ||
| 136 | KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU), | ||
| 137 | KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE), | ||
| 138 | KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), | ||
| 139 | KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), | ||
| 140 | __ATTR_NULL | ||
| 141 | }; | ||
| 142 | |||
| 143 | static int konepure_init_konepure_device_struct(struct usb_device *usb_dev, | ||
| 144 | struct konepure_device *konepure) | ||
| 145 | { | ||
| 146 | mutex_init(&konepure->konepure_lock); | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static int konepure_init_specials(struct hid_device *hdev) | ||
| 152 | { | ||
| 153 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 154 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
| 155 | struct konepure_device *konepure; | ||
| 156 | int retval; | ||
| 157 | |||
| 158 | if (intf->cur_altsetting->desc.bInterfaceProtocol | ||
| 159 | != USB_INTERFACE_PROTOCOL_MOUSE) { | ||
| 160 | hid_set_drvdata(hdev, NULL); | ||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | konepure = kzalloc(sizeof(*konepure), GFP_KERNEL); | ||
| 165 | if (!konepure) { | ||
| 166 | hid_err(hdev, "can't alloc device descriptor\n"); | ||
| 167 | return -ENOMEM; | ||
| 168 | } | ||
| 169 | hid_set_drvdata(hdev, konepure); | ||
| 170 | |||
| 171 | retval = konepure_init_konepure_device_struct(usb_dev, konepure); | ||
| 172 | if (retval) { | ||
| 173 | hid_err(hdev, "couldn't init struct konepure_device\n"); | ||
| 174 | goto exit_free; | ||
| 175 | } | ||
| 176 | |||
| 177 | retval = roccat_connect(konepure_class, hdev, | ||
| 178 | sizeof(struct konepure_mouse_report_button)); | ||
| 179 | if (retval < 0) { | ||
| 180 | hid_err(hdev, "couldn't init char dev\n"); | ||
| 181 | } else { | ||
| 182 | konepure->chrdev_minor = retval; | ||
| 183 | konepure->roccat_claimed = 1; | ||
| 184 | } | ||
| 185 | |||
| 186 | return 0; | ||
| 187 | exit_free: | ||
| 188 | kfree(konepure); | ||
| 189 | return retval; | ||
| 190 | } | ||
| 191 | |||
| 192 | static void konepure_remove_specials(struct hid_device *hdev) | ||
| 193 | { | ||
| 194 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 195 | struct konepure_device *konepure; | ||
| 196 | |||
| 197 | if (intf->cur_altsetting->desc.bInterfaceProtocol | ||
| 198 | != USB_INTERFACE_PROTOCOL_MOUSE) | ||
| 199 | return; | ||
| 200 | |||
| 201 | konepure = hid_get_drvdata(hdev); | ||
| 202 | if (konepure->roccat_claimed) | ||
| 203 | roccat_disconnect(konepure->chrdev_minor); | ||
| 204 | kfree(konepure); | ||
| 205 | } | ||
| 206 | |||
| 207 | static int konepure_probe(struct hid_device *hdev, | ||
| 208 | const struct hid_device_id *id) | ||
| 209 | { | ||
| 210 | int retval; | ||
| 211 | |||
| 212 | retval = hid_parse(hdev); | ||
| 213 | if (retval) { | ||
| 214 | hid_err(hdev, "parse failed\n"); | ||
| 215 | goto exit; | ||
| 216 | } | ||
| 217 | |||
| 218 | retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); | ||
| 219 | if (retval) { | ||
| 220 | hid_err(hdev, "hw start failed\n"); | ||
| 221 | goto exit; | ||
| 222 | } | ||
| 223 | |||
| 224 | retval = konepure_init_specials(hdev); | ||
| 225 | if (retval) { | ||
| 226 | hid_err(hdev, "couldn't install mouse\n"); | ||
| 227 | goto exit_stop; | ||
| 228 | } | ||
| 229 | |||
| 230 | return 0; | ||
| 231 | |||
| 232 | exit_stop: | ||
| 233 | hid_hw_stop(hdev); | ||
| 234 | exit: | ||
| 235 | return retval; | ||
| 236 | } | ||
| 237 | |||
| 238 | static void konepure_remove(struct hid_device *hdev) | ||
| 239 | { | ||
| 240 | konepure_remove_specials(hdev); | ||
| 241 | hid_hw_stop(hdev); | ||
| 242 | } | ||
| 243 | |||
| 244 | static int konepure_raw_event(struct hid_device *hdev, | ||
| 245 | struct hid_report *report, u8 *data, int size) | ||
| 246 | { | ||
| 247 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | ||
| 248 | struct konepure_device *konepure = hid_get_drvdata(hdev); | ||
| 249 | |||
| 250 | if (intf->cur_altsetting->desc.bInterfaceProtocol | ||
| 251 | != USB_INTERFACE_PROTOCOL_MOUSE) | ||
| 252 | return 0; | ||
| 253 | |||
| 254 | if (data[0] != KONEPURE_MOUSE_REPORT_NUMBER_BUTTON) | ||
| 255 | return 0; | ||
| 256 | |||
| 257 | if (konepure != NULL && konepure->roccat_claimed) | ||
| 258 | roccat_report_event(konepure->chrdev_minor, data); | ||
| 259 | |||
| 260 | return 0; | ||
| 261 | } | ||
| 262 | |||
| 263 | static const struct hid_device_id konepure_devices[] = { | ||
| 264 | { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) }, | ||
| 265 | { } | ||
| 266 | }; | ||
| 267 | |||
| 268 | MODULE_DEVICE_TABLE(hid, konepure_devices); | ||
| 269 | |||
| 270 | static struct hid_driver konepure_driver = { | ||
| 271 | .name = "konepure", | ||
| 272 | .id_table = konepure_devices, | ||
| 273 | .probe = konepure_probe, | ||
| 274 | .remove = konepure_remove, | ||
| 275 | .raw_event = konepure_raw_event | ||
| 276 | }; | ||
| 277 | |||
| 278 | static int __init konepure_init(void) | ||
| 279 | { | ||
| 280 | int retval; | ||
| 281 | |||
| 282 | konepure_class = class_create(THIS_MODULE, "konepure"); | ||
| 283 | if (IS_ERR(konepure_class)) | ||
| 284 | return PTR_ERR(konepure_class); | ||
| 285 | konepure_class->dev_bin_attrs = konepure_bin_attributes; | ||
| 286 | |||
| 287 | retval = hid_register_driver(&konepure_driver); | ||
| 288 | if (retval) | ||
| 289 | class_destroy(konepure_class); | ||
| 290 | return retval; | ||
| 291 | } | ||
| 292 | |||
| 293 | static void __exit konepure_exit(void) | ||
| 294 | { | ||
| 295 | hid_unregister_driver(&konepure_driver); | ||
| 296 | class_destroy(konepure_class); | ||
| 297 | } | ||
| 298 | |||
| 299 | module_init(konepure_init); | ||
| 300 | module_exit(konepure_exit); | ||
| 301 | |||
| 302 | MODULE_AUTHOR("Stefan Achatz"); | ||
| 303 | MODULE_DESCRIPTION("USB Roccat KonePure driver"); | ||
| 304 | MODULE_LICENSE("GPL v2"); | ||
| @@ -0,0 +1,72 @@ | |||
| 1 | #ifndef __HID_ROCCAT_KONEPURE_H | ||
| 2 | #define __HID_ROCCAT_KONEPURE_H | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the Free | ||
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 12 | * any later version. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | |||
| 17 | enum { | ||
| 18 | KONEPURE_SIZE_ACTUAL_PROFILE = 0x03, | ||
| 19 | KONEPURE_SIZE_CONTROL = 0x03, | ||
| 20 | KONEPURE_SIZE_FIRMWARE_WRITE = 0x0402, | ||
| 21 | KONEPURE_SIZE_INFO = 0x06, | ||
| 22 | KONEPURE_SIZE_MACRO = 0x0822, | ||
| 23 | KONEPURE_SIZE_PROFILE_SETTINGS = 0x1f, | ||
| 24 | KONEPURE_SIZE_PROFILE_BUTTONS = 0x3b, | ||
| 25 | KONEPURE_SIZE_SENSOR = 0x06, | ||
| 26 | KONEPURE_SIZE_TALK = 0x10, | ||
| 27 | KONEPURE_SIZE_TCU = 0x04, | ||
| 28 | KONEPURE_SIZE_TCU_IMAGE = 0x0404, | ||
| 29 | }; | ||
| 30 | |||
| 31 | enum konepure_control_requests { | ||
| 32 | KONEPURE_CONTROL_REQUEST_GENERAL = 0x80, | ||
| 33 | KONEPURE_CONTROL_REQUEST_BUTTONS = 0x90, | ||
| 34 | }; | ||
| 35 | |||
| 36 | enum konepure_commands { | ||
| 37 | KONEPURE_COMMAND_CONTROL = 0x04, | ||
| 38 | KONEPURE_COMMAND_ACTUAL_PROFILE = 0x05, | ||
| 39 | KONEPURE_COMMAND_PROFILE_SETTINGS = 0x06, | ||
| 40 | KONEPURE_COMMAND_PROFILE_BUTTONS = 0x07, | ||
| 41 | KONEPURE_COMMAND_MACRO = 0x08, | ||
| 42 | KONEPURE_COMMAND_INFO = 0x09, | ||
| 43 | KONEPURE_COMMAND_TCU = 0x0c, | ||
| 44 | KONEPURE_COMMAND_TCU_IMAGE = 0x0c, | ||
| 45 | KONEPURE_COMMAND_E = 0x0e, | ||
| 46 | KONEPURE_COMMAND_SENSOR = 0x0f, | ||
| 47 | KONEPURE_COMMAND_TALK = 0x10, | ||
| 48 | KONEPURE_COMMAND_FIRMWARE_WRITE = 0x1b, | ||
| 49 | KONEPURE_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c, | ||
| 50 | }; | ||
| 51 | |||
| 52 | enum { | ||
| 53 | KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3, | ||
| 54 | }; | ||
| 55 | |||
| 56 | struct konepure_mouse_report_button { | ||
| 57 | uint8_t report_number; /* always KONEPURE_MOUSE_REPORT_NUMBER_BUTTON */ | ||
| 58 | uint8_t zero; | ||
| 59 | uint8_t type; | ||
| 60 | uint8_t data1; | ||
| 61 | uint8_t data2; | ||
| 62 | uint8_t zero2; | ||
| 63 | uint8_t unknown[2]; | ||
| 64 | } __packed; | ||
| 65 | |||
| 66 | struct konepure_device { | ||
| 67 | int roccat_claimed; | ||
| 68 | int chrdev_minor; | ||
| 69 | struct mutex konepure_lock; | ||
| 70 | }; | ||
| 71 | |||
| 72 | #endif | ||
| @@ -242,7 +242,6 @@ static int roccat_release(struct inode *inode, struct file *file) · 241 unmodified lines | |||
| 242 | * roccat_report_event() - output data to readers | 242 | * roccat_report_event() - output data to readers |
| 243 | * @minor: minor device number returned by roccat_connect() | 243 | * @minor: minor device number returned by roccat_connect() |
| 244 | * @data: pointer to data | 244 | * @data: pointer to data |
| 245 | * @len: size of data | ||
| 246 | * | 245 | * |
| 247 | * Return value is zero on success, a negative error code on failure. | 246 | * Return value is zero on success, a negative error code on failure. |
| 248 | * | 247 | * |
| @@ -290,6 +289,7 @@ EXPORT_SYMBOL_GPL(roccat_report_event); · 41 unmodified lines | |||
| 290 | * @class: the class thats used to create the device. Meant to hold device | 289 | * @class: the class thats used to create the device. Meant to hold device |
| 291 | * specific sysfs attributes. | 290 | * specific sysfs attributes. |
| 292 | * @hid: the hid device the char device should be connected to. | 291 | * @hid: the hid device the char device should be connected to. |
| 292 | * @report_size: size of reports | ||
| 293 | * | 293 | * |
| 294 | * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on | 294 | * Return value is minor device number in Range [0, ROCCAT_MAX_DEVICES] on |
| 295 | * success, a negative error code on failure. | 295 | * success, a negative error code on failure. |
| @@ -18,8 +18,6 @@ · 17 unmodified lines | |||
| 18 | */ | 18 | */ |
| 19 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 20 | #include <linux/hid.h> | 20 | #include <linux/hid.h> |
| 21 | #include <linux/usb.h> | ||
| 22 | #include "usbhid/usbhid.h" | ||
| 23 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 24 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 25 | #include <linux/mfd/core.h> | 23 | #include <linux/mfd/core.h> |
| @@ -204,8 +202,8 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, · 178 unmodified lines | |||
| 204 | goto done_proc; | 202 | goto done_proc; |
| 205 | } | 203 | } |
| 206 | hid_set_field(report->field[field_index], 0, value); | 204 | hid_set_field(report->field[field_index], 0, value); |
| 207 | usbhid_submit_report(hsdev->hdev, report, USB_DIR_OUT); | 205 | hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); |
| 208 | usbhid_wait_io(hsdev->hdev); | 206 | hid_hw_wait(hsdev->hdev); |
| 209 | 207 | ||
| 210 | done_proc: | 208 | done_proc: |
| 211 | mutex_unlock(&data->mutex); | 209 | mutex_unlock(&data->mutex); |
| @@ -227,8 +225,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, · 15 unmodified lines | |||
| 227 | ret = -EINVAL; | 225 | ret = -EINVAL; |
| 228 | goto done_proc; | 226 | goto done_proc; |
| 229 | } | 227 | } |
| 230 | usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN); | 228 | hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); |
| 231 | usbhid_wait_io(hsdev->hdev); | 229 | hid_hw_wait(hsdev->hdev); |
| 232 | *value = report->field[field_index]->value[0]; | 230 | *value = report->field[field_index]->value[0]; |
| 233 | 231 | ||
| 234 | done_proc: | 232 | done_proc: |
| @@ -262,7 +260,7 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, · 27 unmodified lines | |||
| 262 | spin_unlock_irqrestore(&data->lock, flags); | 260 | spin_unlock_irqrestore(&data->lock, flags); |
| 263 | goto err_free; | 261 | goto err_free; |
| 264 | } | 262 | } |
| 265 | usbhid_submit_report(hsdev->hdev, report, USB_DIR_IN); | 263 | hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); |
| 266 | spin_unlock_irqrestore(&data->lock, flags); | 264 | spin_unlock_irqrestore(&data->lock, flags); |
| 267 | wait_for_completion_interruptible_timeout(&data->pending.ready, HZ*5); | 265 | wait_for_completion_interruptible_timeout(&data->pending.ready, HZ*5); |
| 268 | switch (data->pending.raw_size) { | 266 | switch (data->pending.raw_size) { |
| @@ -28,13 +28,11 @@ · 27 unmodified lines | |||
| 28 | 28 | ||
| 29 | #include <linux/input.h> | 29 | #include <linux/input.h> |
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/usb.h> | ||
| 32 | #include <linux/hid.h> | 31 | #include <linux/hid.h> |
| 33 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 34 | #include "hid-ids.h" | 33 | #include "hid-ids.h" |
| 35 | 34 | ||
| 36 | #ifdef CONFIG_SMARTJOYPLUS_FF | 35 | #ifdef CONFIG_SMARTJOYPLUS_FF |
| 37 | #include "usbhid/usbhid.h" | ||
| 38 | 36 | ||
| 39 | struct sjoyff_device { | 37 | struct sjoyff_device { |
| 40 | struct hid_report *report; | 38 | struct hid_report *report; |
| @@ -57,7 +55,7 @@ static int hid_sjoyff_play(struct input_dev *dev, void *data, · 16 unmodified lines | |||
| 57 | sjoyff->report->field[0]->value[1] = right; | 55 | sjoyff->report->field[0]->value[1] = right; |
| 58 | sjoyff->report->field[0]->value[2] = left; | 56 | sjoyff->report->field[0]->value[2] = left; |
| 59 | dev_dbg(&dev->dev, "running with 0x%02x 0x%02x\n", left, right); | 57 | dev_dbg(&dev->dev, "running with 0x%02x 0x%02x\n", left, right); |
| 60 | usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); | 58 | hid_hw_request(hid, sjoyff->report, HID_REQ_SET_REPORT); |
| 61 | 59 | ||
| 62 | return 0; | 60 | return 0; |
| 63 | } | 61 | } |
| @@ -115,7 +113,7 @@ static int sjoyff_init(struct hid_device *hid) · 51 unmodified lines | |||
| 115 | sjoyff->report->field[0]->value[0] = 0x01; | 113 | sjoyff->report->field[0]->value[0] = 0x01; |
| 116 | sjoyff->report->field[0]->value[1] = 0x00; | 114 | sjoyff->report->field[0]->value[1] = 0x00; |
| 117 | sjoyff->report->field[0]->value[2] = 0x00; | 115 | sjoyff->report->field[0]->value[2] = 0x00; |
| 118 | usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); | 116 | hid_hw_request(hid, sjoyff->report, HID_REQ_SET_REPORT); |
| 119 | } | 117 | } |
| 120 | 118 | ||
| 121 | hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); | 119 | hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); |
| @@ -16,10 +16,8 @@ · 15 unmodified lines | |||
| 16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
| 17 | #include <linux/hid.h> | 17 | #include <linux/hid.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/usb.h> | ||
| 20 | 19 | ||
| 21 | #include "hid-ids.h" | 20 | #include "hid-ids.h" |
| 22 | #include "usbhid/usbhid.h" | ||
| 23 | 21 | ||
| 24 | static const struct hid_device_id speedlink_devices[] = { | 22 | static const struct hid_device_id speedlink_devices[] = { |
| 25 | { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE)}, | 23 | { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE)}, |
| @@ -16,7 +16,6 @@ · 15 unmodified lines | |||
| 16 | #include <linux/hid.h> | 16 | #include <linux/hid.h> |
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | 18 | ||
| 19 | #include "usbhid/usbhid.h" | ||
| 20 | #include "hid-ids.h" | 19 | #include "hid-ids.h" |
| 21 | 20 | ||
| 22 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) | 21 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
| @@ -132,7 +131,7 @@ static void steelseries_srws1_set_leds(struct hid_device *hdev, __u16 leds) · 109 unmodified lines | |||
| 132 | value[14] = 0x00; | 131 | value[14] = 0x00; |
| 133 | value[15] = 0x00; | 132 | value[15] = 0x00; |
| 134 | 133 | ||
| 135 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 134 | hid_hw_request(hdev, report, HID_REQ_SET_REPORT); |
| 136 | 135 | ||
| 137 | /* Note: LED change does not show on device until the device is read/polled */ | 136 | /* Note: LED change does not show on device until the device is read/polled */ |
| 138 | } | 137 | } |
| @@ -378,16 +377,5 @@ static struct hid_driver steelseries_srws1_driver = { · 239 unmodified lines | |||
| 378 | .report_fixup = steelseries_srws1_report_fixup | 377 | .report_fixup = steelseries_srws1_report_fixup |
| 379 | }; | 378 | }; |
| 380 | 379 | ||
| 381 | static int __init steelseries_srws1_init(void) | 380 | module_hid_driver(steelseries_srws1_driver); |
| 382 | { | ||
| 383 | return hid_register_driver(&steelseries_srws1_driver); | ||
| 384 | } | ||
| 385 | |||
| 386 | static void __exit steelseries_srws1_exit(void) | ||
| 387 | { | ||
| 388 | hid_unregister_driver(&steelseries_srws1_driver); | ||
| 389 | } | ||
| 390 | |||
| 391 | module_init(steelseries_srws1_init); | ||
| 392 | module_exit(steelseries_srws1_exit); | ||
| 393 | MODULE_LICENSE("GPL"); | 381 | MODULE_LICENSE("GPL"); |
| @@ -12,7 +12,6 @@ · 11 unmodified lines | |||
| 12 | #include <linux/hid.h> | 12 | #include <linux/hid.h> |
| 13 | #include <linux/leds.h> | 13 | #include <linux/leds.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/usb.h> | ||
| 16 | 15 | ||
| 17 | #include "hid-ids.h" | 16 | #include "hid-ids.h" |
| 18 | 17 | ||
| @@ -30,7 +30,6 @@ · 29 unmodified lines | |||
| 30 | #include <linux/hid.h> | 30 | #include <linux/hid.h> |
| 31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include <linux/usb.h> | ||
| 34 | #include <linux/module.h> | 33 | #include <linux/module.h> |
| 35 | 34 | ||
| 36 | #include "hid-ids.h" | 35 | #include "hid-ids.h" |
| @@ -46,7 +45,6 @@ static const signed short ff_joystick[] = { · 9 unmodified lines | |||
| 46 | }; | 45 | }; |
| 47 | 46 | ||
| 48 | #ifdef CONFIG_THRUSTMASTER_FF | 47 | #ifdef CONFIG_THRUSTMASTER_FF |
| 49 | #include "usbhid/usbhid.h" | ||
| 50 | 48 | ||
| 51 | /* Usages for thrustmaster devices I know about */ | 49 | /* Usages for thrustmaster devices I know about */ |
| 52 | #define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) | 50 | #define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb) |
| @@ -103,7 +101,7 @@ static int tmff_play(struct input_dev *dev, void *data, · 50 unmodified lines | |||
| 103 | dbg_hid("(x, y)=(%04x, %04x)\n", x, y); | 101 | dbg_hid("(x, y)=(%04x, %04x)\n", x, y); |
| 104 | ff_field->value[0] = x; | 102 | ff_field->value[0] = x; |
| 105 | ff_field->value[1] = y; | 103 | ff_field->value[1] = y; |
| 106 | usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); | 104 | hid_hw_request(hid, tmff->report, HID_REQ_SET_REPORT); |
| 107 | break; | 105 | break; |
| 108 | 106 | ||
| 109 | case FF_RUMBLE: | 107 | case FF_RUMBLE: |
| @@ -117,7 +115,7 @@ static int tmff_play(struct input_dev *dev, void *data, · 7 unmodified lines | |||
| 117 | dbg_hid("(left,right)=(%08x, %08x)\n", left, right); | 115 | dbg_hid("(left,right)=(%08x, %08x)\n", left, right); |
| 118 | ff_field->value[0] = left; | 116 | ff_field->value[0] = left; |
| 119 | ff_field->value[1] = right; | 117 | ff_field->value[1] = right; |
| 120 | usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); | 118 | hid_hw_request(hid, tmff->report, HID_REQ_SET_REPORT); |
| 121 | break; | 119 | break; |
| 122 | } | 120 | } |
| 123 | return 0; | 121 | return 0; |
| @@ -789,12 +789,20 @@ static void __ir_to_input(struct wiimote_data *wdata, const __u8 *ir, · 788 unmodified lines | |||
| 789 | input_report_abs(wdata->ir, yid, y); | 789 | input_report_abs(wdata->ir, yid, y); |
| 790 | } | 790 | } |
| 791 | 791 | ||
| 792 | static void handler_status(struct wiimote_data *wdata, const __u8 *payload) | 792 | /* reduced status report with "BB BB" key data only */ |
| 793 | static void handler_status_K(struct wiimote_data *wdata, | ||
| 794 | const __u8 *payload) | ||
| 793 | { | 795 | { |
| 794 | handler_keys(wdata, payload); | 796 | handler_keys(wdata, payload); |
| 795 | 797 | ||
| 796 | /* on status reports the drm is reset so we need to resend the drm */ | 798 | /* on status reports the drm is reset so we need to resend the drm */ |
| 797 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); | 799 | wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL); |
| 800 | } | ||
| 801 | |||
| 802 | /* extended status report with "BB BB LF 00 00 VV" data */ | ||
| 803 | static void handler_status(struct wiimote_data *wdata, const __u8 *payload) | ||
| 804 | { | ||
| 805 | handler_status_K(wdata, payload); | ||
| 798 | 806 | ||
| 799 | wiiext_event(wdata, payload[2] & 0x02); | 807 | wiiext_event(wdata, payload[2] & 0x02); |
| 800 | 808 | ||
| @@ -804,6 +812,12 @@ static void handler_status(struct wiimote_data *wdata, const __u8 *payload) · 3 unmodified lines | |||
| 804 | } | 812 | } |
| 805 | } | 813 | } |
| 806 | 814 | ||
| 815 | /* reduced generic report with "BB BB" key data only */ | ||
| 816 | static void handler_generic_K(struct wiimote_data *wdata, const __u8 *payload) | ||
| 817 | { | ||
| 818 | handler_keys(wdata, payload); | ||
| 819 | } | ||
| 820 | |||
| 807 | static void handler_data(struct wiimote_data *wdata, const __u8 *payload) | 821 | static void handler_data(struct wiimote_data *wdata, const __u8 *payload) |
| 808 | { | 822 | { |
| 809 | __u16 offset = payload[3] << 8 | payload[4]; | 823 | __u16 offset = payload[3] << 8 | payload[4]; |
| @@ -947,16 +961,26 @@ struct wiiproto_handler { · 137 unmodified lines | |||
| 947 | 961 | ||
| 948 | static struct wiiproto_handler handlers[] = { | 962 | static struct wiiproto_handler handlers[] = { |
| 949 | { .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status }, | 963 | { .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status }, |
| 964 | { .id = WIIPROTO_REQ_STATUS, .size = 2, .func = handler_status_K }, | ||
| 950 | { .id = WIIPROTO_REQ_DATA, .size = 21, .func = handler_data }, | 965 | { .id = WIIPROTO_REQ_DATA, .size = 21, .func = handler_data }, |
| 966 | { .id = WIIPROTO_REQ_DATA, .size = 2, .func = handler_generic_K }, | ||
| 951 | { .id = WIIPROTO_REQ_RETURN, .size = 4, .func = handler_return }, | 967 | { .id = WIIPROTO_REQ_RETURN, .size = 4, .func = handler_return }, |
| 968 | { .id = WIIPROTO_REQ_RETURN, .size = 2, .func = handler_generic_K }, | ||
| 952 | { .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys }, | 969 | { .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys }, |
| 953 | { .id = WIIPROTO_REQ_DRM_KA, .size = 5, .func = handler_drm_KA }, | 970 | { .id = WIIPROTO_REQ_DRM_KA, .size = 5, .func = handler_drm_KA }, |
| 971 | { .id = WIIPROTO_REQ_DRM_KA, .size = 2, .func = handler_generic_K }, | ||
| 954 | { .id = WIIPROTO_REQ_DRM_KE, .size = 10, .func = handler_drm_KE }, | 972 | { .id = WIIPROTO_REQ_DRM_KE, .size = 10, .func = handler_drm_KE }, |
| 973 | { .id = WIIPROTO_REQ_DRM_KE, .size = 2, .func = handler_generic_K }, | ||
| 955 | { .id = WIIPROTO_REQ_DRM_KAI, .size = 17, .func = handler_drm_KAI }, | 974 | { .id = WIIPROTO_REQ_DRM_KAI, .size = 17, .func = handler_drm_KAI }, |
| 975 | { .id = WIIPROTO_REQ_DRM_KAI, .size = 2, .func = handler_generic_K }, | ||
| 956 | { .id = WIIPROTO_REQ_DRM_KEE, .size = 21, .func = handler_drm_KEE }, | 976 | { .id = WIIPROTO_REQ_DRM_KEE, .size = 21, .func = handler_drm_KEE }, |
| 977 | { .id = WIIPROTO_REQ_DRM_KEE, .size = 2, .func = handler_generic_K }, | ||
| 957 | { .id = WIIPROTO_REQ_DRM_KAE, .size = 21, .func = handler_drm_KAE }, | 978 | { .id = WIIPROTO_REQ_DRM_KAE, .size = 21, .func = handler_drm_KAE }, |
| 979 | { .id = WIIPROTO_REQ_DRM_KAE, .size = 2, .func = handler_generic_K }, | ||
| 958 | { .id = WIIPROTO_REQ_DRM_KIE, .size = 21, .func = handler_drm_KIE }, | 980 | { .id = WIIPROTO_REQ_DRM_KIE, .size = 21, .func = handler_drm_KIE }, |
| 981 | { .id = WIIPROTO_REQ_DRM_KIE, .size = 2, .func = handler_generic_K }, | ||
| 959 | { .id = WIIPROTO_REQ_DRM_KAIE, .size = 21, .func = handler_drm_KAIE }, | 982 | { .id = WIIPROTO_REQ_DRM_KAIE, .size = 21, .func = handler_drm_KAIE }, |
| 983 | { .id = WIIPROTO_REQ_DRM_KAIE, .size = 2, .func = handler_generic_K }, | ||
| 960 | { .id = WIIPROTO_REQ_DRM_E, .size = 21, .func = handler_drm_E }, | 984 | { .id = WIIPROTO_REQ_DRM_E, .size = 21, .func = handler_drm_E }, |
| 961 | { .id = WIIPROTO_REQ_DRM_SKAI1, .size = 21, .func = handler_drm_SKAI1 }, | 985 | { .id = WIIPROTO_REQ_DRM_SKAI1, .size = 21, .func = handler_drm_SKAI1 }, |
| 962 | { .id = WIIPROTO_REQ_DRM_SKAI2, .size = 21, .func = handler_drm_SKAI2 }, | 986 | { .id = WIIPROTO_REQ_DRM_SKAI2, .size = 21, .func = handler_drm_SKAI2 }, |
| @@ -970,7 +994,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, · 7 unmodified lines | |||
| 970 | struct wiiproto_handler *h; | 994 | struct wiiproto_handler *h; |
| 971 | int i; | 995 | int i; |
| 972 | unsigned long flags; | 996 | unsigned long flags; |
| 973 | bool handled = false; | ||
| 974 | 997 | ||
| 975 | if (size < 1) | 998 | if (size < 1) |
| 976 | return -EINVAL; | 999 | return -EINVAL; |
| @@ -981,11 +1004,11 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, · 4 unmodified lines | |||
| 981 | h = &handlers[i]; | 1004 | h = &handlers[i]; |
| 982 | if (h->id == raw_data[0] && h->size < size) { | 1005 | if (h->id == raw_data[0] && h->size < size) { |
| 983 | h->func(wdata, &raw_data[1]); | 1006 | h->func(wdata, &raw_data[1]); |
| 984 | handled = true; | 1007 | break; |
| 985 | } | 1008 | } |
| 986 | } | 1009 | } |
| 987 | 1010 | ||
| 988 | if (!handled) | 1011 | if (!handlers[i].id) |
| 989 | hid_warn(hdev, "Unhandled report %hhu size %d\n", raw_data[0], | 1012 | hid_warn(hdev, "Unhandled report %hhu size %d\n", raw_data[0], |
| 990 | size); | 1013 | size); |
| 991 | 1014 | ||
| @@ -1160,6 +1183,7 @@ static void wiimote_destroy(struct wiimote_data *wdata) · 168 unmodified lines | |||
| 1160 | wiimote_leds_destroy(wdata); | 1183 | wiimote_leds_destroy(wdata); |
| 1161 | 1184 | ||
| 1162 | power_supply_unregister(&wdata->battery); | 1185 | power_supply_unregister(&wdata->battery); |
| 1186 | kfree(wdata->battery.name); | ||
| 1163 | input_unregister_device(wdata->accel); | 1187 | input_unregister_device(wdata->accel); |
| 1164 | input_unregister_device(wdata->ir); | 1188 | input_unregister_device(wdata->ir); |
| 1165 | input_unregister_device(wdata->input); | 1189 | input_unregister_device(wdata->input); |
| @@ -1216,9 +1240,14 @@ static int wiimote_hid_probe(struct hid_device *hdev, · 50 unmodified lines | |||
| 1216 | wdata->battery.properties = wiimote_battery_props; | 1240 | wdata->battery.properties = wiimote_battery_props; |
| 1217 | wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props); | 1241 | wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props); |
| 1218 | wdata->battery.get_property = wiimote_battery_get_property; | 1242 | wdata->battery.get_property = wiimote_battery_get_property; |
| 1219 | wdata->battery.name = "wiimote_battery"; | ||
| 1220 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; | 1243 | wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY; |
| 1221 | wdata->battery.use_for_apm = 0; | 1244 | wdata->battery.use_for_apm = 0; |
| 1245 | wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s", | ||
| 1246 | wdata->hdev->uniq); | ||
| 1247 | if (!wdata->battery.name) { | ||
| 1248 | ret = -ENOMEM; | ||
| 1249 | goto err_battery_name; | ||
| 1250 | } | ||
| 1222 | 1251 | ||
| 1223 | ret = power_supply_register(&wdata->hdev->dev, &wdata->battery); | 1252 | ret = power_supply_register(&wdata->hdev->dev, &wdata->battery); |
| 1224 | if (ret) { | 1253 | if (ret) { |
| @@ -1254,6 +1283,8 @@ err_free: · 29 unmodified lines | |||
| 1254 | return ret; | 1283 | return ret; |
| 1255 | 1284 | ||
| 1256 | err_battery: | 1285 | err_battery: |
| 1286 | kfree(wdata->battery.name); | ||
| 1287 | err_battery_name: | ||
| 1257 | input_unregister_device(wdata->input); | 1288 | input_unregister_device(wdata->input); |
| 1258 | wdata->input = NULL; | 1289 | wdata->input = NULL; |
| 1259 | err_input: | 1290 | err_input: |
| @@ -1283,6 +1314,8 @@ static void wiimote_hid_remove(struct hid_device *hdev) · 23 unmodified lines | |||
| 1283 | static const struct hid_device_id wiimote_hid_devices[] = { | 1314 | static const struct hid_device_id wiimote_hid_devices[] = { |
| 1284 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, | 1315 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, |
| 1285 | USB_DEVICE_ID_NINTENDO_WIIMOTE) }, | 1316 | USB_DEVICE_ID_NINTENDO_WIIMOTE) }, |
| 1317 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, | ||
| 1318 | USB_DEVICE_ID_NINTENDO_WIIMOTE2) }, | ||
| 1286 | { } | 1319 | { } |
| 1287 | }; | 1320 | }; |
| 1288 | MODULE_DEVICE_TABLE(hid, wiimote_hid_devices); | 1321 | MODULE_DEVICE_TABLE(hid, wiimote_hid_devices); |
| @@ -24,13 +24,11 @@ · 23 unmodified lines | |||
| 24 | #include <linux/hid.h> | 24 | #include <linux/hid.h> |
| 25 | #include <linux/input.h> | 25 | #include <linux/input.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/usb.h> | ||
| 28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 29 | 28 | ||
| 30 | #include "hid-ids.h" | 29 | #include "hid-ids.h" |
| 31 | 30 | ||
| 32 | #ifdef CONFIG_ZEROPLUS_FF | 31 | #ifdef CONFIG_ZEROPLUS_FF |
| 33 | #include "usbhid/usbhid.h" | ||
| 34 | 32 | ||
| 35 | struct zpff_device { | 33 | struct zpff_device { |
| 36 | struct hid_report *report; | 34 | struct hid_report *report; |
| @@ -59,7 +57,7 @@ static int zpff_play(struct input_dev *dev, void *data, · 22 unmodified lines | |||
| 59 | zpff->report->field[2]->value[0] = left; | 57 | zpff->report->field[2]->value[0] = left; |
| 60 | zpff->report->field[3]->value[0] = right; | 58 | zpff->report->field[3]->value[0] = right; |
| 61 | dbg_hid("running with 0x%02x 0x%02x\n", left, right); | 59 | dbg_hid("running with 0x%02x 0x%02x\n", left, right); |
| 62 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); | 60 | hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT); |
| 63 | 61 | ||
| 64 | return 0; | 62 | return 0; |
| 65 | } | 63 | } |
| @@ -104,7 +102,7 @@ static int zpff_init(struct hid_device *hid) · 38 unmodified lines | |||
| 104 | zpff->report->field[1]->value[0] = 0x02; | 102 | zpff->report->field[1]->value[0] = 0x02; |
| 105 | zpff->report->field[2]->value[0] = 0x00; | 103 | zpff->report->field[2]->value[0] = 0x00; |
| 106 | zpff->report->field[3]->value[0] = 0x00; | 104 | zpff->report->field[3]->value[0] = 0x00; |
| 107 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); | 105 | hid_hw_request(hid, zpff->report, HID_REQ_SET_REPORT); |
| 108 | 106 | ||
| 109 | hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); | 107 | hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula <anssi.hannula@gmail.com>\n"); |
| 110 | 108 | ||
| @@ -563,6 +563,36 @@ static int i2c_hid_output_raw_report(struct hid_device *hid, __u8 *buf, · 562 unmodified lines | |||
| 563 | return ret; | 563 | return ret; |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | static void i2c_hid_request(struct hid_device *hid, struct hid_report *rep, | ||
| 567 | int reqtype) | ||
| 568 | { | ||
| 569 | struct i2c_client *client = hid->driver_data; | ||
| 570 | char *buf; | ||
| 571 | int ret; | ||
| 572 | int len = i2c_hid_get_report_length(rep) - 2; | ||
| 573 | |||
| 574 | buf = kzalloc(len, GFP_KERNEL); | ||
| 575 | if (!buf) | ||
| 576 | return; | ||
| 577 | |||
| 578 | switch (reqtype) { | ||
| 579 | case HID_REQ_GET_REPORT: | ||
| 580 | ret = i2c_hid_get_raw_report(hid, rep->id, buf, len, rep->type); | ||
| 581 | if (ret < 0) | ||
| 582 | dev_err(&client->dev, "%s: unable to get report: %d\n", | ||
| 583 | __func__, ret); | ||
| 584 | else | ||
| 585 | hid_input_report(hid, rep->type, buf, ret, 0); | ||
| 586 | break; | ||
| 587 | case HID_REQ_SET_REPORT: | ||
| 588 | hid_output_report(rep, buf); | ||
| 589 | i2c_hid_output_raw_report(hid, buf, len, rep->type); | ||
| 590 | break; | ||
| 591 | } | ||
| 592 | |||
| 593 | kfree(buf); | ||
| 594 | } | ||
| 595 | |||
| 566 | static int i2c_hid_parse(struct hid_device *hid) | 596 | static int i2c_hid_parse(struct hid_device *hid) |
| 567 | { | 597 | { |
| 568 | struct i2c_client *client = hid->driver_data; | 598 | struct i2c_client *client = hid->driver_data; |
| @@ -742,6 +772,7 @@ static struct hid_ll_driver i2c_hid_ll_driver = { · 173 unmodified lines | |||
| 742 | .open = i2c_hid_open, | 772 | .open = i2c_hid_open, |
| 743 | .close = i2c_hid_close, | 773 | .close = i2c_hid_close, |
| 744 | .power = i2c_hid_power, | 774 | .power = i2c_hid_power, |
| 775 | .request = i2c_hid_request, | ||
| 745 | .hidinput_input_event = i2c_hid_hidinput_input_event, | 776 | .hidinput_input_event = i2c_hid_hidinput_input_event, |
| 746 | }; | 777 | }; |
| 747 | 778 | ||
| @@ -639,7 +639,7 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re · 638 unmodified lines | |||
| 639 | } | 639 | } |
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) | 642 | static void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) |
| 643 | { | 643 | { |
| 644 | struct usbhid_device *usbhid = hid->driver_data; | 644 | struct usbhid_device *usbhid = hid->driver_data; |
| 645 | unsigned long flags; | 645 | unsigned long flags; |
| @@ -648,7 +648,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns · 2 unmodified lines | |||
| 648 | __usbhid_submit_report(hid, report, dir); | 648 | __usbhid_submit_report(hid, report, dir); |
| 649 | spin_unlock_irqrestore(&usbhid->lock, flags); | 649 | spin_unlock_irqrestore(&usbhid->lock, flags); |
| 650 | } | 650 | } |
| 651 | EXPORT_SYMBOL_GPL(usbhid_submit_report); | ||
| 652 | 651 | ||
| 653 | /* Workqueue routine to send requests to change LEDs */ | 652 | /* Workqueue routine to send requests to change LEDs */ |
| 654 | static void hid_led(struct work_struct *work) | 653 | static void hid_led(struct work_struct *work) |
| @@ -706,7 +705,7 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un · 51 unmodified lines | |||
| 706 | return 0; | 705 | return 0; |
| 707 | } | 706 | } |
| 708 | 707 | ||
| 709 | int usbhid_wait_io(struct hid_device *hid) | 708 | static int usbhid_wait_io(struct hid_device *hid) |
| 710 | { | 709 | { |
| 711 | struct usbhid_device *usbhid = hid->driver_data; | 710 | struct usbhid_device *usbhid = hid->driver_data; |
| 712 | 711 | ||
| @@ -720,7 +719,6 @@ int usbhid_wait_io(struct hid_device *hid) · 7 unmodified lines | |||
| 720 | 719 | ||
| 721 | return 0; | 720 | return 0; |
| 722 | } | 721 | } |
| 723 | EXPORT_SYMBOL_GPL(usbhid_wait_io); | ||
| 724 | 722 | ||
| 725 | static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) | 723 | static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle) |
| 726 | { | 724 | { |
| @@ -1243,6 +1241,32 @@ static int usbhid_power(struct hid_device *hid, int lvl) · 516 unmodified lines | |||
| 1243 | return r; | 1241 | return r; |
| 1244 | } | 1242 | } |
| 1245 | 1243 | ||
| 1244 | static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int reqtype) | ||
| 1245 | { | ||
| 1246 | switch (reqtype) { | ||
| 1247 | case HID_REQ_GET_REPORT: | ||
| 1248 | usbhid_submit_report(hid, rep, USB_DIR_IN); | ||
| 1249 | break; | ||
| 1250 | case HID_REQ_SET_REPORT: | ||
| 1251 | usbhid_submit_report(hid, rep, USB_DIR_OUT); | ||
| 1252 | break; | ||
| 1253 | } | ||
| 1254 | } | ||
| 1255 | |||
| 1256 | static int usbhid_idle(struct hid_device *hid, int report, int idle, | ||
| 1257 | int reqtype) | ||
| 1258 | { | ||
| 1259 | struct usb_device *dev = hid_to_usb_dev(hid); | ||
| 1260 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | ||
| 1261 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
| 1262 | int ifnum = interface->desc.bInterfaceNumber; | ||
| 1263 | |||
| 1264 | if (reqtype != HID_REQ_SET_IDLE) | ||
| 1265 | return -EINVAL; | ||
| 1266 | |||
| 1267 | return hid_set_idle(dev, ifnum, report, idle); | ||
| 1268 | } | ||
| 1269 | |||
| 1246 | static struct hid_ll_driver usb_hid_driver = { | 1270 | static struct hid_ll_driver usb_hid_driver = { |
| 1247 | .parse = usbhid_parse, | 1271 | .parse = usbhid_parse, |
| 1248 | .start = usbhid_start, | 1272 | .start = usbhid_start, |
| @@ -1251,6 +1275,9 @@ static struct hid_ll_driver usb_hid_driver = { · 2 unmodified lines | |||
| 1251 | .close = usbhid_close, | 1275 | .close = usbhid_close, |
| 1252 | .power = usbhid_power, | 1276 | .power = usbhid_power, |
| 1253 | .hidinput_input_event = usb_hidinput_input_event, | 1277 | .hidinput_input_event = usb_hidinput_input_event, |
| 1278 | .request = usbhid_request, | ||
| 1279 | .wait = usbhid_wait_io, | ||
| 1280 | .idle = usbhid_idle, | ||
| 1254 | }; | 1281 | }; |
| 1255 | 1282 | ||
| 1256 | static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1283 | static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) |
| @@ -263,8 +263,8 @@ static void pidff_set_envelope_report(struct pidff_device *pidff, · 262 unmodified lines | |||
| 263 | envelope->attack_level, | 263 | envelope->attack_level, |
| 264 | pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); | 264 | pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); |
| 265 | 265 | ||
| 266 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], | 266 | hid_hw_request(pidff->hid, pidff->reports[PID_SET_ENVELOPE], |
| 267 | USB_DIR_OUT); | 267 | HID_REQ_SET_REPORT); |
| 268 | } | 268 | } |
| 269 | 269 | ||
| 270 | /* | 270 | /* |
| @@ -290,8 +290,8 @@ static void pidff_set_constant_force_report(struct pidff_device *pidff, · 19 unmodified lines | |||
| 290 | pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE], | 290 | pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE], |
| 291 | effect->u.constant.level); | 291 | effect->u.constant.level); |
| 292 | 292 | ||
| 293 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT], | 293 | hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONSTANT], |
| 294 | USB_DIR_OUT); | 294 | HID_REQ_SET_REPORT); |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | /* | 297 | /* |
| @@ -325,8 +325,8 @@ static void pidff_set_effect_report(struct pidff_device *pidff, · 27 unmodified lines | |||
| 325 | pidff->effect_direction); | 325 | pidff->effect_direction); |
| 326 | pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; | 326 | pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; |
| 327 | 327 | ||
| 328 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], | 328 | hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT], |
| 329 | USB_DIR_OUT); | 329 | HID_REQ_SET_REPORT); |
| 330 | } | 330 | } |
| 331 | 331 | ||
| 332 | /* | 332 | /* |
| @@ -357,8 +357,8 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, · 24 unmodified lines | |||
| 357 | pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); | 357 | pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); |
| 358 | pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; | 358 | pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; |
| 359 | 359 | ||
| 360 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC], | 360 | hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC], |
| 361 | USB_DIR_OUT); | 361 | HID_REQ_SET_REPORT); |
| 362 | 362 | ||
| 363 | } | 363 | } |
| 364 | 364 | ||
| @@ -399,8 +399,8 @@ static void pidff_set_condition_report(struct pidff_device *pidff, · 34 unmodified lines | |||
| 399 | effect->u.condition[i].left_saturation); | 399 | effect->u.condition[i].left_saturation); |
| 400 | pidff_set(&pidff->set_condition[PID_DEAD_BAND], | 400 | pidff_set(&pidff->set_condition[PID_DEAD_BAND], |
| 401 | effect->u.condition[i].deadband); | 401 | effect->u.condition[i].deadband); |
| 402 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], | 402 | hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONDITION], |
| 403 | USB_DIR_OUT); | 403 | HID_REQ_SET_REPORT); |
| 404 | } | 404 | } |
| 405 | } | 405 | } |
| 406 | 406 | ||
| @@ -440,8 +440,8 @@ static void pidff_set_ramp_force_report(struct pidff_device *pidff, · 33 unmodified lines | |||
| 440 | effect->u.ramp.start_level); | 440 | effect->u.ramp.start_level); |
| 441 | pidff_set_signed(&pidff->set_ramp[PID_RAMP_END], | 441 | pidff_set_signed(&pidff->set_ramp[PID_RAMP_END], |
| 442 | effect->u.ramp.end_level); | 442 | effect->u.ramp.end_level); |
| 443 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP], | 443 | hid_hw_request(pidff->hid, pidff->reports[PID_SET_RAMP], |
| 444 | USB_DIR_OUT); | 444 | HID_REQ_SET_REPORT); |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | /* | 447 | /* |
| @@ -465,19 +465,19 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) · 17 unmodified lines | |||
| 465 | int j; | 465 | int j; |
| 466 | 466 | ||
| 467 | pidff->create_new_effect_type->value[0] = efnum; | 467 | pidff->create_new_effect_type->value[0] = efnum; |
| 468 | usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], | 468 | hid_hw_request(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], |
| 469 | USB_DIR_OUT); | 469 | HID_REQ_SET_REPORT); |
| 470 | hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum); | 470 | hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum); |
| 471 | 471 | ||
| 472 | pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; | 472 | pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; |
| 473 | pidff->block_load_status->value[0] = 0; | 473 | pidff->block_load_status->value[0] = 0; |
| 474 | usbhid_wait_io(pidff->hid); | 474 | hid_hw_wait(pidff->hid); |
| 475 | 475 | ||
| 476 | for (j = 0; j < 60; j++) { | 476 | for (j = 0; j < 60; j++) { |
| 477 | hid_dbg(pidff->hid, "pid_block_load requested\n"); | 477 | hid_dbg(pidff->hid, "pid_block_load requested\n"); |
| 478 | usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], | 478 | hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_LOAD], |
| 479 | USB_DIR_IN); | 479 | HID_REQ_GET_REPORT); |
| 480 | usbhid_wait_io(pidff->hid); | 480 | hid_hw_wait(pidff->hid); |
| 481 | if (pidff->block_load_status->value[0] == | 481 | if (pidff->block_load_status->value[0] == |
| 482 | pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { | 482 | pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { |
| 483 | hid_dbg(pidff->hid, "device reported free memory: %d bytes\n", | 483 | hid_dbg(pidff->hid, "device reported free memory: %d bytes\n", |
| @@ -513,8 +513,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n) · 29 unmodified lines | |||
| 513 | pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; | 513 | pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], | 516 | hid_hw_request(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], |
| 517 | USB_DIR_OUT); | 517 | HID_REQ_SET_REPORT); |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | /** | 520 | /** |
| @@ -535,8 +535,8 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value) · 14 unmodified lines | |||
| 535 | static void pidff_erase_pid(struct pidff_device *pidff, int pid_id) | 535 | static void pidff_erase_pid(struct pidff_device *pidff, int pid_id) |
| 536 | { | 536 | { |
| 537 | pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id; | 537 | pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id; |
| 538 | usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE], | 538 | hid_hw_request(pidff->hid, pidff->reports[PID_BLOCK_FREE], |
| 539 | USB_DIR_OUT); | 539 | HID_REQ_SET_REPORT); |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | /* | 542 | /* |
| @@ -551,7 +551,7 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id) · 8 unmodified lines | |||
| 551 | effect_id, pidff->pid_id[effect_id]); | 551 | effect_id, pidff->pid_id[effect_id]); |
| 552 | /* Wait for the queue to clear. We do not want a full fifo to | 552 | /* Wait for the queue to clear. We do not want a full fifo to |
| 553 | prevent the effect removal. */ | 553 | prevent the effect removal. */ |
| 554 | usbhid_wait_io(pidff->hid); | 554 | hid_hw_wait(pidff->hid); |
| 555 | pidff_playback_pid(pidff, pid_id, 0); | 555 | pidff_playback_pid(pidff, pid_id, 0); |
| 556 | pidff_erase_pid(pidff, pid_id); | 556 | pidff_erase_pid(pidff, pid_id); |
| 557 | 557 | ||
| @@ -718,8 +718,8 @@ static void pidff_set_gain(struct input_dev *dev, u16 gain) · 160 unmodified lines | |||
| 718 | struct pidff_device *pidff = dev->ff->private; | 718 | struct pidff_device *pidff = dev->ff->private; |
| 719 | 719 | ||
| 720 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain); | 720 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain); |
| 721 | usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], | 721 | hid_hw_request(pidff->hid, pidff->reports[PID_DEVICE_GAIN], |
| 722 | USB_DIR_OUT); | 722 | HID_REQ_SET_REPORT); |
| 723 | } | 723 | } |
| 724 | 724 | ||
| 725 | static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) | 725 | static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) |
| @@ -744,8 +744,8 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) · 18 unmodified lines | |||
| 744 | pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1; | 744 | pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1; |
| 745 | pidff->set_effect[PID_START_DELAY].value[0] = 0; | 745 | pidff->set_effect[PID_START_DELAY].value[0] = 0; |
| 746 | 746 | ||
| 747 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], | 747 | hid_hw_request(pidff->hid, pidff->reports[PID_SET_EFFECT], |
| 748 | USB_DIR_OUT); | 748 | HID_REQ_SET_REPORT); |
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | /* | 751 | /* |
| @@ -1158,19 +1158,19 @@ static void pidff_reset(struct pidff_device *pidff) · 406 unmodified lines | |||
| 1158 | 1158 | ||
| 1159 | pidff->device_control->value[0] = pidff->control_id[PID_RESET]; | 1159 | pidff->device_control->value[0] = pidff->control_id[PID_RESET]; |
| 1160 | /* We reset twice as sometimes hid_wait_io isn't waiting long enough */ | 1160 | /* We reset twice as sometimes hid_wait_io isn't waiting long enough */ |
| 1161 | usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); | 1161 | hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); |
| 1162 | usbhid_wait_io(hid); | 1162 | hid_hw_wait(hid); |
| 1163 | usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); | 1163 | hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); |
| 1164 | usbhid_wait_io(hid); | 1164 | hid_hw_wait(hid); |
| 1165 | 1165 | ||
| 1166 | pidff->device_control->value[0] = | 1166 | pidff->device_control->value[0] = |
| 1167 | pidff->control_id[PID_ENABLE_ACTUATORS]; | 1167 | pidff->control_id[PID_ENABLE_ACTUATORS]; |
| 1168 | usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); | 1168 | hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT); |
| 1169 | usbhid_wait_io(hid); | 1169 | hid_hw_wait(hid); |
| 1170 | 1170 | ||
| 1171 | /* pool report is sometimes messed up, refetch it */ | 1171 | /* pool report is sometimes messed up, refetch it */ |
| 1172 | usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); | 1172 | hid_hw_request(hid, pidff->reports[PID_POOL], HID_REQ_GET_REPORT); |
| 1173 | usbhid_wait_io(hid); | 1173 | hid_hw_wait(hid); |
| 1174 | 1174 | ||
| 1175 | if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { | 1175 | if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { |
| 1176 | while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) { | 1176 | while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) { |
| @@ -1181,9 +1181,9 @@ static void pidff_reset(struct pidff_device *pidff) · 4 unmodified lines | |||
| 1181 | break; | 1181 | break; |
| 1182 | } | 1182 | } |
| 1183 | hid_dbg(pidff->hid, "pid_pool requested again\n"); | 1183 | hid_dbg(pidff->hid, "pid_pool requested again\n"); |
| 1184 | usbhid_submit_report(hid, pidff->reports[PID_POOL], | 1184 | hid_hw_request(hid, pidff->reports[PID_POOL], |
| 1185 | USB_DIR_IN); | 1185 | HID_REQ_GET_REPORT); |
| 1186 | usbhid_wait_io(hid); | 1186 | hid_hw_wait(hid); |
| 1187 | } | 1187 | } |
| 1188 | } | 1188 | } |
| 1189 | } | 1189 | } |
| @@ -1269,8 +1269,8 @@ int hid_pidff_init(struct hid_device *hid) · 79 unmodified lines | |||
| 1269 | 1269 | ||
| 1270 | if (test_bit(FF_GAIN, dev->ffbit)) { | 1270 | if (test_bit(FF_GAIN, dev->ffbit)) { |
| 1271 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); | 1271 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); |
| 1272 | usbhid_submit_report(hid, pidff->reports[PID_DEVICE_GAIN], | 1272 | hid_hw_request(hid, pidff->reports[PID_DEVICE_GAIN], |
| 1273 | USB_DIR_OUT); | 1273 | HID_REQ_SET_REPORT); |
| 1274 | } | 1274 | } |
| 1275 | 1275 | ||
| 1276 | error = pidff_check_autocenter(pidff, dev); | 1276 | error = pidff_check_autocenter(pidff, dev); |
| @@ -705,8 +705,8 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 704 unmodified lines | |||
| 705 | if (report == NULL) | 705 | if (report == NULL) |
| 706 | break; | 706 | break; |
| 707 | 707 | ||
| 708 | usbhid_submit_report(hid, report, USB_DIR_IN); | 708 | hid_hw_request(hid, report, HID_REQ_GET_REPORT); |
| 709 | usbhid_wait_io(hid); | 709 | hid_hw_wait(hid); |
| 710 | 710 | ||
| 711 | r = 0; | 711 | r = 0; |
| 712 | break; | 712 | break; |
| @@ -724,8 +724,8 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 11 unmodified lines | |||
| 724 | if (report == NULL) | 724 | if (report == NULL) |
| 725 | break; | 725 | break; |
| 726 | 726 | ||
| 727 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 727 | hid_hw_request(hid, report, HID_REQ_SET_REPORT); |
| 728 | usbhid_wait_io(hid); | 728 | hid_hw_wait(hid); |
| 729 | 729 | ||
| 730 | r = 0; | 730 | r = 0; |
| 731 | break; | 731 | break; |
| @@ -34,12 +34,9 @@ · 33 unmodified lines | |||
| 34 | #include <linux/input.h> | 34 | #include <linux/input.h> |
| 35 | 35 | ||
| 36 | /* API provided by hid-core.c for USB HID drivers */ | 36 | /* API provided by hid-core.c for USB HID drivers */ |
| 37 | int usbhid_wait_io(struct hid_device* hid); | ||
| 38 | void usbhid_close(struct hid_device *hid); | 37 | void usbhid_close(struct hid_device *hid); |
| 39 | int usbhid_open(struct hid_device *hid); | 38 | int usbhid_open(struct hid_device *hid); |
| 40 | void usbhid_init_reports(struct hid_device *hid); | 39 | void usbhid_init_reports(struct hid_device *hid); |
| 41 | void usbhid_submit_report | ||
| 42 | (struct hid_device *hid, struct hid_report *report, unsigned char dir); | ||
| 43 | int usbhid_get_power(struct hid_device *hid); | 40 | int usbhid_get_power(struct hid_device *hid); |
| 44 | void usbhid_put_power(struct hid_device *hid); | 41 | void usbhid_put_power(struct hid_device *hid); |
| 45 | struct usb_interface *usbhid_find_interface(int minor); | 42 | struct usb_interface *usbhid_find_interface(int minor); |
| @@ -22,11 +22,12 @@ · 21 unmodified lines | |||
| 22 | * | 22 | * |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #define HID_DEBUG_BUFSIZE 512 | ||
| 26 | |||
| 27 | #ifdef CONFIG_DEBUG_FS | 25 | #ifdef CONFIG_DEBUG_FS |
| 28 | 26 | ||
| 27 | #define HID_DEBUG_BUFSIZE 512 | ||
| 28 | |||
| 29 | void hid_dump_input(struct hid_device *, struct hid_usage *, __s32); | 29 | void hid_dump_input(struct hid_device *, struct hid_usage *, __s32); |
| 30 | void hid_dump_report(struct hid_device *, int , u8 *, int); | ||
| 30 | void hid_dump_device(struct hid_device *, struct seq_file *); | 31 | void hid_dump_device(struct hid_device *, struct seq_file *); |
| 31 | void hid_dump_field(struct hid_field *, int, struct seq_file *); | 32 | void hid_dump_field(struct hid_field *, int, struct seq_file *); |
| 32 | char *hid_resolv_usage(unsigned, struct seq_file *); | 33 | char *hid_resolv_usage(unsigned, struct seq_file *); |
| @@ -50,6 +51,7 @@ struct hid_debug_list { · 17 unmodified lines | |||
| 50 | #else | 51 | #else |
| 51 | 52 | ||
| 52 | #define hid_dump_input(a,b,c) do { } while (0) | 53 | #define hid_dump_input(a,b,c) do { } while (0) |
| 54 | #define hid_dump_report(a,b,c,d) do { } while (0) | ||
| 53 | #define hid_dump_device(a,b) do { } while (0) | 55 | #define hid_dump_device(a,b) do { } while (0) |
| 54 | #define hid_dump_field(a,b,c) do { } while (0) | 56 | #define hid_dump_field(a,b,c) do { } while (0) |
| 55 | #define hid_resolv_usage(a,b) do { } while (0) | 57 | #define hid_resolv_usage(a,b) do { } while (0) |
| @@ -282,6 +282,7 @@ struct hid_item { · 281 unmodified lines | |||
| 282 | #define HID_QUIRK_BADPAD 0x00000020 | 282 | #define HID_QUIRK_BADPAD 0x00000020 |
| 283 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | 283 | #define HID_QUIRK_MULTI_INPUT 0x00000040 |
| 284 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 | 284 | #define HID_QUIRK_HIDINPUT_FORCE 0x00000080 |
| 285 | #define HID_QUIRK_NO_EMPTY_INPUT 0x00000100 | ||
| 285 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 286 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
| 286 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 | 287 | #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 |
| 287 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 | 288 | #define HID_QUIRK_NO_INIT_REPORTS 0x20000000 |
| @@ -456,7 +457,8 @@ struct hid_device { /* device report descriptor */ · 168 unmodified lines | |||
| 456 | unsigned country; /* HID country */ | 457 | unsigned country; /* HID country */ |
| 457 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; | 458 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; |
| 458 | 459 | ||
| 459 | struct semaphore driver_lock; /* protects the current driver */ | 460 | struct semaphore driver_lock; /* protects the current driver, except during input */ |
| 461 | struct semaphore driver_input_lock; /* protects the current driver */ | ||
| 460 | struct device dev; /* device */ | 462 | struct device dev; /* device */ |
| 461 | struct hid_driver *driver; | 463 | struct hid_driver *driver; |
| 462 | struct hid_ll_driver *ll_driver; | 464 | struct hid_ll_driver *ll_driver; |
| @@ -477,6 +479,7 @@ struct hid_device { /* device report descriptor */ · 14 unmodified lines | |||
| 477 | unsigned int status; /* see STAT flags above */ | 479 | unsigned int status; /* see STAT flags above */ |
| 478 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | 480 | unsigned claimed; /* Claimed by hidinput, hiddev? */ |
| 479 | unsigned quirks; /* Various quirks the device can pull on us */ | 481 | unsigned quirks; /* Various quirks the device can pull on us */ |
| 482 | bool io_started; /* Protected by driver_lock. If IO has started */ | ||
| 480 | 483 | ||
| 481 | struct list_head inputs; /* The list of inputs */ | 484 | struct list_head inputs; /* The list of inputs */ |
| 482 | void *hiddev; /* The hiddev structure */ | 485 | void *hiddev; /* The hiddev structure */ |
| @@ -512,6 +515,7 @@ struct hid_device { /* device report descriptor */ · 29 unmodified lines | |||
| 512 | struct dentry *debug_rdesc; | 515 | struct dentry *debug_rdesc; |
| 513 | struct dentry *debug_events; | 516 | struct dentry *debug_events; |
| 514 | struct list_head debug_list; | 517 | struct list_head debug_list; |
| 518 | struct mutex debug_list_lock; | ||
| 515 | wait_queue_head_t debug_wait; | 519 | wait_queue_head_t debug_wait; |
| 516 | }; | 520 | }; |
| 517 | 521 | ||
| @@ -599,6 +603,10 @@ struct hid_usage_id { · 81 unmodified lines | |||
| 599 | * @resume: invoked on resume if device was not reset (NULL means nop) | 603 | * @resume: invoked on resume if device was not reset (NULL means nop) |
| 600 | * @reset_resume: invoked on resume if device was reset (NULL means nop) | 604 | * @reset_resume: invoked on resume if device was reset (NULL means nop) |
| 601 | * | 605 | * |
| 606 | * probe should return -errno on error, or 0 on success. During probe, | ||
| 607 | * input will not be passed to raw_event unless hid_device_io_start is | ||
| 608 | * called. | ||
| 609 | * | ||
| 602 | * raw_event and event should return 0 on no action performed, 1 when no | 610 | * raw_event and event should return 0 on no action performed, 1 when no |
| 603 | * further processing should be done and negative on error | 611 | * further processing should be done and negative on error |
| 604 | * | 612 | * |
| @@ -662,6 +670,9 @@ struct hid_driver { · 57 unmodified lines | |||
| 662 | * @hidinput_input_event: event input event (e.g. ff or leds) | 670 | * @hidinput_input_event: event input event (e.g. ff or leds) |
| 663 | * @parse: this method is called only once to parse the device data, | 671 | * @parse: this method is called only once to parse the device data, |
| 664 | * shouldn't allocate anything to not leak memory | 672 | * shouldn't allocate anything to not leak memory |
| 673 | * @request: send report request to device (e.g. feature report) | ||
| 674 | * @wait: wait for buffered io to complete (send/recv reports) | ||
| 675 | * @idle: send idle request to device | ||
| 665 | */ | 676 | */ |
| 666 | struct hid_ll_driver { | 677 | struct hid_ll_driver { |
| 667 | int (*start)(struct hid_device *hdev); | 678 | int (*start)(struct hid_device *hdev); |
| @@ -676,6 +687,13 @@ struct hid_ll_driver { · 8 unmodified lines | |||
| 676 | unsigned int code, int value); | 687 | unsigned int code, int value); |
| 677 | 688 | ||
| 678 | int (*parse)(struct hid_device *hdev); | 689 | int (*parse)(struct hid_device *hdev); |
| 690 | |||
| 691 | void (*request)(struct hid_device *hdev, | ||
| 692 | struct hid_report *report, int reqtype); | ||
| 693 | |||
| 694 | int (*wait)(struct hid_device *hdev); | ||
| 695 | int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); | ||
| 696 | |||
| 679 | }; | 697 | }; |
| 680 | 698 | ||
| 681 | #define PM_HINT_FULLON 1<<5 | 699 | #define PM_HINT_FULLON 1<<5 |
| @@ -737,6 +755,44 @@ const struct hid_device_id *hid_match_id(struct hid_device *hdev, · 55 unmodified lines | |||
| 737 | const struct hid_device_id *id); | 755 | const struct hid_device_id *id); |
| 738 | s32 hid_snto32(__u32 value, unsigned n); | 756 | s32 hid_snto32(__u32 value, unsigned n); |
| 739 | 757 | ||
| 758 | /** | ||
| 759 | * hid_device_io_start - enable HID input during probe, remove | ||
| 760 | * | ||
| 761 | * @hid - the device | ||
| 762 | * | ||
| 763 | * This should only be called during probe or remove and only be | ||
| 764 | * called by the thread calling probe or remove. It will allow | ||
| 765 | * incoming packets to be delivered to the driver. | ||
| 766 | */ | ||
| 767 | static inline void hid_device_io_start(struct hid_device *hid) { | ||
| 768 | if (hid->io_started) { | ||
| 769 | dev_warn(&hid->dev, "io already started"); | ||
| 770 | return; | ||
| 771 | } | ||
| 772 | hid->io_started = true; | ||
| 773 | up(&hid->driver_input_lock); | ||
| 774 | } | ||
| 775 | |||
| 776 | /** | ||
| 777 | * hid_device_io_stop - disable HID input during probe, remove | ||
| 778 | * | ||
| 779 | * @hid - the device | ||
| 780 | * | ||
| 781 | * Should only be called after hid_device_io_start. It will prevent | ||
| 782 | * incoming packets from going to the driver for the duration of | ||
| 783 | * probe, remove. If called during probe, packets will still go to the | ||
| 784 | * driver after probe is complete. This function should only be called | ||
| 785 | * by the thread calling probe or remove. | ||
| 786 | */ | ||
| 787 | static inline void hid_device_io_stop(struct hid_device *hid) { | ||
| 788 | if (!hid->io_started) { | ||
| 789 | dev_warn(&hid->dev, "io already stopped"); | ||
| 790 | return; | ||
| 791 | } | ||
| 792 | hid->io_started = false; | ||
| 793 | down(&hid->driver_input_lock); | ||
| 794 | } | ||
| 795 | |||
| 740 | /** | 796 | /** |
| 741 | * hid_map_usage - map usage input bits | 797 | * hid_map_usage - map usage input bits |
| 742 | * | 798 | * |
| @@ -883,6 +939,49 @@ static inline int hid_hw_power(struct hid_device *hdev, int level) · 140 unmodified lines | |||
| 883 | return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; | 939 | return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; |
| 884 | } | 940 | } |
| 885 | 941 | ||
| 942 | |||
| 943 | /** | ||
| 944 | * hid_hw_request - send report request to device | ||
| 945 | * | ||
| 946 | * @hdev: hid device | ||
| 947 | * @report: report to send | ||
| 948 | * @reqtype: hid request type | ||
| 949 | */ | ||
| 950 | static inline void hid_hw_request(struct hid_device *hdev, | ||
| 951 | struct hid_report *report, int reqtype) | ||
| 952 | { | ||
| 953 | if (hdev->ll_driver->request) | ||
| 954 | hdev->ll_driver->request(hdev, report, reqtype); | ||
| 955 | } | ||
| 956 | |||
| 957 | /** | ||
| 958 | * hid_hw_idle - send idle request to device | ||
| 959 | * | ||
| 960 | * @hdev: hid device | ||
| 961 | * @report: report to control | ||
| 962 | * @idle: idle state | ||
| 963 | * @reqtype: hid request type | ||
| 964 | */ | ||
| 965 | static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle, | ||
| 966 | int reqtype) | ||
| 967 | { | ||
| 968 | if (hdev->ll_driver->idle) | ||
| 969 | return hdev->ll_driver->idle(hdev, report, idle, reqtype); | ||
| 970 | |||
| 971 | return 0; | ||
| 972 | } | ||
| 973 | |||
| 974 | /** | ||
| 975 | * hid_hw_wait - wait for buffered io to complete | ||
| 976 | * | ||
| 977 | * @hdev: hid device | ||
| 978 | */ | ||
| 979 | static inline void hid_hw_wait(struct hid_device *hdev) | ||
| 980 | { | ||
| 981 | if (hdev->ll_driver->wait) | ||
| 982 | hdev->ll_driver->wait(hdev); | ||
| 983 | } | ||
| 984 | |||
| 886 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | 985 | int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
| 887 | int interrupt); | 986 | int interrupt); |
| 888 | 987 | ||
| @@ -17,10 +17,9 @@ · 16 unmodified lines | |||
| 17 | /* | 17 | /* |
| 18 | * Ugly hack to work around failing compilation on systems that don't | 18 | * Ugly hack to work around failing compilation on systems that don't |
| 19 | * yet populate new version of hidraw.h to userspace. | 19 | * yet populate new version of hidraw.h to userspace. |
| 20 | * | ||
| 21 | * If you need this, please have your distro update the kernel headers. | ||
| 22 | */ | 20 | */ |
| 23 | #ifndef HIDIOCSFEATURE | 21 | #ifndef HIDIOCSFEATURE |
| 22 | #warning Please have your distro update the userspace kernel headers | ||
| 24 | #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) | 23 | #define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len) |
| 25 | #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) | 24 | #define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len) |
| 26 | #endif | 25 | #endif |